#include <libxml/parser.h>
#include <cstdarg> //For va_list.
-#include <memory> //For auto_ptr.
+#include <memory> //For unique_ptr.
namespace xmlpp {
Validator::Validator()
-: valid_(0), exception_(0)
+: exception_ptr_(nullptr)
{
}
release_underlying();
}
-void Validator::initialize_valid()
+void Validator::initialize_context()
{
- // valid_ is used only by DtdValidator.
- //TODO: When we can break ABI, move valid_ to DtdValidator.
- if (valid_)
- {
- //Tell the validation context about the callbacks:
- valid_->error = &callback_validity_error;
- valid_->warning = &callback_validity_warning;
-
- //Allow the callback_validity_*() methods to retrieve the C++ instance:
- valid_->userData = this;
- }
-
- //Clear these temporary buffers too:
+ //Clear these temporary buffers:
validate_error_.erase();
validate_warning_.erase();
}
void Validator::release_underlying()
{
- if(valid_)
- {
- valid_->userData = 0; //Not really necessary.
-
- xmlFreeValidCtxt(valid_);
- valid_ = 0;
- }
}
void Validator::on_validity_error(const Glib::ustring& message)
void Validator::check_for_validity_messages()
{
- Glib::ustring msg(exception_ ? exception_->what() : "");
+ Glib::ustring msg;
+ try
+ {
+ if (exception_ptr_)
+ std::rethrow_exception(exception_ptr_);
+ }
+ catch (const std::exception& e)
+ {
+ msg = e.what();
+ }
+ catch (...)
+ {
+ msg = "Unknown exception\n";
+ }
bool validity_msg = false;
if (!validate_error_.empty())
validate_warning_.erase();
}
- if (validity_msg)
+ try
+ {
+ if (validity_msg)
+ throw validity_error(msg);
+ }
+ catch (...)
{
- delete exception_;
- exception_ = new validity_error(msg);
+ exception_ptr_ = std::current_exception();
}
}
void Validator::callback_validity_error(void* valid_, const char* msg, ...)
{
- Validator* validator = static_cast<Validator*>(valid_);
+ auto validator = static_cast<Validator*>(valid_);
if(validator)
{
{
validator->on_validity_error(Glib::ustring(buff));
}
- catch(const exception& e)
+ catch (...)
{
- validator->handleException(e);
+ validator->handle_exception();
}
}
}
void Validator::callback_validity_warning(void* valid_, const char* msg, ...)
{
- Validator* validator = static_cast<Validator*>(valid_);
+ auto validator = static_cast<Validator*>(valid_);
if(validator)
{
{
validator->on_validity_warning(Glib::ustring(buff));
}
- catch(const exception& e)
+ catch (...)
{
- validator->handleException(e);
+ validator->handle_exception();
}
}
}
-void Validator::handleException(const exception& e)
+void Validator::handle_exception()
{
- delete exception_;
- exception_ = e.Clone();
+ exception_ptr_ = std::current_exception();
// Don't delete the DTD validation context or schema validation context
// while validating. It would cause accesses to deallocated memory in libxml2
// functions after the return from Validator::callback_validity_...().
- // Parser::handleException() calls xmlStopParser(), but there is no
+ // Parser::handle_exception() calls xmlStopParser(), but there is no
// xmlStopValidator() or similar function to call here.
// We don't throw the exception here, since it would have to pass through
// C functions. That's not guaranteed to work. It might work, but it depends
void Validator::check_for_exception()
{
check_for_validity_messages();
-
- if(exception_)
+
+ if (exception_ptr_)
{
- std::auto_ptr<exception> tmp(exception_);
- exception_ = 0;
- tmp->Raise();
+ std::exception_ptr tmp(exception_ptr_);
+ exception_ptr_ = nullptr;
+ std::rethrow_exception(tmp);
}
}