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

📄 vxi.cpp

📁 OSB-PIK-OpenVXI-3.0.0源代码 “中国XML论坛 - 专业的XML技术讨论区--XML在语音技术中的应用”
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    // (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);     }   }    // 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;    VXIint32 numRethrows = 0;   VXIException::InterpreterEvent event = e;    // retrieve field name   vxistring fieldName;   item.GetAttribute(ATTRIBUTE__ITEMNAME, fieldName);    do {     try {       // (2) Increments counts associated with this event.       exe->eventcounts.Increment(fieldName, 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 (++numRethrows < DEFAULT_MAX_EVENT_RETHROWS);      // (6) Probable loop - catch X throws X?  Quit handling after a while.     log->LogError(216);   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;   VXMLElement bestMatch;    enum {     DOCUMENT,     APPLICATION,     DEFAULTS   } stage = DOCUMENT;    bool done = false;    // Start from current item in document.   VXMLElement currentNode = item;   vxistring oldFieldName, fieldName;   item.GetAttribute(ATTRIBUTE__ITEMNAME, oldFieldName);      do {     // Retrieve the field name for the current node for event counter     currentNode.GetAttribute(ATTRIBUTE__ITEMNAME, fieldName);     // If we move to the next level, we must initialize the event counter     // because the event may have not been initialized yet!     if( oldFieldName != fieldName )       exe->eventcounts.Increment(fieldName, event);            // (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) continue;        // (2.2) Is this an active match?       int eventCount;       vxistring catchEvent;        // Treat <catch> and <catch event=""> and <catch event=".">       // identically.       if (!elem.GetAttribute(ATTRIBUTE_EVENT, catchEvent))         catchEvent.erase();       if (catchEvent == L".")         catchEvent.erase();        // Find the best match in the event list.       bool goNext = false; /// JC       STRINGDEQUE catchList;       ProcessNameList(catchEvent, catchList);       catchEvent.erase();        // Find field name       if (catchList.empty()) {         eventCount = exe->eventcounts.GetCount(fieldName, event, catchEvent);       }       else {         STRINGDEQUE::iterator i;         for (i = catchList.begin(); i != catchList.end(); ++i) {           int temp = exe->eventcounts.GetCount(fieldName, event, *i);           if (temp != 0 && (*i).length() > catchEvent.length()) {             catchEvent = (*i);             eventCount = temp;           }         }         if (catchEvent.empty()) continue;       }        // sanity check event count       if (eventCount > DEFAULT_MAX_EVENT_COUNT) {         log->LogError(216);         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));       }        // (2.3) Matching catch element found.  Evaluate its 'cond' attribute.       vxistring attr;       elem.GetAttribute(ATTRIBUTE_COND, attr);       if (!attr.empty() && !exe->script.TestCondition(attr))         continue;        // (2.4) Condition okay.  Check the count against the eventCount.       int catchCount = 1;       if (elem.GetAttribute(ATTRIBUTE_COUNT, attr)) { #if (defined(__GNUC__) || defined(_decunix_))         // The G++ 2.95 and 3.0.2 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( catchList.empty() && bestCount > 0)         if( catchCount == eventCount ) continue;          if (catchCount < 1 || catchCount > eventCount) continue;              // (2.5) We now have a candidate.       if (catchCount <= bestCount)         continue;  // Names match, but count isn't better.        // (2.6) Update best match.       bestCount = catchCount;       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);    if (e.GetMessage().empty())     temp = reinterpret_cast<VXIValue *>(VXIPtrCreate(NULL));   else     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, e.GetActiveDialog());   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,                           const VXMLElement& activeDialog) {   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);     if (VXIValueGetType(value) == VALUE_PTR)       exe->script.MakeVar(key, L"");    // Set to ECMAScript undefined     else       exe->script.MakeVar(key, value);      while (VXIMapGetNextProperty(i, &key, &value) == VXIvalue_RESULT_SUCCESS) {       if (VXIValueGetType(value) == VALUE_PTR)         exe->script.MakeVar(key, L"");  // Set to ECMAScript undefined       else         exe->script.MakeVar(key, value);     }      VXIMapIteratorDestroy(&i);   }    // (3) Walk through the children and execute each node.   for (VXMLNodeIterator it(doc); it; ++it) {     VXMLNode child = *it;      if (child.GetType() != VXMLNode::Type_VXMLElement) continue;     const VXMLElement & elem = reinterpret_cast<VXMLElement &>(child);     executable_element(elem, activeDialog);   } }   // Executable element dispatch // void VXI::executable_element(const VXMLElement & elem, const VXMLElement & activeDialog) {   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)     executable_prompt(elem);   else if (nodeName == NODE_REPROMPT)     reprompt_element(elem, activeDialog);   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 &

⌨️ 快捷键说明

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