예제 #1
0
/**
 * Sample object echoing back all parameters
 *
 * @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 
ProcessComSpeechworksEchoObject (struct VXIobjectInterface *pThis,
                                 const VXIMap              *properties,
                                 const VXIMap              *parameters,
                                 VXIbool                    execute,
         VXIValue                 **result)
{
  static const wchar_t func[] = L"ProcessComSpeechworksEchoObject";
  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) {
    // 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);

    // Simply add the input properties and parameters to the result object
    VXIMapSetProperty(resultObj, L"attributes", 
          VXIValueClone((VXIValue *)properties));
    VXIMapSetProperty(resultObj, L"parameters", 
          VXIValueClone((VXIValue *)parameters));

  }

  return VXIobj_RESULT_SUCCESS;
}
예제 #2
0
/**
 * 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;
}
예제 #3
0
inline void AddParamValue(VXIMapHolder & m, const vxistring & name,
                          VXIflt32 value)
{
  if (m.GetValue() == NULL) return;
  VXIFloat * val = VXIFloatCreate(value);
  if (val == NULL) throw VXIException::OutOfMemory();
  VXIMapSetProperty(m.GetValue(), name.c_str(),
                    reinterpret_cast<VXIValue *>(val));
}
예제 #4
0
inline void AddParamValue(VXIMapHolder & m, const vxistring & name,
                          bool value)
{
  if (m.GetValue() == NULL) return;
  VXIBoolean * val = VXIBooleanCreate((value ? TRUE : FALSE));
  if (val == NULL) throw VXIException::OutOfMemory();
  VXIMapSetProperty(m.GetValue(), name.c_str(),
                    reinterpret_cast<VXIValue *>(val));
}
예제 #5
0
파일: osbtel.cpp 프로젝트: mranga/sipxecs
/**
 * 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;
}
예제 #6
0
파일: osbtel.cpp 프로젝트: mranga/sipxecs
/**
 * 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;
}
예제 #7
0
// Open an entry
VXIcacheResult SBcacheManager::Open(VXIlogInterface       *log,
				    const SBcacheString   &moduleName,
				    const SBcacheKey      &key,
				    VXIcacheOpenMode       mode,
				    VXIint32               flags,
				    const VXIMap          *properties,
				    VXIMap                *streamInfo,
				    VXIcacheStream       **stream)
{
  VXIcacheResult rc = VXIcache_RESULT_SUCCESS;

  // Big loop where we attempt to open and re-open the cache entry for
  // as long as we get recoverable errors
  VXIcacheOpenMode finalMode;
  do {
    finalMode = mode;
    rc = VXIcache_RESULT_SUCCESS;

    if ( _entryTableMutex.StartRead( ) != VXItrd_RESULT_SUCCESS ) {
      Error (log, 110, L"%s%s", L"mutex", L"entry table mutex");
      return VXIcache_RESULT_SYSTEM_ERROR;
    }

    // Find the entry and open it, only need read permission
    bool entryOpened = false;
    SBcacheEntry entry;
    SBcacheEntryTable::iterator vi = _entryTable.find (key);
    if ( vi == _entryTable.end( ) ) {
      rc = VXIcache_RESULT_NOT_FOUND;
    } else {
      entry = (*vi).second;
      finalMode = (mode == CACHE_MODE_READ_CREATE ? CACHE_MODE_READ : mode);
    }

    if ( _entryTableMutex.EndRead( ) != VXItrd_RESULT_SUCCESS ) {
      Error (log, 111, L"%s%s", L"mutex", L"entry table mutex");
      rc = VXIcache_RESULT_SYSTEM_ERROR;
    }


    // For write and read/create mode, create the entry if not found
    if (( rc == VXIcache_RESULT_NOT_FOUND ) && ( mode != CACHE_MODE_READ )) {
      rc = VXIcache_RESULT_SUCCESS;

      // Get write permission
      if ( _entryTableMutex.Lock( ) != VXItrd_RESULT_SUCCESS ) {
	Error (log, 110, L"%s%s", L"mutex", L"entry table mutex");
	rc = VXIcache_RESULT_SYSTEM_ERROR;
      } else {
	// Try to find the entry again, it may have been created by now
	vi = _entryTable.find (key);
	if ( vi != _entryTable.end( ) ) {
	  // Found it this time
	  entry = (*vi).second;
	  finalMode = (mode == CACHE_MODE_READ_CREATE ? CACHE_MODE_READ : mode);
	} else {
	  // Create and open the entry for write
	  rc = entry.Create (GetLog( ), GetDiagBase( ),
			     _refCntMutexPool.GetMutex( ));

	  if ( rc == VXIcache_RESULT_SUCCESS ) {
	    finalMode = (mode == CACHE_MODE_READ_CREATE ? CACHE_MODE_WRITE :
			 mode);

            // Note entry lock obtained while entrytable lock is held! We
            // can get away with this, because the lock isn't visible to
            // anyone else yet.
	    rc = entry.Open (log, moduleName, key,
			     GetNewEntryPath (moduleName, key),
			     finalMode, flags, _entryMaxSizeBytes, properties,
			     streamInfo, stream);
	  }

	  // Insert the entry
	  if ( rc == VXIcache_RESULT_SUCCESS ) {
	    entryOpened = true;

	    SBcacheEntryTable::value_type tableEntry (key, entry);
	    if ( !InsertEntry(entry)) {
	      Error (log, 100, NULL);
	      (*stream)->Close (true);
	      *stream = NULL;
	      rc = VXIcache_RESULT_OUT_OF_MEMORY;
	    } 
	  }
	}

	if ( _entryTableMutex.Unlock( ) != VXItrd_RESULT_SUCCESS ) {
	  Error (log, 111, L"%s%s", L"mutex", L"entry table mutex");
	  rc = VXIcache_RESULT_SYSTEM_ERROR;
	}
      }
    }


    // Open pre-existing entry. Note that this may return
    // VXIcache_RESULT_FAILURE in some cases where we then need to
    // retry the entire process of opening the entry -- that occurs
    // when a writer opens the entry, we attempt to open for read
    // access here before the writer finishes writing the entry, then
    // the writer invalidates the entry on us. When that happens, if
    // we're attempting MODE_READ_CREATE we want to get that invalid
    // entry out of the table and create the entry ourselves returning
    // in WRITE mode, for MODE_READ we just want to see if another
    // writer has created a new entry that is valid for us to use
    // otherwise we bail out with the normal RESULT_NOT_FOUND.
    if (( rc == VXIcache_RESULT_SUCCESS ) && ( ! entryOpened )) {
      // If this is a write over an existing entry, wipe the previous entry
      // accounting from the cache.
      if (finalMode == CACHE_MODE_WRITE)
        _curSizeBytes.Decrement(entry.GetSizeBytes(false));

      rc = entry.Open (log, moduleName, key, entry.GetPath( ), finalMode,
		       flags, _entryMaxSizeBytes, properties, streamInfo,
		       stream);

      // Don't let a corrupt entry persist
      if (( rc != VXIcache_RESULT_SUCCESS ) &&
	  ( rc != VXIcache_RESULT_FAILURE ))
	Delete (log, key);
    }

    // Accessed, so move it to the top of the LRU list
    if ( _entryTableMutex.Lock( ) != VXItrd_RESULT_SUCCESS ) {
      Error (log, 110, L"%s%s", L"mutex", L"entry table mutex");
      rc = VXIcache_RESULT_SYSTEM_ERROR;
    } else {
      if (rc == VXIcache_RESULT_SUCCESS)
        TouchEntry(entry);
      if ( _entryTableMutex.Unlock( ) != VXItrd_RESULT_SUCCESS ) {
        Error (log, 111, L"%s%s", L"mutex", L"entry table mutex");
        rc = VXIcache_RESULT_SYSTEM_ERROR;
      }
    }

  } while ( rc == VXIcache_RESULT_FAILURE );

  // Finish up returning the stream information
  if (( rc == VXIcache_RESULT_SUCCESS ) && ( streamInfo ) &&
      ( VXIMapSetProperty (streamInfo, CACHE_INFO_FINAL_KEY,
			   (VXIValue *) VXIStringCreate(key.c_str( ))) !=
	VXIvalue_RESULT_SUCCESS )) {
    Error (log, 100, NULL);
    (*stream)->Close (true);
    *stream = NULL;
    rc = VXIcache_RESULT_OUT_OF_MEMORY;
  }

  if (( rc == VXIcache_RESULT_SUCCESS ) &&
      ( mode == CACHE_MODE_READ_CREATE ) && ( finalMode == CACHE_MODE_WRITE ))
    rc = VXIcache_RESULT_ENTRY_CREATED;

  // Maybe do cleanup, ignore all but fatal errors
  VXIcacheResult rc2 = Cleanup (false, key);
  if ( rc2 < VXIcache_RESULT_SUCCESS ) {
    (*stream)->Close (true);
    *stream = NULL;
    rc = rc2;
  }

  Diag (log, SBCACHE_MGR_TAGID, L"Open", L"%s: rc = %d", key.c_str( ), rc);
  return rc;
}
예제 #8
0
/**
 * 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;
}
예제 #9
0
/**
 * 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;
}
예제 #10
0
// Open the entry
VXIcacheResult SBcacheEntryDetails::Open(VXIlogInterface       *log,
					 const SBcacheString   &moduleName,
					 const SBcacheKey      &key,
					 const SBcachePath     &path,
					 VXIcacheOpenMode       mode,
					 VXIint32               flags,
					 VXIulong               maxSizeBytes,
					 const VXIMap          *properties,
					 VXIMap                *streamInfo,
					 VXIcacheStream       **stream)
{
  VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
  FILE *filePtr = NULL;

  // Lock and copy input data
  switch ( mode ) {
  case CACHE_MODE_WRITE:
    if ( _rwMutex.Lock( ) != VXItrd_RESULT_SUCCESS ) {
      Error (log, 110, L"%s%s", L"mutex", L"cache entry rw mutex, writer");
      rc = VXIcache_RESULT_SYSTEM_ERROR;
    } else {
      // If the open fails due to directory not existing, call
      // path.CreateDirectories( ) to create the dir tree then open
      // again
      if ( ! _invalidated ) {
	filePtr = fopen (path.c_str( ), "wb");
        int retries = 10; // work around possible race condition w/ rmdir
	while ((retries-- > 0) &&
            ( ! filePtr ) &&
            ( path.CreateDirectories( ) == VXIcache_RESULT_SUCCESS ))
	  filePtr = fopen (path.c_str( ), "wb");
      }

      if ( ! filePtr ) {
	if ( _invalidated ) {
	  // Invalidated or another thread attempted an open for write
	  // and failed, we only got here due to a race condition
	  // where we were waiting on the mutex to start our write
	  // before the failure/invalidation happened by the previous
	  // writer
	  rc = VXIcache_RESULT_FAILURE;
	} else {
	  // File open error
	  LogIOError (log, 213, path);
	  rc = VXIcache_RESULT_IO_ERROR;
	}

	_fileExists = false;
	_rwMutex.Unlock( );
      } else {
	_fileExists = true;
	_creationCost = CACHE_CREATION_COST_DEFAULT;
	_flags = flags;
	_sizeBytes = 0;

        // Only set the path and key if they differ
        if (path != _path || key != _key) {
          _path = path;
          _key = key;
        }

	// Load properties
	if ( properties ) {
	  const VXIValue *value =
	    VXIMapGetProperty (properties, CACHE_CREATION_COST);
	  if ( value ) {
	    if ( VXIValueGetType(value) == VALUE_INTEGER )
	      _creationCost = (VXIcacheCreationCost)
		VXIIntegerValue ((const VXIInteger *) value);
	    else
	      Error (log, 301, L"%s%d", L"VXIValueType",
		     VXIValueGetType(value));
	  }
	}
      }
    }
    break;

  case CACHE_MODE_READ:
    if ( _rwMutex.StartRead( ) != VXItrd_RESULT_SUCCESS ) {
      Error (log, 110, L"%s%s", L"mutex", L"cache entry rw mutex, reader");
      rc = VXIcache_RESULT_SYSTEM_ERROR;
    } else {
      if (( _fileExists ) && ( ! _invalidated )) {
	filePtr = fopen (_path.c_str( ), "rb");
	if ( ! filePtr ) {
	  _fileExists = false;
	  LogIOError (log, 214, _path);
	  _rwMutex.EndRead( );
	  rc = VXIcache_RESULT_IO_ERROR;
	}
      } else {
	// Invalidated or another thread attempted an open for write
	// and failed, we only got here due to a race condition where
	// we were waiting on the mutex to start our read before the
	// failure/invalidation happened by the writer
	_rwMutex.EndRead( );
	rc = VXIcache_RESULT_FAILURE;
      }
    }
    break;

  default:
    Error (log, 215, L"%s%d", L"mode", mode);
    rc = VXIcache_RESULT_UNSUPPORTED;
  }

  if ( rc == VXIcache_RESULT_SUCCESS ) {
    // Update the accessed time
    _lastAccessed = time(0);
    if (mode == CACHE_MODE_WRITE)
      _lastModified = _lastAccessed;

    // Return stream information
    if ( streamInfo ) {
      if (( VXIMapSetProperty (streamInfo, CACHE_INFO_LAST_MODIFIED,
			       (VXIValue *) VXIIntegerCreate(_lastModified)) !=
	    VXIvalue_RESULT_SUCCESS ) ||
	  ( VXIMapSetProperty (streamInfo, CACHE_INFO_SIZE_BYTES,
			       (VXIValue *) VXIIntegerCreate (_sizeBytes)) !=
	    VXIvalue_RESULT_SUCCESS )) {
	Error (log, 100, NULL);
	rc = VXIcache_RESULT_OUT_OF_MEMORY;
      }
    }
  }

  // Return the stream
  if ( rc == VXIcache_RESULT_SUCCESS ) {
    SBcacheEntry entry(this);
    *stream = new SBcacheStream (log, GetDiagBase( ), moduleName, key,
				 entry, mode,
				 ((flags & CACHE_FLAG_NONBLOCKING_IO) == 0),
				 maxSizeBytes, filePtr);
    if ( ! *stream ) {
      Error (log, 100, NULL);
      fclose (filePtr);
      Close (log, mode, 0, true);
      rc = VXIcache_RESULT_OUT_OF_MEMORY;
    }
  }

  Diag (log, SBCACHE_ENTRY_TAGID, L"Open", L"%s, %S, 0x%x, 0x%x: rc = %d",
	key.c_str( ), path.c_str( ), mode, flags, rc);
  return rc;
}
예제 #11
0
VXIinetResult
SBinetFileStream::Open(VXIint32                  flags,
		       const VXIMap             *properties,
		       VXIMap                   *streamInfo)
{
  VXIinetResult returnValue = VXIinet_RESULT_SUCCESS;

  /*
     Get the flag to determine whether to open local files. Also check
     the validator to see if it contains INET_INFO_VALIDATOR and if it
     does contain the modified time. */
  SBinetValidator validator(GetLog(), GetDiagBase());
  const VXIValue *validatorVal = NULL;
  if (properties)
  {
    const VXIValue *val = VXIMapGetProperty(properties, INET_OPEN_LOCAL_FILE);
    if (val != NULL)
    {
      if (VXIValueGetType(val) == VALUE_INTEGER)
      {
        if (VXIIntegerValue((const VXIInteger *) val) == FALSE)
          returnValue = VXIinet_RESULT_LOCAL_FILE;
      }
      else
      {
        Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetFileStream::Open",
             L"Passed invalid type for INET_OPEN_LOCAL_FILE property");
      }
    }

    // SBinetValidator::Create() logs errors for us
    validatorVal = VXIMapGetProperty(properties, INET_OPEN_IF_MODIFIED);
    if((validatorVal != NULL) &&
       (validator.Create(validatorVal) != VXIinet_RESULT_SUCCESS))
      validatorVal = NULL;
  }

  Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetFileStream::Open",
       _url->getAbsolute( ));

  // Stat the file to make sure it exists and to get the length and
  // last modified time
  VXIStatStruct statInfo;
  if (VXIStat(SBinetNString(_url->getPath()).c_str(), &statInfo) != 0) {
    Error(222, L"%s%s", L"File", _url->getPath());
    return(VXIinet_RESULT_NOT_FOUND);
  }

  _content_length = statInfo.st_size;

  // If there is a conditional open using a validator, see if the
  // validator is still valid (no need to re-read and re-process)
  if (validatorVal)
  {
    if (! validator.isModified(statInfo.st_mtime, statInfo.st_size))
    {
      Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetFileStream::Open",
           L"Validator OK, returning NOT_MODIFIED");
      returnValue = VXIinet_RESULT_NOT_MODIFIED;
    }
    else
    {
      Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetFileStream::Open",
           L"Validator modified, must re-fetch");
    }
  }

  if (returnValue != VXIinet_RESULT_LOCAL_FILE)
  {
    // Use fopen for now. Note: Open support reads for now
    _pFile = ::fopen( SBinetNString(_url->getPath()).c_str(), "rb" );
    if(!_pFile){
      Error(223, L"%s%s", L"File", _url->getPath());
      return(VXIinet_RESULT_NOT_FOUND);
    }
    _ReadSoFar = 0;
  }

  if (streamInfo != NULL)
  {
    // Set FILE data source information   
    VXIMapSetProperty(streamInfo, INET_INFO_DATA_SOURCE, 
                     (VXIValue*) VXIIntegerCreate(INET_DATA_SOURCE_FILE));
    
    // Use extension mapping algorithm to determine MIME content type
    VXIString *guessContent = _url->getContentTypeFromUrl();
    if (guessContent == NULL) {
      guessContent = VXIStringCreate(_channel->getDefaultMimeType());
      // This error message is useful, but unfortunately it gets printed
      // for all the grammar files etc. whose extensions are unknown...
      //Error (303, L"%s%s", L"URL", _url->getPath());
    }
    VXIMapSetProperty(streamInfo, INET_INFO_MIME_TYPE, (VXIValue*) guessContent);

    // Set the absolute path, any file:// prefix and host name is
    // already stripped prior to this method being invoked
    VXIMapSetProperty(streamInfo, INET_INFO_ABSOLUTE_NAME,
		      (VXIValue*)VXIStringCreate( _url->getPath() ));

    // Set the validator property
    VXIValue *newValidator = NULL;
    if (returnValue == VXIinet_RESULT_NOT_MODIFIED) {
      newValidator = VXIValueClone(validatorVal);
    } else {
      SBinetValidator validator(GetLog(), GetDiagBase());
      if (validator.Create(_url->getPath(), statInfo.st_size,
                           statInfo.st_mtime) == VXIinet_RESULT_SUCCESS)
      {
	newValidator = (VXIValue *) validator.serialize();
      }
    }

    if (newValidator)
      VXIMapSetProperty(streamInfo, INET_INFO_VALIDATOR, newValidator);
    else {
      Error(103, NULL);
      returnValue = VXIinet_RESULT_OUT_OF_MEMORY;
    }

    // Set the size
    VXIMapSetProperty(streamInfo, INET_INFO_SIZE_BYTES,
		      (VXIValue*)VXIIntegerCreate( _content_length));
  }

  if (!validatorVal && (returnValue == VXIinet_RESULT_NOT_MODIFIED))
    return VXIinet_RESULT_SUCCESS;

  return returnValue;
}