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

📄 vxi.cpp

📁 sloedgy open sip stack source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
   if (nodeName == NODE_FIELD     || nodeName == NODE_RECORD ||
       nodeName == NODE_TRANSFER  || nodeName == NODE_OBJECT ||
       nodeName == NODE_SUBDIALOG || nodeName == NODE_MENU)
     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);
     }
   }
 
   // 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) {
     VXM

⌨️ 快捷键说明

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