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

📄 vxirec_utils.cpp

📁 openvxi3.4是一个voicexml对话脚本语言的解释器源码.可用VC6.0编译.
💻 CPP
📖 第 1 页 / 共 3 页
字号:

static void GetNextToken(const vxistring & grammar,
                         vxistring::size_type pos,
                         vxistring::size_type end,
                         vxistring & token)
{
  // Find first real character
  while (pos != grammar.length() && VXIrecIsSpace(grammar[pos])) ++pos;
  if (pos == grammar.length()) {
    token.erase();
    return;
  }

  // Extract wordRaw; we know there is at least one character
  while (VXIrecIsSpace(grammar[end - 1])) --end;
  token = grammar.substr(pos, end - pos);
}

//
// This conversion function is tied to ScanSoft's semantic interpretation
//
bool VXIrecData::JSGFToSRGS(const vxistring & incoming,
                            vxistring & result,
                            const VXIMap* props)
{
  // These define the symbols used in the JSGF-lite that defines these grammars
  const wchar_t NEXT      = L'|';
  const wchar_t BEGIN_VAL = L'{';
  const wchar_t END_VAL   = L'}';

  // retrieve language id
  vxistring xmllang(L"");
  const VXIValue *v = VXIMapGetProperty(props, REC_LANGUAGE);
  if( v && VXIValueGetType(v) == VALUE_STRING )
    xmllang = VXIStringCStr((const VXIString*)v);

  // Unable to detect language id
  if( xmllang.empty() ) return false;

  // retrieve dtmf id
  bool isDTMF = false;
  v = VXIMapGetProperty(props, REC_INPUT_MODES);
  if( v && VXIValueGetType(v) == VALUE_INTEGER)
  {
    isDTMF = (VXIIntegerValue((const VXIInteger*)v) == REC_INPUT_MODE_DTMF);
  }

  // create ROOT id, potential bug anyone care???
  VXItrdMutexLock(gblMutex);
  VXIulong cnt = GRAM_ROOT_COUNTER++;
  VXItrdMutexUnlock(gblMutex);
  std::basic_stringstream<VXIchar> ROOT_ID;
  ROOT_ID << GRAM_ROOT_PREFIX << cnt;


  result = L"<?xml version='1.0'?>"
           L"<grammar xmlns='http://www.w3.org/2001/06/grammar' "
           L"version='1.0' root='";
  result += ROOT_ID.str();
  result += L"' tag-format='swi-semantics/1.0' xml:lang='";
  result += xmllang;
  result += L"'";
  if (isDTMF)
    result += L" mode='dtmf'";
  result += L">\n"
            L"<meta name=\"swirec_simple_result_key\" content=\"MEANING\"/>"
            L"<rule id='";
  result += ROOT_ID.str();
  result += L"' scope='public'>\n"
            L"<one-of>\n";

  // These define the units from which we'll build new rules.
  const vxistring RULE_BEGIN  = L"<item>";
  const vxistring RULE_MIDDLE = L"<tag>MEANING=\"";
  const vxistring RULE_END    = L"\";</tag></item>\n";
  // TODO: Must escape values in tags???

  // These are positions within the string that we're parsing.
  vxistring::size_type pos = 0;
  vxistring::size_type next;
  vxistring::size_type valmark;

  vxistring wordRaw;
  vxistring wordValue;

  while (pos < incoming.length()) {
    // Find the next item
    next = incoming.find(NEXT, pos);
    if (next == vxistring::npos) next = incoming.length();

    // Find the start of the value
    valmark = incoming.find(BEGIN_VAL, pos);
    if (valmark == vxistring::npos || valmark > next) valmark = next;

    // Extract left hand side (raw text)
    GetNextToken(incoming, pos, valmark, wordRaw);
    if (wordRaw.empty()) {
      pos = next + 1;
      continue;
    }
    pos = valmark + 1;

    // Extract right hand side (value)
    if (valmark != next && pos < incoming.length()) {
      valmark = incoming.find(END_VAL, pos);
      if (valmark == vxistring::npos || valmark > next) {
        LogError(280, L"%s%s", L"Error", L"Mismatched { } pair");
        return false;
      }
      GetNextToken(incoming, pos, valmark, wordValue);
      if (wordValue.empty()) {
        return false;
      }
      pos = next + 1;
    }
    else
      wordValue.erase();

    // Add word to grammar
    FixEscapeChar(wordRaw);
    if (!wordValue.empty()) {
      // Got tag value
      FixEscapeChar(wordValue);
      result += RULE_BEGIN + wordRaw + RULE_MIDDLE + wordValue + RULE_END;
    } else {
      // Didn't get tag value
      result += RULE_BEGIN + wordRaw + RULE_MIDDLE + wordRaw + RULE_END;
    }
  }
  // add end tag
  result += L"</one-of></rule></grammar>";
  return true;
}


bool VXIrecData::OptionToSRGS(const VXIMap    * props,
                  const VXIVector * choices,
                  const VXIVector * values,
                  const VXIVector * acceptances,
                  const VXIbool     isDTMF,
                  vxistring & srgs)
{
  static const VXIchar* fnname = L"OptionToSRGS";
  srgs = L"";

  // (1) Validate vectors.
  if (choices == NULL || values == NULL || acceptances == NULL) {
    LogError(281, L"%s%s", L"A Vector", L"NULL");
    return false;
  }

  unsigned int len = VXIVectorLength(choices);
  if (len != VXIVectorLength(values)) {
    LogError(281, L"%s%s", L"Vectors", L"Mismatched vector lengths");
    return false;
  }

  for (unsigned int j = 0; j < len; ++j) {
    const VXIValue * c = VXIVectorGetElement(choices, j);
    const VXIValue * v = VXIVectorGetElement(values, j);
    const VXIValue * a = VXIVectorGetElement(acceptances, j);

    if (c == NULL || v == NULL || VXIValueGetType(c) != VALUE_STRING ||
        VXIValueGetType(v) != VALUE_STRING)
    {
      LogError(281, L"%s%s", L"Options", L"Contents not all strings");
      return false;
    }

    LogDiag(4, fnname, L"%s%s%s%s%s%d",
            L"choice: ", VXIStringCStr(reinterpret_cast<const VXIString *>(c)),
            L", value: ", VXIStringCStr(reinterpret_cast<const VXIString *>(v)),
            L", accept: ", VXIIntegerValue(reinterpret_cast<const VXIInteger *>(a)) );
  }

  // (2) extracting weight (does not meaning anything for simulator ???)
  VXIulong weight = 1;
  const VXIValue* val = VXIMapGetProperty(props, REC_GRAMMAR_WEIGHT);
  if( val && VXIValueGetType(val) == VALUE_FLOAT )
    weight *= (VXIulong)VXIFloatValue((const VXIFloat*)val);


  // (3) retrieve language id
  vxistring xmllang(L"");
  const VXIValue *v = VXIMapGetProperty(props, REC_LANGUAGE);
  if( v && VXIValueGetType(v) == VALUE_STRING )
    xmllang = VXIStringCStr((const VXIString*)v);
  // Unable to detect language id
  if( xmllang.empty() ) return false;

  // (4) create ROOT id, wrap-round potential bug, anyone care???
  VXItrdMutexLock(gblMutex);
  VXIulong cnt = GRAM_ROOT_COUNTER++;
  VXItrdMutexUnlock(gblMutex);
  std::basic_stringstream<VXIchar> ROOT_ID;
  ROOT_ID << GRAM_ROOT_PREFIX << cnt;

  // (4) construct srgs -- NOTES: this construction is tied to SSFT's semantic
  srgs = L"<?xml version='1.0'?><grammar "
         L"xmlns='http://www.w3.org/2001/06/grammar' "
         L"version='1.0' root='";
  srgs += ROOT_ID.str();
  srgs += L"' tag-format='swi-semantics/1.0' xml:lang='";
  srgs += xmllang;
  srgs += L"'";
  if (isDTMF) srgs += L" mode='dtmf'";
  srgs += L"><meta name='swirec_simple_result_key' content='MEANING'/>"
          L"<rule id='";
  srgs += ROOT_ID.str();
  srgs += L"' scope='public'><one-of>";

  // (5) Add item for each <option>.

  // These define the units from which we'll build new rules.
  const vxistring RULE_BEGIN  = L"<item>";
  const vxistring RULE_MIDDLE = L"<tag>MEANING='";
  const vxistring RULE_END    = L"';</tag></item>";

  for (unsigned int i = 0; i < len; ++i) {
    const VXIValue * c = VXIVectorGetElement(choices, i);
    const VXIValue * v = VXIVectorGetElement(values, i);
    const VXIValue * a = VXIVectorGetElement(acceptances, i);
    vxistring aitem( VXIStringCStr(reinterpret_cast<const VXIString *>(c)));
    vxistring avalue(VXIStringCStr(reinterpret_cast<const VXIString *>(v)));
    // normalize text
    FixEscapeChar(aitem);

    if( !isDTMF && VXIIntegerValue(reinterpret_cast<const VXIInteger *>(a)) > 0 )
    {
      // If Recongizer does not support approximate recognition we need to
      // split the string into single item based on single space
      bool done = false;
      vxistring tmpStr(aitem);
      vxistring::size_type idx;
      VXIchar aWord[1024];
      const VXIchar *ptr = tmpStr.c_str();

      // search for the 1st white space
      // TODO: should take care about tab, multiple spaces!!!
      idx = tmpStr.find(L" ", 0);
      do
      {
        // create single item separated by space
        if( idx == vxistring::npos )
        {
          idx = tmpStr.length();
          done = true;
        }
        // create separate <item> for each word
        wcsncpy(aWord, ptr, idx);
        aWord[idx] = L'\0';
        srgs += RULE_BEGIN;
        srgs += aWord;
        srgs += RULE_MIDDLE;
        srgs += avalue;
        srgs += RULE_END;

        // search for the next word
        if( !done )
        {
          ptr += (idx+1);
          tmpStr = ptr;
          idx = tmpStr.find(L" ", idx + 1);
        }
      } while( !done );

    } else {
      srgs += RULE_BEGIN;
      srgs += aitem;
      srgs += RULE_MIDDLE;
      srgs += avalue;
      srgs += RULE_END;
    }
  }

  // (6) Finish everything and add grammar.

  srgs += L"</one-of></rule></grammar>";
  LogDiag(DIAG_TAG_RECOGNITION, fnname, L"%s%s", L"OPTION GRAMMAR: ", srgs.c_str());
  return true;
}

VXIlogResult VXIrecData::LogError(VXIunsigned errorID,
                               const VXIchar *format, ...) const
{
  VXIlogResult rc;
  va_list args;

  if (!log)
    return VXIlog_RESULT_NON_FATAL_ERROR;

  if (format) {
    va_start(args, format);
    rc = (*log->VError)(log, COMPANY_DOMAIN L".VXIrec", errorID, format, args);
    va_end(args);
  } else {
    rc = (*log->Error)(log, COMPANY_DOMAIN L".VXIrec", errorID, NULL);
  }

  return rc;
}

VXIlogResult VXIrecData::LogDiag(VXIunsigned tag, const VXIchar *subtag,
                              const VXIchar *format, ...) const
{
  VXIlogResult rc;
  va_list args;

  if (!log)
    return VXIlog_RESULT_NON_FATAL_ERROR;

  if (format) {
    va_start(args, format);
    rc = (*log->VDiagnostic)(log, tag + diagLogBase, subtag, format, args);
    va_end(args);
  } else {
    rc = (*log->Diagnostic)(log, tag + diagLogBase, subtag, NULL);
  }

  return rc;
}

bool VXIrecData::FetchContent(
    const VXIchar *  name, 
    const VXIMap  *  properties,
    VXIbyte       ** result,
    VXIulong      &  read )
{
  *result = NULL;
  read = 0;

  VXIinetStream *stream;
  VXIMapHolder streamInfo;
		 
  if (inet->Open(inet,
		L"Rec",
		name,
		INET_MODE_READ,
		0,
		properties,
		streamInfo.GetValue(),
		&stream ) != VXIinet_RESULT_SUCCESS ) return false;

  const VXIValue * tempSize = NULL;
  tempSize = VXIMapGetProperty(streamInfo.GetValue(), INET_INFO_SIZE_BYTES);
  if (tempSize == NULL || VXIValueGetType(tempSize) != VALUE_INTEGER) {
    inet->Close(inet, &stream);
	return false;
  }

  VXIint32 bufSize
    = VXIIntegerValue(reinterpret_cast<const VXIInteger *>(tempSize));

  if (bufSize < 2047)
    bufSize = 2047;

  ++bufSize;
  VXIbyte * buffer = new VXIbyte[bufSize];
  if(buffer == NULL){
    inet->Close(inet, &stream);
    return false;
  }

  bool reachedEnd = false; 
  while (!reachedEnd) {
    VXIulong bytesRead = 0;
    switch (inet->Read(inet, buffer+read, bufSize-read, &bytesRead, stream)) {
    case VXIinet_RESULT_SUCCESS:
      read += bytesRead;
      break;
    case VXIinet_RESULT_END_OF_STREAM:
      read += bytesRead;
      reachedEnd = true;  // exit while
      break;
    case VXIinet_RESULT_WOULD_BLOCK:
      VXItrdThreadYield();
      break;
    default:
      inet->Close(inet, &stream);
      delete[] buffer;
      return false;
    }

    if (read == static_cast<VXIulong>(bufSize)) {
      // The number of bytes read exceeds the number expected.  Double the
      // size and keep reading.
      VXIbyte * temp = new VXIbyte[2*bufSize];
      if(temp == NULL) {
        delete [] buffer;
        return false;
      }
      memcpy(static_cast<void *>(temp), static_cast<void *>(buffer),
             bufSize * sizeof(VXIbyte));
      delete[] buffer;
      buffer = temp;
      bufSize *= 2;
    }
  }

  inet->Close(inet, &stream);
  *result = buffer;

  return true;
}

⌨️ 快捷键说明

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