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

📄 vxi.cpp

📁 sloedgy open sip stack source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:

 /****************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 "VXI.hpp"
 #include "DocumentParser.hpp"
 #include "SimpleLogger.hpp"
 #include "ValueLogging.hpp"            // for VXIValue dumping
 #include "Scripter.hpp"                // for use in ExecutionContext
 #include "GrammarManager.hpp"          // for use in ExecutionContext
 #include "Counters.hpp"                // for EventCounter
 #include "PropertyList.hpp"            // for PropertyList
 #include "PromptManager.hpp"           // for PromptManager
 #include "AnswerParser.hpp"            // for AnswerParser
 #include "VXML.h"                      // for node & attribute names
 #include "vxi/VXItel.h"                    // for VXItelInterface
 #include "vxi/VXIrec.h"                    // for parameters from rec answer
 #include "vxi/VXIlog.h"                    // for event IDs
 #include "vxi/VXIobject.h"                 // for Object type
 #include "vxi/VXIinet.h"
 #include <deque>                       // for deque (used by Prompts)
 #include <sstream>                     // by ProcessNameList()
 #include <algorithm>                   // for sort, set_intersection, etc.
 
 //#pragma message ("Cleanup comments - Did FIA level functions")
 
 static const wchar_t * const SCOPE_Session       = L"session";
 static const wchar_t * const SCOPE_Defaults      = L"$_platDefaults_";
 static const wchar_t * const SCOPE_Application   = L"application";
 static const wchar_t * const SCOPE_Document      = L"document";
 static const wchar_t * const SCOPE_Dialog        = L"dialog";
 static const wchar_t * const SCOPE_Local         = L"local";
 static const wchar_t * const SCOPE_Anonymous     = L"$_execAnonymous_";
 
 static const wchar_t * const GENERIC_DEFAULTS    = L"*";
 
 const int DEFAULT_MAX_EXE_STACK_DEPTH = 5;
 const int DEFAULT_MAX_EVENT_RETHROWS  = 6;
 const int DEFAULT_MAX_EVENT_COUNT     = 12;

#ifdef _MSC_VER
#pragma warning(disable:4505)
#endif

 
 // ------*---------*---------*---------*---------*---------*---------*---------
 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;
 }
 
 // ------*---------*---------*---------*---------*---------*---------*---------
 
 class VXIPromptTranslator : public PromptTranslator {
 public:
   virtual VXIValue * EvaluateExpression(const vxistring & expression)
   { if (expression.empty()) return NULL;
     return jsi.EvalScriptToValue(expression); }
 
   virtual void SetVariable(const vxistring & name, const vxistring & value)
   { if (name.empty()) return;
     jsi.MakeVar(name, NULL);
     jsi.SetString(name, value); }
 
   VXIPromptTranslator(Scripter & j) : jsi(j) { }
   virtual ~VXIPromptTranslator() { }
 
 private:
   Scripter & jsi;
 };
 
 class VXIAnswerTranslator : public AnswerTranslator {
 public:
   virtual void EvaluateExpression(const vxistring & expression)
   { if (expression.empty()) return;
     jsi.EvalScript(expression); }
 
   virtual void SetString(const vxistring & var, const vxistring & val)
   { jsi.SetString(var, val); }
 
   VXIAnswerTranslator(Scripter & j) : jsi(j) { }
   virtual ~VXIAnswerTranslator() { }
 
 private:
   Scripter & jsi;
 };
 
 // VXIContent  wrapper that aid to
 // do automated memory managment, the class take ownership of the
 // passed-in content
 class VXIContentHolder {
 public:
   VXIContentHolder() : _content(NULL), _contentSize(0),
                        _contentValue(NULL), _contentType(NULL) { }
   VXIContentHolder(VXIContent* c) 
                      : _content(NULL), _contentSize(0),
                        _contentValue(NULL), _contentType(NULL) {SetContent(c);}
 
   virtual ~VXIContentHolder()   { if (_content) VXIContentDestroy(&_content); }
   const VXIbyte* GetValue()      { return _contentValue; }
   const VXIchar* GetType()       { return _contentType; }
   VXIulong GetSize()             { return _contentSize; }
   const VXIContent* GetContent() { return _content; }
 
   VXIContent* Release(void)
     { VXIContent* c = _content; _content = NULL; return c; }
 
   void SetContent(VXIContent* content) 
   {
     _content = content; 
     if( _content )
       VXIContentValue(_content, &_contentType, &_contentValue, &_contentSize);
   }
   
 private:
   VXIContent* _content;
   const VXIchar* _contentType;
   const VXIbyte* _contentValue;
   VXIulong _contentSize;
   
   // do not allow these operations
   VXIContentHolder(const VXIContentHolder &);
   VXIContentHolder & operator=(const VXIContentHolder &);
 };
 
 // Thrown after a successful recognition.
 //
 class AnswerInformation {
 public:
   VXMLElement element;
   VXMLElement dialog;
 
   AnswerInformation(VXMLElement & e, VXMLElement & d)
     : element(e), dialog(d)  { }
 };
 
 class JumpReturn {
 public:
   JumpReturn() { }
 };
 
 class JumpItem {
 public:
   VXMLElement item;
   JumpItem(const VXMLElement & i) : item(i) { }
 };
 
 class JumpDialog {
 public:
   VXMLElement dialog;
   JumpDialog(const VXMLElement d) : dialog(d)  { }
 };
 
 class JumpDoc {
 public:
   VXMLElement  defaults;
   VXMLDocument application;
   vxistring    applicationURI;
   VXMLDocument document;
   vxistring    documentURI;
   VXMLElement  documentDialog;
   bool         isSubdialog;
   bool         isSubmitElement;
   PropertyList properties;
   
   JumpDoc(const VXMLElement & def, const VXMLDocument & app,
           const vxistring & appURI, const VXMLDocument & doc, const vxistring & docURI,
           const VXMLElement & docdial, bool issub, bool issubmit, const PropertyList & p)
     : defaults(def), application(app), applicationURI(appURI),
       document(doc), documentURI(docURI), documentDialog(docdial), isSubdialog(issub), 
       isSubmitElement(issubmit), properties(p)
   { }
 
   ~JumpDoc() { }
 };
 
 //#############################################################################
 // ExecutionContext & Utilities
 //#############################################################################
 
 class ExecutionContext {
 public:
   // These are used by the main run loops, event handling, and subdialog.
   // Each of these gets initialized by InstallDocument.
 
   VXMLElement    platDefaults;
 
   VXMLDocument   application;
   vxistring      applicationURI;
 
   VXMLDocument   document;
   vxistring      documentName;
   vxistring      documentURI;
 
   VXMLElement    currentDialog;
   VXMLElement    currentFormItem;
 
   // Limited purpose members.
   VXMLElement    eventSource;        // For prompting (enumerate) during events
   VXMLElement    lastItem;           // Set by <subdialog>
 
 public: // These are used more generally.
   Scripter       script;
   GrammarManager gm;
   PromptTracker  promptcounts;
   EventCounter   eventcounts;
   PropertyList   properties;
 
   typedef std::deque<vxistring> STRINGDEQUE;
   STRINGDEQUE formitems;
 
   bool playingPrompts;
 
   ExecutionContext * next;
 
   ExecutionContext(VXIrecInterface * r, VXIjsiInterface * j,
                    const SimpleLogger & l, ExecutionContext * n)
     : script(j), gm(r, l), next(n), playingPrompts(true), properties(l) { }
     // may throw VXIException::OutOfMemory()
 
   ~ExecutionContext() { }
 };
 
 
 typedef std::deque<vxistring> STRINGDEQUE;
 
 static void ProcessNameList(const vxistring & namelist, STRINGDEQUE & names)
 {
   names.clear();
   if (namelist.empty()) return;
 
   // The namelist is a series of whitespace delimited strings.  Read each in
   // and insert it into the deque.
 
   std::basic_stringstream<VXIchar> namestream(namelist);
 
 #if (defined(__GNUC__) || defined(_decunix_))
   // G++ 2.95 and 3.0.2 do not fully support istream_iterator.
   while (namestream.good()) {
     vxistring temp;
     namestream >> temp;
     if (!temp.empty()) names.push_back(temp);
   }
 #else
   std::copy(std::istream_iterator<vxistring, VXIchar>(namestream),
             std::istream_iterator<vxistring, VXIchar>(),
             std::back_inserter(names));
 #endif
 
   // Now sort the deque and return the unique set of names.
 
   if (names.empty()) return;
   std::sort(names.begin(), names.end());
   STRINGDEQUE::iterator i = std::unique(names.begin(), names.end());
   if (i != names.end()) names.erase(i, names.end());
 }
 
 //#############################################################################
 // Creation and Run
 //#############################################################################
 
 VXI::VXI()
   : parser(NULL), log(NULL), inet(NULL), rec(NULL), jsi(NULL), tel(NULL),
     exe(NULL), stackDepth(0), sdParams(NULL), sdResult(NULL), sdEvent(NULL),
     updateDefaultDoc(true), mutex(), uriPlatDefaults(), uriBeep(),
     lineHungUp(false), stopRequested(false), haveExternalEvents(false)
 {
   try {
     parser = new DocumentParser();
   }
   catch (const VXIException::OutOfMemory &) {
     parser = NULL;
     throw;
   }
 
   try {
     pm = new PromptManager();
   }
   catch (...) {
     delete parser;
     parser = NULL;
     pm = NULL;
     throw;
   }
 
   if (pm == NULL) {
     delete parser;
     parser = NULL;
     throw VXIException::OutOfMemory();
   }
 }
 
 
 VXI::~VXI()
 {
   while (exe != NULL) {
     ExecutionContext * temp = exe->next;
     delete exe;
     exe = temp;
   }
 
   delete pm;
   delete parser;
 }
 
 
 // Determine if the user has already hung-up
 // if it is the case, throw the exit element to indicate
 // end of call
 void VXI::CheckLineStatus()
 {
   VXItelStatus status;
   int telResult = tel->GetStatus(tel, &status);
 
   bool needToThrow = false;
   if (telResult != VXItel_RESULT_SUCCESS) {
     needToThrow = true;
     log->LogError(201);
   }
   else if (status == VXItel_STATUS_INACTIVE)
     needToThrow = true;
 
   if (needToThrow) {
     mutex.Lock();
     bool alreadyHungup = lineHungUp;
     lineHungUp = true;
     mutex.Unlock();
     if (alreadyHungup) {
       log->LogDiagnostic(1, L"VXI::CheckLineStatus - Call has been hung-up, "
                          L"exiting...");
       throw VXIException::Exit(NULL);
     }
     else
       throw VXIException::InterpreterEvent(EV_TELEPHONE_HANGUP);
   }
 }
 
 
 bool VXI::SetRuntimeProperty(PropertyID id, const VXIchar * value)
 {
   mutex.Lock();
 
   switch (id) {
   case VXI::BeepURI:
     if (value == NULL) uriBeep.erase();
     else uriBeep = value;
     break;
   case VXI::PlatDefaultsURI:
     if (value == NULL) uriPlatDefaults.erase();
     else uriPlatDefaults = value;
     updateDefaultDoc = true;
     break;
   default:
     mutex.Unlock();
     return false;
   }
 
   mutex.Unlock();
   return true;
 }
 
 
 void VXI::GetRuntimeProperty(PropertyID id, vxistring & value) const
 {
   mutex.Lock();
 

⌨️ 快捷键说明

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