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.
8 #include "libxml++/validators/validator.h"
10 #include <libxml/parser.h>
12 #include <cstdarg> //For va_list.
13 #include <memory> //For auto_ptr.
17 Validator::Validator()
18 : valid_(nullptr), exception_(nullptr)
22 Validator::~Validator()
27 void Validator::initialize_valid()
29 // valid_ is used only by DtdValidator.
30 //TODO: When we can break ABI, move valid_ to DtdValidator.
33 //Tell the validation context about the callbacks:
34 valid_->error = &callback_validity_error;
35 valid_->warning = &callback_validity_warning;
37 //Allow the callback_validity_*() methods to retrieve the C++ instance:
38 valid_->userData = this;
41 //Clear these temporary buffers too:
42 validate_error_.erase();
43 validate_warning_.erase();
46 void Validator::release_underlying()
50 valid_->userData = nullptr; //Not really necessary.
52 xmlFreeValidCtxt(valid_);
57 void Validator::on_validity_error(const Glib::ustring& message)
59 //Throw an exception later when the whole message has been received:
60 validate_error_ += message;
63 void Validator::on_validity_warning(const Glib::ustring& message)
65 //Throw an exception later when the whole message has been received:
66 validate_warning_ += message;
69 void Validator::check_for_validity_messages()
71 Glib::ustring msg(exception_ ? exception_->what() : "");
72 bool validity_msg = false;
74 if (!validate_error_.empty())
77 msg += "\nValidity error:\n" + validate_error_;
78 validate_error_.erase();
81 if (!validate_warning_.empty())
84 msg += "\nValidity warning:\n" + validate_warning_;
85 validate_warning_.erase();
91 exception_ = new validity_error(msg);
95 void Validator::callback_validity_error(void* valid_, const char* msg, ...)
97 auto validator = static_cast<Validator*>(valid_);
101 //Convert the ... to a string:
103 char buff[1024]; //TODO: Larger/Shared
106 vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), msg, arg);
111 validator->on_validity_error(Glib::ustring(buff));
113 catch(const exception& e)
115 validator->handleException(e);
120 void Validator::callback_validity_warning(void* valid_, const char* msg, ...)
122 auto validator = static_cast<Validator*>(valid_);
126 //Convert the ... to a string:
128 char buff[1024]; //TODO: Larger/Shared
131 vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), msg, arg);
136 validator->on_validity_warning(Glib::ustring(buff));
138 catch(const exception& e)
140 validator->handleException(e);
145 void Validator::handleException(const exception& e)
148 exception_ = e.Clone();
150 // Don't delete the DTD validation context or schema validation context
151 // while validating. It would cause accesses to deallocated memory in libxml2
152 // functions after the return from Validator::callback_validity_...().
153 // Parser::handleException() calls xmlStopParser(), but there is no
154 // xmlStopValidator() or similar function to call here.
155 // We don't throw the exception here, since it would have to pass through
156 // C functions. That's not guaranteed to work. It might work, but it depends
157 // on the C compiler and the options used when building libxml2.
159 //release_underlying();
162 void Validator::check_for_exception()
164 check_for_validity_messages();
168 std::auto_ptr<exception> tmp(exception_);
169 exception_ = nullptr;