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 unique_ptr.
17 Validator::Validator()
18 : exception_ptr_(nullptr)
22 Validator::~Validator()
27 void Validator::initialize_context()
29 //Clear these temporary buffers:
30 validate_error_.erase();
31 validate_warning_.erase();
34 void Validator::release_underlying()
38 void Validator::on_validity_error(const Glib::ustring& message)
40 //Throw an exception later when the whole message has been received:
41 validate_error_ += message;
44 void Validator::on_validity_warning(const Glib::ustring& message)
46 //Throw an exception later when the whole message has been received:
47 validate_warning_ += message;
50 void Validator::check_for_validity_messages()
56 std::rethrow_exception(exception_ptr_);
58 catch (const std::exception& e)
64 msg = "Unknown exception\n";
66 bool validity_msg = false;
68 if (!validate_error_.empty())
71 msg += "\nValidity error:\n" + validate_error_;
72 validate_error_.erase();
75 if (!validate_warning_.empty())
78 msg += "\nValidity warning:\n" + validate_warning_;
79 validate_warning_.erase();
85 throw validity_error(msg);
89 exception_ptr_ = std::current_exception();
93 void Validator::callback_validity_error(void* valid_, const char* msg, ...)
95 auto validator = static_cast<Validator*>(valid_);
99 //Convert the ... to a string:
101 char buff[1024]; //TODO: Larger/Shared
104 vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), msg, arg);
109 validator->on_validity_error(Glib::ustring(buff));
113 validator->handle_exception();
118 void Validator::callback_validity_warning(void* valid_, const char* msg, ...)
120 auto validator = static_cast<Validator*>(valid_);
124 //Convert the ... to a string:
126 char buff[1024]; //TODO: Larger/Shared
129 vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), msg, arg);
134 validator->on_validity_warning(Glib::ustring(buff));
138 validator->handle_exception();
143 void Validator::handle_exception()
145 exception_ptr_ = std::current_exception();
147 // Don't delete the DTD validation context or schema validation context
148 // while validating. It would cause accesses to deallocated memory in libxml2
149 // functions after the return from Validator::callback_validity_...().
150 // Parser::handle_exception() calls xmlStopParser(), but there is no
151 // xmlStopValidator() or similar function to call here.
152 // We don't throw the exception here, since it would have to pass through
153 // C functions. That's not guaranteed to work. It might work, but it depends
154 // on the C compiler and the options used when building libxml2.
156 //release_underlying();
159 void Validator::check_for_exception()
161 check_for_validity_messages();
165 std::exception_ptr tmp(exception_ptr_);
166 exception_ptr_ = nullptr;
167 std::rethrow_exception(tmp);