📄 propertylist.cpp
字号:
/****************License************************************************ * * Copyright 2000-2003. ScanSoft, Inc. * * Use of this software is subject to notices and obligations set forth * in the SpeechWorks Public License - Software Version 1.2 which is * included with this software. * * ScanSoft is a registered trademark of ScanSoft, Inc., and OpenSpeech, * SpeechWorks and the SpeechWorks logo are registered trademarks or * trademarks of SpeechWorks International, Inc. in the United States * and other countries. * ***********************************************************************/ #include "PropertyList.hpp" #include "CommonExceptions.hpp" // for VXIException class #include "VXIinet.h" #include "VXML.h" #include "SimpleLogger.hpp" // for SimpleLogger #include "DocumentParser.hpp" // for string constants #include "DocumentModel.hpp" #include <sstream> // ------*---------*---------*---------*---------*---------*---------*--------- // The use of spaces here creates identifiers which cannot be specified // within the property or meta tags. const VXIchar * const PropertyList::BaseURI = L" base"; const VXIchar * const PropertyList::Language = L" lang"; const VXIchar * const PropertyList::AbsoluteURI = L" absoluteURI"; static vxistring toString(const VXIString * s) { if (s == NULL) return L""; const VXIchar * temp = VXIStringCStr(s); if (temp == NULL) return L""; return temp; } static vxistring toString(const VXIchar * s) { if (s == NULL) return L""; return s; } // ------*---------*---------*---------*---------*---------*---------*--------- PropertyList::PropertyList(const SimpleLogger & l) : log(l) { properties.reserve(LAST_PROP); while (properties.size() < LAST_PROP) properties.push_back(STRINGMAP()); } PropertyList::PropertyList(const PropertyList & p) : log(p.log) { properties = p.properties; } PropertyList& PropertyList::operator=(const PropertyList & x) { if (this != &x) { properties = x.properties; } return *this; } const VXIchar* PropertyList::GetProperty(const VXIchar * key, PropertyLevel L) const { int pos = L; do { if (pos == LAST_PROP) --pos; STRINGMAP::const_iterator i = properties[pos].find(key); if (i != properties[pos].end()) return (*i).second.c_str(); } while (--pos >= 0); return NULL; } bool PropertyList::SetProperty(const VXIchar * key, const VXIchar * value, PropertyLevel level) { if (level == LAST_PROP || key == NULL || value == NULL) return false; STRINGMAP & propmap = properties[level]; propmap[key] = value; return true; } void PropertyList::SetProperties(const VXMLElement & doc, PropertyLevel level, const VXIMapHolder & docProps) { // (0) Check the arguments if (doc == 0) return; if (properties.size() != LAST_PROP) { log.LogError(999, SimpleLogger::MESSAGE, L"internal property list corrupted"); throw VXIException::Fatal(); } // (1) Clear all properties at this level and above. #if 0 for (unsigned int i = level; i < LAST_PROP; ++i) properties[i].clear(); #endif properties[level].clear(); STRINGMAP & propmap = properties[level]; // (2) Add document properties. if (docProps.GetValue() != NULL) { const VXIValue * val; const VXIString * str; // (2.1) Handle document base URI. val = VXIMapGetProperty(docProps.GetValue(), PropertyList::BaseURI); str = reinterpret_cast<const VXIString *>(val); if (VXIStringLength(str) != 0) propmap.insert(propmap.end(), STRINGMAP::value_type(PropertyList::BaseURI, toString(str))); // (2.2) Handle document language. If the document property is not // specified, the value of the xml:lang property will be used. val = VXIMapGetProperty(docProps.GetValue(), PropertyList::Language); str = reinterpret_cast<const VXIString *>(val); if (VXIStringLength(str) != 0) propmap.insert(propmap.end(), STRINGMAP::value_type(PropertyList::Language, toString(str))); else { const VXIchar * lang = GetProperty(L"xml:lang"); if (lang != NULL) propmap.insert(propmap.end(), STRINGMAP::value_type(PropertyList::Language, toString(lang))); } // (2.3) Handle document absolute URI. val = VXIMapGetProperty(docProps.GetValue(), PropertyList::AbsoluteURI); str = reinterpret_cast<const VXIString *>(val); if (VXIStringLength(str) != 0) propmap.insert(propmap.end(), STRINGMAP::value_type(PropertyList::AbsoluteURI, toString(str))); } // (3) Walk through this level. Find all <property> nodes and set the // corresponding values. for (VXMLNodeIterator it(doc); it; ++it) { VXMLNode child = *it; if (child.GetType() != VXMLNode::Type_VXMLElement) continue; const VXMLElement & elem = reinterpret_cast<const VXMLElement &>(child); VXMLElementType nodeName = elem.GetName(); if (nodeName == NODE_PROPERTY) { vxistring name; vxistring value; elem.GetAttribute(ATTRIBUTE_NAME, name); elem.GetAttribute(ATTRIBUTE_VALUE, value); // This added the name / value pair, converting to vxistrings. propmap.insert(propmap.end(), STRINGMAP::value_type(name, value)); } } } //**************************************************************** //* Fetchobj building routines //**************************************************************** bool PropertyList::ConvertTimeToMilliseconds(const SimpleLogger & log, const vxistring & time, VXIint & result) { result = 0; if (time.empty()) { log.LogDiagnostic(0, L"PropertyList::ConvertTimeToMilliseconds - empty"); return false; } for (unsigned int i = 0; i < time.length(); ++i) { char c; switch (time[i]) { case L'+': continue; case L'0': c = 0; break; case L'1': c = 1; break; case L'2': c = 2; break; case L'3': c = 3; break; case L'4': c = 4; break; case L'5': c = 5; break; case L'6': c = 6; break; case L'7': c = 7; break; case L'8': c = 8; break; case L'9': c = 9; break; default: const vxistring units = time.substr(i, time.length() - i); if (units == L"ms") return true; if (units == L"s") { result *= 1000; return true; } // Otherwise the unit type is not recognized. log.StartDiagnostic(0) << L"PropertyList::ConvertTimeToMilliseconds - " L"Invalid units in value \"" << time << L"\"."; log.EndDiagnostic(); return false; } result = 10*result + c; } // No units were specified. Milliseconds are assumed. return true; } bool PropertyList::ConvertValueToFraction(const SimpleLogger & log, const vxistring & value, VXIflt32& result) { #if defined(__GNUC__) // The G++ 2.95/3.0 implementation of basic_stringstream is faulty. VXIchar * temp; result = VXIflt32(wcstod(value.c_str(), &temp)); if (*temp) { result = -1.0; return false; } #else std::basic_stringstream<VXIchar> attrStream(value); attrStream >> result; if (attrStream.bad()) { result = -1.0; return false; } #endif return true; } void PropertyList::GetFetchobjCacheAttrs(const VXMLElement & elem, PropertyList::CacheAttrType type, VXIMapHolder & fetchobj) const { vxistring attr; const VXIchar * propName; // (1) Attribute: maxage // (1.1) Get the attribute - first locally, then from the defaults. elem.GetAttribute(ATTRIBUTE_MAXAGE, attr); if (attr.empty()) { switch (type) { case PropertyList::Audio: propName = L"audiomaxage"; break; case PropertyList::Document: propName = L"documentmaxage"; break; case PropertyList::Grammar: propName = L"grammarmaxage"; break; case PropertyList::Object: propName = L"objectmaxage"; break; case PropertyList::Script: propName = L"scriptmaxage"; break; } attr = toString(GetProperty(propName)); } // (1.2) Process the value. if (!attr.empty()) { VXIint value = -1; #if defined(__GNUC__) // The G++ 2.95/3.0 implementation of basic_stringstream is faulty. VXIchar * temp; value = VXIint(wcstol(attr.c_str(), &temp, 10)); if (*temp) value = -1; #else std::basic_stringstream<VXIchar> attrStream(attr); attrStream >> value;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -