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

📄 vxi.cpp

📁 Open VXI. This is a open source.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  log->LogDiagnostic(2, L"VXI::DoInnerJump - no match found.");}//#############################################################################// Utility functions//#############################################################################// do_event() - top level call into event handler; deals with // event counts and defaults.//void VXI::DoEvent(const VXMLElement & item,                  const VXIException::InterpreterEvent & e){  // (0) Initial logging  if (item == 0) {    log->LogDiagnostic(0, L"VXI::DoEvent - invalid argument, ignoring event");    return;  }  else if (log->IsLogging(2)) {    log->StartDiagnostic(2) << L"VXI::DoEvent(" << e.GetValue() << L")";    log->EndDiagnostic();  }  // (1) Disable queuing of prompts outside of event handler.  exe->playingPrompts = false;  unsigned int count = 0;  VXIException::InterpreterEvent event = e;  do {    try {      // (2) Increments counts associated with this event.      exe->eventcounts.Increment(event.GetValue());      // (3) Process the current event.      exe->eventSource = item;      bool handled = do_event(item, event);      exe->eventSource = VXMLElement();      if (handled) {        if (log->IsLogging(2)) {          log->StartDiagnostic(2) << L"VXI::DoEvent - event processed.";          log->EndDiagnostic();        }        return;      }      // (4) No one willing to handle this event.  Exit.      vxistring exitmessage(L"Unhandled exception: ");      exitmessage += event.GetValue();      VXIString * val = VXIStringCreate(exitmessage.c_str());      if (val == NULL) throw VXIException::OutOfMemory();      throw VXIException::Exit(reinterpret_cast<VXIValue*>(val));    }    // (5) The catch had a <throw> element inside.  Must process the new event.    catch (const VXIException::InterpreterEvent & e) {      event = e;    }  } while (++count < MAX_LOOP_ITERATIONS);    // (6) Probable loop - catch X throws X?  Quit handling after a while.   vxistring exitmessage(L"Unhandled exception (suspected infinite loop)");  VXIString * val = VXIStringCreate(exitmessage.c_str());  if (val == NULL) throw VXIException::OutOfMemory();  throw VXIException::Exit(reinterpret_cast<VXIValue*>(val));}bool VXI::do_event(const VXMLElement & item,                   const VXIException::InterpreterEvent & e){  const vxistring & event = e.GetValue();  // (1) Define the variables for the best match.  int bestCount = 0;  vxistring::size_type bestMatchLength = 0;  VXMLElement bestMatch;  enum {    DOCUMENT,    APPLICATION,    DEFAULTS  } stage = DOCUMENT;  bool done = false;  // Start from current item in document.  VXMLElement currentNode = item;  do {    // (2) Walk through all nodes at this level looking for catch elements.    for (VXMLNodeIterator it(currentNode); it; ++it) {      VXMLNode child = *it;      if (child.GetType() != VXMLNode::Type_VXMLElement) continue;      const VXMLElement & elem = reinterpret_cast<const VXMLElement &>(child);      // (2.1) Can this node catch events?      VXMLElementType nodeName = elem.GetName();      if (nodeName != NODE_CATCH   && nodeName != NODE_ERROR   &&          nodeName != NODE_HELP    && nodeName != NODE_NOINPUT &&          nodeName != NODE_NOMATCH) continue;      // (2.2) If it is not a catch, is this an active match?      int eventCount;      vxistring catchEvent;      if (nodeName != NODE_CATCH) {        // Map back to strings.        if      (nodeName == NODE_ERROR)   catchEvent = L"error";        else if (nodeName == NODE_HELP)    catchEvent = L"help";        else if (nodeName == NODE_NOINPUT) catchEvent = L"noinput";        else if (nodeName == NODE_NOMATCH) catchEvent = L"nomatch";                eventCount = exe->eventcounts.GetCount(event, catchEvent);        if (eventCount == 0) continue;      }      // (2.3) If it is a catch, we need to examine the list.      else {        elem.GetAttribute(ATTRIBUTE_EVENT, catchEvent);        // Find the best match in the event list.        STRINGDEQUE catchList;        ProcessNameList(catchEvent, catchList);        catchEvent.erase();        if (catchList.empty())          eventCount = exe->eventcounts.GetCount(event, catchEvent);        else {          STRINGDEQUE::iterator i;          for (i = catchList.begin(); i != catchList.end(); ++i) {            int temp = exe->eventcounts.GetCount(event, *i);            if (temp != 0 && (*i).length() > catchEvent.length()) {              catchEvent = (*i);              eventCount = temp;            }          }          if (catchEvent.empty()) continue;        }      }      // (2.4) Matching catch element found.  Evaluate its 'cond' attribute.      vxistring attr;      elem.GetAttribute(ATTRIBUTE_COND, attr);      if (!attr.empty() && !exe->script.TestCondition(attr))        continue;      // (2.5) Condition okay.  Check the count against the eventCount.      int catchCount = 1;      if (elem.GetAttribute(ATTRIBUTE_COUNT, attr)) {#if defined(__GNUC__) && (__GNUC__ <= 2 || (__GNUC__ == 3 && __GNUC_MINOR__ == 0))        // The G++ implementation of basic_stringstream is faulty.        VXIchar * temp;        catchCount = int(wcstol(attr.c_str(), &temp, 10));#else        std::basic_stringstream<VXIchar> attrStream(attr);        attrStream >> catchCount;#endif      }      if (catchCount < 1 || catchCount > eventCount) continue;      // (2.6) We now have a candidate.      vxistring::size_type catchEventLength = catchEvent.length();      if (catchEventLength < bestMatchLength) continue; // Name isn't as good.      if (catchEventLength == bestMatchLength && catchCount <= bestCount)        continue;  // Names match, but count isn't better.      // (2.7) Update best match.      bestCount = catchCount;      bestMatchLength = catchEventLength;      bestMatch = elem;    }    // (3) Decide where to search next.    const VXMLElement & parent = currentNode.GetParent();    if (parent != 0)      currentNode = parent;    else {      if (stage == DOCUMENT) {        stage = APPLICATION;        currentNode = exe->application.GetRoot();        if (currentNode != 0) continue;        // Otherwise, fall through to application level.      }      if (stage == APPLICATION) {        stage = DEFAULTS;        // We resort to this level _only_ if no match has been found.        if (bestCount < 1) {          vxistring language =            toString(exe->properties.GetProperty(PropertyList::Language));          // We clear the current node.  It will be set either to the global          // language (*) or to an exact match.          currentNode = VXMLElement();          VXMLElement defaultsRoot = domDefaultDoc.GetRoot();          for (VXMLNodeIterator it(defaultsRoot); it; ++it) {            VXMLNode child = *it;            // Look for a language node.            if (child.GetType() != VXMLNode::Type_VXMLElement) continue;                        const VXMLElement & elem              = reinterpret_cast<const VXMLElement &>(child);            if (elem.GetName() != DEFAULTS_LANGUAGE) continue;            vxistring id;            elem.GetAttribute(ATTRIBUTE_ID, id);            if (id == language || (id == GENERIC_DEFAULTS && currentNode == 0))              currentNode = elem;          }          if (currentNode != 0) continue;        }      }      done = true;    }  } while (!done);  if (bestCount == 0)    return false;  // Compliance Note:  //  // Because of the 'as-if-by-copy' semantic, we now execute the catch content,  // including relative URIs, in the local scope.  So nothing special needs to  // be done.  VXIMapHolder vars;  VXIValue * temp = NULL;  temp = reinterpret_cast<VXIValue *>(VXIStringCreate(e.GetValue().c_str()));  if (temp == NULL) throw VXIException::OutOfMemory();  VXIMapSetProperty(vars.GetValue(), L"_event", temp);  temp = reinterpret_cast<VXIValue *>(VXIStringCreate(e.GetMessage().c_str()));  if (temp == NULL) throw VXIException::OutOfMemory();  VXIMapSetProperty(vars.GetValue(), L"_message", temp);  execute_content(bestMatch, vars);  return true;}// Top level call into executable content section.// Called from <block>,<catch>, and <filled>//void VXI::execute_content(const VXMLElement& doc, const VXIMapHolder & vars){  log->LogDiagnostic(2, L"VXI::execute_content()");  // (1) Add a new scope.  The allows anonymous variables to be defined.   if (exe->script.CurrentScope(SCOPE_Anonymous)) exe->script.PopScope();  exe->script.PushScope(SCOPE_Anonymous);  // (2) Set externally specified variables (if necessary).  if (vars.GetValue() != NULL) {    const VXIchar * key;    const VXIValue * value;    VXIMapIterator * i = VXIMapGetFirstProperty(vars.GetValue(), &key, &value);    exe->script.SetValue(key, value);    while (VXIMapGetNextProperty(i, &key, &value) == VXIvalue_RESULT_SUCCESS)      exe->script.SetValue(key, value);    VXIMapIteratorDestroy(&i);  }  // (3) Walk through the children and execute each node.  for (VXMLNodeIterator it(doc); it; ++it) {    VXMLNode child = *it;    switch (child.GetType()) {    case VXMLNode::Type_VXMLContent:      executable_prompt(child);      break;    case VXMLNode::Type_VXMLElement:    {      const VXMLElement & elem = reinterpret_cast<VXMLElement &>(child);      executable_element(elem);      break;    }    default: // do nothing      break;    }  }}// Executable element dispatch//void VXI::executable_element(const VXMLElement & elem){  if (elem == 0) {    log->LogError(999, SimpleLogger::MESSAGE, L"empty executable element");    return;  }  VXMLElementType nodeName = elem.GetName();  if (log->IsLogging(2)) {    log->StartDiagnostic(2) << L"VXI::executable_element - " << nodeName;    log->EndDiagnostic();  }  if (nodeName == NODE_VAR)    var_element(elem);  else if (nodeName == NODE_ASSIGN)    assign_element(elem);  else if (nodeName == NODE_CLEAR)    clear_element(elem);  else if (nodeName == NODE_DISCONNECT)    disconnect_element(elem);  else if (nodeName == NODE_EXIT)    exit_element(elem);  else if (nodeName == NODE_GOTO)    goto_element(elem);  else if (nodeName == NODE_IF)    if_element(elem);  else if (nodeName == NODE_LOG)    log_element(elem);  else if (nodeName == NODE_PROMPT || nodeName == NODE_AUDIO ||           nodeName == NODE_VALUE  || nodeName == NODE_ENUMERATE)    executable_prompt(elem);  else if (nodeName == NODE_REPROMPT)    reprompt_element(elem);  else if (nodeName == NODE_RETURN)    return_element(elem);  else if (nodeName == NODE_SCRIPT)    script_element(elem);  else if (nodeName == NODE_SUBMIT)    submit_element(elem);  else if (nodeName == NODE_THROW)    throw_element(elem);  else    log->LogError(999, SimpleLogger::MESSAGE,L"unexpected executable element");}/*  * Process <var> elements in current interp context. * * This differs from assign in that it makes new var in current scope * assign follows scope chain lookup for var name (and throws  *   error if fails) * * This is also used for initialiation of guard vars in field items * * <var> processing is compliated by the need to check for <param> values *  from subdialog calls. */void VXI::var_element(const VXMLElement & doc){  vxistring name;  vxistring expr;  doc.GetAttribute(ATTRIBUTE_NAME, name);  doc.GetAttribute(ATTRIBUTE_EXPR, expr);  if (log->IsLogging(2)) {    log->StartDiagnostic(2) << L"VXI::var_element(name=\"" << name                            << L"\" expr = \"" << expr << L"\")";    log->EndDiagnostic();  }  if (name.empty()) return;  exe->script.MakeVar(name, expr);} // Process <assign> elements in current interpreter context//void VXI::assign_element(const VXMLElement & doc){  vxistring name;  doc.GetAttribute(ATTRIBUTE_NAME, name);  if (name.empty()) return;  vxistring expr;  doc.GetAttribute(ATTRIBUTE_EXPR, expr);  if (log->IsLogging(2)) {    log->StartDiagnostic(2) << L"VXI::assign_element(name=\"" << name                            << L"\" expr = \"" << expr << L"\"";    log->EndDiagnostic();  }  exe->script.SetVar(name, expr);}// Handler for meta elements. Do nothing for now.//void VXI::meta_element(const VXMLElement & doc){  // vxistring & name = doc.GetAttribute("name");  // vxistring & name = doc.GetAttribute("content");  // vxistring & name = doc.GetAttribute("http-equiv");}// Handler for clear elements.  This may resets all form items or a user// specified subset.//void VXI::clear_element(const VXMLElement & doc){  log->LogDiagnostic(2, L"VXI::clear_element()");  // (1) Get the namelist.  vxistring namelist;  doc.GetAttribute(ATTRIBUTE_NAMELIST, namelist);  // (2) Handle the easy case: empty namelist --> clear all  if (namelist.empty()) {    // (2.1) Clear prompt and event counts.    exe->promptcounts.Clear();    exe->eventcounts.Clear();    // (2.2) The list of form items resides in the slot map.    ExecutionContext::STRINGDEQUE::iterator i;    ExecutionContext::STRINGDEQUE & formitems = exe->formitems;    for (i = formitems.begin(); i != formitems.end(); ++i)      exe->script.ClearVar(*i);    return;  }  // (3) Handle case where user specifies form items.  STRINGDEQUE names;  ProcessNameList(namelist, names);  for (STRINGDEQUE::const_iterator i = names.begin(); i != names.end(); ++i) {    // (3.1) Check that the name is a real form item.  A linear search should

⌨️ 快捷键说明

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