📄 documentparser.cpp
字号:
if (bufSize < 2047) bufSize = 2047; ++bufSize; VXIbyte * buffer = new VXIbyte[bufSize]; if(buffer == NULL) { log.LogError(202); return -1; } 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]; if(temp == NULL) { log.LogError(202); delete [] buffer; return -1; } memcpy(static_cast<void *>(temp), static_cast<void *>(buffer), bufSize * sizeof(VXIbyte)); delete[] buffer; buffer = temp; bufSize *= 2; } } inet->Close(inet, &stream); result = buffer; log.LogDiagnostic(2, L"DocumentParser::FetchBuffer - success"); return 0; } void DocumentParser::ReleaseBuffer(const VXIbyte * & buffer) { if (buffer != VALIDATOR_DATA + VXML_DEFAULTS) delete[] const_cast<VXIbyte *>(buffer); buffer = NULL; } //############################################################################# // FetchDocument //############################################################################# // -2: Internal error int DocumentParser::FetchDocument(const VXIchar * url, const VXIMapHolder & properties, VXIinetInterface * inet, VXIcacheInterface * cache, SimpleLogger & log, VXMLDocument & document, VXIMapHolder & docProperties, bool isDefaults, VXIbyte **content, VXIulong *size) { int result; if (log.IsLogging(2)) { log.StartDiagnostic(2) << L"DocumentParser::FetchDocument(" << url << L")"; log.EndDiagnostic(); } // (1) Load the VXML DTD for validation. This will override an externally // specified DTD if the user provides a link. try { if (isDefaults) { parser->parse(MemBufInputSource(VALIDATOR_DATA + DUMMY_VXML_DEFAULTS_DOC, DUMMY_VXML_DEFAULTS_DOC_SIZE, "vxml 1.0 defaults")); converter->ResetDocument(); // Throw this document away. } if (!isDefaults && !loadedVXML20) { // Preload the VXML 2.0 schema. VXIcharToXMLCh name(L"http://www.w3.org/TR/voicexml20/vxml.xsd"); LockLoadGrammar(); parser->loadGrammar(name.c_str(), Grammar::SchemaGrammarType, true); // Reuse cached grammars if available. parser->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true); loadedVXML20 = true; UnlockLoadGrammar(); } } catch (const XMLException & exception) { log.StartDiagnostic(0) << L"DocumentParser::FetchDocument - XML parsing " L"error from DOM: " << XMLChToVXIchar(exception.getMessage()); log.EndDiagnostic(); log.LogError(999, SimpleLogger::MESSAGE, L"unable to load VXML DTD"); return 4; } catch (const SAXParseException & exception) { log.StartDiagnostic(0) << L"DocumentParser::FetchDocument - Parse error " << L"in file \"" << XMLChToVXIchar(exception.getSystemId()) << L"\", line " << exception.getLineNumber() << L", column " << exception.getColumnNumber() << L" - " << XMLChToVXIchar(exception.getMessage()); log.EndDiagnostic(); log.LogError(999, SimpleLogger::MESSAGE, L"unable to load VXML DTD"); return 4; } // (2) Load the url into memory. const VXIbyte * buffer; VXIulong bufSize; vxistring docURL; bool isDefaultDoc = false; if (isDefaults && wcslen(url) == 0) { buffer = VALIDATOR_DATA + VXML_DEFAULTS; bufSize = VXML_DEFAULTS_SIZE; docURL = L"builtin defaults"; result = 0; isDefaultDoc = true; } else { result = DocumentParser::FetchBuffer(url, properties, docProperties, inet, log, buffer, bufSize, docURL); } if (result != 0) { if (log.IsLogging(0)) { log.StartDiagnostic(0) << L"DocumentParser::FetchDocument - exiting " L"with error result " << result; log.EndDiagnostic(); } return result; // may return { -1, 1, 2, 3 } } // store buffer for reference if (content) { VXIbyte *tempbuf = new VXIbyte[bufSize]; if(tempbuf == NULL) { log.LogError(202); DocumentParser::ReleaseBuffer(buffer); return -1; } memcpy(tempbuf, buffer, bufSize); if (size != NULL) *size = bufSize; *content = tempbuf; } // (3) Pull the document from cache. // (3.1) Set the base uri for this document, but // ignore if it is the default doc if(!isDefaultDoc) converter->SetBaseUri(docURL.c_str()); VXMLDocument doc; if (!DocumentStorageSingleton::Instance()->Retrieve(doc, buffer, bufSize)) { // (4) Not in cache; parse buffer into our VXML document representation try { VXIcharToXMLCh membufURL(docURL.c_str()); parser->parse(MemBufInputSource(buffer, bufSize, membufURL.c_str(), false)); } catch (const XMLException & exception) { DocumentParser::ReleaseBuffer(buffer); if (log.IsLogging(0)) { log.StartDiagnostic(0) << L"DocumentParser::FetchDocument - XML " L"parsing error from DOM: " <<XMLChToVXIchar(exception.getMessage()); log.EndDiagnostic(); } return 4; } catch (const SAXParseException & exception) { DocumentParser::ReleaseBuffer(buffer); if (log.IsLogging(0)) { log.StartDiagnostic(0) << L"DocumentParser::FetchDocument - Parse " << L"error in file \"" << XMLChToVXIchar(exception.getSystemId()) << L"\", line " << exception.getLineNumber() << L", column " << exception.getColumnNumber() << L" - " << XMLChToVXIchar(exception.getMessage()); log.EndDiagnostic(); } return 4; } // (5) Write the compiled form out to the cache. doc = converter->GetDocument(); DocumentStorageSingleton::Instance()->Store(doc, buffer, bufSize); } DocumentParser::ReleaseBuffer(buffer); // (6) Parse was successful, process document. We want only the top level // <vxml> node. const VXMLElement root = doc.GetRoot(); VXMLElementType nodeName = root.GetName(); // If we're looking for the defaults, we can exit early. if (isDefaults && nodeName == DEFAULTS_ROOT) { log.LogDiagnostic(2, L"DocumentParser::FetchDocument - success"); document = doc; return 0; } else if (nodeName != NODE_VXML) { document = VXMLDocument(); if (log.IsLogging(0)) { log.StartDiagnostic(0) << L"DocumentParser::FetchDocument - unable to " L"find " << NODE_VXML << L" in document."; log.EndDiagnostic(); } return 4; } vxistring temp; // If the properties map is NULL, don't bother with the remaining settings if (docProperties.GetValue() != NULL) { // Retrieve the properties and put them into the map. VXIString * str = NULL; temp = docURL; str = VXIStringCreate(temp.c_str()); if (str == NULL) throw VXIException::OutOfMemory(); VXIMapSetProperty(docProperties.GetValue(), PropertyList::AbsoluteURI, reinterpret_cast<VXIValue *>(str)); str = VXIStringCreate(converter->GetBaseUri().empty() ? L"" : converter->GetBaseUri().c_str()); if (str == NULL) throw VXIException::OutOfMemory(); VXIMapSetProperty(docProperties.GetValue(), PropertyList::BaseURI, reinterpret_cast<VXIValue *>(str)); if (root.GetAttribute(ATTRIBUTE_XMLLANG, temp)) { str = VXIStringCreate(temp.c_str()); if (str == NULL) throw VXIException::OutOfMemory(); VXIMapSetProperty(docProperties.GetValue(), PropertyList::Language, reinterpret_cast<VXIValue *>(str)); } } log.LogDiagnostic(2, L"DocumentParser::FetchDocument - success"); document = doc; return 0; } int DocumentParser::FetchContent(const VXIchar * uri, const VXIMapHolder & properties, VXIMapHolder & fetchInfo, VXIinetInterface * inet, SimpleLogger & log, const vxistring & encoding, vxistring & content) { const VXIbyte * buffer; VXIulong bufSize; vxistring docURL; // (1) Retrieve the URI. switch (DocumentParser::FetchBuffer(uri, properties, fetchInfo, inet, log, buffer, bufSize, docURL)) { case -1: // Out of memory? return -1; case 0: // Success break; case 2: // Unable to open URI return 2; case 3: // Unable to read from URI return 3; case 1: // Invalid parameter default: return 1; } // (2) Create a transcoder for the requested type. VXIcharToXMLCh encName(encoding.c_str()); XMLTransService::Codes failReason; XMLTranscoder* transcoder = XMLPlatformUtils::fgTransService->makeNewTranscoderFor(encName.c_str(), failReason, 8*1064 #if _XERCES_VERSION <= 20200 ); #else ,XMLPlatformUtils::fgMemoryManager); #endif if (transcoder == NULL) return 4; // (3) Allocate memory for the conversion. XMLCh * convertedString = new XMLCh[bufSize+1]; unsigned char* charSizes = new unsigned char[bufSize]; if (convertedString == NULL || charSizes == NULL) { delete[] convertedString; delete[] charSizes; return -1; } // (4) Transcode the values into our string. unsigned int bytesEaten; unsigned int charsDone = transcoder->transcodeFrom(buffer, bufSize, convertedString, bufSize, bytesEaten, charSizes); // (5) Finally convert from XMLCh to VXIchar. convertedString[charsDone] = '\0'; // Add terminator. XMLChToVXIchar result(convertedString); // (6) Done. Release memory. content = result.c_str(); delete[] convertedString; delete[] charSizes; ReleaseBuffer(buffer); return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -