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

📄 vxi.cpp

📁 sloedgy open sip stack source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
       if (val != NULL && VXIValueGetType(val) == VALUE_STRING)
         diagUri = VXIStringCStr(reinterpret_cast<const VXIString *>(val));
 
       vxistring temp(L"URL");
       temp += L": ";
       temp += diagUri.c_str();
       temp += L", ";
       temp += VXIStringCStr(key);
       temp += L": ";
       temp += VXIStringCStr(value);
       log->LogDiagnostic(SimpleLogger::DOC_DUMPS, temp.c_str());
     }
     delete [] cbuffer;
     cbuffer = NULL;
     if (key) VXIStringDestroy(&key);
     if (value) VXIStringDestroy(&value);
   }
   
   // (3) Handle error conditions.
   switch (result) {
   case -1: // Out of memory
     throw VXIException::OutOfMemory();
   case 0:  // Success
     break;
   case 1: // Invalid parameter
   case 2: // Unable to open URI
     log->LogError(203);
     // now look at the http status code to throw the 
     // compiliant error.badfetch.http.<response code> 
     if (docProperties.GetValue()) {
       // retrieve response code
       VXIint iv = 0;
       const VXIValue *v = 
         VXIMapGetProperty(docProperties.GetValue(), INET_INFO_HTTP_STATUS);
       if( v && VXIValueGetType(v) == VALUE_INTEGER &&
           ((iv = VXIIntegerValue(reinterpret_cast<const VXIInteger *>(v))) > 0)
          )
       {
         std::basic_stringstream<VXIchar> respStream;
         respStream << EV_ERROR_BADFETCH << L".http.";
         respStream << iv;
         
         throw VXIException::InterpreterEvent(respStream.str().c_str());    
       }
     }                      
     throw VXIException::InterpreterEvent(EV_ERROR_BADFETCH);  
   case 3: // Unable to read from URI
     log->LogError(204);
     throw VXIException::InterpreterEvent(EV_ERROR_BADFETCH);
   case 4: // Unable to parse contents of URI
   { 
     VXIString *key = NULL, *value = NULL;
     if ((cbuffer) && 
         ((log->IsLogging(SimpleLogger::DOC_PARSE_ERROR_DUMPS)) ||
          (log->IsLogging(SimpleLogger::DOC_DUMPS))) &&
         (log->LogContent(VXI_MIME_XML, cbuffer, bufferSize, &key, &value)))
       log->LogError(205, VXIStringCStr(key), VXIStringCStr(value));
     else
       log->LogError(205);
     if (cbuffer) delete [] cbuffer;
     if (key) VXIStringDestroy(&key);
     if (value) VXIStringDestroy(&value);
     throw VXIException::InterpreterEvent(EV_ERROR_BADFETCH);
   }
   default:
     log->LogError(206);
     throw VXIException::Fatal();
   }
 
   if (doc.GetRoot() == 0) {
     log->LogError(999, SimpleLogger::MESSAGE,
                   L"able to fetch initial document but node empty");
     throw VXIException::Fatal();
   }
 }
 
 
 void VXI::ProcessRootScripts(VXMLElement& doc)
 {
   if (doc == 0) return;
 
   log->LogDiagnostic(2, L"VXI::ProcessRootScripts()");
 
   // Do <var> <script> and <meta> <property> elements
   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_VAR)
       var_element(elem);
     else if (nodeName == NODE_META)
       meta_element(elem);
     else if (nodeName == NODE_SCRIPT)
       script_element(elem);
   }
 
   log->LogDiagnostic(2, L"VXI::ProcessRootScripts - done");
 }
 
 
 //#############################################################################
 // Dialog Loop
 //#############################################################################
 
 // There are two cases in which this routine may be entered.
 //   A. After a new document is loaded  (lastItem == 0)
 //   B. After a return from <subdialog>
 // and three ways in which the loop may be re-entered.
 //   1. Jump to new dialog.
 //   2. Jump to new form item in the existing dialog.
 //   3. Jump to new dialog after recognizing a document scope grammar.
 //
 // The ECMA script scopes are reset accordingly:
 //   anonymous: A B 1 2 3
 //   local:     A   1 2 3
 //   dialog:    A   1   3
 
 void VXI::RunInnerLoop()
 {
   log->LogDiagnostic(2, L"VXI::RunInnerLoop()");
 
   if (exe->currentDialog == 0) {
     log->LogError(999, SimpleLogger::MESSAGE, L"no current active document");
     return;
   }
 
   exe->currentFormItem = exe->lastItem; // next item to process; <goto> etc.
   exe->lastItem = VXMLElement();        // reset after <subdialog>
   bool newDialog = (exe->currentFormItem == 0);
   exe->playingPrompts = true;           // flag for prompting after events
 
   // Are we re-entering after a recognition?
   bool unprocessedAnswer = false;
 
   while (1) {
     if (stopRequested) throw VXIException::StopRequest();
 
     try {
       try {
         // (1) Adjust scope if necessary
         if (exe->script.CurrentScope(SCOPE_Anonymous)) exe->script.PopScope();
         if (exe->script.CurrentScope(SCOPE_Local))  exe->script.PopScope();
 
         // (2) Initialize dialog (if necessary)
         if (newDialog) {
           newDialog = false;
           exe->playingPrompts = true;
 
           // (2.1) Reset ECMA script scope.
           if (exe->script.CurrentScope(SCOPE_Dialog)) exe->script.PopScope();
           exe->script.PushScope(SCOPE_Dialog);
 
           // (2.2) Do 'initialization phase' from FIA.
           VXIMapHolder params(sdParams);
           sdParams = NULL;
           FormInit(exe->currentDialog, params);
 
           // (2.3) Do 'select phase' from FIA if the item is not already known
           if (exe->currentFormItem == 0) {
             DoInnerJump(exe->currentDialog, L"");
             break;
           }
         }
 
         // (3) The loop cases.
 
         // (3.1) Re-entering loop with an unprocessed recognition result.
         if (unprocessedAnswer == true) {
           unprocessedAnswer = false;
           HandleRemoteMatch(exe->currentDialog, exe->currentFormItem);
         }
 
         // (3.2) Re-entering loop after returning from a <subdialog>.
         else if (sdResult != NULL) {
           VXIMapHolder temp(sdResult);
           sdResult = NULL;
           ProcessReturn(exe->currentDialog, exe->currentFormItem, temp);
         }
         else if (sdEvent != NULL) {
           // The sdEvent is deallocated in the catch (below).
           throw VXIException::InterpreterEvent(*sdEvent);
         }
 
         // (3.3) Each time we enter collect phase, we get fresh local scope.
         // All filled and catched triggered form here will execute in this
         // scope.  The final local scope is popped with we leave.
         else {
           if (exe->script.CurrentScope(SCOPE_Local)) exe->script.PopScope();
           exe->script.PushScope(SCOPE_Local);
 
           mutex.Lock();
           if (haveExternalEvents) {
             vxistring event, message;
             if (externalEvents.size() > 0) {
               event = externalEvents.front();
               externalEvents.pop_front();
               message = externalMessages.front();
               externalMessages.pop_front();
             }
             if (externalEvents.empty()) haveExternalEvents = false;
             mutex.Unlock();
             throw VXIException::InterpreterEvent(event, message,
                                                  exe->currentDialog);
           }
           mutex.Unlock();
           
           // Do the 'collect phase & process phase' from the FIA.
           CollectPhase(exe->currentDialog, exe->currentFormItem);
         }
       }
       catch (const VXIException::InterpreterEvent & e) {
         // Cleanup sdEvent (if necessary).
         if (sdEvent != NULL) {
           delete sdEvent;
           sdEvent = NULL;
         }
         
         // Handles document events.
         if (log->IsLogging(2)) {
           log->StartDiagnostic(2) << L"VXI::RunInnerLoop - got exception: "
                                   << e.GetValue();
           log->EndDiagnostic();
         }
 
         if (exe->currentFormItem != 0)
           DoEvent(exe->currentFormItem, e);
         else
           DoEvent(exe->currentDialog, e);
       }
 
       DoInnerJump(exe->currentDialog, L"");
       break;
     }
     catch (JumpDialog & e) { // Handle <goto> events
       exe->currentDialog = e.dialog;
       exe->currentFormItem = VXMLElement();
       newDialog = true;
     }
     catch (const JumpItem & e) { // This handles local <goto>s.
       exe->currentFormItem = e.item;
     }
     catch (AnswerInformation & e) {
       if (exe->currentDialog != e.dialog) {
         exe->currentDialog = e.dialog;
         newDialog = true;
       }
       exe->currentFormItem = e.element;
       unprocessedAnswer = true;
     }
   } // while (1)
 
   log->LogDiagnostic(2, L"VXI::RunInnerLoop - done");
 }
 
 
 void VXI::ProcessReturn(const VXMLElement& form, const VXMLElement & item,
                         VXIMapHolder & result)
 {
   log->LogDiagnostic(2, L"VXI::ProcessReturn()");
 
   vxistring filled;
   item.GetAttribute(ATTRIBUTE__ITEMNAME, filled);
 
   exe->script.SetValue(filled, reinterpret_cast<VXIValue*>(result.GetValue()));
   ProcessFilledElements(filled, form);
 }
 
 
 // Perform initialization associated with property tags and form level
 // variables.  Reset the event and prompts counts.
 //
 void VXI::FormInit(const VXMLElement & form, VXIMapHolder & params)
 {
   log->LogDiagnostic(2, L"VXI::FormInit()");
 
   // (1) Set the form properties.
   exe->properties.SetProperties(form, DIALOG_PROP, VXIMapHolder());
 
   // (2) Clear the prompt & event counts when the form is entered.
   exe->promptcounts.Clear();
   exe->eventcounts.Clear();
 
   exe->formitems.clear();
   vxistring itemname;
   form.GetAttribute(ATTRIBUTE__ITEMNAME, itemname);
 
   // (3) Walk through the form nodes.  Set up variables as necessary.
   for (VXMLNodeIterator it(form); it; ++it) {
     VXMLNode child = *it;
 
     if (child.GetType() != VXMLNode::Type_VXMLElement) continue;
     const VXMLElement & elem = reinterpret_cast<const VXMLElement &>(child);
  
     // (3.1) Handle <var> and <script> elements.
     VXMLElementType nodeName = elem.GetName();
     if (nodeName == NODE_VAR) {
       if (params.GetValue() != NULL) {
         // (3.1.1) Set matching variables to the value in the param list.
         // Each located parameter gets removed from the map.
         vxistring name;
         elem.GetAttribute(ATTRIBUTE_NAME, name);
         if (!name.empty()) {
           const VXIValue * value = VXIMapGetProperty(params.GetValue(),
                                                      name.c_str());
           if (value != NULL) {
             exe->script.MakeVar(name, value);
             VXIMapDeleteProperty(params.GetValue(), name.c_str());
             continue;
           }
         }
       }
 
       // (3.1.2) Otherwise, follow the normal proceedure.
       var_element(elem);
       continue;
     }
     else if (nodeName == NODE_SCRIPT)
       script_element(elem);
 
     // (3.2) Ignore anything which is not a form item.
     if (!IsFormItemNode(elem)) continue;
 
     // (3.3) Initialize variables for each form item.
     vxistring name;
     vxistring expr;
     elem.GetAttribute(ATTRIBUTE__ITEMNAME, name);
 
     if (exe->script.IsVarDeclared(name)) {
       throw VXIException::InterpreterEvent(EV_ERROR_BADFETCH, 
                                          L"input item variable name conflict");
     }
 
     elem.GetAttribute(ATTRIBUTE_EXPR, expr);
     exe->script.MakeVar(name, expr);
 
     nodeName = elem.GetName();
     if (nodeName == NODE_FIELD || nodeName == NODE_RECORD ||
         nodeName == NODE_TRANSFER)
       exe->script.EvalScript(vxistring(L"var ") + name + L"$ = new Object();");
 
     exe->formitems.push_back(name);
   }
 
   // (4) Did all incoming parameters get used?
   if (params.GetValue() != NULL &&
       VXIMapNumProperties(params.GetValue()) != 0) {
     if (log->IsLogging(2)) {
       const VXIchar *key;
       const VXIValue *value;
       VXIMapIterator *vi = VXIMapGetFirstProperty(params.GetValue(), &key,
                                                   &value);
       while (vi) {
         vxistring text(L"VXI::FormInit - unused parameter ");
         text += key;
         log->LogDiagnostic(2, text.c_str());
         if (VXIMapGetNextProperty(vi, &key, &value) !=VXIvalue_RESULT_SUCCESS){
           VXIMapIteratorDestroy(&vi);
           vi = NULL;
         }
       }
     }
     throw VXIException::InterpreterEvent(EV_ERROR_SEMANTIC);
   }
 
   log->LogDiagnostic(2, L"VXI::FormInit - Done");
 }
 
 
 // Returns true iff the element is a form item.
 //
 // This is the list from section 6.2 of the VXML 1.0 specification with one
 // addition - <menu>.
 //
 bool VXI::IsFormItemNode(const VXMLElement & doc)
 {
   VXMLElementType nodeName = doc.GetName();
   if (nodeName == NODE_FIELD  || nodeName == NODE_INITIAL   ||
       nodeName == NODE_RECORD || nodeName == NODE_TRANSFER  ||
       nodeName == NODE_OBJECT || nodeName == NODE_SUBDIALOG ||
       nodeName == NODE_MENU   || nodeName == NODE_BLOCK)
     return true;
 
   return false;
 }
 
 
 bool VXI::IsInputItemNode(const VXMLElement & doc)
 {
   VXMLElementType nodeName = doc.GetName();

⌨️ 快捷键说明

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