📄 documentparser.cpp
字号:
/****************License************************************************ * * Copyright 2000-2001. SpeechWorks International, Inc. * * Use of this software is subject to notices and obligations set forth * in the SpeechWorks Public License - Software Version 1.1 which is * included with this software. * * SpeechWorks is a registered trademark, and SpeechWorks Here, * DialogModules and the SpeechWorks logo are trademarks of SpeechWorks * International, Inc. in the United States and other countries. * *********************************************************************** * * Routines to handle fetching of documents and resources. * ***********************************************************************/#include "DocumentParser.hpp"#include "CommonExceptions.hpp"#include "VXIinet.h"#include <util/PlatformUtils.hpp>#include <util/TransService.hpp>#include <parsers/SAXParser.hpp>#include <framework/MemBufInputSource.hpp>#include "SimpleLogger.hpp"#include "DTD.hpp"#include "DefaultsDTD.hpp"#include "Defaults.hpp"#include "VXML.h" // for attribute names#include "VXItrd.h" // for ThreadYield#include <sax/ErrorHandler.hpp> // by DOMTreeErrorReporter#include <sax/SAXParseException.hpp> // by DOMTreeErrorReporter#include <sax/EntityResolver.hpp> // by DTDResolver#include "DocumentConverter.hpp" // for DocumentConverter#include "DocumentModel.hpp"#include "PropertyList.hpp"#include "XMLChConverter.hpp"//#############################################################################// Utilities - these are specific to Xerces//#############################################################################class DOMTreeErrorReporter : public ErrorHandler {public: DOMTreeErrorReporter() { } ~DOMTreeErrorReporter() { } void warning(const SAXParseException& toCatch) { /* Ignore */ } void fatalError(const SAXParseException& toCatch) { error(toCatch); } void resetErrors() { } void error(const SAXParseException & toCatch) { throw SAXParseException(toCatch); }private: DOMTreeErrorReporter(const DOMTreeErrorReporter &); void operator=(const DOMTreeErrorReporter &);};class DTDResolver : public EntityResolver {public: virtual ~DTDResolver() { } DTDResolver() { } virtual InputSource * resolveEntity(const XMLCh * const publicId, const XMLCh * const systemId) { // The size - 1 is used to drop the final \0. if (Compare(publicId, L"SB_Defaults")) { VXIcharToXMLCh name(L"VXML Defaults DTD (for SB 1.0)"); return new MemBufInputSource(VXML_DEFAULTS_DTD, VXML_DEFAULTS_DTD_SIZE - 1, name.c_str(), false); } VXIcharToXMLCh name(L"VXML DTD (for SB 1.0)"); return new MemBufInputSource(VXML_DTD, VXML_DTD_SIZE - 1, name.c_str(), false); }};//#############################################################################// Document Parser//#############################################################################bool DocumentParser::Initialize(){ try { XMLPlatformUtils::Initialize(); if (!VXMLDocumentModel::Initialize()) return false; DocumentConverter::Initialize(); } catch (const XMLException &) { return false; } return true;}void DocumentParser::Deinitialize(){ try { DocumentConverter::Deinitialize(); VXMLDocumentModel::Deinitialize(); XMLPlatformUtils::Terminate(); } catch (const XMLException &) { // do nothing }}DocumentParser::DocumentParser() : parser(NULL), converter(NULL), lastParse(DocumentParser::NOTHING){ converter = new DocumentConverter(); if (converter == NULL) throw VXIException::OutOfMemory(); parser = new SAXParser; if (parser == NULL) { delete converter; throw VXIException::OutOfMemory(); } DTDResolver * dtd = new DTDResolver(); if (dtd == NULL) { delete converter; delete parser; throw VXIException::OutOfMemory(); } parser->setEntityResolver(dtd); parser->setDoNamespaces(false); parser->setValidationScheme(SAXParser::Val_Always); ErrorHandler *errReporter = new DOMTreeErrorReporter(); parser->setErrorHandler(errReporter); parser->setDocumentHandler(converter);}DocumentParser::~DocumentParser(){ if (parser != NULL) { const ErrorHandler * reporter = parser->getErrorHandler(); delete reporter; const EntityResolver * resolver = parser->getEntityResolver(); delete resolver; delete parser; delete converter; parser = NULL; }}//****************************************************************************// FetchBuffer//****************************************************************************// 1: Invalid parameter// 2: Unable to open URL// 3: Unable to read from URLint DocumentParser::FetchBuffer(const VXIchar * url, const VXIMapHolder & properties, VXIinetInterface * inet, SimpleLogger & log, const VXIbyte * & result, VXIulong & read, vxistring & docURL){ if (log.IsLogging(2)) { log.StartDiagnostic(2) << L"DocumentParser::FetchBuffer(" << url << L")"; log.EndDiagnostic(); } if (inet == NULL || url == NULL || wcslen(url) == 0) return 1; // (1) Open URL VXIinetStream * stream; VXIMapHolder streamInfo; if (streamInfo.GetValue() == NULL) return -1; if (inet->Open(inet, L"vxi", url, INET_MODE_READ, 0, properties.GetValue(), streamInfo.GetValue(), &stream) != 0) { if (log.IsLogging(0)) { log.StartDiagnostic(0) << L"DocumentParser::FetchBuffer - could not " L"open URL: " << url; log.EndDiagnostic(); } return 2; } // (2) Determine document size & read into local memory buffer. const VXIValue * tempURL = NULL; tempURL = VXIMapGetProperty(streamInfo.GetValue(), INET_INFO_ABSOLUTE_NAME); if (tempURL == NULL || VXIValueGetType(tempURL) != VALUE_STRING) { inet->Close(inet, &stream); if (log.IsLogging(0)) { log.StartDiagnostic(0) << L"DocumentParser::FetchBuffer - could not " L"retrieve absolute path of document at URL: " << url; log.EndDiagnostic(); } return 2; } docURL = VXIStringCStr(reinterpret_cast<const VXIString *>(tempURL)); const VXIValue * tempSize = NULL; tempSize = VXIMapGetProperty(streamInfo.GetValue(), INET_INFO_SIZE_BYTES); if (tempSize == NULL || VXIValueGetType(tempSize) != VALUE_INTEGER) { inet->Close(inet, &stream); if (log.IsLogging(0)) { log.StartDiagnostic(0) << L"DocumentParser::FetchBuffer - could not " L"retrieve size of document at URL: " << url; log.EndDiagnostic(); } return 2; } VXIint32 bufSize = VXIIntegerValue(reinterpret_cast<const VXIInteger *>(tempSize)); if (bufSize < 2047) bufSize = 2047; ++bufSize; VXIbyte * buffer = new VXIbyte[bufSize]; bool reachedEnd = false; read = 0; while (!reachedEnd) { VXIulong bytesRead = 0; switch (inet->Read(inet, buffer+read, bufSize-read, &bytesRead, stream)) { case VXIinet_RESULT_SUCCESS: read += bytesRead; break; case VXIinet_RESULT_END_OF_STREAM: read += bytesRead; reachedEnd = true; // exit while break; case VXIinet_RESULT_WOULD_BLOCK: VXItrdThreadYield(); break; default: inet->Close(inet, &stream); delete[] buffer; log.LogDiagnostic(0, L"DocumentParser::FetchBuffer - " L"could not read from URL."); return 3; } if (read == static_cast<VXIulong>(bufSize)) { // The number of bytes read exceeds the number expected. Double the // size and keep reading. VXIbyte * temp = new VXIbyte[2*bufSize]; memcpy(static_cast<void *>(temp), static_cast<void *>(buffer), bufSize * sizeof(VXIbyte)); delete[] buffer; buffer = temp; bufSize *= 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -