Imported Upstream version 2.35.2
[platform/upstream/libxml++.git] / libxml++ / validators / validator.cc
1 /* xml++.cc
2  * libxml++ and this file are copyright (C) 2000 by Ari Johnson
3  * (C) 2002-2004 by the libxml dev team and
4  * are covered by the GNU Lesser General Public License, which should be
5  * included with libxml++ as the file COPYING.
6  */
7
8 #include "libxml++/validators/validator.h"
9
10 #include <libxml/parser.h>
11
12 #include <cstdarg> //For va_list.
13 #include <memory> //For auto_ptr.
14
15 namespace xmlpp {
16
17 Validator::Validator()
18 : valid_(0), exception_(0)
19 {
20 }
21
22 Validator::~Validator()
23 {
24   release_underlying();
25 }
26
27 void Validator::initialize_valid()
28 {
29   //Tell the validity valid about the callbacks:
30   //(These are only called if validation is on - see above)
31   valid_->error = &callback_validity_error;
32   valid_->warning = &callback_validity_warning;
33
34   //Allow the callback_validity_*() methods to retrieve the C++ instance:
35   valid_->userData = this;
36
37   //Clear these temporary buffers too:
38   validate_error_.erase();
39   validate_warning_.erase();
40 }
41
42 void Validator::release_underlying()
43 {
44   if(valid_)
45   {
46     valid_->userData = 0; //Not really necessary.
47
48     xmlFreeValidCtxt(valid_);
49     valid_ = 0;
50   }
51 }
52
53 void Validator::on_validity_error(const Glib::ustring& message)
54 {
55   //Throw an exception later when the whole message has been received:
56   validate_error_ += message;
57 }
58
59 void Validator::on_validity_warning(const Glib::ustring& message)
60 {
61   //Throw an exception later when the whole message has been received:
62   validate_warning_ += message;
63 }
64
65 void Validator::check_for_validity_messages()
66 {
67   if(!validate_error_.empty())
68   {
69     if(!exception_)
70       exception_ = new validity_error("Validity error:\n" + validate_error_);
71
72     validate_error_.erase();
73   }
74
75   if(!validate_warning_.empty())
76   {
77     if(!exception_)
78       exception_ = new validity_error("Validity warning:\n" + validate_warning_);
79
80     validate_warning_.erase();
81   }
82 }
83
84 void Validator::callback_validity_error(void* valid_, const char* msg, ...)
85 {
86   Validator* validator = static_cast<Validator*>(valid_);
87
88   if(validator)
89   {
90     //Convert the ... to a string:
91     va_list arg;
92     char buff[1024]; //TODO: Larger/Shared
93
94     va_start(arg, msg);
95     vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), msg, arg);
96     va_end(arg);
97
98     try
99     {
100       validator->on_validity_error(Glib::ustring(buff));
101     }
102     catch(const exception& e)
103     {
104       validator->handleException(e);
105     }
106   }
107 }
108
109 void Validator::callback_validity_warning(void* valid_, const char* msg, ...)
110 {
111   Validator* validator = static_cast<Validator*>(valid_);
112
113   if(validator)
114   {
115     //Convert the ... to a string:
116     va_list arg;
117     char buff[1024]; //TODO: Larger/Shared
118
119     va_start(arg, msg);
120     vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), msg, arg);
121     va_end(arg);
122
123     try
124     {
125       validator->on_validity_warning(Glib::ustring(buff));
126     }
127     catch(const exception& e)
128     {
129       validator->handleException(e);
130     }
131   }
132 }
133
134 void Validator::handleException(const exception& e)
135 {
136   exception_ = e.Clone();
137
138   release_underlying();
139 }
140
141 void Validator::check_for_exception()
142 {
143   check_for_validity_messages();
144
145   if(exception_)
146   {
147     std::auto_ptr<exception> tmp(exception_);
148     exception_ = 0;
149     tmp->Raise();
150   }
151 }
152
153 } // namespace xmlpp
154
155