VXIobject.cpp
上传用户:xqtpzdz
上传日期:2022-05-21
资源大小:1764k
文件大小:34k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. /****************License************************************************
  2.  * Vocalocity OpenVXI
  3.  * Copyright (C) 2004-2005 by Vocalocity, Inc. All Rights Reserved.
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *  
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  * Vocalocity, the Vocalocity logo, and VocalOS are trademarks or 
  18.  * registered trademarks of Vocalocity, Inc. 
  19.  * OpenVXI is a trademark of Scansoft, Inc. and used under license 
  20.  * by Vocalocity.
  21.  ***********************************************************************/
  22. // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8
  23. #include <string.h>                     // For memset( )
  24. #include <stdio.h>                      // For fopen( ), fclose( ), fwrite( )
  25. #include <errno.h>                      // For errno
  26. #include <VXIlog.h>                     // For VXIlog interface
  27. #include "VXIobjectAPI.h"               // Header for these functions
  28. #include "VXIclient.h"
  29. #ifndef MODULE_PREFIX
  30. #define MODULE_PREFIX  COMPANY_DOMAIN L"."
  31. #endif
  32. static const VXIchar MODULE_VXIOBJECT[]              = MODULE_PREFIX L"VXIobject";
  33. static const VXIchar VXIOBJECT_IMPLEMENTATION_NAME[] = COMPANY_DOMAIN L".VXIobject";
  34. // Global variable to track whether this is initialized
  35. static bool gblInitialized = false;
  36. // Global diagnostic logging base
  37. static VXIunsigned gblDiagLogBase;
  38. // Diagnostic logging tags
  39. static const VXIunsigned LOG_API = 0;
  40. // VXIobject interface, "inherits" from VXIobjectInterface
  41. typedef struct VXIobjectAPI
  42. {
  43.   // Base interface, must be the first member
  44.   VXIobjectInterface  object;
  45.   // Resources for this channel
  46.   VXIobjectResources  *resources;
  47. } VXIobjectAPI;
  48. // Convenience macro
  49. #define GET_VXIOBJECT(pThis, vxiObject, log, rc) 
  50.   VXIobjResult rc = VXIobj_RESULT_SUCCESS; 
  51.   VXIobjectAPI *objectAPI = (VXIobjectAPI *) pThis; 
  52.   if ( ! objectAPI ) { rc = VXIobj_RESULT_INVALID_ARGUMENT; return rc; } 
  53.   VXIlogInterface *log = objectAPI->resources->log;
  54. // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8
  55. /**
  56.  * Internal function for error logging
  57.  */
  58. static VXIlogResult
  59. Error (VXIlogInterface *log, VXIunsigned errorID, const VXIchar *format, ...)
  60. {
  61.   va_list arguments;
  62.   if ( ! log )
  63.     return VXIlog_RESULT_FAILURE;
  64.   
  65.   VXIlogResult rc;
  66.   if ( format ) {
  67.     va_start(arguments, format);
  68.     rc = (*log->VError)(log, MODULE_VXIOBJECT, errorID, format, arguments);
  69.     va_end(arguments);
  70.   } else {
  71.     rc = (*log->Error)(log, MODULE_VXIOBJECT, errorID, NULL);
  72.   }
  73.   return rc;
  74. }
  75. /**
  76.  * Internal function for diagnostic logging
  77.  */
  78. static VXIlogResult
  79. Diag (VXIlogInterface *log, VXIunsigned tag, const VXIchar *subtag,
  80.       const VXIchar *format, ...)
  81. {
  82.   va_list arguments;
  83.   if ( ! log )
  84.     return VXIlog_RESULT_FAILURE;
  85.   
  86.   VXIlogResult rc;
  87.   if ( format ) {
  88.     va_start(arguments, format);
  89.     rc = (*log->VDiagnostic)(log, tag + gblDiagLogBase, subtag, format,
  90.            arguments);
  91.     va_end(arguments);
  92.   } else {
  93.     rc = (*log->Diagnostic)(log, tag + gblDiagLogBase, subtag, NULL);
  94.   }
  95.   return rc;
  96. }
  97. static void ShowPropertyValues(const VXIchar *key,
  98.            const VXIValue *value, VXIunsigned PROP_TAG,
  99.            VXIlogInterface *log)
  100. {
  101.   VXIchar subtag[512] = L"Property";
  102.   if( value == 0 ) return;
  103.   VXIvalueType type = VXIValueGetType(value);
  104.   {
  105.     switch( type )
  106.     {
  107.       case VALUE_INTEGER:
  108.         wcscpy(subtag, L"Property:INT");
  109.         Diag(log, PROP_TAG, subtag, 
  110.              L"%s=%d", key, VXIIntegerValue((const VXIInteger*)value));
  111.         break;
  112.       case VALUE_FLOAT:
  113.         wcscpy(subtag, L"Property:FLT");
  114.         Diag(log, PROP_TAG, subtag, 
  115.              L"%s=%f", key, VXIFloatValue((const VXIFloat*)value));
  116.         break;
  117.       case VALUE_BOOLEAN:     
  118.         wcscpy(subtag, L"Property:BOOL");
  119.         Diag(log, PROP_TAG, subtag, 
  120.              L"%s=%d", key, VXIBooleanValue((const VXIBoolean*)value));
  121.         break;
  122.       case VALUE_STRING:
  123.         wcscpy(subtag, L"Property:STR");
  124.         Diag(log, PROP_TAG, subtag, 
  125.              L"%s=%s", key, VXIStringCStr((const VXIString*)value));
  126.         break;
  127.       case VALUE_PTR:
  128.         wcscpy(subtag, L"Property:PTR");
  129.         Diag(log, PROP_TAG, subtag, 
  130.              L"%s(ptr)=0x%p", key, VXIPtrValue((const VXIPtr*)value));
  131.         break;
  132.       case VALUE_CONTENT:
  133.         wcscpy(subtag, L"Property:CNT");
  134.         Diag(log, PROP_TAG, subtag, 
  135.              L"%s(content)=0x%p", key, value);
  136.         break;
  137.       case VALUE_MAP:
  138.         {
  139.           VXIchar endtag[512];
  140.           const VXIchar *mykey = key ? key : L"NULL";
  141.           wcscpy(subtag, L"Property:MAP:BEG");
  142.           wcscpy(endtag, L"Property:MAP:END");
  143.           Diag(log, PROP_TAG, subtag, L"%s", mykey);
  144.           const VXIchar *key = NULL;
  145.           const VXIValue *gvalue = NULL;
  146.           VXIMapIterator *it = VXIMapGetFirstProperty((const VXIMap*)value, &key, &gvalue);
  147.           int ret = 0;
  148.           while( ret == 0 && key && gvalue )
  149.           {
  150.             ShowPropertyValues(key, gvalue, PROP_TAG, log);
  151.             ret = VXIMapGetNextProperty(it, &key, &gvalue);
  152.           }
  153.           VXIMapIteratorDestroy(&it);         
  154.           Diag(log, PROP_TAG, endtag, L"%s", mykey);
  155.         }   
  156.         break;
  157.       case VALUE_VECTOR:
  158.         {
  159.           VXIunsigned vlen = VXIVectorLength((const VXIVector*)value);
  160.           for(VXIunsigned i = 0; i < vlen; ++i)
  161.           {
  162.             const VXIValue *gvalue = VXIVectorGetElement((const VXIVector*)value, i);
  163.             ShowPropertyValues(L"Vector", gvalue, PROP_TAG, log);
  164.           }
  165.         }
  166.         break;
  167.       default:
  168.         Diag(log, PROP_TAG, subtag, L"%s=%s", key, L"UNKOWN");
  169.     }          
  170.   }
  171.   return;
  172. }
  173. static void ShowPropertyValue(const VXIMap *properties, VXIlogInterface *log)
  174. {
  175.   const VXIchar *key = NULL;
  176.   const VXIValue *gvalue = NULL;
  177.   const VXIunsigned PROP_TAG = 5;
  178.   if( log && log->DiagnosticIsEnabled(log, PROP_TAG+gblDiagLogBase) && properties) {
  179.     VXIMapIterator *it = VXIMapGetFirstProperty(properties, &key, &gvalue);
  180.     int ret = 0;
  181.     while( ret == 0 && key && gvalue )
  182.     {
  183.       ShowPropertyValues(key, gvalue, PROP_TAG, log);
  184.       ret = VXIMapGetNextProperty(it, &key, &gvalue);
  185.     }
  186.     VXIMapIteratorDestroy(&it);     
  187.   }
  188.   return;
  189. }
  190. /**
  191.  * Sample diagnostic logging object
  192.  *
  193.  * @param properties    [IN]  See description in VXIobjectExecute() 
  194.  *                            or VXIobjectValidate()
  195.  * @param parameters    [IN]  See description in VXIobjectExecute() 
  196.  *                            or VXIobjectValidate()
  197.  * @param execute       [IN]  Specifies whether the object should be
  198.  *                            executed (true) or simply validated (false)
  199.  * @param result        [OUT] See description in VXIobjectExecute() 
  200.  *                            or VXIobjectValidate()
  201.  *
  202.  * @result VXIobj_RESULT_SUCCESS on success
  203.  */
  204. static VXIobjResult 
  205. ProcessComSpeechworksDiagObject (struct VXIobjectInterface *pThis,
  206.                                  const VXIMap              *properties,
  207.                                  const VXIMap              *parameters,
  208.                                  VXIbool                    execute,
  209.          VXIValue                 **result)
  210. {
  211.   static const wchar_t func[] = L"ProcessComSpeechworksDiagObject";
  212.   GET_VXIOBJECT (pThis, sbObject, log, rc);
  213.   if((execute) && (result == NULL)) return VXIobj_RESULT_INVALID_ARGUMENT;
  214.   if((! properties) || (! parameters)) return VXIobj_RESULT_INVALID_ARGUMENT;
  215.   // Get the tag ID
  216.   const VXIValue *val = VXIMapGetProperty(parameters, L"tag");
  217.   if(val == NULL) {
  218.     Error(log, 202, L"%s%s", L"parameter", L"tag");
  219.     return VXIobj_RESULT_INVALID_PROP_VALUE;
  220.   } 
  221.   VXIint tag;
  222.   switch (VXIValueGetType(val)) {
  223.   case VALUE_INTEGER:
  224.     tag = VXIIntegerValue((VXIInteger *)val);
  225.     break;
  226.   case VALUE_STRING: {
  227.     wchar_t *ptr;
  228.     tag = ::wcstol(VXIStringCStr((VXIString *)val), &ptr, 10);
  229.     } break;
  230.   default:
  231.     Error(log, 203, L"%s%s%s%d", L"parameter", L"tag", 
  232.     L"type", VXIValueGetType(val));
  233.     return VXIobj_RESULT_INVALID_PROP_VALUE;
  234.   }
  235.   // Get the message string
  236.   val = VXIMapGetProperty(parameters, L"message");
  237.   if(val == NULL) {
  238.     Error(log, 202, L"%s%s", L"parameter", L"message");
  239.     return VXIobj_RESULT_INVALID_PROP_VALUE;
  240.   }
  241.   // Check whether the message was sent in "data" or "ref" format.
  242.   // If it is "ref", we need to retrieve it in the embedded map.
  243.   const VXIchar *messageStr = NULL;
  244.   switch (VXIValueGetType(val)) {
  245.   case VALUE_MAP: {
  246.     const VXIValue *val2 = VXIMapGetProperty((const VXIMap *)val, 
  247.                                              OBJECT_VALUE);
  248.     if (VXIValueGetType(val2) == VALUE_STRING)
  249.       messageStr = VXIStringCStr((VXIString *)val2);
  250.     } break;
  251.   case VALUE_STRING:
  252.     messageStr = VXIStringCStr((VXIString *)val);
  253.     break;
  254.   default:
  255.     Error(log, 203, L"%s%s%s%d", L"parameter", L"message", 
  256.     L"type", VXIValueGetType(val));
  257.     return VXIobj_RESULT_INVALID_PROP_VALUE;
  258.   }
  259.   if ((! messageStr) || (! messageStr[0])) {
  260.     Error(log, 204, L"%s%s", L"parameter", L"message");
  261.     return VXIobj_RESULT_INVALID_PROP_VALUE;
  262.   }
  263.   
  264.   if(execute) {
  265.     // Print a diagnostic message using the retrieved arguments.
  266.     // To see this message, you must enable client.log.diagTag.xxx
  267.     // in your VXIclient configuration file, where 'xxx' is the 
  268.     // value of client.object.diagLogBase defined in the same file.
  269.     VXIlogResult rc = Diag (log, tag, NULL, messageStr);
  270.     // Create the result object
  271.     VXIMap *resultObj = VXIMapCreate();
  272.     if(resultObj == NULL) {
  273.       Error(log, 100, NULL);
  274.       return VXIobj_RESULT_OUT_OF_MEMORY;
  275.     }
  276.     *result = reinterpret_cast<VXIValue *>(resultObj);
  277.     // Set the result object's status field to 'success' or 'failure'
  278.     if(rc == VXIlog_RESULT_SUCCESS)
  279.       VXIMapSetProperty(resultObj, L"status",
  280.                reinterpret_cast<VXIValue *>(VXIStringCreate(L"success")));
  281.     else
  282.       VXIMapSetProperty(resultObj, L"status", 
  283.                reinterpret_cast<VXIValue *>(VXIStringCreate(L"failure")));
  284.   }
  285.   return VXIobj_RESULT_SUCCESS;
  286. }
  287. /**
  288.  * Sample object echoing back all parameters
  289.  *
  290.  * @param properties    [IN]  See description in VXIobjectExecute() 
  291.  *                            or VXIobjectValidate()
  292.  * @param parameters    [IN]  See description in VXIobjectExecute() 
  293.  *                            or VXIobjectValidate()
  294.  * @param execute       [IN]  Specifies whether the object should be
  295.  *                            executed (true) or simply validated (false)
  296.  * @param result        [OUT] See description in VXIobjectExecute() 
  297.  *                            or VXIobjectValidate()
  298.  *
  299.  * @result VXIobj_RESULT_SUCCESS on success
  300.  */
  301. static VXIobjResult 
  302. ProcessComSpeechworksEchoObject (struct VXIobjectInterface *pThis,
  303.                                  const VXIMap              *properties,
  304.                                  const VXIMap              *parameters,
  305.                                  VXIbool                    execute,
  306.          VXIValue                 **result)
  307. {
  308.   static const wchar_t func[] = L"ProcessComSpeechworksEchoObject";
  309.   GET_VXIOBJECT (pThis, sbObject, log, rc);
  310.   if((execute) && (result == NULL)) return VXIobj_RESULT_INVALID_ARGUMENT;
  311.   if((! properties) || (! parameters)) return VXIobj_RESULT_INVALID_ARGUMENT;
  312.   if(execute) {
  313.     // Create the result object
  314.     VXIMap *resultObj = VXIMapCreate();
  315.     if(resultObj == NULL) {
  316.       Error(log, 100, NULL);
  317.       return VXIobj_RESULT_OUT_OF_MEMORY;
  318.     }
  319.     *result = reinterpret_cast<VXIValue *>(resultObj);
  320.     // Simply add the input properties and parameters to the result object
  321.     VXIMapSetProperty(resultObj, L"attributes", 
  322.           VXIValueClone((VXIValue *)properties));
  323.     VXIMapSetProperty(resultObj, L"parameters", 
  324.           VXIValueClone((VXIValue *)parameters));
  325.   }
  326.   return VXIobj_RESULT_SUCCESS;
  327. }
  328. /**
  329.  * Sample object to save a recording to a file
  330.  *
  331.  * @param properties    [IN]  See description in VXIobjectExecute() 
  332.  *                            or VXIobjectValidate()
  333.  * @param parameters    [IN]  See description in VXIobjectExecute() 
  334.  *                            or VXIobjectValidate()
  335.  * @param execute       [IN]  Specifies whether the object should be
  336.  *                            executed (true) or simply validated (false)
  337.  * @param result        [OUT] See description in VXIobjectExecute() 
  338.  *                            or VXIobjectValidate()
  339.  *
  340.  * @result VXIobj_RESULT_SUCCESS on success
  341.  */
  342. static VXIobjResult 
  343. ProcessComSpeechworksSaveRecordingObject (struct VXIobjectInterface *pThis,
  344.             const VXIMap             *properties,
  345.             const VXIMap             *parameters,
  346.             VXIbool                    execute,
  347.             VXIValue                 **result)
  348. {
  349.   static const wchar_t func[] = L"ProcessComSpeechworksSaveRecordingObject";
  350.   GET_VXIOBJECT (pThis, sbObject, log, rc);
  351.   if((execute) && (result == NULL)) return VXIobj_RESULT_INVALID_ARGUMENT;
  352.   if((! properties) || (! parameters)) return VXIobj_RESULT_INVALID_ARGUMENT;
  353.   // Get the recording, MIME type, size, and destination path
  354.   const VXIbyte *recording = NULL;
  355.   const VXIchar *type = NULL, *dest = NULL;
  356.   VXIulong size = 0;
  357.   const VXIValue *val = VXIMapGetProperty(parameters, L"recording");
  358.   if (! val) {
  359.     Error(log, 202, L"%s%s", L"parameter", L"recording");
  360.     return VXIobj_RESULT_INVALID_PROP_VALUE;
  361.   } else if (VXIValueGetType(val) != VALUE_CONTENT) {
  362.     Error(log, 203, L"%s%s%s%d", L"parameter", L"recording", 
  363.     L"type", VXIValueGetType(val));
  364.     return VXIobj_RESULT_INVALID_PROP_VALUE;
  365.   }
  366.   if (VXIContentValue(reinterpret_cast<const VXIContent *>(val),
  367.           &type, &recording, &size) != VXIvalue_RESULT_SUCCESS) {
  368.     Error(log, 204, L"%s%s", L"parameter", L"recording");
  369.     return VXIobj_RESULT_INVALID_PROP_VALUE;
  370.   } else if (size < 1) {
  371.     Error(log, 204, L"%s%s%s%d", L"parameter", L"recording.size", 
  372.     L"value", L"size");
  373.     return VXIobj_RESULT_INVALID_PROP_VALUE;
  374.   }
  375.   
  376.   val = VXIMapGetProperty(parameters, L"dest");
  377.   if (! val) {
  378.     Error(log, 202, L"%s%s", L"parameter", L"dest");
  379.     return VXIobj_RESULT_INVALID_PROP_VALUE;
  380.   } else if (VXIValueGetType(val) != VALUE_STRING) {
  381.     Error(log, 203, L"%s%s%s%d", L"parameter", L"dest", 
  382.     L"type", VXIValueGetType(val));
  383.     return VXIobj_RESULT_INVALID_PROP_VALUE;
  384.   }
  385.   dest = VXIStringCStr(reinterpret_cast<const VXIString *>(val));
  386.   if (! dest[0]) {
  387.     Error(log, 204, L"%s%s%s%s", L"parameter", L"dest", L"value", dest);
  388.     return VXIobj_RESULT_INVALID_PROP_VALUE;
  389.   }
  390.   if(execute) {
  391.     // Convert the destination to narrow characters, use an upside
  392.     // down question mark for unsupported Unicode characters
  393.     size_t len = wcslen(dest);
  394.     char *ndest = new char [len + 1];
  395.     if (! ndest) {
  396.       Error(log, 100, NULL);
  397.       return VXIobj_RESULT_OUT_OF_MEMORY;
  398.     }
  399.     for (size_t i = 0; i <= len; i++)
  400.       ndest[i] = (dest[i] & 0xff00 ? '277' : static_cast<char>(dest[i]));
  401.     
  402.     // Open the destination and save the file
  403.     size_t totWritten = 0;
  404. #ifdef VXIOBJECT_PERMIT_FILE_WRITES
  405.     FILE *fp = fopen(ndest, "wb");
  406.     delete [] ndest;
  407.     if (fp) {
  408.       do {
  409.   size_t w = fwrite(&recording[totWritten], 1, 
  410.         ((size_t) size) - totWritten, fp);
  411.   totWritten += w;
  412.       } while ((totWritten < (size_t) size) && (! ferror(fp)));
  413.       
  414.       fclose(fp);
  415.     } else {
  416.       Error(log, 205, L"%s%s%s%d", L"file", dest, L"errno", errno);
  417.     }
  418. #else
  419.     Error(log, 206, L"%s%s", L"file", dest);
  420. #endif
  421.     // Create the result object
  422.     VXIMap *resultObj = VXIMapCreate();
  423.     if(resultObj == NULL) {
  424.       Error(log, 100, NULL);
  425.       return VXIobj_RESULT_OUT_OF_MEMORY;
  426.     }
  427.     *result = reinterpret_cast<VXIValue *>(resultObj);
  428.     // Set the result object's status field to 'success' or 'failure'
  429.     if (totWritten == (size_t) size)
  430.       VXIMapSetProperty(resultObj, L"status",
  431.                reinterpret_cast<VXIValue *>(VXIStringCreate(L"success")));
  432.     else
  433.       VXIMapSetProperty(resultObj, L"status", 
  434.                reinterpret_cast<VXIValue *>(VXIStringCreate(L"failure")));
  435.   }
  436.   return VXIobj_RESULT_SUCCESS;
  437. }
  438. /**
  439.  * Sample object setting the defaults document for subsequent calls
  440.  *
  441.  * @param properties    [IN]  See description in VXIobjectExecute() 
  442.  *                            or VXIobjectValidate()
  443.  * @param parameters    [IN]  See description in VXIobjectExecute() 
  444.  *                            or VXIobjectValidate()
  445.  * @param execute       [IN]  Specifies whether the object should be
  446.  *                            executed (true) or simply validated (false)
  447.  * @param result        [OUT] See description in VXIobjectExecute() 
  448.  *                            or VXIobjectValidate()
  449.  *
  450.  * @result VXIobj_RESULT_SUCCESS on success
  451.  */
  452. static VXIobjResult 
  453. ProcessComSpeechworksSetDefaultsObject (struct VXIobjectInterface *pThis,
  454. const VXIMap              *properties,
  455. const VXIMap              *parameters,
  456. VXIbool                    execute,
  457. VXIValue                 **result)
  458. {
  459.   static const wchar_t func[] = L"ProcessComSpeechworksSetDefaults";
  460.   GET_VXIOBJECT (pThis, sbObject, log, rc);
  461.   if((execute) && (result == NULL)) return VXIobj_RESULT_INVALID_ARGUMENT;
  462.   if((! properties) || (! parameters)) return VXIobj_RESULT_INVALID_ARGUMENT;
  463.   if(execute) {
  464.     const VXIchar *defaults = NULL;
  465.     const VXIValue *val = VXIMapGetProperty(parameters, L"defaults");
  466.     if (! val) {
  467.       Error(log, 202, L"%s%s", L"parameter", L"defaults");
  468.       return VXIobj_RESULT_INVALID_PROP_VALUE;
  469.     } else if (VXIValueGetType(val) != VALUE_STRING) {
  470.       Error(log, 203, L"%s%s%s%d", L"parameter", L"defaults", 
  471.     L"type", VXIValueGetType(val));
  472.       return VXIobj_RESULT_INVALID_PROP_VALUE;
  473.     }
  474.     defaults = VXIStringCStr(reinterpret_cast<const VXIString *>(val));
  475.     if (! defaults[0]) {
  476.       Error(log, 204, L"%s%s%s%s", L"parameter", L"defaults", L"value", defaults);
  477.       return VXIobj_RESULT_INVALID_PROP_VALUE;
  478.     }
  479.     
  480.     // Hack to set the defaults document
  481.     VXIobjectAPI *objectAPI = (VXIobjectAPI *) pThis;
  482.     if ( ! objectAPI ) { rc = VXIobj_RESULT_INVALID_ARGUMENT; return rc; }
  483.     VXIplatform *plat = objectAPI->resources->platform;
  484.     VXIMap *vxiProperties = VXIMapCreate();
  485.     VXIString * valstr = VXIStringCreate(defaults);
  486.     VXIMapSetProperty(vxiProperties, VXI_PLATFORM_DEFAULTS, (VXIValue *) valstr);
  487.     plat->VXIinterpreter->SetProperties(plat->VXIinterpreter,
  488. vxiProperties);
  489.     // Create the result object
  490.     VXIMap *resultObj = VXIMapCreate();
  491.     if(resultObj == NULL) {
  492.       Error(log, 100, NULL);
  493.       return VXIobj_RESULT_OUT_OF_MEMORY;
  494.     }
  495.     *result = reinterpret_cast<VXIValue *>(resultObj);
  496.     // Set the result object's status field to 'success'
  497.     VXIMapSetProperty(resultObj, L"status",
  498.       reinterpret_cast<VXIValue *>(VXIStringCreate(L"success")));
  499.   }
  500.   return VXIobj_RESULT_SUCCESS;
  501. }
  502. // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8
  503. /**
  504.  * @name GetVersion
  505.  * @memo Get the VXI interface version implemented
  506.  *
  507.  * @return  VXIint32 for the version number. The high high word is 
  508.  *          the major version number, the low word is the minor version 
  509.  *          number, using the native CPU/OS byte order. The current
  510.  *          version is VXI_CURRENT_VERSION as defined in VXItypes.h.
  511.  */ 
  512. static
  513. VXIint32 VXIobjectGetVersion(void)
  514. {
  515.   return VXI_CURRENT_VERSION;
  516. }
  517. /**
  518.  * @name GetImplementationName
  519.  * @memo Get the name of the implementation
  520.  *
  521.  * @return  Implementation defined string that must be different from
  522.  *          all other implementations. The recommended name is one
  523.  *          where the interface name is prefixed by the implementator's
  524.  *          Internet address in reverse order, such as com.xyz.rec for
  525.  *          VXIobject from xyz.com. This is similar to how VoiceXML 1.0
  526.  *          recommends defining application specific error types.
  527.  */
  528. static
  529. const VXIchar* VXIobjectGetImplementationName(void)
  530. {
  531.   return VXIOBJECT_IMPLEMENTATION_NAME;
  532. }
  533. /**
  534.  * Execute an object
  535.  *
  536.  * @param properties  [IN] Map containing properties and attributes for
  537.  *                      the <object> as specified above.
  538.  * @param parameters  [IN] Map containing parameters for the <object> as
  539.  *                      specified by the VoiceXML <param> tag. The keys
  540.  *                      of the map correspond to the parameter name ("name"
  541.  *                      attribute) while the value of each key corresponds
  542.  *                      to a VXIValue based type.
  543.  *
  544.  *                      For each parameter, any ECMAScript expressions are
  545.  *                      evaluated by the interpreter. Then if the "valuetype"
  546.  *                      attribute is set to "ref" the parameter value is
  547.  *                      packaged into a VXIMap with three properties:
  548.  *
  549.  *                      OBJECT_VALUE:       actual parameter value
  550.  *                      OBJECT_VALUETYPE:   "valuetype" attribute value
  551.  *                      OBJECT_TYPE:        "type" attribute value
  552.  *
  553.  *                      Otherwise a primitive VXIValue based type will
  554.  *                      be used to specify the value.
  555.  * @param result      [OUT] Return value for the <object> execution, this
  556.  *                      is allocated on success, the caller is responsible
  557.  *                      for destroying the returned value by calling 
  558.  *                      VXIValueDestroy( ). The object's field variable
  559.  *                      will be set to this value.
  560.  *
  561.  * @return        VXIobj_RESULT_SUCCESS on success,
  562.  *                VXIobj_RESULT_NON_FATAL_ERROR on error, 
  563.  *                VXIobj_RESULT_UNSUPPORTED for unsupported object types
  564.  *                 (this will cause interpreter to throw the correct event)
  565.  */
  566. static
  567. VXIobjResult VXIobjectExecute(struct VXIobjectInterface *pThis,
  568.                               const VXIMap              *properties,
  569.                               const VXIMap              *parameters,
  570.                               VXIValue                  **result)
  571. {
  572.   static const wchar_t func[] = L"VXIobjectExecute";
  573.   GET_VXIOBJECT (pThis, sbObject, log, rc);
  574.   Diag (log, LOG_API, func, L"entering: 0x%p, 0x%p, 0x%p, 0x%p", 
  575.   pThis, properties, parameters, result);
  576.   
  577.   if(properties == NULL) {
  578.     Error (log, 200, NULL);
  579.     return VXIobj_RESULT_INVALID_ARGUMENT;
  580.   }
  581.   ShowPropertyValue(properties, log);
  582.   // Get the name of the object to execute
  583.   const VXIValue *val = VXIMapGetProperty(properties, OBJECT_CLASS_ID);
  584.   if(val == NULL) {
  585.     Error(log, 202, L"%s%s", L"parameter", OBJECT_CLASS_ID);
  586.     return VXIobj_RESULT_INVALID_PROP_VALUE;
  587.   } else if (VXIValueGetType(val) != VALUE_STRING) {
  588.     Error(log, 203, L"%s%s%s%d", L"parameter", OBJECT_CLASS_ID,
  589.     L"type", VXIValueGetType(val));
  590.     return VXIobj_RESULT_INVALID_PROP_VALUE;
  591.   }
  592.   const VXIchar *classID = VXIStringCStr((VXIString *)val);
  593.   // Handle the object
  594.   if (::wcscmp(classID, L"com.vocalocity.diag") == 0) {
  595.     //
  596.     // Sample diagnostic logging object.
  597.     // 
  598.     rc = ProcessComSpeechworksDiagObject(pThis, properties, parameters, true,
  599.            result);
  600.     if(rc != VXIobj_RESULT_SUCCESS) rc = VXIobj_RESULT_NON_FATAL_ERROR;
  601.   } 
  602.   else if (::wcscmp(classID, L"com.vocalocity.echo") == 0) {
  603.     //
  604.     // Sample object echoing back all attributes and parameters
  605.     // 
  606.     rc = ProcessComSpeechworksEchoObject(pThis, properties, parameters, true,
  607.            result);
  608.     if(rc != VXIobj_RESULT_SUCCESS) rc = VXIobj_RESULT_NON_FATAL_ERROR;
  609.   } 
  610.   else if (::wcscmp(classID, L"com.vocalocity.saveRecording") == 0) {
  611.     //
  612.     // Sample object that saves a recording to a file
  613.     // 
  614.     rc = ProcessComSpeechworksSaveRecordingObject(pThis, properties, 
  615.               parameters, true, result);
  616.     if(rc != VXIobj_RESULT_SUCCESS) rc = VXIobj_RESULT_NON_FATAL_ERROR;
  617.   } 
  618.   else if (::wcscmp(classID, L"com.vocalocity.setDefaults") == 0) {
  619.     //
  620.     // Sample object that sets the defaults document for subsequent
  621.     // calls. This is really a hack and not recommended. This was
  622.     // done more for fun than any value.
  623.     // 
  624.     rc = ProcessComSpeechworksSetDefaultsObject(pThis, properties, 
  625.               parameters, true, result);
  626.     if(rc != VXIobj_RESULT_SUCCESS) rc = VXIobj_RESULT_NON_FATAL_ERROR;
  627.   } 
  628.   else {
  629.     //
  630.     // Unsupported object
  631.     //
  632.     rc = VXIobj_RESULT_UNSUPPORTED;
  633.   }
  634.   Diag (log, LOG_API, func, L"exiting: returned %d", rc);
  635.   return rc;
  636. }
  637. /**
  638.  * Validate an object, performing validity checks without execution
  639.  *
  640.  * @param properties  [IN] Map containing properties and attributes for
  641.  *                      the <object> as specified in the VoiceXML
  642.  *                      specification except that "expr" and "cond" are
  643.  *                      always omitted (are handled by the interpreter).
  644.  * @param parameters  [IN] Map containing parameters for the <object> as
  645.  *                      specified by the VoiceXML <param> tag. The keys
  646.  *                      of the map correspond to the parameter name ("name"
  647.  *                      attribute) while the value of each key corresponds
  648.  *                      to a VXIValue based type. See Execute( ) above 
  649.  *                      for details.
  650.  *
  651.  * @return        VXIobj_RESULT_SUCCESS on success,
  652.  *                VXIobj_RESULT_NON_FATAL_ERROR on error, 
  653.  *                VXIobj_RESULT_UNSUPPORTED for unsupported object types
  654.  *                 (this will cause interpreter to throw the correct event)
  655.  */
  656. static
  657. VXIobjResult VXIobjectValidate(struct VXIobjectInterface *pThis,
  658.                                const VXIMap              *properties,
  659.                                const VXIMap              *parameters)
  660. {
  661.   static const wchar_t func[] = L"VXIobjectValidate";
  662.   GET_VXIOBJECT (pThis, sbObject, log, rc);
  663.   Diag (log, LOG_API, func, L"entering: 0x%p, 0x%p, 0x%p", 
  664.   pThis, properties, parameters);
  665.   if(properties == NULL) {
  666.     Error (log, 201, NULL);
  667.     return VXIobj_RESULT_INVALID_ARGUMENT;
  668.   }
  669.   // Get the name of the object to execute
  670.   const VXIValue *val = VXIMapGetProperty(properties, OBJECT_CLASS_ID);
  671.   if(val == NULL) {
  672.     Error(log, 202, L"%s%s", L"parameter", OBJECT_CLASS_ID);
  673.     return VXIobj_RESULT_INVALID_PROP_VALUE;
  674.   } else if (VXIValueGetType(val) != VALUE_STRING) {
  675.     Error(log, 203, L"%s%s%s%d", L"parameter", OBJECT_CLASS_ID,
  676.     L"type", VXIValueGetType(val));
  677.     return VXIobj_RESULT_INVALID_PROP_VALUE;
  678.   }
  679.   const VXIchar *classID = VXIStringCStr((VXIString *)val);
  680.   // Handle the object
  681.   if (::wcscmp(classID, L"com.vocalocity.diag") == 0) {
  682.     //
  683.     // Sample diagnostic logging object
  684.     // 
  685.     rc = ProcessComSpeechworksDiagObject(pThis, properties, parameters, false,
  686.            NULL);
  687.     if(rc != VXIobj_RESULT_SUCCESS) rc = VXIobj_RESULT_NON_FATAL_ERROR;
  688.   }
  689.   else if (::wcscmp(classID, L"com.vocalocity.echo") == 0) {
  690.     //
  691.     // Sample object echoing back all attributes and parameters
  692.     // 
  693.     rc = ProcessComSpeechworksEchoObject(pThis, properties, parameters, false,
  694.            NULL);
  695.     if(rc != VXIobj_RESULT_SUCCESS) rc = VXIobj_RESULT_NON_FATAL_ERROR;
  696.   } 
  697.   else if (::wcscmp(classID, L"com.vocalocity.saveRecording") == 0) {
  698.     //
  699.     // Sample object that saves a recording to a file
  700.     // 
  701.     rc = ProcessComSpeechworksSaveRecordingObject(pThis, properties, 
  702.               parameters, false, NULL);
  703.     if(rc != VXIobj_RESULT_SUCCESS) rc = VXIobj_RESULT_NON_FATAL_ERROR;
  704.   } 
  705.   else if (::wcscmp(classID, L"com.vocalocity.setDefaults") == 0) {
  706.     //
  707.     // Sample object that sets the defaults document for subsequent
  708.     // calls. This is really a hack and not recommended. This was
  709.     // done more for fun than any value.
  710.     // 
  711.     rc = ProcessComSpeechworksSetDefaultsObject(pThis, properties, 
  712.               parameters, false, NULL);
  713.     if(rc != VXIobj_RESULT_SUCCESS) rc = VXIobj_RESULT_NON_FATAL_ERROR;
  714.   } 
  715.   else {
  716.     //
  717.     // Unsupported object
  718.     //
  719.     rc = VXIobj_RESULT_UNSUPPORTED;
  720.   }
  721.   Diag (log, LOG_API, func, L"exiting: returned %d", rc);
  722.   return rc;
  723. }
  724. // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8
  725. /**
  726.  * Global platform initialization of VXIobject
  727.  *
  728.  * @param log            VXI Logging interface used for error/diagnostic 
  729.  *                       logging, only used for the duration of this 
  730.  *                       function call
  731.  * @param  diagLogBase   Base tag number for diagnostic logging purposes.
  732.  *                       All diagnostic tags for VXIobject will start at this
  733.  *                       ID and increase upwards.
  734.  *
  735.  * @result VXIobj_RESULT_SUCCESS on success
  736.  */
  737. VXIOBJECT_API_EX VXIobjResult 
  738. VXIobjectInit (VXIlogInterface  *log,
  739.                VXIunsigned       diagLogBase)
  740. {
  741.   static const wchar_t func[] = L"VXIobjectInit";
  742.   gblDiagLogBase = diagLogBase;
  743.   Diag (log, LOG_API, func, L"entering: 0x%p, %u", log, diagLogBase);
  744.   VXIobjResult rc = VXIobj_RESULT_SUCCESS;
  745.   if (gblInitialized == true) {
  746.     rc = VXIobj_RESULT_FATAL_ERROR;
  747.     Error (log, 101, NULL);
  748.     Diag (log, LOG_API, func, L"exiting: returned %d", rc);
  749.     return rc;
  750.   }
  751.   if ( ! log )
  752.     return VXIobj_RESULT_INVALID_ARGUMENT;
  753.   // Return
  754.   gblInitialized = true;
  755.   Diag (log, LOG_API, func, L"exiting: returned %d", rc);
  756.   return rc;
  757. }
  758. /**
  759.  * Global platform shutdown of VXIobject
  760.  *
  761.  * @param log    VXI Logging interface used for error/diagnostic logging,
  762.  *               only used for the duration of this function call
  763.  *
  764.  * @result VXIobj_RESULT_SUCCESS on success
  765.  */
  766. VXIOBJECT_API_EX VXIobjResult 
  767. VXIobjectShutDown (VXIlogInterface  *log)
  768. {
  769.   static const wchar_t func[] = L"VXIobjectShutDown";
  770.   Diag (log, LOG_API, func, L"entering: 0x%p",log);
  771.   VXIobjResult rc = VXIobj_RESULT_SUCCESS;
  772.   if (gblInitialized == false) {
  773.     rc = VXIobj_RESULT_FATAL_ERROR;
  774.     Error (log, 102, NULL);
  775.     Diag (log, LOG_API, func, L"exiting: returned %d", rc);
  776.     return rc;
  777.   }
  778.   if ( ! log )
  779.     return VXIobj_RESULT_INVALID_ARGUMENT;
  780.   gblInitialized = false;
  781.   Diag (log, LOG_API, func, L"exiting: returned %d", rc);
  782.   return rc;
  783. }
  784. /**
  785.  * Create a new object service handle
  786.  *
  787.  * @param resources  A pointer to a structure containing all the interfaces
  788.  *                   that may be required by the object resource
  789.  *
  790.  * @result VXIobj_RESULT_SUCCESS on success 
  791.  */
  792. VXIOBJECT_API_EX VXIobjResult 
  793. VXIobjectCreateResource(VXIobjectResources   *resources,
  794.                         VXIobjectInterface   **object)
  795. {
  796.   static const wchar_t func[] = L"VXIobjectCreateResource";
  797.   VXIlogInterface *log = NULL;
  798.   if (( resources ) && ( resources->log )) {
  799.     log = resources->log;
  800.     Diag (log, LOG_API, func, L"entering: 0x%p, 0x%p", resources, object);
  801.   }
  802.   VXIobjResult rc = VXIobj_RESULT_SUCCESS;
  803.   if (gblInitialized == false) {
  804.     rc = VXIobj_RESULT_FATAL_ERROR;
  805.     Error (log, 102, NULL);
  806.     Diag (log, LOG_API, func, L"exiting: returned %d, 0x%p",
  807.     rc, (object ? *object : NULL));
  808.     return rc;
  809.   }
  810.   if (( ! log ) || ( ! resources ) || ( ! object )) {
  811.     rc = VXIobj_RESULT_INVALID_ARGUMENT;
  812.     Error (log, 103, NULL);
  813.     Diag (log, LOG_API, func, L"exiting: returned %d, 0x%p",
  814.     rc, (object ? *object : NULL));
  815.     return rc;
  816.   }
  817.   *object = NULL;
  818.   // Get a new interface instance
  819.   VXIobjectAPI *newObject = new VXIobjectAPI;
  820.   if (newObject == false) {
  821.     rc = VXIobj_RESULT_OUT_OF_MEMORY;
  822.     Error (log, 100, NULL);
  823.     Diag (log, LOG_API, func, L"exiting: returned %d, 0x%p", rc, *object);
  824.     return rc;
  825.   }
  826.   memset (newObject, 0, sizeof (VXIobjectAPI));
  827.   // Initialize the function pointers
  828.   newObject->object.GetVersion            = VXIobjectGetVersion;
  829.   newObject->object.GetImplementationName = VXIobjectGetImplementationName;
  830.   newObject->object.Execute               = VXIobjectExecute;
  831.   newObject->object.Validate              = VXIobjectValidate;
  832.   // Initialize data members
  833.   newObject->resources = resources;
  834.   // Return the object
  835.   if ( rc != VXIobj_RESULT_SUCCESS ) {
  836.     if ( newObject )
  837.       delete newObject;
  838.   } else {
  839.     *object = &(newObject->object);
  840.   }
  841.   Diag (log, LOG_API, func, L"exiting: returned %d, 0x%p", rc, *object);
  842.   return rc;
  843. }
  844. /**
  845.  * Destroy the interface and free internal resources. Once this is
  846.  *  called, the resource interfaces passed to VXIobjectCreateResource( )
  847.  *  may be released as well.
  848.  *
  849.  * @result VXIobj_RESULT_SUCCESS on success 
  850.  */
  851. VXIOBJECT_API_EX VXIobjResult
  852. VXIobjectDestroyResource(VXIobjectInterface **object)
  853. {
  854.   VXIobjResult rc = VXIobj_RESULT_SUCCESS;
  855.   static const wchar_t func[] = L"VXIobjectDestroyResource";
  856.   // Can't log yet, don't have a log handle
  857.   if (gblInitialized == false)
  858.     return VXIobj_RESULT_FATAL_ERROR;
  859.   if ((object == NULL) || (*object == NULL))
  860.     return VXIobj_RESULT_INVALID_ARGUMENT;
  861.   // Get the real underlying interface
  862.   VXIobjectAPI *objectAPI = (VXIobjectAPI *) *object;
  863.   VXIlogInterface *log = objectAPI->resources->log;
  864.   Diag (log, LOG_API, func, L"entering: 0x%p (0x%p)", object, *object);
  865.   // Delete the object
  866.   delete objectAPI;
  867.   *object = NULL;
  868.   Diag (log, LOG_API, func, L"exiting: returned %d", rc);
  869.   return rc;
  870. }