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.
This commit is contained in:
jez_higgins 2004-02-24 09:52:18 +00:00
parent 9bff72c42a
commit 5a339ca613

View file

@ -543,7 +543,10 @@ class msxml2_wrapper : public SAX::basic_XMLReader<string_type>
class ErrorHandlerAdaptor : public ISAXErrorHandler class ErrorHandlerAdaptor : public ISAXErrorHandler
{ {
public: public:
ErrorHandlerAdaptor() : errorHandler_(0) { } ErrorHandlerAdaptor() : errorHandler_(0),
bWarning_(false), bError_(false), bFatal_(false),
eWarning_("none"), eError_("none"), eFatal_("none")
{ }
virtual ~ErrorHandlerAdaptor() { } virtual ~ErrorHandlerAdaptor() { }
void setErrorHandler(SAX::basic_ErrorHandler<stringT>& handler) { errorHandler_ = &handler; } void setErrorHandler(SAX::basic_ErrorHandler<stringT>& handler) { errorHandler_ = &handler; }
@ -554,9 +557,9 @@ class msxml2_wrapper : public SAX::basic_XMLReader<string_type>
/* [in] */ const wchar_t *pwchErrorMessage, /* [in] */ const wchar_t *pwchErrorMessage,
/* [in] */ HRESULT hrErrorCode) /* [in] */ HRESULT hrErrorCode)
{ {
bError_ = true;
stringT errorMsg(SA_.makeStringT(pwchErrorMessage)); stringT errorMsg(SA_.makeStringT(pwchErrorMessage));
if(errorHandler_) eError_ = SAXParseExceptionT(SA_.asStdString(errorMsg), LocatorAdaptor(pLocator));
errorHandler_->error(SAX::basic_SAXParseException<stringT>(SA_.asStdString(errorMsg), LocatorAdaptor(pLocator)));
return S_OK; return S_OK;
} // error } // error
@ -565,10 +568,10 @@ class msxml2_wrapper : public SAX::basic_XMLReader<string_type>
/* [in] */ const wchar_t *pwchErrorMessage, /* [in] */ const wchar_t *pwchErrorMessage,
/* [in] */ HRESULT hrErrorCode) /* [in] */ HRESULT hrErrorCode)
{ {
bFatal_ = true;
stringT errorMsg(SA_.makeStringT(pwchErrorMessage)); stringT errorMsg(SA_.makeStringT(pwchErrorMessage));
if(errorHandler_) eFatal_ = SAXParseExceptionT(SA_.asStdString(errorMsg), LocatorAdaptor(pLocator));
errorHandler_->fatalError(SAX::basic_SAXParseException<stringT>(SA_.asStdString(errorMsg), LocatorAdaptor(pLocator))); return S_FALSE;
return S_OK;
} // fatalError } // fatalError
virtual HRESULT STDMETHODCALLTYPE ignorableWarning( virtual HRESULT STDMETHODCALLTYPE ignorableWarning(
@ -576,18 +579,45 @@ class msxml2_wrapper : public SAX::basic_XMLReader<string_type>
/* [in] */ const wchar_t *pwchErrorMessage, /* [in] */ const wchar_t *pwchErrorMessage,
/* [in] */ HRESULT hrErrorCode) /* [in] */ HRESULT hrErrorCode)
{ {
bWarning_ = true;
stringT errorMsg(SA_.makeStringT(pwchErrorMessage)); stringT errorMsg(SA_.makeStringT(pwchErrorMessage));
if(errorHandler_) eWarning_ = SAXParseExceptionT(SA_.asStdString(errorMsg), LocatorAdaptor(pLocator));
errorHandler_->warning(SAX::basic_SAXParseException<stringT>(SA_.asStdString(errorMsg), LocatorAdaptor(pLocator)));
return S_OK; return S_OK;
} // ignorableWarning } // 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 // satisfy COM interface even if we're not a COM object
long __stdcall QueryInterface(const struct _GUID &riid,void **ppvObject) { return 0; } long __stdcall QueryInterface(const struct _GUID &riid,void **ppvObject) { return 0; }
unsigned long __stdcall AddRef() { return 0; } unsigned long __stdcall AddRef() { return 0; }
unsigned long __stdcall Release() { return 0; } unsigned long __stdcall Release() { return 0; }
private: private:
typedef SAX::basic_SAXParseException<stringT> SAXParseExceptionT;
bool bWarning_;
bool bError_;
bool bFatal_;
SAXParseExceptionT eWarning_;
SAXParseExceptionT eError_;
SAXParseExceptionT eFatal_;
SAX::basic_ErrorHandler<stringT>* errorHandler_; SAX::basic_ErrorHandler<stringT>* errorHandler_;
string_adaptorT SA_; string_adaptorT SA_;
}; // class ErrorHandlerAdaptor }; // class ErrorHandlerAdaptor
@ -948,6 +978,7 @@ void msxml2_wrapper<stringT, COMInitializerT, string_adaptorT>::parse(SAX::basic
wrapper.punkVal = static_cast<ISequentialStream*>(&sa); wrapper.punkVal = static_cast<ISequentialStream*>(&sa);
reader_->parse(wrapper); reader_->parse(wrapper);
} // if ... } // if ...
errorHandler_.report();
} // parse } // parse
} // namespace SAX } // namespace SAX