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

📄 vxi.cpp

📁 Open VXI. This is a open source.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
bool VXI::PushExecutionContext(const VXIMap * sessionArgs){  log->LogDiagnostic(2, L"VXI::PushExecutionContext()");  if (stackDepth >= MAX_EXE_STACK_DEPTH) {    log->LogError(211);    return false;  }  ExecutionContext * ep = new ExecutionContext(rec, jsi, *log, exe);  if (ep == NULL) throw VXIException::OutOfMemory();  exe = ep;  ++stackDepth;  // Init new context from channel  exe->script.PushScope(SCOPE_Session);  if (sessionArgs != NULL && VXIMapNumProperties(sessionArgs) != 0) {    const vxistring SESSIONDOT = vxistring(SCOPE_Session) + L".";    const VXIchar * key;    const VXIValue * value;    VXIMapIterator * i = VXIMapGetFirstProperty(sessionArgs, &key, &value);    exe->script.SetValue(SESSIONDOT + key, value);    while (VXIMapGetNextProperty(i, &key, &value) == VXIvalue_RESULT_SUCCESS)      exe->script.SetValue(SESSIONDOT + key, value);    VXIMapIteratorDestroy(&i);  }    log->LogDiagnostic(2, L"VXI::PushExecutionContext - session variables "                       L"initialized");  return true;}void VXI::PopExecutionContext(){  if (exe == NULL) return;  ExecutionContext * current = exe;  exe = current->next;  --stackDepth;  delete current;}void VXI::AttemptDocumentLoad(const vxistring & uri,                              const VXIMapHolder & uriProperties,                              VXMLDocument & doc,                              VXIMapHolder & docProperties,                              bool isDefaults){  // (1) Create map to store document properties.  if (docProperties.GetValue() == NULL)     throw VXIException::OutOfMemory();  // (2) Fetch the document  int result = parser->FetchDocument(uri.c_str(), uriProperties, inet,                                     *log, doc, docProperties, isDefaults);  // (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, SimpleLogger::URI, uri.c_str());    throw VXIException::InterpreterEvent(EV_ERROR_BADFETCH);  case 3: // Unable to read from URI    log->LogError(204, SimpleLogger::URI, uri.c_str());    throw VXIException::InterpreterEvent(EV_ERROR_BADFETCH);  case 4: // Unable to parse contents of URI    log->LogError(205, SimpleLogger::URI, uri.c_str());    throw VXIException::InterpreterEvent(EV_ERROR_BADFETCH);  default:    log->LogError(206, SimpleLogger::URI, uri.c_str());    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   3void VXI::RunInnerLoop(){  log->LogDiagnostic(2, L"VXI::RunInnerLoop()");  if (exe->currentDialog == 0) {    log->LogError(999, SimpleLogger::MESSAGE, L"no current active document");    return;  }  int loop_count = 0;  VXMLElement item = exe->lastItem;  exe->lastItem = VXMLElement();  bool newDialog = (item == 0);  exe->playingPrompts = true;  // For passing answers.  RecognitionAnswer unprocessedAnswer;  bool usedDTMF = false;  bool formLevelGrammar = false;  while (1) {    try {      // (1) Check loop count. Throw event if exceeded, caught in DocumentLoop      if (++loop_count > 4 * MAX_LOOP_ITERATIONS) {        log->LogError(210);        throw VXIException::InterpreterEvent(EV_ERROR_LOOP_COUNT);      }      try {        if (exe->script.CurrentScope(SCOPE_Anonymous)) 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_Local))  exe->script.PopScope();          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 (item == 0) {            DoInnerJump(exe->currentDialog, L"");            break;          }        }        // (3) The loop cases.        if (!unprocessedAnswer.keys.empty()) {          // (3.1) Re-entering loop with an unprocessed recognition result.          RecognitionAnswer temp = unprocessedAnswer;          unprocessedAnswer.Clear();          ProcessRecognitionResult(exe->currentDialog,                                    formLevelGrammar ? VXMLElement() : item,                                   usedDTMF, temp);        }        else if (sdResult != NULL) {          // (3.2) Re-entering loop after returning from a <subdialog>.          VXIValue * temp = sdResult;          sdResult = NULL;          ProcessReturn(exe->currentDialog, item, temp);        }        else {          // (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.          if (exe->script.CurrentScope(SCOPE_Local)) exe->script.PopScope();          exe->script.PushScope(SCOPE_Local);                    // Do the 'collect phase & process phase' from the FIA.          CollectPhase(exe->currentDialog, item);        }      }      catch (const VXIException::InterpreterEvent & e) {        // Handles document events.        if (log->IsLogging(2)) {          log->StartDiagnostic(2) << L"VXI::RunInnerLoop - got exception: "                                  << e.GetValue();          log->EndDiagnostic();        }        if (item != 0)          DoEvent(item, e);        else          DoEvent(exe->currentDialog, e);      }      DoInnerJump(exe->currentDialog, L"");      break;    }    catch (JumpDialog & e) { // Handle <goto> events      exe->currentDialog = e.dialog;      item = VXMLElement();      newDialog = true;    }    catch (const JumpItem & e) { // This handles local <goto>s.      item = e.item;    }    catch (AnswerInformation & e) {      if (exe->currentDialog != e.dialog) {        exe->currentDialog = e.dialog;        item = e.element;        newDialog = true;      }      unprocessedAnswer = e.recAnswer;      usedDTMF = e.usedDTMF;      formLevelGrammar = (e.dialog == e.element);    }  } // while (1)  log->LogDiagnostic(2, L"VXI::RunInnerLoop - done");}void VXI::ProcessReturn(const VXMLElement& form, const VXMLElement & item,                        VXIValue * & result){  log->LogDiagnostic(2, L"VXI::ProcessReturn()");  if (VXIValueGetType(result) == VALUE_STRING) {    const VXIString * temp = reinterpret_cast<const VXIString *>(result);    throw VXIException::InterpreterEvent(toString(temp));  }      vxistring filled;  item.GetAttribute(ATTRIBUTE__ITEMNAME, filled);  exe->script.SetValue(filled, result);  VXIValueDestroy(&result);  EasyFilled(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();  // (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> elements.    VXMLElementType nodeName = elem.GetName();    if (nodeName == NODE_VAR) {      // (3.1.1) We first follow the normal proceedure.      var_element(elem);      if (params.GetValue() != NULL) {        // (3.1.2) Undefined variables get set 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() && !exe->script.IsVarDefined(name)) {          const VXIValue * value = VXIMapGetProperty(params.GetValue(),                                                     name.c_str());          if (value != NULL) {            exe->script.SetValue(name, value);            VXIMapDeleteProperty(params.GetValue(), name.c_str());          }        }      }      continue;    }    // (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);    elem.GetAttribute(ATTRIBUTE_EXPR, expr);    exe->script.MakeVar(name, expr);    exe->formitems.push_back(name);  }  // (4) Did all incoming parameters get used?  if (params.GetValue() != NULL &&      VXIMapNumProperties(params.GetValue()) != 0)    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;}// Finds the named form item within the dialog.  If the name is empty, the// first non-filled item is returned.//void VXI::DoInnerJump(const VXMLElement & elem, const vxistring & item){  if (elem == 0) return;  if (log->IsLogging(2)) {    log->StartDiagnostic(2) << L"VXI::DoInnerJump(" << item << L")";    log->EndDiagnostic();  }  // find form.  VXMLElement current = elem;  while (1) {    VXMLElementType nodeName = current.GetName();    if (nodeName == NODE_MENU)      throw JumpItem(current); // Menu is a special case.    if (nodeName == NODE_FORM)      break;    const VXMLElement & parent = current.GetParent();    if (parent == 0) {      log->LogError(999, SimpleLogger::MESSAGE,                    L"could not locate form on local jump");      throw VXIException::Fatal();    }    current = parent;  };  // (2) If the next item is specified (such as from a previous <goto>, look  //     for an exact match.  if (!item.empty()) {    for (VXMLNodeIterator it(current); it; ++it) {      VXMLNode child = *it;      if (child.GetType() != VXMLNode::Type_VXMLElement) continue;      const VXMLElement & elem = reinterpret_cast<const VXMLElement &>(child);      if (!IsFormItemNode(elem)) continue;      vxistring name;      if (!elem.GetAttribute(ATTRIBUTE__ITEMNAME, name)) continue;      if (item == name) throw JumpItem(elem);    }  }  // (3) Otherwise, find the first non-filled item with a valid condition.  else {    for (VXMLNodeIterator it(current); it; ++it) {      VXMLNode child = *it;      if (child.GetType() != VXMLNode::Type_VXMLElement) continue;      const VXMLElement & elem = reinterpret_cast<const VXMLElement &>(child);      if (!IsFormItemNode(elem)) continue;      // Must use itemname here, as could be implicit name      vxistring itemname;      if (!elem.GetAttribute(ATTRIBUTE__ITEMNAME, itemname)) {        log->LogError(999, SimpleLogger::MESSAGE,                      L"unnamed item found on local jump");        throw VXIException::Fatal();      }      if (exe->script.IsVarDefined(itemname)) continue;      // OK if var is undefined, check condition      vxistring cond;      elem.GetAttribute(ATTRIBUTE_COND, cond);      if (cond.empty() || exe->script.TestCondition(cond))        throw JumpItem(elem);    }  }

⌨️ 快捷键说明

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