static VXIbool VXIrecSupportsHotwordTransfer( struct VXIrecInterface * pThis, const VXIMap * properties, const VXIchar * transferDest) { VXIbool result = FALSE; // this is really just to demonstrate how the platform could // support hotword for some type of transfers, but not others. // this could just as easily been based on other properties of // the transfer. i.e., destination type, required line type, etc... const VXIValue* dval = VXIMapGetProperty(properties, TEL_TRANSFER_TYPE); if( dval && VXIValueGetType(dval) == VALUE_STRING ){ const wchar_t* hid = VXIStringCStr(reinterpret_cast<const VXIString *>(dval)); if (wcscmp(hid, L"consultation") == 0) return FALSE; } dval = VXIMapGetProperty(properties, L"SupportsHotwordTransfer"); if( dval && VXIValueGetType(dval) == VALUE_STRING ){ const wchar_t* hid = VXIStringCStr(reinterpret_cast<const VXIString *>(dval)); result = (wcscmp(hid, L"true") == 0) ? TRUE : FALSE; } return result; }
// Begin a session // static VXItelResult OSBtelBeginSession(VXItelInterface * pThis, VXIMap *sessionArgs) { OSBtelImpl *impl = ToOSBtelImpl(pThis); impl->live = -1; // not quite live yet, other threads shouldn't its access resources Diag(impl, DIAG_TAG_SIGNALING, NULL, L"tel BeginSession"); const VXIchar *callId = NULL; const VXIValue *val; val = VXIMapGetProperty(sessionArgs, L"callid"); impl->pExitGuard = new OsBSem(OsBSem::Q_PRIORITY, OsBSem::FULL); impl->transferred = 0; impl->callId = NULL; if ((val) && (VXIValueGetType(val) == VALUE_STRING)) { callId = VXIStringCStr((const VXIString *) val); int len = strlen((char*)callId) + 1; VXIchar *vxiCallid = (VXIchar *) calloc(len, sizeof(VXIchar)); if (vxiCallid) { strncpy((char*)vxiCallid, (char*)callId, len); impl->callId = vxiCallid; } else return VXItel_RESULT_OUT_OF_MEMORY; } else return VXItel_RESULT_INVALID_ARGUMENT; impl->live = 1; // live return VXItel_RESULT_SUCCESS; }
/** * Sample object setting the defaults document for subsequent calls * * @param properties [IN] See description in VXIobjectExecute() * or VXIobjectValidate() * @param parameters [IN] See description in VXIobjectExecute() * or VXIobjectValidate() * @param execute [IN] Specifies whether the object should be * executed (true) or simply validated (false) * @param result [OUT] See description in VXIobjectExecute() * or VXIobjectValidate() * * @result VXIobj_RESULT_SUCCESS on success */ static VXIobjResult ProcessComSpeechworksSetDefaultsObject (struct VXIobjectInterface *pThis, const VXIMap *properties, const VXIMap *parameters, VXIbool execute, VXIValue **result) { static const wchar_t func[] = L"ProcessComSpeechworksSetDefaults"; GET_VXIOBJECT (pThis, sbObject, log, rc); if((execute) && (result == NULL)) return VXIobj_RESULT_INVALID_ARGUMENT; if((! properties) || (! parameters)) return VXIobj_RESULT_INVALID_ARGUMENT; if(execute) { const VXIchar *defaults = NULL; const VXIValue *val = VXIMapGetProperty(parameters, L"defaults"); if (! val) { Error(log, 202, L"%s%s", L"parameter", L"defaults"); return VXIobj_RESULT_INVALID_PROP_VALUE; } else if (VXIValueGetType(val) != VALUE_STRING) { Error(log, 203, L"%s%s%s%d", L"parameter", L"defaults", L"type", VXIValueGetType(val)); return VXIobj_RESULT_INVALID_PROP_VALUE; } defaults = VXIStringCStr(reinterpret_cast<const VXIString *>(val)); if (! defaults[0]) { Error(log, 204, L"%s%s%s%s", L"parameter", L"defaults", L"value", defaults); return VXIobj_RESULT_INVALID_PROP_VALUE; } // Hack to set the defaults document VXIobjectAPI *objectAPI = (VXIobjectAPI *) pThis; if ( ! objectAPI ) { rc = VXIobj_RESULT_INVALID_ARGUMENT; return rc; } VXIplatform *plat = objectAPI->resources->platform; VXIMap *vxiProperties = VXIMapCreate(); VXIString * valstr = VXIStringCreate(defaults); VXIMapSetProperty(vxiProperties, VXI_PLATFORM_DEFAULTS, (VXIValue *) valstr); plat->VXIinterpreter->SetProperties(plat->VXIinterpreter, vxiProperties); // Create the result object VXIMap *resultObj = VXIMapCreate(); if(resultObj == NULL) { Error(log, 100, NULL); return VXIobj_RESULT_OUT_OF_MEMORY; } *result = reinterpret_cast<VXIValue *>(resultObj); // Set the result object's status field to 'success' VXIMapSetProperty(resultObj, L"status", reinterpret_cast<VXIValue *>(VXIStringCreate(L"success"))); } return VXIobj_RESULT_SUCCESS; }
static VXIrecResult VXIrecRecognize(VXIrecInterface *pThis, const VXIMap *properties, VXIrecRecognitionResult **recogResult) { const wchar_t* fnname = L"VXIrecRecognize"; VXIrecData* tp = GetRecData(pThis); if (tp == NULL) return VXIrec_RESULT_INVALID_ARGUMENT; LogBlock logger(tp->GetLog(), gblDiagLogBase, fnname, VXIREC_MODULE); VXIchar* input = NULL; VXIMap* res = NULL; VXIchar* str = NULL; VXIchar console[512]; bool recordUtterance = false; bool haveUtterance = true; // DEBUG if (voiceglue_loglevel() >= LOG_DEBUG) { std::ostringstream logstring; logstring << "VXIrecRecognize called with properties " << VXIValue_to_Std_String ((const VXIValue *) properties); voiceglue_log ((char) LOG_DEBUG, logstring); }; if (properties != NULL) { const VXIValue * ru = VXIMapGetProperty(properties, REC_RECORDUTTERANCE); if (ru) recordUtterance = wcscmp(VXIStringCStr((const VXIString*)ru), L"true") == 0; /* Ignore force-feed input option const VXIValue * val = VXIMapGetProperty(properties, L"SpeechInput"); if( val ) { logger.logDiag(DIAG_TAG_RECOGNITION, L"%s%s", L"SpeechInput: ", VXIStringCStr((const VXIString*)val)); } if (val == NULL || VXIValueGetType(val) != VALUE_STRING) { val = VXIMapGetProperty(properties, L"DTMFInput"); if( val ) { logger.logDiag(DIAG_TAG_RECOGNITION, L"%s%s", L"DTMFInput: ", VXIStringCStr((const VXIString*)val)); } } VXIString* vect = (VXIString*) val; if (vect != NULL) input = (VXIchar*) VXIStringCStr(vect); */ /* Ignore console input option if (input && wcscmp(input, L"-") == 0) { unsigned int i; VXIchar* cp = console; char lbuf[512]; printf("Console: "); fgets(lbuf, 511, stdin); // copy to VXIchar for(i = 0; i < strlen(lbuf); ++i) { if (lbuf[i] == '\r' || lbuf[i] == '\n') continue; *cp++ = lbuf[i] & 0x7f; } *cp++ = 0; input = console; logger.logDiag(DIAG_TAG_RECOGNITION, L"%s%s", L"Input: ", (input ? input : L"NULL")); } */ } // Get NLSML recognition result from perl in nlsmlresult vxistring nlsmlresult; VXIrecResult rec_res; rec_res = voiceglue_recognize (properties, nlsmlresult); if (rec_res != VXIrec_RESULT_SUCCESS) { return (rec_res); }; // Create a new results structure. const unsigned int CHARSIZE = sizeof(VXIchar) / sizeof(VXIbyte); VXIContent * xmlresult = NULL; logger.logDiag(DIAG_TAG_RECOGNITION, L"%s%s", L"NLSML_RESULT: ", nlsmlresult.c_str()); unsigned int BUFFERSIZE = (nlsmlresult.length() + 1) * CHARSIZE; VXIbyte * buffer = new VXIbyte[BUFFERSIZE]; if (buffer == NULL) return VXIrec_RESULT_OUT_OF_MEMORY; memcpy(buffer, nlsmlresult.c_str(), BUFFERSIZE); xmlresult = VXIContentCreate(VXIREC_MIMETYPE_XMLRESULT, buffer, BUFFERSIZE, DestroyNLSMLBuffer, buffer); if (xmlresult == NULL) { delete [] buffer; return VXIrec_RESULT_OUT_OF_MEMORY; } VXIrecRecognitionResult * result = new VXIrecRecognitionResult(); if (result == NULL) { VXIContentDestroy(&xmlresult); return VXIrec_RESULT_OUT_OF_MEMORY; } result->Destroy = RecognitionResultDestroy; result->markname = NULL; result->marktime = 0; result->xmlresult = xmlresult; if (!haveUtterance ||!recordUtterance) { result->utterance = NULL; result->utteranceDuration = 0; } else { result->utteranceDuration = 5000; // 5sec unsigned int waveformSizeBytes = (result->utteranceDuration / 1000 ) * 8000 * sizeof(unsigned char); unsigned char * c_waveform = new unsigned char[waveformSizeBytes]; if (c_waveform == NULL) { result->utterance = NULL; result->utteranceDuration = 0; } else { for (unsigned int i = 0; i < waveformSizeBytes; ++i) c_waveform[i] = i & 0x00ff; result->utterance = VXIContentCreate(VXIREC_MIMETYPE_ULAW, c_waveform, waveformSizeBytes, ResultContentDestroy, NULL); } } *recogResult = result; return VXIrec_RESULT_SUCCESS; }
static VXIrecResult VXIrecLoadGrammarOption(VXIrecInterface * pThis, const VXIMap * properties, const VXIVector * gramChoice, const VXIVector * gramValue, const VXIVector * gramAcceptance, const VXIbool isDTMF, VXIrecGrammar ** gram) { const wchar_t* fnname = L"VXIrecLoadGrammarOption"; std::ostringstream srgs_version; vxistring srgs_wide_version; VXIunsigned num_choices; VXIvalueType value_type; const VXIValue *utterance_value; // Check the arguments VXIrecData* tp = GetRecData(pThis); if (tp == NULL) return VXIrec_RESULT_INVALID_ARGUMENT; LogBlock logger(tp->GetLog(), gblDiagLogBase, fnname, VXIREC_MODULE); if (gram == NULL) { logger = VXIrec_RESULT_INVALID_ARGUMENT; return VXIrec_RESULT_INVALID_ARGUMENT; } // DEBUG if (voiceglue_loglevel() >= LOG_DEBUG) { std::ostringstream logstring; logstring << "VXIrecLoadGrammarOption called with type " << (isDTMF ? "DTMF" : "speech") << ", choices " << VXIValue_to_Std_String ((VXIValue *) gramChoice) << ", values " << VXIValue_to_Std_String ((VXIValue *) gramValue) << ", properties " << VXIValue_to_Std_String ((const VXIValue *) properties); voiceglue_log ((char) LOG_DEBUG, logstring); }; tp->ShowPropertyValue(properties); // Convert to SRGS grammar num_choices = VXIVectorLength (gramChoice); srgs_version << "<rule id=\"choice\">\n <one-of>\n"; for (VXIunsigned choice_num = 0; choice_num < num_choices; ++choice_num) { srgs_version << " <item> "; utterance_value = VXIVectorGetElement (gramChoice, choice_num); value_type = VXIValueGetType (utterance_value); if (value_type == VALUE_INTEGER) { srgs_version << VXIIntegerValue ((const VXIInteger*) utterance_value); } else if (value_type == VALUE_LONG) { srgs_version << VXILongValue ((const VXILong*) utterance_value); } else if (value_type == VALUE_ULONG) { srgs_version << VXIULongValue ((const VXIULong*) utterance_value); } else if (isDTMF) { srgs_version << VXIchar_to_Std_String ( VXIStringCStr ((VXIString *) utterance_value)); } else { srgs_version << (choice_num + 1); }; srgs_version << " <tag>" << VXIchar_to_Std_String ( VXIStringCStr ( (VXIString *) VXIVectorGetElement (gramValue, choice_num))) << "</tag> </item>\n"; }; srgs_version << " </one-of>\n</rule>\n"; srgs_wide_version = Std_String_to_vxistring (srgs_version.str()); return VXIrecLoadGrammarFromString (pThis, properties, L"text/x-grammar-choice-dtmf", (const VXIchar *) srgs_wide_version.c_str(), gram); VXIrecGrammar * gp = NULL; vxistring srgsGram; if( !tp->OptionToSRGS(properties, gramChoice, gramValue, gramAcceptance, isDTMF, srgsGram) ) return VXIrec_RESULT_FAILURE; // Parsing SRGS grammar. // NOTES: The parsing is very simple, therefore it may not work // for complex grammar. As you know, this is a simulator!!! VXIrecGrammar * gramPtr = tp->ParseSRGSGrammar(srgsGram, properties, isDTMF); if( gramPtr == NULL ) return VXIrec_RESULT_FAILURE; tp->AddGrammar(gramPtr); *gram = ToVXIrecGrammar(gramPtr); return VXIrec_RESULT_SUCCESS; }
/** * Bridging Transfer. * */ static VXItelResult OSBtelTransferBridge(VXItelInterface * vxip, const VXIMap * prop, const VXIchar * transferDestination, const VXIMap * data, VXIMap **resp) { OSBtelImpl *impl = ToOSBtelImpl(vxip); Diag(impl, DIAG_TAG_SIGNALING, NULL, L"TransferBridge: %s", transferDestination); *resp = VXIMapCreate(); VXIchar* dest = 0; VXIchar* xaudio = 0; if (prop != NULL) { VXIString* vect =(VXIString*)VXIMapGetProperty(prop, L"Destination"); if (vect != NULL) dest = (VXIchar*) VXIStringCStr(vect); vect =(VXIString*)VXIMapGetProperty(prop, TEL_TRANSFER_AUDIO); if (vect != NULL) xaudio = (VXIchar*) VXIStringCStr(vect); } *resp = VXIMapCreate(); if (impl->callId && transferDestination) { vxistring dest = transferDestination; if (! dest.empty()) { char* str = 0; int len = dest.length() + 1; if (len > 0) { str = new char [len + 1]; wcstombs(str, transferDestination, len); str[len] = 0; } if (str) { UtlString from(str); HttpMessage::unescape( from ); if (impl->live == 1) { impl->pCallMgr->connect((char*)impl->callId, from.data()); impl->transferred = 0; int state = 0; int status = VXItel_TRANSFER_UNKNOWN; int duration = 0; OsTime startTime; OsTime endTime; OsDateTimeBase::getCurTime(startTime); VXItelResult ret; do { ret = setTransferState(impl, prop, transferDestination, resp, &state, &status); } while (state != PtEvent::CONNECTION_DISCONNECTED && state != PtEvent::CONNECTION_FAILED && ret != VXItel_RESULT_TIMEOUT); OsDateTimeBase::getCurTime(endTime); duration = (endTime.cvtToMsecs() - startTime.cvtToMsecs())/1000; VXIMapSetProperty(*resp, TEL_TRANSFER_STATUS, (VXIValue *) VXIIntegerCreate(status)); VXIMapSetProperty(*resp, TEL_TRANSFER_DURATION, (VXIValue *)VXIIntegerCreate(duration)); } else { Diag(impl, DIAG_TAG_SIGNALING, NULL, L"Exiting called, live=%d, cancel TransferBridge: %s", impl->live, transferDestination); } } } } return VXItel_RESULT_SUCCESS; }
/** * Blind Transfer. */ static VXItelResult OSBtelTransferBlind(VXItelInterface * vxip, const VXIMap * prop, const VXIchar * transferDestination, const VXIMap * data, VXIMap ** resp) { OSBtelImpl *impl = ToOSBtelImpl(vxip); Diag(impl, DIAG_TAG_SIGNALING, NULL, L"TransferBlind: %s", transferDestination); VXIchar* best = (VXIchar *) calloc(128, sizeof(VXIchar)); if (prop != NULL) { VXIString* vect =(VXIString*)VXIMapGetProperty(prop, L"Destination"); if (vect != NULL) best = (VXIchar*) VXIStringCStr(vect); } *resp = VXIMapCreate(); if (impl->callId && transferDestination) { vxistring dest = transferDestination; if (! dest.empty()) { char* str = 0; int len = dest.length() + 1; if (len > 0) { str = new char [len + 1]; wcstombs(str, transferDestination, len); str[len] = 0; } if (str) { UtlString from(str); HttpMessage::unescape( from ); OsSysLog::add(FAC_MEDIASERVER_VXI, PRI_DEBUG, "OSBtelTransferBlind from = '%s'", from.data()); if (impl->live == 1) { if (PT_SUCCESS == impl->pCallMgr->transfer_blind((char*)impl->callId, from.data(), // to url 0, // target call id 0, // target connect addr false // no remote hold first ) ) { impl->transferred = 0; int state = 0; int status = VXItel_TRANSFER_UNKNOWN; int duration = 0; OsTime startTime; OsTime endTime; OsDateTimeBase::getCurTime(startTime); setTransferState(impl, prop, transferDestination, resp, &state, &status); OsDateTimeBase::getCurTime(endTime); duration = (endTime.cvtToMsecs() - startTime.cvtToMsecs())/1000; VXIMapSetProperty(*resp, TEL_TRANSFER_STATUS, (VXIValue *) VXIIntegerCreate(status)); VXIMapSetProperty(*resp, TEL_TRANSFER_DURATION, (VXIValue *)VXIIntegerCreate(duration)); } } else { Diag(impl, DIAG_TAG_SIGNALING, NULL, L"Exiting called, live=%d, cancel TransferBlind: %s", impl->live, transferDestination); } } } } return VXItel_RESULT_SUCCESS; }
/** * Validate an object, performing validity checks without execution * * @param properties [IN] Map containing properties and attributes for * the <object> as specified in the VoiceXML * specification except that "expr" and "cond" are * always omitted (are handled by the interpreter). * @param parameters [IN] Map containing parameters for the <object> as * specified by the VoiceXML <param> tag. The keys * of the map correspond to the parameter name ("name" * attribute) while the value of each key corresponds * to a VXIValue based type. See Execute( ) above * for details. * * @return VXIobj_RESULT_SUCCESS on success, * VXIobj_RESULT_NON_FATAL_ERROR on error, * VXIobj_RESULT_UNSUPPORTED for unsupported object types * (this will cause interpreter to throw the correct event) */ static VXIobjResult VXIobjectValidate(struct VXIobjectInterface *pThis, const VXIMap *properties, const VXIMap *parameters) { static const wchar_t func[] = L"VXIobjectValidate"; GET_VXIOBJECT (pThis, sbObject, log, rc); Diag (log, LOG_API, func, L"entering: 0x%p, 0x%p, 0x%p", pThis, properties, parameters); if(properties == NULL) { Error (log, 201, NULL); return VXIobj_RESULT_INVALID_ARGUMENT; } // Get the name of the object to execute const VXIValue *val = VXIMapGetProperty(properties, OBJECT_CLASS_ID); if(val == NULL) { Error(log, 202, L"%s%s", L"parameter", OBJECT_CLASS_ID); return VXIobj_RESULT_INVALID_PROP_VALUE; } else if (VXIValueGetType(val) != VALUE_STRING) { Error(log, 203, L"%s%s%s%d", L"parameter", OBJECT_CLASS_ID, L"type", VXIValueGetType(val)); return VXIobj_RESULT_INVALID_PROP_VALUE; } const VXIchar *classID = VXIStringCStr((VXIString *)val); // Handle the object if (::wcscmp(classID, L"com.vocalocity.diag") == 0) { // // Sample diagnostic logging object // rc = ProcessComSpeechworksDiagObject(pThis, properties, parameters, false, NULL); if(rc != VXIobj_RESULT_SUCCESS) rc = VXIobj_RESULT_NON_FATAL_ERROR; } else if (::wcscmp(classID, L"com.vocalocity.echo") == 0) { // // Sample object echoing back all attributes and parameters // rc = ProcessComSpeechworksEchoObject(pThis, properties, parameters, false, NULL); if(rc != VXIobj_RESULT_SUCCESS) rc = VXIobj_RESULT_NON_FATAL_ERROR; } else if (::wcscmp(classID, L"com.vocalocity.saveRecording") == 0) { // // Sample object that saves a recording to a file // rc = ProcessComSpeechworksSaveRecordingObject(pThis, properties, parameters, false, NULL); if(rc != VXIobj_RESULT_SUCCESS) rc = VXIobj_RESULT_NON_FATAL_ERROR; } else if (::wcscmp(classID, L"com.vocalocity.setDefaults") == 0) { // // Sample object that sets the defaults document for subsequent // calls. This is really a hack and not recommended. This was // done more for fun than any value. // rc = ProcessComSpeechworksSetDefaultsObject(pThis, properties, parameters, false, NULL); if(rc != VXIobj_RESULT_SUCCESS) rc = VXIobj_RESULT_NON_FATAL_ERROR; } else { // // Unsupported object // rc = VXIobj_RESULT_UNSUPPORTED; } Diag (log, LOG_API, func, L"exiting: returned %d", rc); return rc; }
/** * Sample object to save a recording to a file * * @param properties [IN] See description in VXIobjectExecute() * or VXIobjectValidate() * @param parameters [IN] See description in VXIobjectExecute() * or VXIobjectValidate() * @param execute [IN] Specifies whether the object should be * executed (true) or simply validated (false) * @param result [OUT] See description in VXIobjectExecute() * or VXIobjectValidate() * * @result VXIobj_RESULT_SUCCESS on success */ static VXIobjResult ProcessComSpeechworksSaveRecordingObject (struct VXIobjectInterface *pThis, const VXIMap *properties, const VXIMap *parameters, VXIbool execute, VXIValue **result) { static const wchar_t func[] = L"ProcessComSpeechworksSaveRecordingObject"; GET_VXIOBJECT (pThis, sbObject, log, rc); if((execute) && (result == NULL)) return VXIobj_RESULT_INVALID_ARGUMENT; if((! properties) || (! parameters)) return VXIobj_RESULT_INVALID_ARGUMENT; // Get the recording, MIME type, size, and destination path const VXIbyte *recording = NULL; const VXIchar *type = NULL, *dest = NULL; VXIulong size = 0; const VXIValue *val = VXIMapGetProperty(parameters, L"recording"); if (! val) { Error(log, 202, L"%s%s", L"parameter", L"recording"); return VXIobj_RESULT_INVALID_PROP_VALUE; } else if (VXIValueGetType(val) != VALUE_CONTENT) { Error(log, 203, L"%s%s%s%d", L"parameter", L"recording", L"type", VXIValueGetType(val)); return VXIobj_RESULT_INVALID_PROP_VALUE; } if (VXIContentValue(reinterpret_cast<const VXIContent *>(val), &type, &recording, &size) != VXIvalue_RESULT_SUCCESS) { Error(log, 204, L"%s%s", L"parameter", L"recording"); return VXIobj_RESULT_INVALID_PROP_VALUE; } else if (size < 1) { Error(log, 204, L"%s%s%s%d", L"parameter", L"recording.size", L"value", L"size"); return VXIobj_RESULT_INVALID_PROP_VALUE; } val = VXIMapGetProperty(parameters, L"dest"); if (! val) { Error(log, 202, L"%s%s", L"parameter", L"dest"); return VXIobj_RESULT_INVALID_PROP_VALUE; } else if (VXIValueGetType(val) != VALUE_STRING) { Error(log, 203, L"%s%s%s%d", L"parameter", L"dest", L"type", VXIValueGetType(val)); return VXIobj_RESULT_INVALID_PROP_VALUE; } dest = VXIStringCStr(reinterpret_cast<const VXIString *>(val)); if (! dest[0]) { Error(log, 204, L"%s%s%s%s", L"parameter", L"dest", L"value", dest); return VXIobj_RESULT_INVALID_PROP_VALUE; } if(execute) { // Convert the destination to narrow characters, use an upside // down question mark for unsupported Unicode characters size_t len = wcslen(dest); char *ndest = new char [len + 1]; if (! ndest) { Error(log, 100, NULL); return VXIobj_RESULT_OUT_OF_MEMORY; } for (size_t i = 0; i <= len; i++) ndest[i] = (dest[i] & 0xff00 ? '\277' : static_cast<char>(dest[i])); // Open the destination and save the file size_t totWritten = 0; #ifdef VXIOBJECT_PERMIT_FILE_WRITES FILE *fp = fopen(ndest, "wb"); delete [] ndest; if (fp) { do { size_t w = fwrite(&recording[totWritten], 1, ((size_t) size) - totWritten, fp); totWritten += w; } while ((totWritten < (size_t) size) && (! ferror(fp))); fclose(fp); } else { Error(log, 205, L"%s%s%s%d", L"file", dest, L"errno", errno); } #else Error(log, 206, L"%s%s", L"file", dest); #endif // Create the result object VXIMap *resultObj = VXIMapCreate(); if(resultObj == NULL) { Error(log, 100, NULL); return VXIobj_RESULT_OUT_OF_MEMORY; } *result = reinterpret_cast<VXIValue *>(resultObj); // Set the result object's status field to 'success' or 'failure' if (totWritten == (size_t) size) VXIMapSetProperty(resultObj, L"status", reinterpret_cast<VXIValue *>(VXIStringCreate(L"success"))); else VXIMapSetProperty(resultObj, L"status", reinterpret_cast<VXIValue *>(VXIStringCreate(L"failure"))); } return VXIobj_RESULT_SUCCESS; }
/** * Sample diagnostic logging object * * @param properties [IN] See description in VXIobjectExecute() * or VXIobjectValidate() * @param parameters [IN] See description in VXIobjectExecute() * or VXIobjectValidate() * @param execute [IN] Specifies whether the object should be * executed (true) or simply validated (false) * @param result [OUT] See description in VXIobjectExecute() * or VXIobjectValidate() * * @result VXIobj_RESULT_SUCCESS on success */ static VXIobjResult ProcessComSpeechworksDiagObject (struct VXIobjectInterface *pThis, const VXIMap *properties, const VXIMap *parameters, VXIbool execute, VXIValue **result) { static const wchar_t func[] = L"ProcessComSpeechworksDiagObject"; GET_VXIOBJECT (pThis, sbObject, log, rc); if((execute) && (result == NULL)) return VXIobj_RESULT_INVALID_ARGUMENT; if((! properties) || (! parameters)) return VXIobj_RESULT_INVALID_ARGUMENT; // Get the tag ID const VXIValue *val = VXIMapGetProperty(parameters, L"tag"); if(val == NULL) { Error(log, 202, L"%s%s", L"parameter", L"tag"); return VXIobj_RESULT_INVALID_PROP_VALUE; } VXIint tag; switch (VXIValueGetType(val)) { case VALUE_INTEGER: tag = VXIIntegerValue((VXIInteger *)val); break; case VALUE_STRING: { wchar_t *ptr; tag = ::wcstol(VXIStringCStr((VXIString *)val), &ptr, 10); } break; default: Error(log, 203, L"%s%s%s%d", L"parameter", L"tag", L"type", VXIValueGetType(val)); return VXIobj_RESULT_INVALID_PROP_VALUE; } // Get the message string val = VXIMapGetProperty(parameters, L"message"); if(val == NULL) { Error(log, 202, L"%s%s", L"parameter", L"message"); return VXIobj_RESULT_INVALID_PROP_VALUE; } // Check whether the message was sent in "data" or "ref" format. // If it is "ref", we need to retrieve it in the embedded map. const VXIchar *messageStr = NULL; switch (VXIValueGetType(val)) { case VALUE_MAP: { const VXIValue *val2 = VXIMapGetProperty((const VXIMap *)val, OBJECT_VALUE); if (VXIValueGetType(val2) == VALUE_STRING) messageStr = VXIStringCStr((VXIString *)val2); } break; case VALUE_STRING: messageStr = VXIStringCStr((VXIString *)val); break; default: Error(log, 203, L"%s%s%s%d", L"parameter", L"message", L"type", VXIValueGetType(val)); return VXIobj_RESULT_INVALID_PROP_VALUE; } if ((! messageStr) || (! messageStr[0])) { Error(log, 204, L"%s%s", L"parameter", L"message"); return VXIobj_RESULT_INVALID_PROP_VALUE; } if(execute) { // Print a diagnostic message using the retrieved arguments. // To see this message, you must enable client.log.diagTag.xxx // in your VXIclient configuration file, where 'xxx' is the // value of client.object.diagLogBase defined in the same file. VXIlogResult rc = Diag (log, tag, NULL, messageStr); // Create the result object VXIMap *resultObj = VXIMapCreate(); if(resultObj == NULL) { Error(log, 100, NULL); return VXIobj_RESULT_OUT_OF_MEMORY; } *result = reinterpret_cast<VXIValue *>(resultObj); // Set the result object's status field to 'success' or 'failure' if(rc == VXIlog_RESULT_SUCCESS) VXIMapSetProperty(resultObj, L"status", reinterpret_cast<VXIValue *>(VXIStringCreate(L"success"))); else VXIMapSetProperty(resultObj, L"status", reinterpret_cast<VXIValue *>(VXIStringCreate(L"failure"))); } return VXIobj_RESULT_SUCCESS; }
static void ShowPropertyValues(const VXIchar *key, const VXIValue *value, VXIunsigned PROP_TAG, VXIlogInterface *log) { VXIchar subtag[512] = L"Property"; if( value == 0 ) return; VXIvalueType type = VXIValueGetType(value); { switch( type ) { case VALUE_INTEGER: wcscpy(subtag, L"Property:INT"); Diag(log, PROP_TAG, subtag, L"%s=%d", key, VXIIntegerValue((const VXIInteger*)value)); break; case VALUE_FLOAT: wcscpy(subtag, L"Property:FLT"); Diag(log, PROP_TAG, subtag, L"%s=%f", key, VXIFloatValue((const VXIFloat*)value)); break; case VALUE_BOOLEAN: wcscpy(subtag, L"Property:BOOL"); Diag(log, PROP_TAG, subtag, L"%s=%d", key, VXIBooleanValue((const VXIBoolean*)value)); break; case VALUE_STRING: wcscpy(subtag, L"Property:STR"); Diag(log, PROP_TAG, subtag, L"%s=%s", key, VXIStringCStr((const VXIString*)value)); break; case VALUE_PTR: wcscpy(subtag, L"Property:PTR"); Diag(log, PROP_TAG, subtag, L"%s(ptr)=0x%p", key, VXIPtrValue((const VXIPtr*)value)); break; case VALUE_CONTENT: wcscpy(subtag, L"Property:CNT"); Diag(log, 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"); Diag(log, 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 ) { ShowPropertyValues(key, gvalue, PROP_TAG, log); ret = VXIMapGetNextProperty(it, &key, &gvalue); } VXIMapIteratorDestroy(&it); Diag(log, 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); ShowPropertyValues(L"Vector", gvalue, PROP_TAG, log); } } break; default: Diag(log, PROP_TAG, subtag, L"%s=%s", key, L"UNKOWN"); } } return; }