⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grammarmanager.cpp

📁 OSB-PIK-OpenVXI-3.0.0源代码 “中国XML论坛 - 专业的XML技术讨论区--XML在语音技术中的应用”
💻 CPP
📖 第 1 页 / 共 4 页
字号:
 /****************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 "GrammarManager.hpp"  #include "SimpleLogger.hpp" #include "CommonExceptions.hpp" #include "PropertyList.hpp" #include "VXML.h" #include "DocumentModel.hpp" #include <sstream>  //############################################################################# // Grammar description class //#############################################################################  const VXIchar * const GrammarManager::DTMFTerm      = L"@dtmfterm"; const VXIchar * const GrammarManager::FinalSilence  = L"@finalsilence"; const VXIchar * const GrammarManager::MaxTime       = L"@maxtime"; const VXIchar * const GrammarManager::RecordingType = L"@rectype";  enum GrammarScope {   GRS_NONE,   GRS_FIELD,   GRS_DIALOG,   GRS_DOC };   class GrammarInfo { public:   GrammarInfo(VXIrecGrammar *, const vxistring &, const VXMLElement &,               unsigned long);   ~GrammarInfo();    VXIrecGrammar * GetRecGrammar() const    { return recgrammar; }    void SetEnabled(bool b, GrammarScope aScope = GRS_NONE)   {     enabled = b;     activatedScope = aScope;   }    GrammarScope GetScope(void) const        { return activatedScope; }   unsigned long GetSequence(void) const     { return grammarSeq; }    bool IsEnabled() const                   { return enabled; }   bool IsScope(GrammarScope s) const       { return s == scope; }    bool IsField(const vxistring & f) const  { return f == field; }   bool IsDialog(const vxistring & d) const { return d == dialog; }   bool IsDoc(const vxistring & d) const    { return d == docID; }   void GetElement(VXMLElement & e) const   { e = element; }  private:   void _Initialize(const VXMLElement & elem);   // This sets the field & dialog names.    const VXMLElement element;   VXIrecGrammar *   recgrammar;   // grammar handle returned from rec interface   GrammarScope      scope;   vxistring         field;   vxistring         dialog;   vxistring         docID;   bool              enabled;    // store current activated info to determine precedence   GrammarScope      activatedScope;   unsigned long     grammarSeq; };   GrammarInfo::GrammarInfo(VXIrecGrammar * g,                          const vxistring & id,                          const VXMLElement & elem,                          unsigned long gSeq)   : element(elem), recgrammar(g), scope(GRS_NONE), docID(id), enabled(false),   activatedScope(GRS_NONE), grammarSeq(gSeq) {   // (1) Determine the grammar scope.    // (1.1) Obtain default from position in the tree.   VXMLElement par = elem;   while (par != 0) {     VXMLElementType name = par.GetName();     if (name == NODE_INITIAL || name == NODE_FIELD ||         name == NODE_RECORD  || name == NODE_TRANSFER)       { scope = GRS_FIELD;  break; }     else if (name == NODE_FORM || name == NODE_MENU)       { scope = GRS_DIALOG; break; }     else if (name == NODE_VXML || name == DEFAULTS_LANGUAGE ||              name == DEFAULTS_ROOT)       { scope = GRS_DOC;    break; }     par = par.GetParent();   }    // (1.2) if scope explicitly specified in grammar or parent, override!   vxistring str;   elem.GetAttribute(ATTRIBUTE_SCOPE, str);   if (str.empty() && par != 0) {     par.GetAttribute(ATTRIBUTE_SCOPE, str);   }   if (!str.empty()) {     if (str == L"dialog")        scope = GRS_DIALOG;     else if (str == L"document") scope = GRS_DOC;   }    // (2) Do remaining initialization.   _Initialize(elem); }   GrammarInfo::~GrammarInfo() {   // NOTE: 'recgrammar' must be freed externally. }   void GrammarInfo::_Initialize(const VXMLElement & elem) {   if (elem == 0) return;    VXMLElementType name = elem.GetName();    if (name == NODE_FIELD || name == NODE_INITIAL ||       name == NODE_RECORD || name == NODE_TRANSFER)     elem.GetAttribute(ATTRIBUTE__ITEMNAME, field);   else if (name == NODE_FORM || name == NODE_MENU) {     elem.GetAttribute(ATTRIBUTE__ITEMNAME, dialog);     return;   }    _Initialize(elem.GetParent()); }  //#############################################################################  class GrammarInfoUniv { public:   GrammarInfoUniv(VXIrecGrammar * g, const VXMLElement & e, const vxistring & l,                   const vxistring & n, unsigned long seq)     : element(e), recgrammar(g), languageID(l), name(n), enabled(false),       grammarSeq(seq) { }    ~GrammarInfoUniv() { } // NOTE: 'recgrammar' must be freed externally.  public:   void SetEnabled(bool b)                  { enabled = b; }   bool IsEnabled() const                   { return enabled; }    VXIrecGrammar * GetRecGrammar() const    { return recgrammar; }   unsigned long GetSequence() const        { return grammarSeq; }   const vxistring & GetLanguage() const    { return languageID; }   const vxistring & GetName() const        { return name; }    void GetElement(VXMLElement & e) const   { e = element; }  private:   const VXMLElement element;   VXIrecGrammar *   recgrammar;   // grammar handle returned from rec interface   vxistring         languageID;   vxistring         name;   bool              enabled;   unsigned long     grammarSeq; };  //############################################################################# // Grammar description class //#############################################################################  GrammarManager::GrammarManager(VXIrecInterface * r, const SimpleLogger & l)   : log(l), vxirec(r), grammarSequence(0) { }   GrammarManager::~GrammarManager() {   ReleaseGrammars(); }  void GrammarManager::ThrowSpecificEventError(VXIrecResult err, OpType opType) {   switch (err) {     case VXIrec_RESULT_SUCCESS: break;     case VXIrec_RESULT_NO_RESOURCE:       throw VXIException::InterpreterEvent(EV_ERROR_NORESOURCE);     case VXIrec_RESULT_NO_AUTHORIZATION:       throw VXIException::InterpreterEvent(EV_ERROR_NOAUTHORIZ);     case VXIrec_RESULT_MAX_SPEECH_TIMEOUT:       throw VXIException::InterpreterEvent(EV_MAXSPEECH);     case VXIrec_RESULT_UNSUPPORTED_FORMAT:       throw VXIException::InterpreterEvent(EV_UNSUPPORT_FORMAT);     case VXIrec_RESULT_UNSUPPORTED_LANGUAGE:       throw VXIException::InterpreterEvent(EV_UNSUPPORT_LANGUAGE);     case VXIrec_RESULT_UNSUPPORTED_BUILTIN:       throw VXIException::InterpreterEvent(EV_UNSUPPORT_BUILTIN);     case VXIrec_RESULT_FETCH_TIMEOUT:     case VXIrec_RESULT_FETCH_ERROR:       throw VXIException::InterpreterEvent(EV_ERROR_BADFETCH);     case VXIrec_RESULT_OUT_OF_MEMORY:       throw VXIException::OutOfMemory();     // these events are supported for hotword transfer functionality     case VXIrec_RESULT_CONNECTION_NO_AUTHORIZATION:       throw VXIException::InterpreterEvent(EV_TELEPHONE_NOAUTHORIZ);     case VXIrec_RESULT_CONNECTION_BAD_DESTINATION:       throw VXIException::InterpreterEvent(EV_TELEPHONE_BAD_DEST);     case VXIrec_RESULT_CONNECTION_NO_ROUTE:       throw VXIException::InterpreterEvent(EV_TELEPHONE_NOROUTE);     case VXIrec_RESULT_CONNECTION_NO_RESOURCE:       throw VXIException::InterpreterEvent(EV_TELEPHONE_NORESOURCE);     case VXIrec_RESULT_UNSUPPORTED_URI:       throw VXIException::InterpreterEvent(EV_TELEPHONE_UNSUPPORT_URI);     default:       if( opType == GRAMMAR )         throw VXIException::InterpreterEvent(EV_ERROR_BAD_GRAMMAR);   } }  void GrammarManager::LoadGrammars(const VXMLElement& doc,                                   vxistring & documentID,                                   PropertyList & properties,                                   bool isDefaults) {   if (doc == 0) return;    // (1) Retrieve the ID for this document.  This is important for grammar   // activation.   if (doc.GetName() == NODE_VXML)     doc.GetAttribute(ATTRIBUTE__ITEMNAME, documentID);    // (2) Recursively find and build all grammars on this page.   if (isDefaults)     BuildUniversals(doc, properties);   else {     VXIMapHolder temp(NULL);     BuildGrammars(doc, documentID, properties, temp);   } }   VXIrecGrammar * GrammarManager::BuildInlineGrammar(const VXMLElement & element,                                                 const VXIMapHolder & localProps) {   vxistring text, header, trailer;    // (1) Get CDATA in this element   GetEnclosedText(log, element, text);    // (2) Get attributes   vxistring mimeType, mode, root, tagFormat, xmlBase, xmlLang;   element.GetAttribute(ATTRIBUTE_TYPE, mimeType);   element.GetAttribute(ATTRIBUTE_MODE, mode);   element.GetAttribute(ATTRIBUTE_ROOT, root);   element.GetAttribute(ATTRIBUTE_TAGFORMAT, tagFormat);   element.GetAttribute(ATTRIBUTE_BASE, xmlBase);   element.GetAttribute(ATTRIBUTE_XMLLANG, xmlLang);    // (3) Determine the mimetype.    // if mimetype is empty but root is defined   // assume that this is srgs+xml mimetype   if( mimeType.empty() && !root.empty())     mimeType = L"application/srgs+xml";    if( mimeType.empty() && mode == L"dtmf" )     mimeType = REC_MIME_CHOICE_DTMF;    // (4) Is this an SRGS grammar?   if (mimeType.find(L"application/srgs+xml") == 0 &&       (mimeType.length() == 20 || mimeType[20] == L';'))   {     // All grammars have a language assigned during parsing.     header = L"<?xml version='1.0'?>"              L"<grammar xmlns='http://www.w3.org/2001/06/grammar'"              L" version='1.0' mode='";     header += mode;     header += L"' root='";     header += root;     if (!tagFormat.empty()) {       header += L"' tag-format='";       header += tagFormat;     }     if (!xmlLang.empty()) {       header += L"' xml:lang='";       header += xmlLang;     }     if (!xmlBase.empty()) {       header += L"' xml:base='";       header += xmlBase;     }     header += L"'>";      trailer = L"</grammar>";   }    // (5) Create the grammar.   if (log.IsLogging(2)) {     log.StartDiagnostic(2) << L"GrammarManager::LoadGrammars - type="            << mimeType << L", grammar=" << header << text << trailer << L">";     log.EndDiagnostic();   }    VXIrecGrammar * vg = NULL;    if (header.empty() && trailer.empty())     vg = GrammarManager::CreateGrammarFromString(vxirec, log, text,                                                  mimeType.c_str(),                                                  localProps);   else     vg = GrammarManager::CreateGrammarFromString(vxirec, log,                                                  header + text + trailer,                                                  mimeType.c_str(),                                                  localProps);    if (vg == NULL)     throw VXIException::InterpreterEvent(EV_ERROR_BAD_INLINE);    return vg; }   // This function is used to recursively walk through the tree, loading and // speech or dtmf grammars which are found. // // NOTE: There is a rather messy optimization with properties, levelProperties, //       and localProps.  This made the code much harder to read but had //       significant performance benefits.  Be very careful! // void GrammarManager::BuildGrammars(const VXMLElement& doc,                                   const vxistring & documentID,                                   PropertyList & properties,                                   VXIMapHolder & levelProperties,                                   int menuAcceptLevel) {   // (1) Look for grammars in current nodes.    for (VXMLNodeIterator it(doc); it; ++it) {     VXMLNode child = *it;     if (child.GetType() != VXMLNode::Type_VXMLElement) continue;     const VXMLElement & element = reinterpret_cast<const VXMLElement &>(child);     VXMLElementType elementName = element.GetName();      // (2) Handle <grammar>      if (elementName == NODE_GRAMMAR) {       vxistring src;       element.GetAttribute(ATTRIBUTE_SRC, src);       // (2.1) Get the recognizer properties associated with this element.       if (levelProperties.GetValue() == NULL)         levelProperties.Acquire(GetRecProperties(properties));        VXIMapHolder localProps(NULL);       localProps = levelProperties;        SetGrammarLoadProperties(element, localProps);        // (2.2) Does the grammar come from an external URI?       if (!src.empty()) {         if (log.IsLogging(2)) {           log.StartDiagnostic(2) << L"GrammarManager::LoadGrammars - <grammar "             L"src=\"" << src << L"\">";           log.EndDiagnostic();         }          // (2.2.1) Generate error if fragment-only URI in external grammar         if (!src.empty() && src[0] == '#') {             log.LogError(215);             throw VXIException::InterpreterEvent(EV_ERROR_SEMANTIC,                 L"a fragment-only URI is not permited in external grammar");         }          VXIMapHolder fetchobj;         if (fetchobj.GetValue() == NULL) throw VXIException::OutOfMemory();         properties.GetFetchobjCacheAttrs(element, PropertyList::Grammar,                                          fetchobj);          // (2.2.2) Load the grammar from the URI.         vxistring mimeType;         element.GetAttribute(ATTRIBUTE_TYPE, mimeType);          VXIrecGrammar * vg           = GrammarManager::CreateGrammarFromURI(vxirec, log, src,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -