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

📄 vxi.cpp

📁 sloedgy open sip stack source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
     }
   }
   catch (const VXIException::InterpreterEvent & e) {
     DoEvent(documentRoot, e);
     throw VXIException::Exit(NULL);
   }
 }
 
 
 void VXI::PerformTransition(const VXMLElement & elem,
                             const vxistring & rawURI,
                             VXIMap * rawSubmitData,
                             bool isSubdialog,
                             bool isSubmitElement)
 {
   if (log->IsLogging(2)) {
     log->StartDiagnostic(2) << L"VXI::PerformTransition(" << rawURI << L")";
     log->EndDiagnostic();
   }
 
   VXIMapHolder submitData(rawSubmitData);
 
   // (1) Determine fetch properties for document load.
 
   // (1.1) Create empty fetch object.  Now we need to fill this in.
   VXIMapHolder fetchobj;
   if (fetchobj.GetValue() == NULL) throw VXIException::OutOfMemory();
    
   // (1.2) Set URIs for the Jump.
   vxistring uri((rawURI.empty() ? L"" : rawURI));
   vxistring fragment;
   const VXIchar * tempStr = L"";
 
   // (1.2.1) Divide raw URI into uri + fragment.
   exe->properties.GetFetchobjURIs(elem, fetchobj, uri, fragment);
 
   // (1.2.2) Handle the degenerate case.
   if (uri.empty() && fragment.empty()) {
     log->StartDiagnostic(0) << L"VXI::PerformTransition - invalid URI, \""
                             << (rawURI.empty() ? L"NULL" : rawURI.c_str()) << L"\"";
     log->EndDiagnostic();
     throw VXIException::InterpreterEvent(EV_ERROR_BADURI);
   }
 
   // (1.2.3) In the fragment only case, just go to the indicated item.
   if (uri.empty()) {
     VXMLElement targetElement = FindDialog(elem, fragment);
     if (targetElement == 0) {
       log->StartDiagnostic(0) << L"VXI::PerformTransition - non-existent "
                                  L"dialog, \"" << (rawURI.empty() ? L"NULL" : rawURI.c_str()) << L"\"";
       log->EndDiagnostic();
       throw VXIException::InterpreterEvent(EV_ERROR_BADDIALOG);
     }
 
     if (!isSubdialog)
       throw JumpDialog(targetElement);
     else {
 //#pragma message("CC - temporarily pop the last field properties so that subdialog won't complain")      
       PropertyList subprop(exe->properties);
       subprop.PopPropertyLevel(FIELD_PROP);
       vxistring absoluteURI(L"");
       tempStr = exe->properties.GetProperty(PropertyList::AbsoluteURI);
       if (tempStr) absoluteURI = tempStr;
       
       throw JumpDoc(exe->platDefaults, exe->application, exe->applicationURI,
                     exe->document, absoluteURI, targetElement, isSubdialog, isSubmitElement,
                     subprop);
     }
   }
 
 //#pragma message ("VXI::PerformTransition - ignoring fetchhint")
   // (1.3) Get remaining fetch properties. At this point, we now need
   //       to assemble seperate fetch properties for fetchaudio, up
   //       until now all the prep work is identical.
   VXIMapHolder fetchAudioFetchobj(NULL);
   fetchAudioFetchobj = fetchobj;
   if (fetchAudioFetchobj.GetValue() == NULL) throw VXIException::OutOfMemory();
 
   exe->properties.GetFetchobjCacheAttrs(elem, PropertyList::Document,fetchobj);
   exe->properties.GetFetchobjCacheAttrs(elem, PropertyList::Audio,
                                         fetchAudioFetchobj);
 
   if (submitData.GetValue() != NULL) {
     if (!exe->properties.GetFetchobjSubmitAttributes(elem, submitData,
                                                      fetchobj))
     {
       // This should never occur.
       log->StartDiagnostic(0) << L"VXI::PerformTransition - couldn't set "
                                  L"the submit attributes.";
       log->EndDiagnostic();
       throw VXIException::InterpreterEvent(EV_ERROR_BADURI);
     }
     submitData.Release(); // This map is now owned by fetchobj.
   }
 
   // (2) Load Document.
 
   // (2.1) Start fetch audio.
 
   vxistring fetchaudio;
   if (!elem.GetAttribute(ATTRIBUTE_FETCHAUDIO, fetchaudio))
     fetchaudio = toString(exe->properties.GetProperty(L"fetchaudio"));
 
   if (!fetchaudio.empty()) {
     // Get All properties for fetching audio
     VXIMapHolder fillerProp(VXIMapClone(fetchAudioFetchobj.GetValue()));
     exe->properties.GetProperties(fillerProp);
 
     pm->PlayAll(); // Finish playing already queued prompts
     pm->PlayFiller(fetchaudio, fillerProp);
   }
 
   // (2.2) Load document and verify that dialog exists.
 
   // (2.2.1) Load the VoiceXML document.
   VXMLDocument document;
   VXMLElement documentDialog;
   VXIMapHolder documentFetchProps;
   AttemptDocumentLoad(uri, fetchobj, document, documentFetchProps);
 
   // (2.2.2) If there was a fragment, does the named dialog exist?
   VXMLElement documentRoot = document.GetRoot();
   documentDialog = FindDialog(documentRoot, fragment);
   if (documentDialog == 0) {
     if (fragment.empty())
       log->StartDiagnostic(0) << L"VXI::PerformTransition - no dialog "
                                  L"element found in \"" << uri << L"\"";
     else 
       log->StartDiagnostic(0) << L"VXI::PerformTransition - named dialog, "
                               << fragment << L" not found in \"" << uri
                               << L"\"";
     log->EndDiagnostic();
     throw VXIException::InterpreterEvent(EV_ERROR_BADDIALOG);
   }
    
   // (3) Get Document language & find associated defaults.
 
   // (3.1) Create a new property list containing the document properties.
   PropertyList newProperties(*log);
 
 //#pragma message("JC: This should set from * then override with specific")
 //#pragma message("JC: Make sure this returns the specific (if present) at the end")
 // WARNING: The defaults document has multiple languages and a language-independent '*' group.
 // This should really read the '*' group and then overlay the set specific to the active language.
 
   // (3.2) Extract the language setting.
   const VXIchar * language = newProperties.GetProperty(PropertyList::Language);
   if (language == NULL) language = GENERIC_DEFAULTS;
 
   // (3.3) Find the language defaults.
   VXMLElement defaults;
 
   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 && defaults == 0))
       defaults = elem;
   }
   if (defaults != 0)
     newProperties.SetProperties(defaults, DEFAULTS_PROP, VXIMapHolder(NULL));
 
   newProperties.SetProperties(documentRoot, DOC_PROP, documentFetchProps);
   // newProperties should now contain the properties from the platform defaults plus
   // the properties at document level.
 
   // (3.4) Copy the document properties in and find the absolute URI. 
   vxistring absoluteURI(L"");
   vxistring applicationURI(L"");
 
   newProperties.SetProperties(documentRoot, DOC_PROP, documentFetchProps);
   tempStr = newProperties.GetProperty(PropertyList::AbsoluteURI, DOC_PROP);
   if (tempStr == NULL) 
     absoluteURI = uri.empty() ? L"" : uri.c_str();
   else
     absoluteURI = tempStr;
 
   // (4) Load the application.
   VXMLDocument application;
   VXIMapHolder appProperties;
 
   // (4.1) Get the application URI.
 
   vxistring appuri;
   documentRoot.GetAttribute(ATTRIBUTE_APPLICATION, appuri);
   if (!appuri.empty()) {      
     // (4.2) Initialize application fetch parameters.
     VXIMapHolder appFetchobj;
     if (appFetchobj.GetValue() == NULL)
       throw VXIException::OutOfMemory();
 
     vxistring appFragment;
     newProperties.GetFetchobjURIs(documentRoot, appFetchobj, appuri,
                                   appFragment);
     if (appuri.empty()) {
       log->LogError(214);
       throw VXIException::InterpreterEvent(EV_ERROR_APP_BADURI);
     }
     newProperties.GetFetchobjCacheAttrs(documentRoot, PropertyList::Document,
                                         appFetchobj);
 
     // (4.3) Load the application and its properties (we must then restore the
     // document properties.
     AttemptDocumentLoad(appuri, appFetchobj, application, appProperties);
 
     // (4.3.1) If an application root document specifies an application root
     //         element error.semantic is thrown.   
     VXMLElement documentRootCheck = application.GetRoot();
 
     vxistring appuriCheck;
     documentRootCheck.GetAttribute(ATTRIBUTE_APPLICATION, appuriCheck);
     if (!appuriCheck.empty())
       throw VXIException::InterpreterEvent(EV_ERROR_SEMANTIC,
             L"application root element presents in application root document");
       
     newProperties.SetProperties(application.GetRoot(), APP_PROP, appProperties);
 
     // (4.4) Get the absolute URI for the application root.
     tempStr = newProperties.GetProperty(PropertyList::AbsoluteURI, APP_PROP);
     applicationURI = (tempStr == NULL ? L"" : tempStr);
   }
 
   // (5) Generate the final event.
   throw JumpDoc(defaults, application, applicationURI,
                 document, absoluteURI, documentDialog, isSubdialog,
                 isSubmitElement, newProperties);
 }
 
 
 // Finds the named dialog in the document.  If the name is empty, the first
 // item is returned.
 //
 VXMLElement VXI::FindDialog(const VXMLElement & start, const vxistring & name)
 {
   if (log->IsLogging(2)) {
     log->StartDiagnostic(2) << L"VXI::FindDialog(" << name << L")";
     log->EndDiagnostic();
   }
 
   // (0) find the root node.
   VXMLElement doc;
   for (doc = start; doc != 0 && doc.GetName() != NODE_VXML;
        doc = doc.GetParent());
   if (doc == 0) return VXMLElement();
 
   // (1) Walk through all elements at this level and find match.
   for (VXMLNodeIterator it(doc); it; ++it) {
     VXMLNode child = *it;
 
     // (1.1) Only <form> & <menu> elements are considered.
     if (child.GetType() != VXMLNode::Type_VXMLElement) continue;
     const VXMLElement & elem = reinterpret_cast<const VXMLElement &>(child);
     VXMLElementType nodeName = elem.GetName();
     if (nodeName != NODE_FORM && nodeName != NODE_MENU) continue;
 
     // (1.2) If no dialog was specified, return the first one.
     if (name.empty()) return elem;
 
     // (1.3) Otherwise, look for an exact match.
     vxistring id;
     if (!elem.GetAttribute(ATTRIBUTE__ITEMNAME, id)) continue;
 
     if (name == id)
       return elem;
   }
 
   // (2) User attempted to GOTO to non-existant dialog or have an empty doc!
   log->LogDiagnostic(2, L"VXI::FindDialog - no match found.");
 
   return VXMLElement();
 }
 
 
 //#############################################################################
 // Document Loop
 //#############################################################################
 
 // return success/failure (can't throw error here as caller needs
 //  a chance to clean up
 // Also initialize new context (session scope)
 bool VXI::PushExecutionContext(const vxistring & sessionScript)
 {
   log->LogDiagnostic(2, L"VXI::PushExecutionContext()");
 
   // (1) Catch recursive <subdialog> case...
   if (stackDepth >= DEFAULT_MAX_EXE_STACK_DEPTH) {
     log->LogError(211);
     return false;
   }
 
   // (2) Create new execution context.
   ExecutionContext * ep = new ExecutionContext(rec, jsi, *log, exe);
   if (ep == NULL) throw VXIException::OutOfMemory();
 
   exe = ep;
   ++stackDepth;
 
   // (3) Init new context from channel (i.e. set up 'session' scope)
   exe->script.PushScope(SCOPE_Session);
   if (!sessionScript.empty()) exe->script.EvalScript(sessionScript);
 
   exe->script.SetVarReadOnly(SCOPE_Session);
 
   log->LogDiagnostic(2, L"VXI::PushExecutionContext - session variables "
                      L"initialized");
 
   // (4) Init new context defaults (i.e. set up platform defaults)
 
   // (4.1) Find generic language properties.
   VXMLElement defaultsRoot = domDefaultDoc.GetRoot();
   for (VXMLNodeIterator it(defaultsRoot); it; ++it) {
     VXMLNode child = *it;
     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 != GENERIC_DEFAULTS) continue;
     exe->platDefaults = elem;
     break;
   }
 
   if (exe->platDefaults == 0) {
     log->LogError(223);
     PopExecutionContext();
     return false;
   }
 
   // (4.2) Install defaults.  We only need to worry about the properties (for
   // document load) and the ECMA variables and scripts (for catch handlers on
   // load failure).  The grammars & prompts may be safely ignored.
 
   exe->properties.SetProperties(exe->platDefaults, DEFAULTS_PROP,
                                 VXIMapHolder());
   exe->script.PushScope(SCOPE_Defaults);
   ProcessRootScripts(exe->platDefaults);
 
   log->LogDiagnostic(2, L"VXI::PushExecutionContext - platform defaults "
                      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
   VXIbyte *cbuffer = NULL;
   VXIulong bufferSize = 0;
   int result = parser->FetchDocument(uri.c_str(), uriProperties, inet, cache,
                                      *log, doc, docProperties, isDefaults,
                                      &cbuffer, &bufferSize);
   
   // If we didn't have a parse error, dump the VoiceXML document if
   // configured to do so, otherwise free the content buffer
   if ((result != 4) && (cbuffer)) {
     VXIString *key = NULL, *value = NULL;
     if ((log->IsLogging(SimpleLogger::DOC_DUMPS)) &&
         (log->LogContent(VXI_MIME_XML, cbuffer, bufferSize, &key, &value))) {
 
       vxistring diagUri(uri);
       const VXIValue * val = VXIMapGetProperty(docProperties.GetValue(),
                                                INET_INFO_ABSOLUTE_NAME);

⌨️ 快捷键说明

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