?? parserengine.cpp
字號:
//
// 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 + -