#ifndef saxxercesH #define saxxercesH //--------------------------------------------------------------------------- // A SAX2 wrapper class for Xerces. // // $Id$ //--------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include // Xerces Includes #include #include #include #include #include #include #include #include #include #include #include namespace SAX { template > class xerces_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_LexicalHandler lexicalHandlerT; typedef SAX::basic_DeclHandler declHandlerT; typedef SAX::basic_InputSource inputSourceT; typedef SAX::basic_Locator locatorT; xerces_wrapper(); virtual ~xerces_wrapper(); ///////////////////////////////////////////////// // Configuration virtual bool getFeature(const stringT& name) const; virtual void setFeature(const stringT& name, bool value); ///////////////////////////////////////////////// // Event Handlers virtual void setEntityResolver(SAX::basic_EntityResolver& resolver); virtual SAX::basic_EntityResolver* getEntityResolver() const; virtual void setDTDHandler(SAX::basic_DTDHandler& handler) { dtdHandlerAdaptor_.setDTDHandler(handler); } virtual SAX::basic_DTDHandler* getDTDHandler() const { return dtdHandlerAdaptor_.getDTDHandler(); } virtual void setContentHandler(SAX::basic_ContentHandler& handler) { contentHandlerAdaptor_.setContentHandler(handler); } virtual SAX::basic_ContentHandler* getContentHandler() const { return contentHandlerAdaptor_.getContentHandler(); } virtual void setErrorHandler(SAX::ErrorHandler& handler) { errorHandlerAdaptor_.setErrorHandler(handler); } virtual SAX::ErrorHandler* getErrorHandler() const { return errorHandlerAdaptor_.getErrorHandler(); } ////////////////////////////////////////////////// // 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: /////////////////////////////// // Adaptors class LocatorAdaptor : public SAX::basic_Locator { public: LocatorAdaptor() : locator_(0) { } LocatorAdaptor(const ::Locator* const locator) : locator_(locator) { } ~LocatorAdaptor() { } stringT getPublicId() const { if(!locator_) return stringT(); return SA_.makeStringT(locator_->getPublicId()); } // getPublicId stringT getSystemId() const { if(!locator_) return stringT(); return SA_.makeStringT(locator_->getSystemId()); } // getSystemId int getLineNumber() const { if(!locator_) return -1; return locator_->getLineNumber(); } // getLineNumber int getColumnNumber() const { if(!locator_) return -1; return locator_->getColumnNumber(); } // getColumnNumber void setLocator(const ::Locator* const locator) { locator_ = locator; } // setLocator private: const ::Locator* locator_; string_adaptorT SA_; }; // class LocatorAdaptor class DTDHandlerAdaptor : public ::DTDHandler { public: DTDHandlerAdaptor() : dtdHandler_(0) { } ~DTDHandlerAdaptor() { } void setDTDHandler(SAX::basic_DTDHandler& handler) { dtdHandler_ = &handler; } SAX::basic_DTDHandler* getDTDHandler() const { return dtdHandler_; } virtual void notationDecl(const XMLCh* const name, const XMLCh* const publicId, const XMLCh* const systemId) { if(dtdHandler_) dtdHandler_->notationDecl(SA_.makeStringT(name), SA_.makeStringT(publicId), SA_.makeStringT(systemId)); } // notationDecl virtual void unparsedEntityDecl(const XMLCh* const name, const XMLCh* const publicId, const XMLCh* const systemId, const XMLCh* const notationName) { if(dtdHandler_) dtdHandler_->unparsedEntityDecl(SA_.makeStringT(name), SA_.makeStringT(publicId), SA_.makeStringT(systemId), SA_.makeStringT(notationName)); } // unparsedEntityDecl virtual void resetDocType() { // no op } // resetDocType private: SAX::basic_DTDHandler* dtdHandler_; string_adaptorT SA_; }; // class DTDHandlerAdaptor class ContentHandlerAdaptor : public ::ContentHandler { public: ContentHandlerAdaptor() : contentHandler_(0) { } ~ContentHandlerAdaptor() { } void setContentHandler(SAX::basic_ContentHandler& handler) { contentHandler_ = &handler; } SAX::basic_ContentHandler* getContentHandler() const { return contentHandler_; } virtual void setDocumentLocator(const ::Locator* const locator) { locator_.setLocator(locator); if(contentHandler_) contentHandler_->setDocumentLocator(locator_); } // putDocumentLocation virtual void startDocument() { if(contentHandler_) contentHandler_->startDocument(); } // startDocument virtual void endDocument() { if(contentHandler_) contentHandler_->endDocument(); } // endDocument virtual void startPrefixMapping(const XMLCh* const prefix, const XMLCh* const uri) { if(contentHandler_) contentHandler_->startPrefixMapping(SA_.makeStringT(prefix), SA_.makeStringT(uri)); } // startPrefixMapping virtual void endPrefixMapping(const XMLCh* const prefix) { if(contentHandler_) contentHandler_->endPrefixMapping(SA_.makeStringT(prefix)); } // endPrefixMapping virtual void startElement(const XMLCh* const namespaceUri, const XMLCh* const localName, const XMLCh* const rawName, const ::Attributes& attrs) { if(contentHandler_) { AttributesAdaptor attrAdaptor(attrs); contentHandler_->startElement(SA_.makeStringT(namespaceUri), SA_.makeStringT(localName), SA_.makeStringT(rawName), attrAdaptor); } // if ... } // startElement virtual void endElement(const XMLCh* const namespaceUri, const XMLCh* const localName, const XMLCh* const rawName) { if(contentHandler_) contentHandler_->endElement(SA_.makeStringT(namespaceUri), SA_.makeStringT(localName), SA_.makeStringT(rawName)); } // endElement virtual void characters(const XMLCh* const chars, const unsigned int length) { if(contentHandler_) contentHandler_->characters(SA_.makeStringT(chars, length)); } // characters virtual void ignorableWhitespace(const XMLCh* const chars, const unsigned int length) { if(contentHandler_) contentHandler_->ignorableWhitespace(SA_.makeStringT(chars, length)); } // ignorableWhitespace virtual void processingInstruction(const XMLCh* const target, const XMLCh* const data) { if(contentHandler_) contentHandler_->processingInstruction(SA_.makeStringT(target), SA_.makeStringT(data)); } // processingInstruction virtual void skippedEntity(const XMLCh* const name) { if(contentHandler_) contentHandler_->skippedEntity(SA_.makeStringT(name)); } // skippedEntity 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(const ::Attributes& attrs) : attributes_(attrs) { } ~AttributesAdaptor() { } ///////////////////////// // indexed access virtual int getLength() const { return attributes_.getLength(); } // getLength virtual stringT getURI(unsigned int index) const { return SA_.makeStringT(attributes_.getURI(index)); } // getURI virtual stringT getLocalName(unsigned int index) const { return SA_.makeStringT(attributes_.getLocalName(index)); } // getLocalName virtual stringT getQName(unsigned int index) const { return SA_.makeStringT(attributes_.getQName(index)); } // getQName virtual stringT getType(unsigned int index) const { return SA_.makeStringT(attributes_.getType(index)); } // getType virtual stringT getValue(unsigned int index) const { return SA_.makeStringT(attributes_.getValue(index)); } // getValue ///////////////////////// // name based query virtual int getIndex(const stringT& uri, const stringT& localName) const { std::wstring wUri(SA_.asStdWString(uri)); std::wstring wLocalName(SA_.asStdWString(localName)); return attributes_.getIndex(wUri.c_str(), wLocalName.c_str()); } // getIndex virtual int getIndex(const stringT& qName) const { std::wstring wQName(SA_.asStdWString(qName)); return attributes_.getIndex(wQName.c_str()); } // getIndex virtual stringT getType(const stringT& uri, const stringT& localName) const { std::wstring wUri(SA_.asStdWString(uri)); std::wstring wLocalName(SA_.asStdWString(localName)); return SA_.makeStringT(attributes_.getType(wUri.c_str(), wLocalName.c_str())); } // getType virtual stringT getType(const stringT& qName) const { std::wstring wQName(SA_.asStdWString(qName)); return SA_.makeStringT(attributes_.getType(wQName.c_str())); } // getType virtual stringT getValue(const stringT& uri, const stringT& localName) const { std::wstring wUri(SA_.asStdWString(uri)); std::wstring wLocalName(SA_.asStdWString(localName)); return SA_.makeStringT(attributes_.getValue(wUri.c_str(), wLocalName.c_str())); } // getValue virtual stringT getValue(const stringT& qname) const { std::wstring wQName(SA_.asStdWString(qname)); return SA_.makeStringT(attributes_.getValue(wQName.c_str())); } // getValue private: const ::Attributes& attributes_; string_adaptorT SA_; AttributesAdaptor(); }; // class AttributesAdaptor }; // class ContentHandlerAdaptor class ErrorHandlerAdaptor : public ::ErrorHandler { public: ErrorHandlerAdaptor() : errorHandler_(0) { } virtual ~ErrorHandlerAdaptor() { } void setErrorHandler(SAX::ErrorHandler& handler) { errorHandler_ = &handler; } SAX::ErrorHandler* getErrorHandler() const { return errorHandler_; } virtual void warning(const ::SAXParseException& exception) { handleError(exception, SAX::ErrorHandler::warning); } // warning virtual void error(const ::SAXParseException& exception) { handleError(exception, SAX::ErrorHandler::error); } // error virtual void fatalError(const ::SAXParseException& exception) { handleError(exception, SAX::ErrorHandler::fatalError); } // fatalError virtual void resetErrors() { // no op } // resetErrors private: typedef void(SAX::ErrorHandler::* ErrorFn)(const SAX::SAXException&); void handleError(const ::SAXParseException& exception, ErrorFn fn) { if(!errorHandler_) return; stringT errorMsg(SA_.makeStringT(exception.getMessage())); SAX::basic_SAXParseException sp(SA_.asStdString(errorMsg), SA_.makeStringT(exception.getPublicId()), SA_.makeStringT(exception.getSystemId()), exception.getLineNumber(), exception.getColumnNumber()); (errorHandler_->*fn)(sp); } // handleError SAX::ErrorHandler* errorHandler_; string_adaptorT SA_; }; // class ErrorHandlerAdaptor class LexicalHandlerAdaptor : public ::LexicalHandler { public: LexicalHandlerAdaptor() : lexicalHandler_(0) { } virtual ~LexicalHandlerAdaptor() { } void setLexicalHandler(SAX::basic_LexicalHandler& handler) { lexicalHandler_ = &handler; } SAX::basic_LexicalHandler* getLexicalHandler() const { return lexicalHandler_; } virtual void startDTD(const XMLCh* const name, const XMLCh* const publicId, const XMLCh* const systemId) { if(lexicalHandler_) lexicalHandler_->startDTD(SA_.makeStringT(name), SA_.makeStringT(publicId), SA_.makeStringT(systemId)); } // startDTD virtual void endDTD() { if(lexicalHandler_) lexicalHandler_->endDTD(); } // endDTD virtual void startEntity(const XMLCh* const name) { if(lexicalHandler_) lexicalHandler_->startEntity(SA_.makeStringT(name)); } // startEntity virtual void endEntity(const XMLCh* const name) { if(lexicalHandler_) lexicalHandler_->endEntity(SA_.makeStringT(name)); } // endEntity virtual void startCDATA() { if(lexicalHandler_) lexicalHandler_->startCDATA(); } // startCDATA virtual void endCDATA() { if(lexicalHandler_) lexicalHandler_->endCDATA(); } // endCDATA virtual void comment(const XMLCh* const chars, const unsigned int length) { if(lexicalHandler_) lexicalHandler_->comment(SA_.makeStringT(chars, length)); } // comment private: SAX::basic_LexicalHandler* lexicalHandler_; string_adaptorT SA_; }; // class LexicalHandlerAdaptor class DeclHandlerAdaptor : public ::DeclHandler { public: DeclHandlerAdaptor() : declHandler_(0) { } virtual ~DeclHandlerAdaptor() { } void setDeclHandler(SAX::basic_DeclHandler& handler) { declHandler_ = &handler; } SAX::basic_DeclHandler* getDeclHandler() const { return declHandler_; } virtual void elementDecl(const XMLCh* const name, const XMLCh* const model) { if(declHandler_) declHandler_->elementDecl(SA_.makeStringT(name), SA_.makeStringT(model)); } // elementDecl virtual void attributeDecl(const XMLCh* const elementName, const XMLCh* const attributeName, const XMLCh* const type, const XMLCh* const valueDefault, const XMLCh* const value) { if(declHandler_) declHandler_->attributeDecl(SA_.makeStringT(elementName), SA_.makeStringT(attributeName), SA_.makeStringT(type), SA_.makeStringT(valueDefault), SA_.makeStringT(value)); } // attributeDecl virtual void internalEntityDecl(const XMLCh* const name, const XMLCh* const value) { if(declHandler_) declHandler_->internalEntityDecl(SA_.makeStringT(name), SA_.makeStringT(value)); } // internalEntityDecl virtual void externalEntityDecl(const XMLCh* const name, const XMLCh* const publicId, const XMLCh* const systemId) { if(declHandler_) declHandler_->externalEntityDecl(SA_.makeStringT(name), SA_.makeStringT(publicId), SA_.makeStringT(systemId)); } // externalEntityDecl private: SAX::basic_DeclHandler* declHandler_; string_adaptorT SA_; }; // class DeclHandlerAdaptor class IStreamAdaptor : public BinInputStream { public: IStreamAdaptor(std::istream* istream) : istream_(istream), curPos_(0) { } virtual ~IStreamAdaptor() { } virtual unsigned int curPos() const { return curPos_; } // curPos virtual unsigned int readBytes(XMLByte* const toFill, const unsigned int maxToRead) { istream_->read(reinterpret_cast(toFill), maxToRead); curPos_ += istream_->gcount(); return istream_->gcount(); } // readBytes private: std::istream* istream_; unsigned int curPos_; }; // IStreamAdaptor class InputSourceAdaptor : public InputSource { public: InputSourceAdaptor(SAX::basic_InputSource& source) : inputSource_(source) { setPublicId(SA_.asStdWString(inputSource_.getPublicId()).c_str()); setSystemId(SA_.asStdWString(inputSource_.getSystemId()).c_str()); } // InputSourceAdaptor virtual ~InputSourceAdaptor() { } virtual BinInputStream* makeStream() const { return new IStreamAdaptor(inputSource_.getByteStream()); } // makeStream private: SAX::basic_InputSource& inputSource_; string_adaptorT SA_; }; // class InputSourceWrapper ///////////////////////////////////////////// // Member variables SAX2XMLReader* xerces_; ContentHandlerAdaptor contentHandlerAdaptor_; DTDHandlerAdaptor dtdHandlerAdaptor_; ErrorHandlerAdaptor errorHandlerAdaptor_; LexicalHandlerAdaptor lexicalHandlerAdaptor_; DeclHandlerAdaptor declHandlerAdaptor_; string_adaptorT SA_; SAX::FeatureNames features_; SAX::PropertyNames properties_; }; // class xerces_wrapper template xerces_wrapper::xerces_wrapper() { try { XMLPlatformUtils::Initialize(); } catch(const XMLException& toCatch) { stringT s = SA_.makeStringT(toCatch.getMessage()); throw SAX::SAXException(SA_.asStdString(s)); } // catch xerces_ = XMLReaderFactory::createXMLReader(); xerces_->setContentHandler(&contentHandlerAdaptor_); xerces_->setDTDHandler(&dtdHandlerAdaptor_); xerces_->setErrorHandler(&errorHandlerAdaptor_); xerces_->setLexicalHandler(&lexicalHandlerAdaptor_); xerces_->setDeclarationHandler(&declHandlerAdaptor_); } // xerces_wrapper template xerces_wrapper::~xerces_wrapper() { delete xerces_; XMLPlatformUtils::Terminate(); } // ~xerces_wrapper template bool xerces_wrapper::getFeature(const stringT& name) const { try { return xerces_->getFeature(SA_.asStdWString(name).c_str()); } // try catch(::SAXNotSupportedException& e) { throw SAX::SAXNotSupportedException(SA_.makeStringT(e.getMessage())); } // catch(SAXNotSupportedException& e) catch(::SAXNotRecognizedException& e) { throw SAX::SAXNotRecognizedException(SA_.makeStringT(e.getMessage())); } // catch(SAXNotRecognizedException& e) } // getFeature template void xerces_wrapper::setFeature(const stringT& name, bool value) { try { xerces_->setFeature(SA_.asStdWString(name).c_str(), value); } // try catch(::SAXNotSupportedException& e) { throw SAX::SAXNotSupportedException(SA_.makeStringT(e.getMessage())); } // catch(SAXNotSupportedException& e) catch(::SAXNotRecognizedException& e) { throw SAX::SAXNotRecognizedException(SA_.makeStringT(e.getMessage())); } // catch(SAXNotRecognizedException& e) } // setFeature template void xerces_wrapper::setEntityResolver(SAX::EntityResolver& handler) { } // setEntityResolver template SAX::EntityResolver* xerces_wrapper::getEntityResolver() const { return 0; } // getEntityResolver template std::auto_ptr::PropertyBase> xerces_wrapper::doGetProperty(const stringT& name) { if(name == properties_.lexicalHandler) { Property*>* prop = new Property*>(lexicalHandlerAdaptor_.getLexicalHandler()); return std::auto_ptr::PropertyBase>(prop); } if(name == properties_.declHandler) { Property*>* prop = new Property*>(declHandlerAdaptor_.getDeclHandler()); return std::auto_ptr::PropertyBase>(prop); } throw SAX::SAXNotRecognizedException("Property not recognized "); } // doGetProperty template void xerces_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&"); lexicalHandlerAdaptor_.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&"); declHandlerAdaptor_.setDeclHandler(prop->get()); return; } // if ... throw SAX::SAXNotRecognizedException("Property not recognized "); } // doSetProperty template void xerces_wrapper::parse(SAX::basic_InputSource& source) { // if no stream is open, let Xerces deal with it if(source.getByteStream() == 0) xerces_->parse(SA_.asStdString(source.getSystemId()).c_str()); else { // we have to wrap everything up in a Xerces friendly way InputSourceAdaptor isAdaptor(source); xerces_->parse(isAdaptor); } // if ... } // parse } // namespace SAX #endif // end of file