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

📄 grammarmanager.cpp

📁 sloedgy open sip stack source code
💻 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 <vxibuildopts.h>
#if P_VXI


 #include "GrammarManager.hpp"
 
 #include "SimpleLogger.hpp"
 #include "CommonExceptions.hpp"
 #include "PropertyList.hpp"
 #include "VXML.h"
 #include "DocumentModel.hpp"
 #include <sstream>

#ifdef _MSC_VER
#pragma warning(disable:4061)
#endif
 
 //#############################################################################
 // 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;

⌨️ 快捷键说明

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