#ifndef saxmsxml2H #define saxmsxml2H //--------------------------------------------------------------------------- // A SAX2 wrapper class for MSXML component. // // $Id$ //--------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include #import namespace SAX { /** * use this as COMInitializer_type if you call * CoInitialize/CoInitializeEx in your own code */ class COMExternalInitializer { public: COMExternalInitializer() { } ~COMExternalInitializer() { } }; // COMExternalInitializer class COMSingleThreadInitializer { public: COMSingleThreadInitializer() { ::CoInitialize(NULL); } ~COMSingleThreadInitializer() { ::CoUninitialize(); } }; // COMSingleThreadInitializer #if(_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM) class COMMultiThreadInitializer { public: COMMultiThreadInitializer() { ::CoInitializeEx(NULL, COINIT_MULTITHREADED); } ~COMMultiThreadInitializer() { ::CoUninitialize(); } }; #endif template > class msxml2_wrapper : public SAX::basic_XMLReader { public: typedef string_type stringT; typedef string_adaptor_type string_adaptorT; typedef SAX::basic_EntityResolver entityResolverT; typedef SAX::basic_DTDHandler dtdHandlerT; typedef SAX::basic_ContentHandler contentHandlerT; typedef SAX::basic_DeclHandler declHandlerT; typedef SAX::basic_LexicalHandler lexicalHandlerT; typedef SAX::basic_InputSource inputSourceT; typedef SAX::basic_Locator locatorT; typedef COMInitializer_type COMInitializerT; msxml2_wrapper(); virtual ~msxml2_wrapper(); ///////////////////////////////////////////////// // Configuration virtual bool getFeature(const stringT& name) const; virtual void setFeature(const stringT& name, bool value); ///////////////////////////////////////////////// // Event Handlers /* MSXML does not use EntityResolver currently */ virtual void setEntityResolver(SAX::basic_EntityResolver& resolver) { } virtual SAX::basic_EntityResolver* getEntityResolver() const { return 0; } virtual void setDTDHandler(SAX::basic_DTDHandler& handler) { dtdHandler_.setDTDHandler(handler); } virtual SAX::basic_DTDHandler* getDTDHandler() const { return dtdHandler_.getDTDHandler(); } virtual void setContentHandler(SAX::basic_ContentHandler& handler) { contentHandler_.setContentHandler(handler); } virtual SAX::basic_ContentHandler* getContentHandler() const { return contentHandler_.getContentHandler(); } virtual void setErrorHandler(SAX::ErrorHandler& handler); virtual SAX::ErrorHandler* getErrorHandler() const; ////////////////////////////////////////////////// // Parsing virtual void parse(SAX::basic_InputSource& input); protected: virtual std::auto_ptr::PropertyBase> doGetProperty(const stringT& name); virtual void doSetProperty(const stringT& name, std::auto_ptr::PropertyBase> value); private: ////////////////////////////////////////////////////// // COM interface -> C++ interface adaptors class LocatorAdaptor : public SAX::basic_Locator { public: LocatorAdaptor() : locator_(0) { } LocatorAdaptor(MSXML2::ISAXLocator __RPC_FAR* locator) : locator_(0) { setLocator(locator); } ~LocatorAdaptor() { setLocator(0); } stringT getPublicId() const { if(!locator_) return stringT(); unsigned short* pwchPublicId; locator_->raw_getPublicId(&pwchPublicId); stringT publicId(SA_.makeStringT(pwchPublicId)); return publicId; } // getPublicId stringT getSystemId() const { if(!locator_) return stringT(); unsigned short* pwchSystemId; locator_->raw_getSystemId(&pwchSystemId); stringT systemId(SA_.makeStringT(pwchSystemId)); return systemId; } // getSystemId int getLineNumber() const { if(!locator_) return -1; int lineNumber; locator_->raw_getLineNumber(&lineNumber); return lineNumber; } // getLineNumber int getColumnNumber() const { if(!locator_) return -1; int columnNumber; locator_->raw_getColumnNumber(&columnNumber); return columnNumber; } // getColumnNumber void setLocator(MSXML2::ISAXLocator __RPC_FAR* locator) { if(locator_) { locator_->Release(); locator_ = 0; } // if ... if(locator) { locator_ = locator; locator_->AddRef(); } // if ... } // setLocator private: MSXML2::ISAXLocator __RPC_FAR *locator_; string_adaptorT SA_; }; // class LocatorAdaptor class DTDHandlerAdaptor : public MSXML2::ISAXDTDHandler { public: DTDHandlerAdaptor() : dtdHandler_(0) { } ~DTDHandlerAdaptor() { } void setDTDHandler(SAX::basic_DTDHandler& handler) { dtdHandler_ = &handler; } SAX::basic_DTDHandler* getDTDHandler() const { return dtdHandler_; } virtual HRESULT __stdcall raw_notationDecl(unsigned short* pwchName, int cchName, unsigned short* pwchPublicId, int cchPublicId, unsigned short* pwchSystemId, int cchSystemId) { if(dtdHandler_) dtdHandler_->notationDecl(SA_.makeStringT(pwchName, cchName), SA_.makeStringT(pwchPublicId, cchPublicId), SA_.makeStringT(pwchSystemId, cchSystemId)); return S_OK; } // notationDecl virtual HRESULT __stdcall raw_unparsedEntityDecl(unsigned short* pwchName, int cchName, unsigned short* pwchPublicId, int cchPublicId, unsigned short* pwchSystemId, int cchSystemId, unsigned short* pwchNotationName, int cchNotationName) { if(dtdHandler_) dtdHandler_->unparsedEntityDecl(SA_.makeStringT(pwchName, cchName), SA_.makeStringT(pwchPublicId, cchPublicId), SA_.makeStringT(pwchSystemId, cchSystemId), SA_.makeStringT(pwchNotationName, cchNotationName)); return S_OK; } // unparsedEntityDecl // satify 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: SAX::basic_DTDHandler* dtdHandler_; string_adaptorT SA_; }; // class DTDHandlerAdaptor class ContentHandlerAdaptor : public MSXML2::ISAXContentHandler { public: ContentHandlerAdaptor() : contentHandler_(0) { } ~ContentHandlerAdaptor() { } void setContentHandler(SAX::basic_ContentHandler& handler) { contentHandler_ = &handler; } SAX::basic_ContentHandler* getContentHandler() const { return contentHandler_; } virtual HRESULT __stdcall raw_putDocumentLocator(MSXML2::ISAXLocator __RPC_FAR *pLocator) { locator_.setLocator(pLocator); if(contentHandler_) contentHandler_->setDocumentLocator(locator_); return S_OK; } // putDocumentLocation virtual HRESULT __stdcall raw_startDocument(void) { if(contentHandler_) contentHandler_->startDocument(); return S_OK; } // startDocument virtual HRESULT __stdcall raw_endDocument(void) { if(contentHandler_) contentHandler_->endDocument(); return S_OK; } // endDocument virtual HRESULT __stdcall raw_startPrefixMapping(wchar_t __RPC_FAR *pwchPrefix, int cchPrefix, wchar_t __RPC_FAR *pwchUri, int cchUri) { if(contentHandler_) contentHandler_->startPrefixMapping(SA_.makeStringT(pwchPrefix, cchPrefix), SA_.makeStringT(pwchUri, cchUri)); return S_OK; } // startPrefixMapping virtual HRESULT __stdcall raw_endPrefixMapping(wchar_t __RPC_FAR *pwchPrefix, int cchPrefix) { if(contentHandler_) contentHandler_->endPrefixMapping(SA_.makeStringT(pwchPrefix, cchPrefix)); return S_OK; } // endPrefixMapping virtual HRESULT __stdcall raw_startElement(wchar_t __RPC_FAR *pwchNamespaceUri, int cchNamespaceUri, wchar_t __RPC_FAR *pwchLocalName, int cchLocalName, wchar_t __RPC_FAR *pwchRawName, int cchRawName, MSXML2::ISAXAttributes __RPC_FAR *pAttributes) { if(contentHandler_) { AttributesAdaptor attrs(pAttributes); contentHandler_->startElement(SA_.makeStringT(pwchNamespaceUri, cchNamespaceUri), SA_.makeStringT(pwchLocalName, cchLocalName), SA_.makeStringT(pwchRawName, cchRawName), attrs); } // if ... return S_OK; } // startElement virtual HRESULT __stdcall raw_endElement(wchar_t __RPC_FAR *pwchNamespaceUri, int cchNamespaceUri, wchar_t __RPC_FAR *pwchLocalName, int cchLocalName, wchar_t __RPC_FAR *pwchRawName, int cchRawName) { if(contentHandler_) contentHandler_->endElement(SA_.makeStringT(pwchNamespaceUri, cchNamespaceUri), SA_.makeStringT(pwchLocalName, cchLocalName), SA_.makeStringT(pwchRawName, cchRawName)); return S_OK; } // endElement virtual HRESULT __stdcall raw_characters(wchar_t __RPC_FAR *pwchChars, int cchChars) { if(contentHandler_) contentHandler_->characters(SA_.makeStringT(pwchChars, cchChars)); return S_OK; } // characters virtual HRESULT __stdcall raw_ignorableWhitespace(wchar_t __RPC_FAR *pwchChars, int cchChars) { if(contentHandler_) contentHandler_->ignorableWhitespace(SA_.makeStringT(pwchChars, cchChars)); return S_OK; } // ignorableWhitespace virtual HRESULT __stdcall raw_processingInstruction(wchar_t __RPC_FAR *pwchTarget, int cchTarget, wchar_t __RPC_FAR *pwchData, int cchData) { if(contentHandler_) contentHandler_->processingInstruction(SA_.makeStringT(pwchTarget, cchTarget), SA_.makeStringT(pwchData, cchData)); return S_OK; } // processingInstruction virtual HRESULT __stdcall raw_skippedEntity(wchar_t __RPC_FAR *pwchName, int cchName) { if(contentHandler_) contentHandler_->skippedEntity(SA_.makeStringT(pwchName, cchName)); return S_OK; } // skippedEntity // 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: //////////////////////////////////////////////// // member varaibles SAX::basic_ContentHandler* contentHandler_; LocatorAdaptor locator_; string_adaptorT SA_; ////////////////////////////////////////////////////// // COM interface -> C++ interface adaptors class AttributesAdaptor : public SAX::basic_Attributes { public: AttributesAdaptor(MSXML2::ISAXAttributes __RPC_FAR *pAttributes) : attributes_(pAttributes) { } ~AttributesAdaptor() { } ///////////////////////// // indexed access virtual int getLength() const { int length; attributes_->raw_getLength(&length); return length; } // getLength virtual stringT getURI(unsigned int index) const { unsigned short* pwchUri; int cchUri; HRESULT hr = attributes_->raw_getURI(index, &pwchUri, &cchUri); if (FAILED(hr)) return stringT(); stringT uri(SA_.makeStringT(pwchUri, cchUri)); return uri; } // getURI virtual stringT getLocalName(unsigned int index) const { unsigned short* pwchLocalName; int cchLocalName; HRESULT hr = attributes_->raw_getLocalName(index, &pwchLocalName, &cchLocalName); if (FAILED(hr)) return stringT(); stringT localName(SA_.makeStringT(pwchLocalName, cchLocalName)); return localName; } // getLocalName virtual stringT getQName(unsigned int index) const { unsigned short* pwchQName; int cchQName; HRESULT hr = attributes_->raw_getQName(index, &pwchQName, &cchQName); if (FAILED(hr)) return stringT(); stringT qName(SA_.makeStringT(pwchQName, cchQName)); return qName; } // getQName virtual stringT getType(unsigned int index) const { unsigned short* pwchType; int cchType; HRESULT hr = attributes_->raw_getType(index, &pwchType, &cchType); if (FAILED(hr)) return stringT(); stringT type(SA_.makeStringT(pwchType, cchType)); return type; } // getType virtual stringT getValue(unsigned int index) const { unsigned short* pwchValue; int cchValue; HRESULT hr = attributes_->raw_getValue(index, &pwchValue, &cchValue); if (FAILED(hr)) return stringT(); stringT value(SA_.makeStringT(pwchValue, cchValue)); return value; } // getValue ///////////////////////// // name based query virtual int getIndex(const stringT& uri, const stringT& localName) const { int index = -1; std::wstring wUri(SA_.asStdWString(uri)); std::wstring wLocalName(SA_.asStdWString(localName)); HRESULT hr = attributes_->raw_getIndexFromName(const_cast(wUri.data()), wUri.length(), const_cast(wLocalName.data()), wLocalName.length(), &index); return index; } // getIndex virtual int getIndex(const stringT& qName) const { int index = -1; std::wstring wQName(SA_.asStdWString(qName)); attributes_->raw_getIndexFromQName(const_cast(wQName.data()), wQName.length(), &index); return index; } // getIndex virtual stringT getType(const stringT& uri, const stringT& localName) const { unsigned short* pwchType; int cchType; std::wstring wUri(SA_.asStdWString(uri)); std::wstring wLocalName(SA_.asStdWString(localName)); HRESULT hr = attributes_->raw_getTypeFromName(const_cast(wUri.data()), wUri.length(), const_cast(wLocalName.data()), wLocalName.length(), &pwchType, &cchType); if (FAILED(hr)) return stringT(); stringT type(SA_.makeStringT(pwchType, cchType)); return type; } // getType virtual stringT getType(const stringT& qName) const { unsigned short* pwchType; int cchType; std::wstring wQName(SA_.asStdWString(qName)); HRESULT hr = attributes_->raw_getTypeFromQName(const_cast(wQName.data()), wQName.length(), &pwchType, &cchType); if (FAILED(hr)) return stringT(); stringT type(SA_.makeStringT(pwchType, cchType)); return type; } // getType virtual stringT getValue(const stringT& uri, const stringT& localName) const { unsigned short* pwchValue; int cchValue; std::wstring wUri(SA_.asStdWString(uri)); std::wstring wLocalName(SA_.asStdWString(localName)); HRESULT hr = attributes_->raw_getValueFromName(const_cast(wUri.data()), wUri.length(), const_cast(wLocalName.data()), wLocalName.length(), &pwchValue, &cchValue); if (FAILED(hr)) return stringT(); stringT value(SA_.makeStringT(pwchValue, cchValue)); return value; } // getValue virtual stringT getValue(const stringT& qname) const { unsigned short* pwchValue; int cchValue; std::wstring wQName(SA_.asStdWString(qname)); HRESULT hr = attributes_->raw_getValueFromQName(const_cast(wQName.data()), wQName.length(), &pwchValue, &cchValue); if (FAILED(hr)) return stringT(); stringT value(SA_.makeStringT(pwchValue, cchValue)); return value; } // getValue private: MSXML2::ISAXAttributes __RPC_FAR *attributes_; string_adaptorT SA_; AttributesAdaptor(); }; // class AttributesAdaptor }; // class ContentHandlerAdaptor class ErrorHandlerAdaptor : public MSXML2::ISAXErrorHandler { public: ErrorHandlerAdaptor() : errorHandler_(0) { } virtual ~ErrorHandlerAdaptor() { } void setErrorHandler(SAX::ErrorHandler& handler) { errorHandler_ = &handler; } SAX::ErrorHandler* getErrorHandler() const { return errorHandler_; } virtual HRESULT __stdcall raw_error(struct MSXML2::ISAXLocator* pLocator, unsigned short * pwchErrorMessage, HRESULT hrErrorCode) { stringT errorMsg(SA_.makeStringT(pwchErrorMessage)); if(errorHandler_) errorHandler_->error(SAX::basic_SAXParseException(SA_.asStdString(errorMsg), LocatorAdaptor(pLocator))); return S_OK; } // error virtual HRESULT __stdcall raw_fatalError(struct MSXML2::ISAXLocator* pLocator, unsigned short * pwchErrorMessage, HRESULT hrErrorCode) { stringT errorMsg(SA_.makeStringT(pwchErrorMessage)); if(errorHandler_) errorHandler_->fatalError(SAX::basic_SAXParseException(SA_.asStdString(errorMsg), LocatorAdaptor(pLocator))); return S_OK; } // fatalError virtual HRESULT __stdcall raw_ignorableWarning(struct MSXML2::ISAXLocator* pLocator, unsigned short * pwchErrorMessage, HRESULT hrErrorCode) { stringT errorMsg(SA_.makeStringT(pwchErrorMessage)); if(errorHandler_) errorHandler_->warning(SAX::basic_SAXParseException(SA_.asStdString(errorMsg), LocatorAdaptor(pLocator))); return S_OK; } // ignorableWarning // 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: SAX::ErrorHandler* errorHandler_; string_adaptorT SA_; }; // class ErrorHandlerAdaptor class LexicalHandlerAdaptor : public MSXML2::ISAXLexicalHandler { public: LexicalHandlerAdaptor() : lexicalHandler_(0) { } virtual ~LexicalHandlerAdaptor() { } void setLexicalHandler(SAX::basic_LexicalHandler& handler) { lexicalHandler_ = &handler; } SAX::basic_LexicalHandler* getLexicalHandler() const { return lexicalHandler_; } virtual HRESULT __stdcall raw_startDTD(unsigned short* pwchName, int cchName, unsigned short* pwchPublicId, int cchPublicId, unsigned short* pwchSystemId, int cchSystemId) { if(lexicalHandler_) lexicalHandler_->startDTD(SA_.makeStringT(pwchName, cchName), SA_.makeStringT(pwchPublicId, cchPublicId), SA_.makeStringT(pwchSystemId, cchSystemId)); return S_OK; } // startDTD virtual HRESULT __stdcall raw_endDTD() { if(lexicalHandler_) lexicalHandler_->endDTD(); return S_OK; } // endDTD virtual HRESULT __stdcall raw_startEntity(unsigned short* pwchName, int cchName) { if(lexicalHandler_) lexicalHandler_->startEntity(SA_.makeStringT(pwchName, cchName)); return S_OK; } // startEntity virtual HRESULT __stdcall raw_endEntity(unsigned short* pwchName, int cchName) { if(lexicalHandler_) lexicalHandler_->endEntity(SA_.makeStringT(pwchName, cchName)); return S_OK; } // endEntity virtual HRESULT __stdcall raw_startCDATA() { if(lexicalHandler_) lexicalHandler_->startCDATA(); return S_OK; } // startCDATA virtual HRESULT __stdcall raw_endCDATA() { if(lexicalHandler_) lexicalHandler_->endCDATA(); return S_OK; } // endCDATA virtual HRESULT __stdcall raw_comment(unsigned short* pwchChars, int cchChars) { if(lexicalHandler_) lexicalHandler_->comment(SA_.makeStringT(pwchChars, cchChars)); return S_OK; } // comment // satisfy COM interface even if we're not a COM object long __stdcall QueryInterface(const struct _GUID &riid,void **ppvObject) { // we have to implement this, because we pass this as an IUnknown but it needs an // ISAXLexicalHandler interface if(riid == __uuidof(MSXML2::ISAXLexicalHandler)) *ppvObject = this; return 0; } // QueryInterface unsigned long __stdcall AddRef() { return 0; } unsigned long __stdcall Release() { return 0; } private: SAX::basic_LexicalHandler* lexicalHandler_; string_adaptorT SA_; }; // class LexicalHandlerAdaptor class DeclHandlerAdaptor : public MSXML2::ISAXDeclHandler { public: DeclHandlerAdaptor() : declHandler_(0) { } virtual ~DeclHandlerAdaptor() { } void setDeclHandler(SAX::basic_DeclHandler& handler) { declHandler_ = &handler; } SAX::basic_DeclHandler* getDeclHandler() const { return declHandler_; } virtual HRESULT __stdcall raw_elementDecl(unsigned short* pwchName, int cchName, unsigned short* pwchModel, int cchModel) { if(declHandler_) declHandler_->elementDecl(SA_.makeStringT(pwchName, cchName), SA_.makeStringT(pwchModel, cchModel)); return S_OK; } // elementDecl virtual HRESULT __stdcall raw_attributeDecl(unsigned short* pwchElementName, int cchElementName, unsigned short* pwchAttributeName, int cchAttributeName, unsigned short* pwchType, int cchType, unsigned short* pwchValueDefault, int cchValueDefault, unsigned short* pwchValue, int cchValue) { if(declHandler_) declHandler_->attributeDecl(SA_.makeStringT(pwchElementName, cchElementName), SA_.makeStringT(pwchAttributeName, cchAttributeName), SA_.makeStringT(pwchType, cchType), SA_.makeStringT(pwchValueDefault, cchValueDefault), SA_.makeStringT(pwchValue, cchValue)); return S_OK; } // attributeDecl virtual HRESULT __stdcall raw_internalEntityDecl(unsigned short* pwchName, int cchName, unsigned short* pwchValue, int cchValue) { if(declHandler_) declHandler_->internalEntityDecl(SA_.makeStringT(pwchName, cchName), SA_.makeStringT(pwchValue, cchValue)); return S_OK; } // internalEntityDecl virtual HRESULT __stdcall raw_externalEntityDecl(unsigned short* pwchName, int cchName, unsigned short* pwchPublicId, int cchPublicId, unsigned short* pwchSystemId, int cchSystemId) { if(declHandler_) declHandler_->externalEntityDecl(SA_.makeStringT(pwchName, cchName), SA_.makeStringT(pwchPublicId, cchPublicId), SA_.makeStringT(pwchSystemId, cchSystemId)); return S_OK; } // externalEntityDecl // satisfy COM interface even if we're not a COM object long __stdcall QueryInterface(const struct _GUID &riid,void **ppvObject) { // we have to implement this, because we pass this as an IUnknown but it needs an // ISAXDeclHandler interface if(riid == __uuidof(MSXML2::ISAXDeclHandler)) *ppvObject = reinterpret_cast(this); return 0; } // QueryInterface unsigned long __stdcall AddRef() { return 0; } unsigned long __stdcall Release() { return 0; } private: SAX::basic_DeclHandler* declHandler_; string_adaptorT SA_; }; // class DeclHandlerAdaptor class StreamAdaptor : public IStream { public: StreamAdaptor(SAX::basic_InputSource& source) : source_(source) { } // StreamAdaptor virtual HRESULT __stdcall Read(void* pv, ULONG cb, ULONG* pcbRead) { source_.getByteStream()->read(reinterpret_cast(pv), cb); *pcbRead = source_.getByteStream()->gcount(); return S_OK; } // Read // stub implementations of everything else virtual HRESULT __stdcall Write(const void* pv, ULONG cb, ULONG* pcbWritten) { return S_FALSE; } // Write virtual HRESULT __stdcall Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) { return S_FALSE; } // Seek virtual HRESULT __stdcall SetSize(ULARGE_INTEGER libNewSize) { return S_FALSE; } // SetSize virtual HRESULT __stdcall CopyTo(IStream* pstm, ULARGE_INTEGER db, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten) { return S_FALSE; } // CopyTo virtual HRESULT __stdcall Commit(DWORD grfCommitFlags) { return S_FALSE; } // Commit virtual HRESULT __stdcall Revert() { return S_FALSE; } // Revert virtual HRESULT __stdcall LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { return S_FALSE; } // LockRegion virtual HRESULT __stdcall UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER db, DWORD dwLockType) { return S_FALSE; } // UnlockRegion virtual HRESULT __stdcall Stat(STATSTG* pstatstg, DWORD grfStatFlag) { return S_FALSE; } // Stat virtual HRESULT __stdcall Clone(IStream** ppstm) { return S_FALSE; } // Clone // satisfy COM interface even if we're not a COM object long __stdcall QueryInterface(const struct _GUID &riid,void **ppvObject) { // we have to implement this, because we pass this as an IUnknown but it needs an // IStream interface if(riid == __uuidof(IStream)) *ppvObject = reinterpret_cast(this); return 0; } // QueryInterface unsigned long __stdcall AddRef() { return 0; } unsigned long __stdcall Release() { return 0; } private: SAX::basic_InputSource& source_; }; // StreamAdaptor ////////////////////////////////////////////////////// // member variables COMInitializer_type init; DTDHandlerAdaptor dtdHandler_; ContentHandlerAdaptor contentHandler_; ErrorHandlerAdaptor errorHandler_; LexicalHandlerAdaptor lexicalHandler_; DeclHandlerAdaptor declHandler_; MSXML2::ISAXXMLReaderPtr reader_; string_adaptorT SA_; SAX::PropertyNames properties_; }; // class msxml template msxml2_wrapper::msxml2_wrapper() { reader_.CreateInstance(__uuidof(MSXML2::SAXXMLReader)); reader_->putContentHandler(&contentHandler_); reader_->putErrorHandler(&errorHandler_); reader_->putDTDHandler(&dtdHandler_); VARIANT wrapper; wrapper.vt = VT_UNKNOWN; wrapper.punkVal = static_cast(&lexicalHandler_); reader_->putProperty(L"http://xml.org/sax/properties/lexical-handler", wrapper); wrapper.punkVal = static_cast(&declHandler_); reader_->putProperty(L"http://xml.org/sax/properties/declaration-handler", wrapper); } // msxml2_wrapper template msxml2_wrapper::~msxml2_wrapper() { } // ~msxml template bool msxml2_wrapper::getFeature(const stringT& name) const { VARIANT_BOOL feature; std::wstring wName(SA_.asStdWString(name)); reader_->raw_getFeature(const_cast(wName.c_str()), &feature); return (feature == VARIANT_TRUE) ? true : false; } // getFeature template void msxml2_wrapper::setFeature(const stringT& name, bool value) { std::wstring wName(SA_.asStdWString(name)); reader_->raw_putFeature(const_cast(wName.c_str()), value); } // setFeature template void msxml2_wrapper::setErrorHandler(SAX::ErrorHandler& handler) { errorHandler_.setErrorHandler(handler); } // setErrorHandler template SAX::ErrorHandler* msxml2_wrapper::getErrorHandler() const { return errorHandler_.getErrorHandler(); } // getErrorHandler template std::auto_ptr::PropertyBase> msxml2_wrapper::doGetProperty(const stringT& name) { if(name == properties_.lexicalHandler) { Property*>* prop = new Property*>(lexicalHandler_.getLexicalHandler()); return std::auto_ptr::PropertyBase>(prop); } if(name == properties_.declHandler) { Property*>* prop = new Property*>(declHandler_.getDeclHandler()); return std::auto_ptr::PropertyBase>(prop); } throw SAX::SAXNotRecognizedException("Property not recognized "); } // doGetProperty template void msxml2_wrapper::doSetProperty(const stringT& name, std::auto_ptr::PropertyBase> value) { if(name == properties_.lexicalHandler) { Property&>* prop = dynamic_cast&>*>(value.get()); if(!prop) throw std::bad_cast("Property LexicalHandler is wrong type, should be SAX::LexicalHandler&"); lexicalHandler_.setLexicalHandler(prop->get()); return; } // if ... if(name == properties_.declHandler) { Property&>* prop = dynamic_cast&>*>(value.get()); if(!prop) throw std::bad_cast("Property DeclHandler is wrong type, should be SAX::DeclHandler&"); declHandler_.setDeclHandler(prop->get()); return; } // if ... throw SAX::SAXNotRecognizedException("Property not recognized "); } // doSetProperty template void msxml2_wrapper::parse(SAX::basic_InputSource& source) { if(source.getByteStream() == 0) { std::wstring wSysId(SA_.asStdWString(source.getSystemId())); reader_->raw_parseURL(const_cast(wSysId.c_str())); } else { StreamAdaptor sa(source); VARIANT wrapper; wrapper.vt = VT_UNKNOWN; wrapper.punkVal = static_cast(&sa); reader_->raw_parse(wrapper); } // if ... } // parse } // namespace SAX #endif // end of file