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++/exceptions/wrapped_exception.h"
9 #include "libxml++/validators/validator.h"
11 #include <libxml/parser.h>
13 #include <cstdarg> //For va_list.
14 #include <memory> //For unique_ptr.
18 Validator::Validator()
23 Validator::~Validator()
28 void Validator::initialize_context()
30 //Clear these temporary buffers:
31 validate_error_.erase();
32 validate_warning_.erase();
35 void Validator::release_underlying()
39 void Validator::on_validity_error(const Glib::ustring& message)
41 //Throw an exception later when the whole message has been received:
42 validate_error_ += message;
45 void Validator::on_validity_warning(const Glib::ustring& message)
47 //Throw an exception later when the whole message has been received:
48 validate_warning_ += message;
51 void Validator::check_for_validity_messages()
53 Glib::ustring msg(exception_ ? exception_->what() : "");
54 bool validity_msg = false;
56 if (!validate_error_.empty())
59 msg += "\nValidity error:\n" + validate_error_;
60 validate_error_.erase();
63 if (!validate_warning_.empty())
66 msg += "\nValidity warning:\n" + validate_warning_;
67 validate_warning_.erase();
71 exception_.reset(new validity_error(msg));
74 void Validator::callback_validity_error(void* valid_, const char* msg, ...)
76 auto validator = static_cast<Validator*>(valid_);
80 //Convert the ... to a string:
83 const Glib::ustring buff = format_printf_message(msg, arg);
88 validator->on_validity_error(buff);
92 validator->handle_exception();
97 void Validator::callback_validity_warning(void* valid_, const char* msg, ...)
99 auto validator = static_cast<Validator*>(valid_);
103 //Convert the ... to a string:
106 const Glib::ustring buff = format_printf_message(msg, arg);
111 validator->on_validity_warning(buff);
115 validator->handle_exception();
120 void Validator::handle_exception()
124 throw; // Re-throw current exception
126 catch (const exception& e)
128 exception_.reset(e.clone());
130 #ifdef LIBXMLXX_HAVE_EXCEPTION_PTR
133 exception_.reset(new wrapped_exception(std::current_exception()));
136 catch (const std::exception& e)
138 exception_.reset(new exception(e.what()));
142 exception_.reset(new exception("An exception was thrown that is not derived from std::exception or xmlpp::exception.\n"
143 "It could not be caught and rethrown because this platform does not support std::exception_ptr."));
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::unique_ptr<exception> tmp(std::move(exception_));