⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parserengine.cpp.svn-base

📁 很好用的网络封装库,不熟悉网络编程的人也可以使用。使用风格良好的标准c++编写。
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
//
// ParserEngine.cpp
//
// $Id: //poco/1.3/XML/src/ParserEngine.cpp#4 $
//
// Library: XML
// Package: XML
// Module:  ParserEngine
//
// Copyright (c) 2004-2007, 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 <cstring>


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::parse(const char* pBuffer, std::size_t size)
{
	init();
	resetContext();
	InputSource src;
	pushContext(_parser, &src);
	if (_pContentHandler) _pContentHandler->setDocumentLocator(this);
	if (_pContentHandler) _pContentHandler->startDocument();
	if (!XML_Parse(_parser, pBuffer, static_cast<int>(size), 1))
		handleError(XML_GetErrorCode(_parser));
	if (_pContentHandler) _pContentHandler->endDocument();
	popContext();
}


void ParserEngine::parseByteInputStream(XMLByteInputStream& istr)
{
	istr.read(_pBuffer, PARSE_BUFFER_SIZE);
	int n = static_cast<int>(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 = static_cast<int>(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 = static_cast<int>(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 = static_cast<int>(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 = static_cast<int>(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 = static_cast<int>(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 = static_cast<int>(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 = static_cast<int>(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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -