From 5a339ca6134b29c933decb3fb97f3b98e78893c4 Mon Sep 17 00:00:00 2001 From: jez_higgins <> Date: Tue, 24 Feb 2004 09:52:18 +0000 Subject: [PATCH] ErrorHandler callbacks should be able to thrown exceptions. However, exceptions cannot propagate through the COM boundary. ErrorHandlerAdaptor now caches reported errors until the parse has completed, then reports them to ErrorHandler afterwards. This ensures that throw exceptions propogate as expected. --- SAX/wrappers/saxmsxml2.h | 47 +++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/SAX/wrappers/saxmsxml2.h b/SAX/wrappers/saxmsxml2.h index 4b1b08fc..94b9273d 100644 --- a/SAX/wrappers/saxmsxml2.h +++ b/SAX/wrappers/saxmsxml2.h @@ -543,7 +543,10 @@ class msxml2_wrapper : public SAX::basic_XMLReader class ErrorHandlerAdaptor : public ISAXErrorHandler { public: - ErrorHandlerAdaptor() : errorHandler_(0) { } + ErrorHandlerAdaptor() : errorHandler_(0), + bWarning_(false), bError_(false), bFatal_(false), + eWarning_("none"), eError_("none"), eFatal_("none") + { } virtual ~ErrorHandlerAdaptor() { } void setErrorHandler(SAX::basic_ErrorHandler& handler) { errorHandler_ = &handler; } @@ -554,9 +557,9 @@ class msxml2_wrapper : public SAX::basic_XMLReader /* [in] */ const wchar_t *pwchErrorMessage, /* [in] */ HRESULT hrErrorCode) { + bError_ = true; stringT errorMsg(SA_.makeStringT(pwchErrorMessage)); - if(errorHandler_) - errorHandler_->error(SAX::basic_SAXParseException(SA_.asStdString(errorMsg), LocatorAdaptor(pLocator))); + eError_ = SAXParseExceptionT(SA_.asStdString(errorMsg), LocatorAdaptor(pLocator)); return S_OK; } // error @@ -565,10 +568,10 @@ class msxml2_wrapper : public SAX::basic_XMLReader /* [in] */ const wchar_t *pwchErrorMessage, /* [in] */ HRESULT hrErrorCode) { + bFatal_ = true; stringT errorMsg(SA_.makeStringT(pwchErrorMessage)); - if(errorHandler_) - errorHandler_->fatalError(SAX::basic_SAXParseException(SA_.asStdString(errorMsg), LocatorAdaptor(pLocator))); - return S_OK; + eFatal_ = SAXParseExceptionT(SA_.asStdString(errorMsg), LocatorAdaptor(pLocator)); + return S_FALSE; } // fatalError virtual HRESULT STDMETHODCALLTYPE ignorableWarning( @@ -576,18 +579,45 @@ class msxml2_wrapper : public SAX::basic_XMLReader /* [in] */ const wchar_t *pwchErrorMessage, /* [in] */ HRESULT hrErrorCode) { + bWarning_ = true; stringT errorMsg(SA_.makeStringT(pwchErrorMessage)); - if(errorHandler_) - errorHandler_->warning(SAX::basic_SAXParseException(SA_.asStdString(errorMsg), LocatorAdaptor(pLocator))); + eWarning_ = SAXParseExceptionT(SA_.asStdString(errorMsg), LocatorAdaptor(pLocator)); return S_OK; } // ignorableWarning + void report() + { + if(!errorHandler_) + return; + + bool bWarning = bWarning_; + bool bError = bError_; + bool bFatal = bFatal_; + + bWarning_ = bError_ = bFatal_ = false; + + if(bFatal) + errorHandler_->fatalError(eFatal_); + if(bError) + errorHandler_->error(eError_); + if(bWarning) + errorHandler_->warning(eWarning_); + } // report + // satisfy COM interface even if we're not a COM object long __stdcall QueryInterface(const struct _GUID &riid,void **ppvObject) { return 0; } unsigned long __stdcall AddRef() { return 0; } unsigned long __stdcall Release() { return 0; } private: + typedef SAX::basic_SAXParseException SAXParseExceptionT; + bool bWarning_; + bool bError_; + bool bFatal_; + SAXParseExceptionT eWarning_; + SAXParseExceptionT eError_; + SAXParseExceptionT eFatal_; + SAX::basic_ErrorHandler* errorHandler_; string_adaptorT SA_; }; // class ErrorHandlerAdaptor @@ -948,6 +978,7 @@ void msxml2_wrapper::parse(SAX::basic wrapper.punkVal = static_cast(&sa); reader_->parse(wrapper); } // if ... + errorHandler_.report(); } // parse } // namespace SAX