📄 vxirec_utils.cpp
字号:
void VXIrecData::ShowPropertyValue(const VXIchar *key,
const VXIValue *value, VXIunsigned PROP_TAG)
{
VXIchar subtag[512] = L"Property";
if( value == 0 ) return;
VXIvalueType type = VXIValueGetType(value);
{
switch( type )
{
case VALUE_INTEGER:
wcscpy(subtag, L"Property:INT");
LogDiag(PROP_TAG, subtag,
L"%s=%d", key, VXIIntegerValue((const VXIInteger*)value));
break;
case VALUE_FLOAT:
wcscpy(subtag, L"Property:FLT");
LogDiag(PROP_TAG, subtag,
L"%s=%f", key, VXIFloatValue((const VXIFloat*)value));
break;
case VALUE_BOOLEAN:
wcscpy(subtag, L"Property:BOOL");
LogDiag(PROP_TAG, subtag,
L"%s=%d", key, VXIBooleanValue((const VXIBoolean*)value));
break;
case VALUE_STRING:
wcscpy(subtag, L"Property:STR");
LogDiag(PROP_TAG, subtag,
L"%s=%s", key, VXIStringCStr((const VXIString*)value));
break;
case VALUE_PTR:
wcscpy(subtag, L"Property:PTR");
LogDiag(PROP_TAG, subtag,
L"%s(ptr)=0x%p", key, VXIPtrValue((const VXIPtr*)value));
break;
case VALUE_CONTENT:
wcscpy(subtag, L"Property:CNT");
LogDiag(PROP_TAG, subtag,
L"%s(content)=0x%p", key, value);
break;
case VALUE_MAP:
{
VXIchar endtag[512];
const VXIchar *mykey = key ? key : L"NULL";
wcscpy(subtag, L"Property:MAP:BEG");
wcscpy(endtag, L"Property:MAP:END");
LogDiag(PROP_TAG, subtag, L"%s", mykey);
const VXIchar *key = NULL;
const VXIValue *gvalue = NULL;
VXIMapIterator *it = VXIMapGetFirstProperty((const VXIMap*)value, &key, &gvalue);
int ret = 0;
while( ret == 0 && key && gvalue )
{
ShowPropertyValue(key, gvalue, PROP_TAG);
ret = VXIMapGetNextProperty(it, &key, &gvalue);
}
VXIMapIteratorDestroy(&it);
LogDiag(PROP_TAG, endtag, L"%s", mykey);
}
break;
case VALUE_VECTOR:
{
VXIunsigned vlen = VXIVectorLength((const VXIVector*)value);
for(VXIunsigned i = 0; i < vlen; ++i)
{
const VXIValue *gvalue = VXIVectorGetElement((const VXIVector*)value, i);
ShowPropertyValue(L"Vector", gvalue, PROP_TAG);
}
}
break;
default:
LogDiag(PROP_TAG, subtag, L"%s=%s", key, L"UNKOWN");
}
}
return;
}
void VXIrecData::ShowPropertyValue(const VXIMap *properties)
{
const VXIchar *key = NULL;
const VXIValue *gvalue = NULL;
const VXIunsigned PROP_TAG = DIAG_TAG_PROPERTY;
if( log && (log->DiagnosticIsEnabled(log, diagLogBase+PROP_TAG) == TRUE)
&& properties )
{
VXIMapIterator *it = VXIMapGetFirstProperty(properties, &key, &gvalue);
int ret = 0;
while( ret == 0 && key && gvalue )
{
ShowPropertyValue(key, gvalue, PROP_TAG);
ret = VXIMapGetNextProperty(it, &key, &gvalue);
}
VXIMapIteratorDestroy(&it);
}
return;
}
// Pasre SRGS grammar
// NOTES: re-parse the same grammar seems to be slow, optimization is welcome!
//
VXIrecGrammar * VXIrecData::ParseSRGSGrammar(const vxistring & srgsgram,
const VXIMap * properties,
bool isdtmf)
{
const VXIchar* fnname = L"ParseSRGSGrammar";
LogBlock logger(log, VXIrecData::diagLogBase, fnname, VXIREC_MODULE);
VXIrecWordList * newGrammarPtr = new VXIrecWordList();
try {
xmlHandler->CreateGrammarInfoList();
const VXIbyte* buffer = reinterpret_cast<const VXIbyte*>(srgsgram.c_str());
VXIulong bufSize = srgsgram.length() * sizeof(VXIchar) / sizeof(VXIbyte);
MemBufInputSource membuf(buffer, bufSize, "SRGSGRAM", false);
parser->parse(membuf);
}
catch (const XMLException & exception) {
LogError(352, L"%s%s", L"Parse Error", XMLChToVXIchar(exception.getMessage()).c_str());
xmlHandler->DestroyGrammarInfoList();
delete newGrammarPtr;
return NULL;
}
catch (const SAXParseException & exception) {
LogError(353, L"%s%s%s%d%s%d%s%s",
L"ID", XMLChToVXIchar(exception.getSystemId()).c_str(),
L"line", exception.getLineNumber(),
L"col", exception.getColumnNumber(),
L"msg", XMLChToVXIchar(exception.getMessage()).c_str());
xmlHandler->DestroyGrammarInfoList();
delete newGrammarPtr;
return NULL;
}
// Take the ownership of grammar info list
if( !isdtmf ) isdtmf = xmlHandler->isDTMFGrammar();
newGrammarPtr->gtype = ( isdtmf ? VXIrecWordList::GTYPE_DTMF :
VXIrecWordList::GTYPE_SPEECH);
newGrammarPtr->grammarInfoList = xmlHandler->AcquireGrammarInfoList();
return newGrammarPtr;
}
void VXIrecData::Clear()
{
if( !grammars.empty() )
for (GRAMMARS::iterator i = grammars.begin(); i != grammars.end(); ++i)
delete *i;
grammars.clear();
}
void VXIrecData::ActivateGrammar(VXIrecGrammar *g)
{
g->SetEnabled(true);
activeGrammars.push_back(g);
}
void VXIrecData::DeactivateGrammar(VXIrecGrammar *g)
{
g->SetEnabled(false);
activeGrammars.remove(g);
}
int VXIrecData::GetActiveCount() const
{
/*int count = 0;
for (GRAMMARS::const_iterator i = grammars.begin(); i != grammars.end(); ++i) {
if ((*i)->IsEnabled()) count++;
}
return count;*/
return activeGrammars.size();
}
void VXIrecData::AddGrammar(VXIrecGrammar * l)
{
if (l == NULL) return;
grammars.push_front(l);
}
void VXIrecData::FreeGrammar(VXIrecGrammar * l)
{
if (l == NULL) return;
if( !grammars.empty() )
grammars.remove(l);
delete l;
}
bool VXIrecData::ProcessSemanticInterp(vxistring & result, const VXIrecGrammarInfo *ginfo)
{
const VXIchar* fnname = L"ProcessSemanticInterp";
LogBlock logger(log, VXIrecData::diagLogBase, fnname, VXIREC_MODULE);
result = L"";
if( !ginfo ) return false;
if( ginfo->tag.empty() ) {
// there is no tag
result = L"<instance></instance>";
return true;
}
// Processin <tag>
// this is only a partial impl.
// given a tag of:
// x=new Object(); x.a='valueA'; x.b='valueB'; y='valueY'; z='valueZ';
// the following should be created:
// <instance>
// <x>
// <a>valueA</a>
// <b>valueB</b>
// </x>
// <y>valueY</y>
// <z>valueZ</z>
// </instance>
//
// but... this code won't do that.
vxistring temp = ginfo->tag;
vxistring::size_type pos = temp.find(L"=");
// handle simple result. ex.: <tag>frog</tag> would
// return <instance>frog</instance>
if( pos == vxistring::npos ){
result = L"<instance>" + ginfo->tag + L"</instance>";
return true;
}
result = L"<instance>";
bool gotit = false;
while (!temp.empty() && pos != vxistring::npos ) {
// retrieve var.
vxistring semvar = temp.substr(0, pos);
PruneWhitespace(semvar);
temp.erase(0, pos+1);
PruneWhitespace(temp);
// find value
vxistring value;
pos = temp.find(L";");
if( pos == vxistring::npos ) {
if( temp.empty() ) return false;
value = temp;
temp = L"";
}
else {
value = temp.substr(0, pos);
temp.erase(0, pos+1);
}
if( !value.empty() ) {
PruneWhitespace(value);
// remove single or double quotes
if( value[0] == L'\"' ) value.erase(0,1);
if( value[value.length()-1] == L'\"' ) value.erase(value.length()-1);
if( value[0] == L'\'' ) value.erase(0,1);
if( value[value.length()-1] == L'\'' ) value.erase(value.length()-1);
}
else {
result = L"";
return false;
}
// construct semantic
logger.logDiag(DIAG_TAG_RECOGNITION, L"%s%s%s%s%s%s", L"tag: ", semvar.c_str(),
L", value: ", value.c_str(),
L", semantic: ", ginfo->semantic.c_str());
if( semvar == ginfo->semantic ) {
if( gotit ) {
result = L"";
return false;
}
gotit = true;
result += value;
}
else {
result += L"<" + semvar;
result += L" confidence='100'>";
result += value;
result += L"</" + semvar + L">";
}
// Search for next var.
pos = temp.find(L"=");
}
result += L"</instance>";
return true;
}
bool VXIrecData::ConstructNLSMLForInput(const VXIchar* input, vxistring & nlsmlresult)
{
const VXIchar* fnname = L"ConstructNLSMLForInput";
LogBlock logger(log, VXIrecData::diagLogBase, fnname, VXIREC_MODULE);
VXIrecGrammar * match = NULL;
VXIrecGrammarInfo * gInfo = NULL;
VXIchar gramid[64];
nlsmlresult = L"";
if( !input || input[0] == L'\0' ) return false;
for (GRAMMARS::iterator i = activeGrammars.begin(); i != activeGrammars.end(); ++i) {
if ((*i)->IsEnabled() && (*i)->GetGrammarInfo(input, &gInfo)) {
logger.logDiag(DIAG_TAG_RECOGNITION, L"%s%p%s%s",
(match ? L"Multiple grammars matched " : L"Found matched grammar "),
(*i), L" for ", gInfo->word.c_str());
match = *i;
// Constructing NLSML result
if( nlsmlresult.empty() ) {
// header
nlsmlresult = L"<?xml version='1.0'?>"
L"<result>";
}
// Create grammar ID
SWIswprintf(gramid, 64, L"%p", match);
// interpretation
nlsmlresult += L"<interpretation grammar='";
nlsmlresult += gramid;
nlsmlresult += L"' confidence='99'><input mode='";
nlsmlresult += ( match->IsDtmf() ? L"dtmf'>" : L"speech'>");
nlsmlresult += gInfo->word;
nlsmlresult += L"</input>";
// Semantic interp.
vxistring temp(L"");
if( !ProcessSemanticInterp(temp, gInfo) )
{
nlsmlresult = L"";
break;
}
nlsmlresult += temp.c_str();
// close interpretation
nlsmlresult += L"</interpretation>";
}
}
if( !nlsmlresult.empty() ) {
nlsmlresult += L"</result>";
return true;
}
return false;
}
//////////////////////////////////////////////////////
// These routines process JSGF-lite grammars. //
//////////////////////////////////////////////////////
static const int FINISH_STAGE = 3;
void VXIrecData::ConvertJSGFType(const vxistring & dataIn, JSGFInfo & info)
{
// search tokens
const vxistring fEqualToken(L"=");
const vxistring fCommaToken(L";");
const vxistring fHeaderToken(L"#JSG");
vxistring data(dataIn);
vxistring fVersion;
vxistring fName;
vxistring fPublic;
// search
vxistring::size_type pos = data.find(fCommaToken);
int stage = 0;
while( pos != vxistring::npos && stage < FINISH_STAGE) {
vxistring temp = data.substr(0, pos);
switch( stage++ ) {
case 0: // version
// confirm JSGF header
if( temp.find(fHeaderToken) == vxistring::npos) {
// quit parsing,
stage = FINISH_STAGE;
break;
}
info.versionStr = temp;
data.erase(0, pos+1);
break;
case 1: // grammar name
info.nameStr = temp;
data.erase(0, pos+1);
break;
case 2: // public type
{
// remove the found token
data.erase(pos);
// search for "=" token
vxistring::size_type tpos = data.find(fEqualToken);
if( tpos != vxistring::npos ) {
info.publicStr = data.substr(0, tpos);
// remove the public string
data.erase(0, tpos+1);
}
} break;
}
// Continue searching
if( stage != FINISH_STAGE ) pos = data.find(fCommaToken);
}
// finally copy the content string
info.contentStr = data;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -