📄 parserengine.cpp
字号:
//// ParserEngine.cpp//// $Id: //poco/1.2/XML/src/ParserEngine.cpp#2 $//// Library: XML// Package: XML// Module: ParserEngine//// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.// and Contributors.//// Permission is hereby granted, free of charge, to any person or organization// obtaining a copy of the software and accompanying documentation covered by// this license (the "Software") to use, reproduce, display, distribute,// execute, and transmit the Software, and to prepare derivative works of the// Software, and to permit third-parties to whom the Software is furnished to// do so, all subject to the following:// // The copyright notices in the Software and this entire statement, including// the above license grant, this restriction and the following disclaimer,// must be included in all copies of the Software, in whole or in part, and// all derivative works of the Software, unless such copies or derivative// works are solely in the form of machine-executable object code generated by// a source language processor.// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER// DEALINGS IN THE SOFTWARE.//#include "Poco/XML/ParserEngine.h"#include "Poco/XML/NamespaceStrategy.h"#include "Poco/XML/XMLException.h"#include "Poco/SAX/EntityResolver.h"#include "Poco/SAX/EntityResolverImpl.h"#include "Poco/SAX/DTDHandler.h"#include "Poco/SAX/DeclHandler.h"#include "Poco/SAX/ContentHandler.h"#include "Poco/SAX/LexicalHandler.h"#include "Poco/SAX/ErrorHandler.h"#include "Poco/SAX/InputSource.h"#include "Poco/SAX/Locator.h"#include "Poco/SAX/LocatorImpl.h"#include "Poco/SAX/SAXException.h"#include "Poco/URI.h"#include <string.h>using Poco::URI;using Poco::TextEncoding;namespace Poco {namespace XML {class ContextLocator: public Locator{public: ContextLocator(XML_Parser parser, const XMLString& publicId, const XMLString& systemId): _parser(parser), _publicId(publicId), _systemId(systemId) { } ~ContextLocator() { } XMLString getPublicId() const { return _publicId; } XMLString getSystemId() const { return _systemId; } int getLineNumber() const { return XML_GetCurrentLineNumber(_parser); } int getColumnNumber() const { return XML_GetCurrentColumnNumber(_parser); } private: XML_Parser _parser; XMLString _publicId; XMLString _systemId;};const int ParserEngine::PARSE_BUFFER_SIZE = 4096;const XMLString ParserEngine::EMPTY_STRING;ParserEngine::ParserEngine(): _parser(0), _pBuffer(0), _encodingSpecified(false), _expandInternalEntities(true), _externalGeneralEntities(false), _externalParameterEntities(false), _pNamespaceStrategy(new NoNamespacesStrategy()), _pEntityResolver(0), _pDTDHandler(0), _pDeclHandler(0), _pContentHandler(0), _pLexicalHandler(0), _pErrorHandler(0){}ParserEngine::ParserEngine(const XMLString& encoding): _parser(0), _pBuffer(0), _encodingSpecified(true), _encoding(encoding), _expandInternalEntities(true), _externalGeneralEntities(false), _externalParameterEntities(false), _pNamespaceStrategy(new NoNamespacesStrategy()), _pEntityResolver(0), _pDTDHandler(0), _pDeclHandler(0), _pContentHandler(0), _pLexicalHandler(0), _pErrorHandler(0){}ParserEngine::~ParserEngine(){ resetContext(); if (_parser) XML_ParserFree(_parser); delete [] _pBuffer; delete _pNamespaceStrategy;}void ParserEngine::setEncoding(const XMLString& encoding){ _encoding = encoding; _encodingSpecified = true;}void ParserEngine::addEncoding(const XMLString& name, TextEncoding* pEncoding){ poco_check_ptr (pEncoding); if (_encodings.find(name) == _encodings.end()) _encodings[name] = pEncoding; else throw XMLException("Encoding already defined"); }void ParserEngine::setNamespaceStrategy(NamespaceStrategy* pStrategy){ poco_check_ptr (pStrategy); delete _pNamespaceStrategy; _pNamespaceStrategy = pStrategy;}void ParserEngine::setExpandInternalEntities(bool flag){ _expandInternalEntities = flag;}void ParserEngine::setExternalGeneralEntities(bool flag){ _externalGeneralEntities = flag;}void ParserEngine::setExternalParameterEntities(bool flag){ _externalParameterEntities = flag;}void ParserEngine::setEntityResolver(EntityResolver* pResolver){ _pEntityResolver = pResolver;}void ParserEngine::setDTDHandler(DTDHandler* pDTDHandler){ _pDTDHandler = pDTDHandler;}void ParserEngine::setDeclHandler(DeclHandler* pDeclHandler){ _pDeclHandler = pDeclHandler;}void ParserEngine::setContentHandler(ContentHandler* pContentHandler){ _pContentHandler = pContentHandler;}void ParserEngine::setLexicalHandler(LexicalHandler* pLexicalHandler){ _pLexicalHandler = pLexicalHandler;}void ParserEngine::setErrorHandler(ErrorHandler* pErrorHandler){ _pErrorHandler = pErrorHandler;}void ParserEngine::parse(InputSource* pInputSource){ init(); resetContext(); pushContext(_parser, pInputSource); if (_pContentHandler) _pContentHandler->setDocumentLocator(this); if (_pContentHandler) _pContentHandler->startDocument(); if (pInputSource->getCharacterStream()) parseCharInputStream(*pInputSource->getCharacterStream()); else if (pInputSource->getByteStream()) parseByteInputStream(*pInputSource->getByteStream()); else throw XMLException("Input source has no stream"); if (_pContentHandler) _pContentHandler->endDocument(); popContext();}void ParserEngine::parseByteInputStream(XMLByteInputStream& istr){ istr.read(_pBuffer, PARSE_BUFFER_SIZE); int n = istr.gcount(); while (n > 0) { if (!XML_Parse(_parser, _pBuffer, n, 0)) handleError(XML_GetErrorCode(_parser)); if (istr.good()) { istr.read(_pBuffer, PARSE_BUFFER_SIZE); n = istr.gcount(); } else n = 0; } if (!XML_Parse(_parser, _pBuffer, 0, 1)) handleError(XML_GetErrorCode(_parser));}void ParserEngine::parseCharInputStream(XMLCharInputStream& istr){ istr.read(reinterpret_cast<XMLChar*>(_pBuffer), PARSE_BUFFER_SIZE/sizeof(XMLChar)); int n = istr.gcount(); while (n > 0) { if (!XML_Parse(_parser, _pBuffer, n*sizeof(XMLChar), 0)) handleError(XML_GetErrorCode(_parser)); if (istr.good()) { istr.read(reinterpret_cast<XMLChar*>(_pBuffer), PARSE_BUFFER_SIZE/sizeof(XMLChar)); n = istr.gcount(); } else n = 0; } if (!XML_Parse(_parser, _pBuffer, 0, 1)) handleError(XML_GetErrorCode(_parser));}void ParserEngine::parseExternal(XML_Parser extParser, InputSource* pInputSource){ pushContext(extParser, pInputSource); if (pInputSource->getCharacterStream()) parseExternalCharInputStream(extParser, *pInputSource->getCharacterStream()); else if (pInputSource->getByteStream()) parseExternalByteInputStream(extParser, *pInputSource->getByteStream()); else throw XMLException("Input source has no stream"); popContext();}void ParserEngine::parseExternalByteInputStream(XML_Parser extParser, XMLByteInputStream& istr){ char *pBuffer = new char[PARSE_BUFFER_SIZE]; try { istr.read(pBuffer, PARSE_BUFFER_SIZE); int n = istr.gcount(); while (n > 0) { if (!XML_Parse(extParser, pBuffer, n, 0)) handleError(XML_GetErrorCode(extParser)); if (istr.good()) { istr.read(pBuffer, PARSE_BUFFER_SIZE); n = istr.gcount(); } else n = 0; } if (!XML_Parse(extParser, pBuffer, 0, 1)) handleError(XML_GetErrorCode(extParser)); } catch (...) { delete [] pBuffer; throw; } delete [] pBuffer;}void ParserEngine::parseExternalCharInputStream(XML_Parser extParser, XMLCharInputStream& istr){ XMLChar *pBuffer = new XMLChar[PARSE_BUFFER_SIZE/sizeof(XMLChar)]; try { istr.read(pBuffer, PARSE_BUFFER_SIZE/sizeof(XMLChar)); int n = istr.gcount(); while (n > 0) { if (!XML_Parse(extParser, reinterpret_cast<char*>(pBuffer), n*sizeof(XMLChar), 0)) handleError(XML_GetErrorCode(extParser)); if (istr.good()) { istr.read(pBuffer, PARSE_BUFFER_SIZE/sizeof(XMLChar)); n = istr.gcount(); } else n = 0; } if (!XML_Parse(extParser, reinterpret_cast<char*>(pBuffer), 0, 1)) handleError(XML_GetErrorCode(extParser)); } catch (...) { delete [] pBuffer; throw; } delete [] pBuffer;}XMLString ParserEngine::getPublicId() const{ return locator().getPublicId();}XMLString ParserEngine::getSystemId() const{ return locator().getSystemId();}int ParserEngine::getLineNumber() const{ return locator().getLineNumber();}int ParserEngine::getColumnNumber() const{ return locator().getColumnNumber();}const Locator& ParserEngine::locator() const{ static LocatorImpl nullLocator; if (_context.empty()) return nullLocator; else return *_context.back();}void ParserEngine::init(){ if (_parser) XML_ParserFree(_parser); if (!_pBuffer) _pBuffer = new char[PARSE_BUFFER_SIZE]; if (dynamic_cast<NoNamespacePrefixesStrategy*>(_pNamespaceStrategy)) { _parser = XML_ParserCreateNS(_encodingSpecified ? _encoding.c_str() : 0, '\t'); XML_SetNamespaceDeclHandler(_parser, handleStartNamespaceDecl, handleEndNamespaceDecl); } else if (dynamic_cast<NamespacePrefixesStrategy*>(_pNamespaceStrategy)) { _parser = XML_ParserCreateNS(_encodingSpecified ? _encoding.c_str() : 0, '\t'); XML_SetReturnNSTriplet(_parser, 1); XML_SetNamespaceDeclHandler(_parser, handleStartNamespaceDecl, handleEndNamespaceDecl); } else { _parser = XML_ParserCreate(_encodingSpecified ? _encoding.c_str() : 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -