📄 grammarmanager.cpp
字号:
// Build option grammar (if one exists). GrammarManager::BuildOptionGrammar(log, element, false, gram); if (!gram.empty()) { vg = GrammarManager::CreateGrammarFromString(vxirec, log, gram, REC_MIME_OPTION, recProps); if (vg == NULL) throw VXIException::InterpreterEvent(EV_ERROR_BAD_OPTION); AddGrammar(vg, documentID, element); } // Build option dtmf grammar (if one exists). gram = L""; GrammarManager::BuildOptionGrammar(log, element, true, gram); if (gram.length() != 0) { vg = GrammarManager::CreateGrammarFromString(vxirec, log, gram, REC_MIME_OPTION_DTMF, recProps); if (vg == NULL) throw VXIException::InterpreterEvent(EV_ERROR_BAD_OPTION); AddGrammar(vg, documentID, element); } // Add the built-in grammars (if they exist). vg = NULL; vxistring type; element.GetAttribute(ATTRIBUTE_TYPE, type); if (!type.empty()) { vxistring newuri(L"builtin:grammar/"); newuri += type; if (vxirec->LoadGrammarURI(vxirec, recProps.GetValue(), NULL, newuri.c_str(), NULL, &vg) != VXIrec_RESULT_SUCCESS) { throw VXIException::InterpreterEvent(EV_ERROR_BAD_GRAMMAR); } AddGrammar(vg, documentID, element); newuri = L"builtin:dtmf/"; newuri += type; if (vxirec->LoadGrammarURI(vxirec, recProps.GetValue(), NULL, newuri.c_str(), NULL, &vg) != VXIrec_RESULT_SUCCESS) { throw VXIException::InterpreterEvent(EV_ERROR_BAD_GRAMMAR); } AddGrammar(vg, documentID, element); } // Recursively add grammars (this handles <grammar>) bool doPop = properties.PushProperties(element); LoadGrammars(element, documentID, properties); if (doPop) properties.PopProperties(); } // (6) Handle <link>. else if (elementName == NODE_LINK) { log.LogDiagnostic(2, L"GrammarManager::LoadGrammars - <link>"); // (6.1) Get properties at this level. bool doPop = properties.PushProperties(element); // (6.2) Create DTMF grammar is specified. vxistring dtmf; element.GetAttribute(ATTRIBUTE_DTMF, dtmf); if (!dtmf.empty()) { VXIrecGrammar * vg = NULL; vg = GrammarManager::CreateGrammarFromString(vxirec, log, dtmf, REC_MIME_CHOICE_DTMF, recProps); if (vg == NULL) throw VXIException::InterpreterEvent(EV_ERROR_BAD_CHOICE); AddGrammar(vg, documentID, element); } // (6.3) Create child grammars. LoadGrammars(element, documentID, properties); if (doPop) properties.PopProperties(); } // (7) Handle <record> and <transfer>. else if (elementName == NODE_RECORD || elementName == NODE_TRANSFER) { // The DTD allows <grammar> elements, but these don't make sense. We // will therefore ignore them. } // (8) Otherwise, nothing was found at this level. Use recursion to check // the next level down. else { bool doPop = properties.PushProperties(element); LoadGrammars(element, documentID, properties); if (doPop) properties.PopProperties(); } }}void GrammarManager::BuildOptionGrammar(const SimpleLogger & log, const VXMLElement & doc, bool isDTMF, vxistring & gram){ log.LogDiagnostic(2, L"GrammarManager::BuildOptionGrammar()"); gram = L""; // Clear grammar string bool firstTime = true; for (VXMLNodeIterator it(doc); it; ++it) { VXMLNode child = *it; if (child.GetType() != VXMLNode::Type_VXMLElement) continue; VXMLElement & domElem = reinterpret_cast<VXMLElement &>(child); if (domElem.GetName() != NODE_OPTION) continue; vxistring text; vxistring value; domElem.GetAttribute(ATTRIBUTE_VALUE, value); if (isDTMF) { domElem.GetAttribute(ATTRIBUTE_DTMF, text); if (value.empty()) GrammarManager::GetEnclosedText(log, domElem, value); } else { GrammarManager::GetEnclosedText(log, domElem, text); } if (text.empty()) continue; if (!firstTime) gram += L" | "; gram += text; if (!value.empty()) { gram += L" {"; gram += value; gram += L"}"; } firstTime = false; } log.LogDiagnostic(2, L"GrammarManager::BuildOptionGrammar - end");}bool GrammarManager::GetEnclosedText(const SimpleLogger & log, const VXMLElement & doc, vxistring & str){ log.LogDiagnostic(2, L"GrammarManager::GetEnclosedText()"); // Clear the result first... str = L""; for (VXMLNodeIterator it(doc); it; ++it) { VXMLNode child = *it; if (child.GetType() == VXMLNode::Type_VXMLContent) { VXMLContent & content = reinterpret_cast<VXMLContent &>(child); vxistring temp = content.GetValue(); while (temp.length() > 0) { // Strip off any empty characters from beginning VXIchar c = temp[0]; if (c == ' ' || c == '\r' || c == '\n' || c == '\t') temp.erase(0, 1); else { str += temp; break; } } } } if (!str.empty()) { // Strip off any trailing whitespace while (str.length() > 0) { unsigned int len = str.length(); VXIchar c = str[len - 1]; if (c == ' ' || c == '\r' || c == '\n' || c == '\t') str.erase(len - 1, 1); else break; } } log.LogDiagnostic(2, L"GrammarManager::GetEnclosedText - end"); return !str.empty();}VXIrecGrammar*GrammarManager::CreateGrammarFromString(VXIrecInterface * vxirec, const SimpleLogger & log, const vxistring & source, const VXIchar * type, const VXIMapHolder & recProps){ if (log.IsLogging(2)) { log.StartDiagnostic(2) << L"GrammarManager::CreateGrammarFromString(" << type << L") " << source; log.EndDiagnostic(); } VXIrecGrammar * grammar; VXIrecResult err = vxirec->LoadGrammarString(vxirec, recProps.GetValue(), type, source.c_str(), &grammar); log.LogDiagnostic(2, L"GrammarManager::CreateGrammarFromString - success"); if (err != VXIrec_RESULT_SUCCESS) return NULL; return grammar;}void GrammarManager::AddGrammar(VXIrecGrammar * gr, const vxistring & documentID, const VXMLElement & elem){ GrammarInfo* gp = new GrammarInfo(gr, documentID, elem); if (gp == NULL) throw VXIException::OutOfMemory(); if (log.IsLogging(2)) { log.StartDiagnostic(2) << L"GrammarManager::AddGrammar(" << gp << L")"; log.EndDiagnostic(); } grammars.push_back(gp);}void GrammarManager::DisableAllGrammars(){ for (GRAMMARS::iterator i = grammars.begin(); i != grammars.end(); ++i) { if ((*i)->IsEnabled()) { vxirec->DeactivateGrammar(vxirec, (*i)->GetRecGrammar()); (*i)->SetEnabled(false); } }}void GrammarManager::ReleaseGrammars(){ for (GRAMMARS::iterator i = grammars.begin(); i != grammars.end(); ++i) { VXIrecGrammar * grammar = (*i)->GetRecGrammar(); vxirec->FreeGrammar(vxirec, &grammar); delete *i; } grammars.clear();}bool GrammarManager::EnableGrammars(const vxistring & documentID, const vxistring & dialogName, const vxistring & fieldName, const VXIMapHolder & properties, bool isModal){ bool enabled = false; for (GRAMMARS::iterator i = grammars.begin(); i != grammars.end(); ++i) { bool docsMatch = (*i)->IsDoc(documentID); bool dialogsMatch = docsMatch && (*i)->IsDialog(dialogName); bool fieldsMatch = dialogsMatch && (*i)->IsField(fieldName); if ((!fieldName.empty() && fieldsMatch) || // Enable those field grammars matching our (field, form) pair (!isModal && (*i)->IsScope(GRS_DIALOG) && dialogsMatch) || // Enable form grammars & dialog scope fields, if not modal (!isModal && (*i)->IsScope(GRS_DOC)) // Enable document level grammars, if not modal ) { if (log.IsLogging(2)) { log.StartDiagnostic(2) << L"GrammarManager::EnableGrammar(" << (*i) << L")"; log.EndDiagnostic(); } VXIrecResult err = vxirec->ActivateGrammar(vxirec, properties.GetValue(), (*i)->GetRecGrammar()); if (err != VXIrec_RESULT_SUCCESS) throw VXIException::InterpreterEvent(EV_ERROR_BAD_GRAMMAR); (*i)->SetEnabled(true); enabled = true; } } return enabled;}// This function is responsible for calling the VXIrec level Recognize function// and then mapping the grammar back to the corresponding VXML node.//int GrammarManager::Recognize(const VXIMapHolder & properties, RecognitionAnswer & recAnswer, VXMLElement & recNode){ recNode = VXMLElement(); VXIrecRecognitionResult * answer = NULL; // (1) Do VXIrec level Recognitize and process return value. // (1.1) Recognize. VXIrecResult err = vxirec->Recognize(vxirec, properties.GetValue(), &answer); if (err == VXIrec_RESULT_OUT_OF_MEMORY) { log.LogDiagnostic(0,L"GrammarManager::InternalRecognize - Out of memory."); return GrammarManager::OutOfMemory; } // (1.2) Anything other than success indicates that recognition failed // (badly). The normal error conditions are returned through the recogntion // result structure. if (err != VXIrec_RESULT_SUCCESS) { log.StartDiagnostic(0) << L"GrammarManager::InternalRecognize - " L"VXIrecInterface::Recognize returned " << int (err); log.EndDiagnostic(); log.LogError(420, SimpleLogger::MESSAGE, L"function did not return the expected VXIrecSUCCESS result"); return GrammarManager::InternalError; } // (1.3) The answer structure must be defined. if (answer == NULL) { log.LogError(420, SimpleLogger::MESSAGE, L"function returned VXIrecSUCCESS but did not allocate " L"an answer structure"); return GrammarManager::InternalError; } // (1.4) Attach the answer structure returned by VXIrec and the waveform to // the recAnswer class. recAnswer.Bind(answer); recAnswer.waveform = answer->waveform; // (2) Process all non-Successful results. // (2.1) First the status code. switch (answer->status) { case REC_STATUS_SUCCESS: // Recognition returned a hypothesis break; case REC_STATUS_FAILURE: // Speech detected, no likely hypothesis return GrammarManager::Failure; case REC_STATUS_TIMEOUT: // No speech was detected return GrammarManager::Timeout; case REC_STATUS_DISCONNECT: // Caller has disconnected; no hypothesis return GrammarManager::Disconnect; case REC_STATUS_ERROR: // An error aborted recognition return GrammarManager::Error; default: log.StartDiagnostic(0) << L"GrammarManager::InternalRecognize - " L"VXIrecInterface::Recognize returned status " << int(answer->status); log.EndDiagnostic(); log.LogError(420, SimpleLogger::MESSAGE, L"function returned an invalid VXIrecStatus code"); return GrammarManager::InternalError; } // (2.2) Recognition success. Verify that the input mode was set correctly. switch (answer->mode) { case REC_INPUT_MODE_DTMF: case REC_INPUT_MODE_SPEECH: break; default: log.StartDiagnostic(0) << L"GrammarManager::InternalRecognize - " L"VXIrecInterface::Recognize returned mode " << int(answer->mode); log.EndDiagnostic(); log.LogError(420, SimpleLogger::MESSAGE, L"function returned an invalid VXIrecInputMode value"); return GrammarManager::InternalError; } // (3) Walk through results array and sanity check the results. // (3.1) How many answers are there?
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -