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

📄 parserengine.cpp

📁 This software aims to create an applet and panel tools to manage a wireless interface card, such as
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// ParserEngine.cpp
//
// $Id: //poco/Main/XML/src/ParserEngine.cpp#5 $
//
// Copyright (c) 2004, Guenter Obiltschnig/Applied Informatics.
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 
// 3. Redistributions in any form must be accompanied by information on
//    how to obtain complete source code for this software and any
//    accompanying software that uses this software.  The source code
//    must either be included in the distribution or be available for no
//    more than the cost of distribution plus a nominal fee, and must be
//    freely redistributable under reasonable conditions.  For an
//    executable file, complete source code means the source code for all
//    modules it contains.  It does not include source code for modules or
//    files that typically accompany the major components of the operating
//    system on which the executable file runs.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//


#include "XML/ParserEngine.h"
#include "XML/NamespaceStrategy.h"
#include "XML/XMLException.h"
#include "SAX/EntityResolver.h"
#include "SAX/EntityResolverImpl.h"
#include "SAX/DTDHandler.h"
#include "SAX/DeclHandler.h"
#include "SAX/ContentHandler.h"
#include "SAX/LexicalHandler.h"
#include "SAX/ErrorHandler.h"
#include "SAX/InputSource.h"
#include "SAX/Locator.h"
#include "SAX/LocatorImpl.h"
#include "SAX/SAXException.h"
#include "Foundation/URI.h"
#include <string.h>


using Foundation::URI;
using Foundation::TextEncoding;


XML_BEGIN


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);
	}

⌨️ 快捷键说明

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