📄 documentparser.cpp
字号:
= VXIIntegerValue(reinterpret_cast<const VXIInteger *>(tempSize));
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;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -