📄 grammarmanager.cpp
字号:
if (!text.empty()) {
VXIVectorAddElement(speechUtts.GetValue(),
reinterpret_cast<VXIValue *>(VXIStringCreate(text.c_str())));
VXIVectorAddElement(speechVals.GetValue(),
reinterpret_cast<VXIValue *>(VXIStringCreate(value.c_str())));
}
if (!dtmf.empty()) {
VXIVectorAddElement(dtmfUtts.GetValue(),
reinterpret_cast<VXIValue *>(VXIStringCreate(dtmf.c_str())));
VXIVectorAddElement(dtmfVals.GetValue(),
reinterpret_cast<VXIValue *>(VXIStringCreate(value.c_str())));
}
if (!accept.empty() && accept == L"approximate") {
VXIVectorAddElement(gramAcceptanceAttrs.GetValue(),
reinterpret_cast<VXIValue *>(VXIIntegerCreate(1)));
} else {
VXIVectorAddElement(gramAcceptanceAttrs.GetValue(),
reinterpret_cast<VXIValue *>(VXIIntegerCreate(0)));
}
}
// (3) Add grammars.
VXIrecGrammar * grammar;
if (VXIVectorLength(speechUtts.GetValue()) > 0) {
VXIrecResult err = vxirec->LoadGrammarOption(vxirec, props.GetValue(),
speechUtts.GetValue(),
speechVals.GetValue(),
gramAcceptanceAttrs.GetValue(),
FALSE, &grammar);
if( err != VXIrec_RESULT_SUCCESS )
ThrowSpecificEventError(err, GRAMMAR);
AddGrammar(grammar, documentID, element);
}
if (VXIVectorLength(dtmfUtts.GetValue()) > 0) {
VXIrecResult err = vxirec->LoadGrammarOption(vxirec, props.GetValue(),
dtmfUtts.GetValue(),
dtmfVals.GetValue(),
gramAcceptanceAttrs.GetValue(),
TRUE, &grammar);
if( err != VXIrec_RESULT_SUCCESS )
ThrowSpecificEventError(err, GRAMMAR);
AddGrammar(grammar, documentID, element);
}
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.erase();
for (VXMLNodeIterator it(doc); it; ++it) {
if ((*it).GetType() == VXMLNode::Type_VXMLContent) {
if (!str.empty()) str += ' ';
VXMLNode temp = *it;
str = reinterpret_cast<VXMLContent &>(temp).GetValue();
}
}
log.LogDiagnostic(2, L"GrammarManager::GetEnclosedText - end");
return !str.empty();
}
VXIrecGrammar*
GrammarManager::CreateGrammarFromURI(VXIrecInterface * vxirec,
const SimpleLogger & log,
const vxistring & source,
const VXIchar * type,
const VXIMap * fetchProps,
const VXIMapHolder & recProps)
{
if (log.IsLogging(3)) {
log.StartDiagnostic(3) << L"GrammarManager::LoadGrammar (type="
<< ((type == NULL) ? L"NULL" : type)
<< L"): " << source;
log.EndDiagnostic();
}
VXIrecGrammar * vg;
VXIrecResult err = vxirec->LoadGrammarURI(vxirec, recProps.GetValue(),
type,
source.c_str(),
fetchProps, &vg);
if( err != VXIrec_RESULT_SUCCESS )
ThrowSpecificEventError(err, GRAMMAR);
log.LogDiagnostic(2, L"GrammarManager::CreateGrammarFromURI - success");
return vg;
}
VXIrecGrammar*
GrammarManager::CreateGrammarFromString(VXIrecInterface * vxirec,
const SimpleLogger & log,
const vxistring & source,
const VXIchar * type,
const VXIMapHolder & recProps)
{
if (log.IsLogging(3)) {
log.StartDiagnostic(3) << L"GrammarManager::LoadGrammar (type=" << type
<< L"): " << source;
log.EndDiagnostic();
}
VXIrecGrammar * grammar;
VXIrecResult err = vxirec->LoadGrammarString(vxirec, recProps.GetValue(),
type, source.c_str(), &grammar);
if( err != VXIrec_RESULT_SUCCESS )
ThrowSpecificEventError(err, GRAMMAR);
log.LogDiagnostic(2, L"GrammarManager::CreateGrammarFromString - success");
return grammar;
}
void GrammarManager::AddGrammar(VXIrecGrammar * gr,
const vxistring & documentID,
const VXMLElement & elem)
{
GrammarInfo* gp = new GrammarInfo(gr, documentID, elem, GetGrammarSequence());
if (gp == NULL) throw VXIException::OutOfMemory();
if (log.IsLogging(2)) {
log.StartDiagnostic(2) << L"GrammarManager::AddGrammar(" << gr << L")"
<< L" seq: " << gp->GetSequence();
log.EndDiagnostic();
}
grammars.push_back(gp);
}
void GrammarManager::AddUniversal(VXIrecGrammar * gr,
const VXMLElement & elem,
const vxistring & langID,
const vxistring & name)
{
GrammarInfoUniv * gp = new GrammarInfoUniv(gr, elem, langID, name,
GetGrammarSequence());
if (gp == NULL) throw VXIException::OutOfMemory();
if (log.IsLogging(2)) {
log.StartDiagnostic(2) << L"GrammarManager::AddGrammar(" << gr << L")"
<< L" seq: " << gp->GetSequence();
log.EndDiagnostic();
}
universals.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);
}
}
for (UNIVERSALS::iterator j = universals.begin(); j != universals.end(); ++j){
if ((*j)->IsEnabled()) {
vxirec->DeactivateGrammar(vxirec, (*j)->GetRecGrammar());
(*j)->SetEnabled(false);
}
}
}
void GrammarManager::ReleaseGrammars()
{
while (!grammars.empty()) {
GrammarInfo * gp = grammars.back();
grammars.pop_back();
VXIrecGrammar * grammar = gp->GetRecGrammar();
if (log.IsLogging(2)) {
log.StartDiagnostic(2) << L"GrammarManager::ReleaseGrammars(" << grammar
<< L")";
log.EndDiagnostic();
}
vxirec->FreeGrammar(vxirec, &grammar);
delete gp;
}
while (!universals.empty()) {
GrammarInfoUniv * gp = universals.back();
universals.pop_back();
VXIrecGrammar * grammar = gp->GetRecGrammar();
if (log.IsLogging(2)) {
log.StartDiagnostic(2) << L"GrammarManager::ReleaseGrammars(" << grammar
<< L")";
log.EndDiagnostic();
}
vxirec->FreeGrammar(vxirec, &grammar);
delete gp;
}
}
bool GrammarManager::EnableGrammars(const vxistring & documentID,
const vxistring & dialogName,
const vxistring & fieldName,
const VXIMapHolder & properties,
bool isModal)
{
bool enabled = false;
if (log.IsLogging(2)) {
log.StartDiagnostic(2) << L"GrammarManager::EnableGrammar: Enter";
log.EndDiagnostic();
}
// (1) Do ordinary grammars...
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);
bool fieldGram = (!fieldName.empty() && fieldsMatch);
bool dialogGram = (!isModal && (*i)->IsScope(GRS_DIALOG) && dialogsMatch);
bool docGram = (!isModal && (*i)->IsScope(GRS_DOC));
GrammarScope cScope = GRS_NONE;
if ( fieldGram ||
// Enable those field grammars matching our (field, form) pair
dialogGram ||
// Enable form grammars & dialog scope fields, if not modal
docGram
// Enable document level grammars, if not modal
)
{
if (log.IsLogging(2)) {
log.StartDiagnostic(2) << L"GrammarManager::EnableGrammar("
<< (*i)->GetRecGrammar() << L")";
log.EndDiagnostic();
}
VXIrecResult err = vxirec->ActivateGrammar(vxirec, properties.GetValue(),
(*i)->GetRecGrammar());
if( err != VXIrec_RESULT_SUCCESS )
ThrowSpecificEventError(err, GRAMMAR);
// determine grammar scope
if (fieldGram)
cScope = GRS_FIELD;
else if (dialogGram)
cScope = GRS_DIALOG;
else if (docGram)
cScope = GRS_DOC;
(*i)->SetEnabled(true, cScope);
enabled = true;
}
}
// (2) Do universals
//#pragma message("JC: Universals should be sensitive to the active language.")
// (2.1) Get the property.
const VXIValue * val = VXIMapGetProperty(properties.GetValue(),
PROP_UNIVERSALS);
if (val == NULL || VXIValueGetType(val) != VALUE_STRING)
return enabled;
const VXIchar * temp = VXIStringCStr(reinterpret_cast<const VXIString*>(val));
// (2.2) Convert the property into a set of tokens separated by the delimiter
// characters.
const VXIchar * DELIM = L"|";
vxistring request = DELIM;
for (; *temp != '\0'; ++temp) {
VXIchar t = *temp;
if (t == ' ' || t == '\t' || t == '\r' || t == '\n')
request += DELIM;
else
request += t;
}
request += DELIM;
// (2.3) If the universals string is 'none', we are done.
if (request == L"|none|")
return enabled;
// (2.4) Check for all anywhere in the string.
bool doAll = (request.find(L"|all|") != vxistring::npos);
// (2.5) Now walk the list.
for (UNIVERSALS::iterator j = universals.begin(); j != universals.end(); ++j)
{
bool doThis = doAll;
if (!doThis) {
vxistring delimName = DELIM;
delimName += (*j)->GetName();
delimName += DELIM;
doThis = (request.find(delimName) != vxistring::npos);
}
if (doThis) {
VXIrecResult err = vxirec->ActivateGrammar(vxirec, properties.GetValue(),
(*j)->GetRecGrammar());
if (err != VXIrec_RESULT_SUCCESS)
ThrowSpecificEventError(err, GRAMMAR);
(*j)->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,
VXIContent * & waveform,
VXIContent * & xmlresult)
{
VXIrecRecognitionResult * result = NULL;
// (1) Attempt a recognition.
VXIrecResult err = vxirec->Recognize(vxirec, properties.GetValue(), &result);
if (err != VXIrec_RESULT_SUCCESS && result != NULL)
result->Destroy(&result);
// (2) Process return value.
switch (err) {
case VXIrec_RESULT_SUCCESS:
break;
default:
// try to throw any specific event for the error before bail out
ThrowSpecificEventError(err, RECOGNIZE);
// throw an internal error
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;
}
// (3) Is the result structure valid?
if (result == NULL) {
log.LogError(420, SimpleLogger::MESSAGE,
L"function returned VXIrecSUCCESS but did not allocate "
L"an answer structure");
return GrammarManager::InternalError;
}
if (result->xmlresult == NULL) {
log.LogError(420, SimpleLogger::MESSAGE,
L"function returned VXIrecSUCCESS but did not allocate "
L"an XML result");
return GrammarManager::InternalError;
}
// (4) Preserve the contents, but delete the result structure.
waveform = result->waveform;
xmlresult = result->xmlresult;
result->waveform = NULL;
result->xmlresult = NULL;
result->Destroy(&result);
return GrammarManager::Success;
}
bool GrammarManager::FindMatchedElement(const vxistring & id,
VXMLElement & match) const
{
unsigned long trash;
return FindMatchedElement(id, match, trash);
}
// Find the VXML element associated with the matched grammar.
//
bool GrammarManager::FindMatchedElement(const vxistring & id,
VXMLElement & match,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -