📄 vxi.cpp
字号:
// Check event if (event == NULL || *event == L'\0' || *event == L'.') return 1; bool lastWasPeriod = false; // This could be stricter for (const VXIchar * i = event; i != L'\0'; ++i) { VXIchar c = *i; if (c == L'.') { if (lastWasPeriod) return 1; lastWasPeriod = true; } if (c == L' ' || c == L'\t' || c == L'\n' || c == L'\r') return 1; lastWasPeriod = false; } mutex.Lock(); externalEvents.push_back(event); if (message == NULL || message == L'\0') externalMessages.push_back(event); else externalMessages.push_back(message); haveExternalEvents = true; mutex.Unlock(); return 0; } int VXI::ClearExternalEventQueue() { mutex.Lock(); if( !externalEvents.empty() ) { haveExternalEvents = false; externalEvents.clear(); externalMessages.clear(); } mutex.Unlock(); return 0; } int VXI::Run(const VXIchar * initialDocument, const VXIchar * sessionScript, SimpleLogger * resourceLog, VXIinetInterface * resourceInet, VXIcacheInterface * resourceCache, VXIjsiInterface * resourceJsi, VXIrecInterface * resourceRec, VXIpromptInterface * resourcePrompt, VXItelInterface * resourceTel, VXIobjectInterface * resourceObject, VXIValue ** resultValue) { // (1) Check arguments. if (stopRequested) { DeclareStopRequest(false); if (log->IsLogging(2)) { log->StartDiagnostic(2) << L"VXI::Run( STOP HAS BEEN REQUESTED ) exiting..."; log->EndDiagnostic(); } return 4; } // (1.1) Check external resources if (resourceLog == NULL || resourceInet == NULL || resourceJsi == NULL || resourceRec == NULL || resourcePrompt == NULL || resourceTel == NULL) return 1; log = resourceLog; inet = resourceInet; jsi = resourceJsi; rec = resourceRec; tel = resourceTel; // These may be NULL. object = resourceObject; cache = resourceCache; if (!pm->ConnectResources(log, resourcePrompt)) return 1; if (log->IsLogging(2)) { log->StartDiagnostic(2) << L"VXI::Run(" << initialDocument << L")"; log->EndDiagnostic(); } // (1.2) Check document if (initialDocument == NULL || wcslen(initialDocument) == 0) { log->LogError(201); return 1; } // (2) Delegate real work to RunDocumentLoop & handle the serious errors. int exitCode; try { exitCode = RunDocumentLoop(initialDocument, (sessionScript ? sessionScript : L""), resultValue); pm->PlayAll(); } catch (VXIException::InterpreterEvent & e) { log->LogError(207, SimpleLogger::EXCEPTION, e.GetValue().c_str()); exitCode = 0; } catch (const VXIException::Exit & e) { *resultValue = e.exprResult; exitCode = 0; } catch (const VXIException::Fatal &) { log->LogError(209); exitCode = -2; } catch (const VXIException::OutOfMemory &) { PopExecutionContext(); log->LogError(202); exitCode = 1; } catch (const VXIException::JavaScriptError &) { log->LogError(212); exitCode = -2; } catch (const VXIException::StopRequest &) { exitCode = 4; } catch (const JumpDialog &) { log->LogError(999, SimpleLogger::MESSAGE, L"unexpected jump to a dialog"); exitCode = -2; } catch (const JumpDoc &) { log->LogError(999, SimpleLogger::MESSAGE,L"unexpected jump to a document"); exitCode = -2; } catch (const JumpItem &) { log->LogError(999, SimpleLogger::MESSAGE, L"unexpected jump to an item"); exitCode = -2; } catch (const JumpReturn &) { log->LogError(999, SimpleLogger::MESSAGE, L"unexpected jump from a return element"); exitCode = -2; } // Clean up execution contexts. try { while (exe != NULL) PopExecutionContext(); } catch (const VXIException::JavaScriptError &) { log->LogError(212); exitCode = -2; } // Clean up event flags. lineHungUp = false; stopRequested = false; //haveExternalEvents = false; //externalEvents.clear(); //externalMessages.clear(); return exitCode; } int VXI::RunDocumentLoop(const vxistring & initialDocument, const vxistring & sessionScript, VXIValue ** resultValue) { // (1) Load the document containing the default handlers. if (updateDefaultDoc) { updateDefaultDoc = false; log->LogDiagnostic(2, L"VXI::RunDocumentLoop - loading defaultDoc."); // (1.1) Get URI if possible. vxistring defaultsUri; GetRuntimeProperty(VXI::PlatDefaultsURI, defaultsUri); // (1.2) Load platform defaults. try { VXIMapHolder domDefaultProp; if (log->IsLogging(4) && !defaultsUri.empty()) { log->StartDiagnostic(4) << L"VXI: Loading platform defaults <" << defaultsUri << L">"; log->EndDiagnostic(); } AttemptDocumentLoad(defaultsUri, VXIMapHolder(NULL), domDefaultDoc, domDefaultProp, true); } catch (const VXIException::InterpreterEvent & e) { log->LogError(221, SimpleLogger::EXCEPTION, e.GetValue().c_str()); return 3; } } // (2) Create a new execution context and initialize the defaults. // (2.1) Create new execution context. if (!PushExecutionContext(sessionScript)) return -1; bool firstTime = true; VXIint32 loopCount = 0; // (3) Start the loops through contexts and documents. while (1) { if (stopRequested) throw VXIException::StopRequest(); try { if (firstTime) { firstTime = false; // Jump to the initial document. Any events which occur while // loading the initial document are handled by the defaults. log->LogDiagnostic(2, L"VXI::RunDocumentLoop - loading initial " L"document."); try { PerformTransition(exe->platDefaults, initialDocument); } catch (const VXIException::InterpreterEvent & e) { DoEvent(exe->platDefaults, e); PopExecutionContext(); throw VXIException::Exit(NULL); } } log->LogDiagnostic(2, L"VXI::RunDocumentLoop - new document"); RunInnerLoop(); break; } catch (JumpDoc & e) { if (e.isSubdialog) if (!PushExecutionContext(sessionScript)) return -1; if (log->IsLogging(4)) { if (e.isSubdialog) log->StartDiagnostic(4) << L"VXI: Subdialog transition <" << e.documentURI << L">"; else log->StartDiagnostic(4) << L"VXI: Document transition <" << e.documentURI << L">"; log->EndDiagnostic(); } InstallDocument(e); } catch (JumpReturn &) { PopExecutionContext(); if (log->IsLogging(4)) { log->StartDiagnostic(4) << L"VXI: Subdialog returned to <" << exe->documentURI << L">"; log->EndDiagnostic(); } } catch (const VXIException::Exit & e) { // This handles <exit>. if (resultValue != NULL) *resultValue = e.exprResult; break; } } PopExecutionContext(); return 0; } void VXI::InstallDocument(JumpDoc & e) { // (1) Check to see what needs to be initialized. // If the transition is from leaf-to-root occurs in <submit> then // the root context is initialized, otherwise it is preserved. bool leafToRoot = !e.isSubmitElement && (!e.documentURI.empty()) && (exe->applicationURI == e.documentURI); bool reinitApplication = e.isSubdialog || (e.applicationURI.empty() && exe->applicationURI.empty()) || (!leafToRoot && (e.applicationURI != exe->applicationURI)); // (2) Set the easy stuff. exe->platDefaults = e.defaults; exe->application = e.application; exe->applicationURI = e.applicationURI; exe->document = e.document; exe->documentURI = e.documentURI; exe->currentDialog = e.documentDialog; exe->currentFormItem= VXMLElement(); exe->eventSource = VXMLElement(); exe->properties = e.properties; exe->gm.ReleaseGrammars(); VXMLElement documentRoot = exe->document.GetRoot(); VXMLElement applicationRoot = exe->application.GetRoot(); // (3) Load grammars. The grammars are reloaded using the current // understanding of the properties. During activation, the actual // properties may differ slightly. try { exe->documentName = L""; exe->gm.LoadGrammars(documentRoot, exe->documentName, exe->properties); VXIPromptTranslator translator(exe->script); pm->PreloadPrompts(documentRoot, exe->properties, translator); } catch (const VXIException::InterpreterEvent & e) { DoEvent(documentRoot, e); throw VXIException::Exit(NULL); } try { vxistring temp; exe->gm.LoadGrammars(applicationRoot, temp, exe->properties); VXIPromptTranslator translator(exe->script); pm->PreloadPrompts(applicationRoot, exe->properties, translator); } catch (const VXIException::InterpreterEvent & e) { DoEvent(applicationRoot, e); throw VXIException::Exit(NULL); } try { vxistring temp; exe->gm.LoadGrammars(exe->platDefaults, temp, exe->properties, true); VXIPromptTranslator translator(exe->script); pm->PreloadPrompts(exe->platDefaults, exe->properties, translator); } catch (const VXIException::InterpreterEvent & e) { DoEvent(exe->platDefaults, e); throw VXIException::Exit(NULL); } // (4) Clear existing ECMA script scopes. Scripter & script = exe->script; if (script.CurrentScope(SCOPE_Anonymous)) script.PopScope(); if (script.CurrentScope(SCOPE_Local)) script.PopScope(); if (script.CurrentScope(SCOPE_Dialog)) script.PopScope(); if (script.CurrentScope(SCOPE_Document)) script.PopScope(); if (script.CurrentScope(SCOPE_Application) && reinitApplication) script.PopScope(); if (reinitApplication && !script.CurrentScope(SCOPE_Defaults)) { log->LogError(999, SimpleLogger::MESSAGE, L"ECMAScript scope inconsistent"); throw VXIException::Fatal(); } // (5) And set the new ones. try { if (script.CurrentScope(SCOPE_Defaults)) { script.PushScope(SCOPE_Application); exe->script.MakeVar(L"lastresult$", L"undefined"); if (!exe->applicationURI.empty()) { ProcessRootScripts(applicationRoot); } } } catch (const VXIException::InterpreterEvent & e) { DoEvent(applicationRoot, e); throw VXIException::Exit(NULL); } try { script.PushScope(SCOPE_Document, leafToRoot || exe->applicationURI.empty()); if (!leafToRoot) { ProcessRootScripts(documentRoot); } } 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"";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -