示例#1
0
/**** Global functions definitions.   ****/
TA_Dict *TA_DictAlloc( TA_Libc *libHandle,
                       unsigned int flags,                       
                       void (*freeValueFunc)( TA_Libc *libHandle, void *) )
{
   TA_PrivDictInfo *theDict;

   if( !libHandle )
      return NULL;

   /* Alloc the structure used as an handle for this dictionary. */
   theDict = (TA_PrivDictInfo *) TA_Malloc( libHandle, sizeof( TA_PrivDictInfo ) );

   if( !theDict )
      return NULL;

   theDict->flags = flags;

   /* Create the Kazlib dictionary. */
   if( flags & TA_DICT_KEY_ONE_STRING )
      dict_init( libHandle, &theDict->d, DICTCOUNT_T_MAX, compareFunction_S );
   else if( flags & TA_DICT_KEY_TWO_STRING )
      dict_init( libHandle, &theDict->d, DICTCOUNT_T_MAX, compareFunction_S );
   else if( flags & TA_DICT_KEY_INTEGER )
      dict_init( libHandle, &theDict->d, DICTCOUNT_T_MAX, compareFunction_I );

   /* Keep a copy of the freeValueFunc pointer for later use. */
   theDict->freeValueFunc = freeValueFunc;

   /* Remember to which memory context we belong. */
   theDict->libHandle = libHandle;

   return (TA_Dict *)theDict;
}
示例#2
0
/**** Global functions definitions.   ****/
TA_Dict *TA_DictAlloc( unsigned int flags, void (*freeValueFunc)( void *) )                       
{
   TA_PrivDictInfo *theDict;

   /* Alloc the structure used as an handle for this dictionary. */
   theDict = (TA_PrivDictInfo *) TA_Malloc( sizeof( TA_PrivDictInfo ) );

   if( !theDict )
      return NULL;

   theDict->flags = flags;

   /* Create the Kazlib dictionary. */
   if( flags & TA_DICT_KEY_ONE_STRING )
      dict_init( &theDict->d, DICTCOUNT_T_MAX, compareFunction_S );
   else if( flags & TA_DICT_KEY_TWO_STRING )
      dict_init( &theDict->d, DICTCOUNT_T_MAX, compareFunction_S );
   else if( flags & TA_DICT_KEY_INTEGER )
      dict_init( &theDict->d, DICTCOUNT_T_MAX, compareFunction_I );

   /* Keep a copy of the freeValueFunc pointer for later use. */
   theDict->freeValueFunc = freeValueFunc;

   return (TA_Dict *)theDict;
}
示例#3
0
/* A little utility to fetch a web page and send the raw data
 * to the provided FILE pointer. This ptr could be "stdout" to
 * display on the console.
 *
 * Example:
 *        TA_WebFetch( "www.yahoo.com", stdout );
 *           or
 *        TA_WebFetch( "http://www.yahoo.com/mt", myFile );
 */
TA_RetCode TA_WebFetch( TA_Libc *libHandle, const char *url, FILE *out )
{
   TA_RetCode retCode;
   TA_WebPage *webPage;

   const char *stringStart;
   const char *webSitePage;
   char *allocString;

   unsigned int webSiteLength;

   if( !url )
      return TA_BAD_PARAM;

   allocString = NULL;

   /* Skip the http:// if specified. */
   stringStart = url;
   if( strncmp( url, "http://", 7 ) == 0 )
      stringStart += 7;
   
   /* Find if there is a specifc web page specified. */
   webSitePage = strchr( stringStart, '/' );
   if( webSitePage )
   {
      webSitePage++;
      if( *webSitePage == '\0' )
      {
         webSitePage = NULL;         
      }
      else
      {
         webSiteLength = webSitePage - stringStart - 1;
         allocString = (char *)TA_Malloc( libHandle, webSiteLength+1 );
         if( !allocString )
            return TA_ALLOC_ERR;
         strncpy( allocString, stringStart, webSiteLength );
         allocString[webSiteLength] = '\0';
         stringStart = allocString;
      }
   }

   retCode = TA_WebPageAlloc( libHandle,
                              stringStart,
                              webSitePage,
                              NULL, NULL,
                              &webPage,
                              2 );

   if( allocString )
      TA_Free( libHandle, allocString );

   if( retCode == TA_SUCCESS )
   {
      retCode = TA_StreamToFile( webPage->content, out );
      TA_WebPageFree( webPage );
   }

   return retCode;
}
示例#4
0
/* Initialize the cache mechanism. */
TA_RetCode TA_StringCacheAlloc( TA_StringCache **newStringCache )
{
   TA_StringCachePriv *stringCachePriv;
   #if !defined( TA_SINGLE_THREAD )
   TA_RetCode retCode;
   #endif

   if( !newStringCache )
      return TA_BAD_PARAM;

   *newStringCache = NULL;

   stringCachePriv = (TA_StringCachePriv *)TA_Malloc( sizeof( TA_StringCachePriv ) );

   if( !stringCachePriv )
      return TA_ALLOC_ERR;

   memset( stringCachePriv, 0, sizeof( TA_StringCachePriv ) );

   #if !defined( TA_SINGLE_THREAD )
   retCode = TA_SemaInit( &stringCachePriv->sema, 1 );
   if( retCode != TA_SUCCESS )
   {
      TA_Free(  stringCachePriv );
      return retCode;
   }
   #endif

   /* Success, return the cache to the caller. */
   *newStringCache = (TA_StringCache *)stringCachePriv;

   return TA_SUCCESS;
}
示例#5
0
/**** Global functions definitions.   ****/
TA_RetCode TA_GroupTableAlloc( TA_StringTable **table )
{
   TA_StringTable *stringTable;
   TA_StringTablePriv *stringTablePriv;

   if( table == NULL )
   {
      return TA_BAD_PARAM;
   }

   stringTable = (TA_StringTable *)TA_Malloc( sizeof(TA_StringTable) + sizeof(TA_StringTablePriv) );
   if( !stringTable )
   {
      *table = NULL;
      return TA_ALLOC_ERR;
   }

   memset( stringTable, 0, sizeof(TA_StringTable) + sizeof(TA_StringTablePriv) );
   stringTablePriv = (TA_StringTablePriv *)(((char *)stringTable)+sizeof(TA_StringTable));
   stringTablePriv->magicNumber = TA_STRING_TABLE_GROUP_MAGIC_NB;

   stringTable->size = TA_NB_GROUP_ID;
   stringTable->string = &TA_GroupString[0];
   stringTable->hiddenData = stringTablePriv;

   /* From this point, TA_FuncTableFree can be safely called. */

   /* Success. Return the table to the caller. */
   *table = stringTable;

   return TA_SUCCESS;
}
示例#6
0
/**** Local functions definitions.     ****/
static TA_RetCode rangeTestFunction( 
                              TA_Integer startIdx,
                              TA_Integer endIdx,
                              TA_Real *outputBuffer,
                              TA_Integer *outBegIdx,
                              TA_Integer *outNbElement,
                              TA_Integer *lookback,
                              void *opaqueData,
                              unsigned int outputNb )
{
   TA_RetCode retCode;
   TA_RangeTestParam *testParam;
   TA_Real *out1;
   TA_Real *out2;
   TA_Real *dummyOutput;
   (void)outputNb;
  
   testParam = (TA_RangeTestParam *)opaqueData;   

   dummyOutput = TA_Malloc( (endIdx-startIdx+1) * sizeof(TA_Real) );
                     
   if( outputNb == 0 )
   {
      out1 = outputBuffer;
      out2 = dummyOutput;
   }
   else
   {
      out1 = dummyOutput;
      out2 = outputBuffer;
   }

   switch( testParam->test->theFunction )
   {
   case TA_HT_PHASOR_TEST:
      retCode = TA_HT_PHASOR( startIdx,
                              endIdx,
                              testParam->price,
                              outBegIdx,
                              outNbElement,                          
                              out1, out2 );
      *lookback = TA_HT_PHASOR_Lookback();
      break;
   case TA_HT_SINE_TEST:
      retCode = TA_HT_SINE( startIdx,
                            endIdx,
                            testParam->price,
                            outBegIdx,
                            outNbElement,                          
                            out1, out2 );
      *lookback = TA_HT_SINE_Lookback();
      break;
   default:
      retCode = TA_INTERNAL_ERROR(132);
   }

   TA_Free(dummyOutput);
   return retCode;
}
示例#7
0
/* Allocate dyamically a copy of string.
 * Eliminate also all whitespace in the copy.
 */
TA_String *TA_StringAllocTrim( TA_StringCache *stringCache,
                               const char *string )
{
   char *str;
   char *ptrCharTmp1;
   const char *ptrCharTmp2;
   unsigned int trimmedSize;
   unsigned int nonTrimmedSize;
   TA_StringCachePriv *stringCachePriv;

   if( stringCache == NULL )
      return NULL;

   stringCachePriv = (TA_StringCachePriv *)stringCache;

   if( !string )
      return NULL;

   /* Evaluate the size and see if any trimming is needed. */
   trimmedSize = 0;
   nonTrimmedSize = 0;
   ptrCharTmp2 = string;
   while( *ptrCharTmp2++ != '\0' )
   {
      if( !isspace(*ptrCharTmp2) )
         trimmedSize++;
      nonTrimmedSize++;
   }

   if( trimmedSize == nonTrimmedSize )
      return TA_StringAlloc( stringCache, string );

   trimmedSize = (trimmedSize + 1)*sizeof( unsigned char );

   str = (char *)TA_Malloc( trimmedSize );

   if( str != NULL )
   {
      /* Eliminate all whitespaces (not speed optimize...) */
      ptrCharTmp1 = &str[0];
      ptrCharTmp2 = string;
      while( *ptrCharTmp2 != '\0' )
      {
         if( !isspace(*ptrCharTmp2) )
         {
            *ptrCharTmp1 = *ptrCharTmp2;
            ptrCharTmp1++;
         }
         ptrCharTmp2++;
      }

      *ptrCharTmp1 = '\0';

      return TA_StringAlloc( stringCache, str );
   }

   /* Allocation error. */
   return (TA_String *)NULL;
}
示例#8
0
TA_RetCode TA_PMAlloc( const TA_Timestamp  *startDate,
                       const TA_Timestamp  *endDate,
                       TA_Real              initialCapital,
                       TA_PM              **allocatedPM )
{
    TA_PM     *pm;
    TA_PMPriv *pmPriv;
    unsigned int delta;
    TA_RetCode retCode;

    /* Check all the parameters. */
    if( !allocatedPM )
        return TA_BAD_PARAM;
    *allocatedPM = NULL;

    if( !startDate || !endDate )
        return TA_BAD_PARAM;

    if( TA_TimestampValidate( startDate ) )
        return TA_BAD_START_DATE;

    if( TA_TimestampValidate( endDate ) || TA_TimestampGreater( startDate, endDate ) )
        return TA_BAD_END_DATE;

    /* To keep things simple, it is assumed that
     * the requested date range contains at least
     * one weekday.
     */
    retCode = TA_TimestampDeltaWeekday( startDate, endDate, &delta );
    if( retCode != TA_SUCCESS )
        return retCode;
    if( delta <= 0 )
        return TA_NO_WEEKDAY_IN_DATE_RANGE;

    /* Allocate the public and private structure. */
    pm = TA_Malloc( sizeof( TA_PM ) + sizeof( TA_PMPriv ) );
    if( !pm )
        return TA_ALLOC_ERR;

    memset( pm, 0, sizeof( TA_PM ) + sizeof( TA_PMPriv ) );
    pmPriv = (TA_PMPriv *)(((char *)pm)+sizeof(TA_PM));
    pmPriv->magicNb        = TA_PMPRIV_MAGIC_NB;
    pmPriv->initialCapital = initialCapital;
    pm->hiddenData         = pmPriv;

    TA_ListInit(  &pmPriv->tradeLogList );

    /* TA_PMFree can be safely called from this point. */

    TA_TimestampCopy( &pmPriv->endDate, endDate );
    TA_TimestampCopy( &pmPriv->startDate, startDate );

    /* Success, return the allocated data to the caller. */
    *allocatedPM = pm;

    return TA_SUCCESS;
}
示例#9
0
/**** Global functions definitions.   ****/
TA_RetCode TA_GroupTableAlloc( TA_Libc *libHandle, TA_StringTable **table )
{
   TA_PROLOG;
   TA_StringTable *stringTable;
   TA_StringTableGroupHidden *stringTableHidden;

   TA_TRACE_BEGIN( libHandle, TA_GroupTableAlloc );

   if( table == NULL )
   {
      TA_TRACE_RETURN( TA_BAD_PARAM );
   }

   *table = NULL;

   stringTable = (TA_StringTable *)TA_Malloc( libHandle, sizeof(TA_StringTable) );

   if( !stringTable )
   {
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }

   stringTableHidden = (TA_StringTableGroupHidden *)TA_Malloc( libHandle, sizeof(TA_StringTableGroupHidden) );
   if( !stringTableHidden )
   {
      TA_Free( libHandle, stringTable );
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }

   stringTableHidden->libHandle = libHandle;
   stringTableHidden->magicNb = TA_STRING_TABLE_GROUP_MAGIC_NB;
   stringTable->size = TA_NB_GROUP_ID;
   stringTable->string = &TA_GroupString[0];
   stringTable->hiddenData = stringTableHidden;

   /* From this point, TA_FuncTableFree can be safely called. */

   /* Success. Return the table to the caller. */
   *table = stringTable;

   TA_TRACE_RETURN( TA_SUCCESS );
}
示例#10
0
/**** Local functions definitions.     ****/
static TA_RetCode TA_NetworkGlobalInit( void **globalToAlloc )
{
   #if !defined( TA_SINGLE_THREAD )
   TA_RetCode retCode;
   #endif
   TA_NetworkGlobal *global;

   if( !globalToAlloc )
      return TA_BAD_PARAM;

   *globalToAlloc = NULL;

   #if defined( USE_LIBCURL )
      #if defined(WIN32)
         if( curl_global_init(CURL_GLOBAL_WIN32) != CURLE_OK )
            return TA_LIBCURL_GLOBAL_INIT_FAILED;
      #else
         if( curl_global_init(CURL_GLOBAL_NOTHING) != CURLE_OK )
            return TA_LIBCURL_GLOBAL_INIT_FAILED;
      #endif
   #endif

   global = (TA_NetworkGlobal *)TA_Malloc( sizeof( TA_NetworkGlobal ) );
   if( !global )
      return TA_ALLOC_ERR;

   memset( global, 0, sizeof( TA_NetworkGlobal ) );

   #if defined( USE_LIBCURL )
      global->curlHandle = curl_easy_init();
      if( global->curlHandle == NULL )
      {
         TA_Free(  global );
         return TA_LIBCURL_INIT_FAILED;
      }
   #endif

   #if !defined( TA_SINGLE_THREAD )
      /* Initialize the mutex in a non-block state. */
      retCode = TA_SemaInit( &global->mutexSema, 1 );
      if( retCode != TA_SUCCESS )
      {
         TA_Free(  global );
         return retCode;
      }
   #endif

   global->initialized = 1;

   /* Success, return the allocated memory to the caller. */
   *globalToAlloc = global;
   return TA_SUCCESS;
}
示例#11
0
TA_RetCode TA_FileIndexAddTokenInfo( TA_FileIndexPriv *data,
                                     TA_TokenId id,
                                     TA_String *value,
                                     TA_TokenInfo *optBefore )
{
   TA_PROLOG;
   TA_RetCode retCode;
   TA_TokenInfo *info;
   TA_Libc *libHandle;
   TA_StringCache *stringCache;

   libHandle   = data->libHandle;
   TA_TRACE_BEGIN( libHandle, TA_FileIndexAddTokenInfo );

   stringCache = TA_GetGlobalStringCache( libHandle );

   info = TA_Malloc( libHandle, sizeof( TA_TokenInfo ) );

   if( !info )
   {
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }

   info->id = id;
   if( value == NULL )
      info->value = NULL;
   else
   {
      info->value = TA_StringDup( stringCache, value );

      if( !info->value )
      {
         TA_Free( libHandle, info );
         TA_TRACE_RETURN( TA_ALLOC_ERR );
      }
   }

   if( optBefore )
      retCode = TA_ListAddBefore( data->listLocationToken, optBefore, info );
   else
      retCode = TA_ListAddTail( data->listLocationToken, info );

    if( retCode != TA_SUCCESS )
    {
      if( info->value )
         TA_StringFree( stringCache, info->value );
      TA_Free( libHandle, info );
      TA_TRACE_RETURN( retCode );
   }

   TA_TRACE_RETURN( TA_SUCCESS );
}
示例#12
0
size_t libcurlWriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
   register int bufferSize;
   TA_WebPage *webPage;
   TA_WebPageHiddenData *webPageHidden;
   TA_RetCode retCode;
   char *buffer;

   webPage = (TA_WebPage *)data;
   webPageHidden = (TA_WebPageHiddenData *)webPage->hiddenData;   

   bufferSize = size * nmemb;
   
   /* Make a copy of the provided data. */
   buffer = TA_Malloc( bufferSize );
   if( !buffer )
      return 0; /* Error. */

   memcpy( buffer, ptr, bufferSize );

   /* Add the data to the stream. */
   if( !webPage->content )
   {
      /* The first buffer will initiate the creation of
       * the stream.
       */
      webPage->content = TA_StreamAllocFromBuffer( buffer, bufferSize,
                                                   NULL, NULL );

      if( !webPage->content )
      {
         TA_Free(  buffer );
         return 0; /* Error. */
      }
   }
   else
   {
      /* Add the buffer to the stream. */
      retCode = TA_StreamAddBuffer( webPage->content, 
                                    buffer, bufferSize,
                                    NULL, NULL );
      if( retCode != TA_SUCCESS )
      {
         TA_Free(  buffer );
         return 0; /* Error */
      }
   }

   return bufferSize;
}
示例#13
0
/**** Local functions definitions.     ****/
static TA_ValueTreeNode *allocTreeNode( TA_Libc *libHandle,
                                        TA_ValueTreeNode *parent,
                                        TA_String *string )
{
   TA_ValueTreeNode *node;
   TA_RetCode retCode;
   TA_StringCache *stringCache;

   stringCache = TA_GetGlobalStringCache( libHandle );

   node = (TA_ValueTreeNode *)TA_Malloc( libHandle, sizeof( TA_ValueTreeNode ) );

   if( !node )
      return (TA_ValueTreeNode *)NULL;

   node->string = NULL;
   node->parent = NULL;

   node->child = TA_ListAlloc( libHandle );
   if( !node->child )
   {
      freeTreeNode( libHandle, node );
      return NULL;
   }

   if( string )
   {
      node->string = TA_StringDup( stringCache, string );
      if( !node->string )
      {
         freeTreeNode( libHandle, node );
         return NULL;
      }
   }

   if( parent )
   {
      retCode = TA_ListAddTail( parent->child, node );
      if( retCode != TA_SUCCESS )
      {
         freeTreeNode( libHandle, node );
         return NULL;
      }
      node->parent = parent;
   }

   return node;
}
示例#14
0
static TA_TracePosition *newTracePosition( const char *funcname, 
                                           const char *filename,
                                           unsigned int lineNb )
{
   TA_TracePosition *tracePosition;

   tracePosition = (TA_TracePosition *)TA_Malloc( sizeof(TA_TracePosition) );
   if( !tracePosition )
       return NULL;

   tracePosition->filename = filename;
   tracePosition->funcname = funcname;
   tracePosition->lineNb = lineNb;
   tracePosition->repetition = 1;

   return tracePosition;
}
示例#15
0
static TA_String *stringAllocInternal( const char *string,
                                       unsigned int newStringLength,
                                       TA_CharCase caseType )
{
   unsigned int size, i;
   char *str;

   /* Not in the cache, or could have reach duplicaton limit.
    * No choice to do an allocation.
    */
   size = ( newStringLength + 2 ) * sizeof( unsigned char );

   str = (char *)TA_Malloc( size );

   if( str != NULL )
   {
      if( caseType == UPPER_CASE )
      {
         for( i=0; i < newStringLength; i++ )
            str[i+1] = (unsigned char)toupper( string[i] );
      }
      else if( caseType == PATH )
      {
         for( i=0; i < newStringLength; i++ )
         {
            if( TA_IsSeparatorChar(string[i]) )
               str[i+1] = TA_SeparatorASCII();
            else
               str[i+1] = string[i];
         }
      }
      else
      {
         for( i=0; i < newStringLength; i++ )
            str[i+1] = string[i];
      }

      str[newStringLength+1] = '\0';
      str[0] = 1;
   }

   return (TA_String *)str;
}
示例#16
0
static TA_String *stringValueAllocInternal( const char *string,
                                            unsigned int value )
{
   unsigned int size;
   char *str;

   size = ( strlen(string) + 2 + 8 );
   str = (char *)TA_Malloc( size );

   if( str != NULL )
   {
      if( value > 0xFFFF )
         value = 0xFFFF;
      sprintf( &str[1], "%08X%s", value, string );
      str[0] = 1;
   }

   return (TA_String *)str;
}
示例#17
0
static TA_String *valueAllocInternal( unsigned long value )
{
   unsigned int size;
   char buffer[100];
   char *str;

   buffer[0] = '\0';
   sprintf(buffer, "%u", (unsigned int)value );
   size = strlen(buffer)+2;
   str = (char *)TA_Malloc( size );
   
   if( str != NULL )
   {
      strcpy( &str[1], buffer );
      str[0] = 1;
   }
   
   return (TA_String *)str;
}
示例#18
0
/* Like TA_FileSeqOpen, but work with a stream instead. */
TA_RetCode TA_FileSeqOpenFromStream( TA_Stream *stream,
                                     TA_FileHandle **handle )
{
   TA_PROLOG
   TA_FileHandlePriv *fileHandlePriv;

   TA_TRACE_BEGIN(  TA_FileSeqOpen );

   TA_ASSERT( stream != NULL );
   TA_ASSERT( handle != NULL );

   /* Allocate the private file handle. */
   fileHandlePriv = (TA_FileHandlePriv *)TA_Malloc( sizeof( TA_FileHandlePriv ) );
   if( !fileHandlePriv )
   {
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }
   memset( fileHandlePriv, 0, sizeof( TA_FileHandlePriv ) );

   /* There is NO file... */
   #if defined( USE_WIN32_API )
   fileHandlePriv->handle = INVALID_HANDLE_VALUE; 
   #endif

   #if defined( USE_OSLAYER )
   fileHandlePriv->handle = (FILE *)NULL;
   #endif

   /* ... use a stream instead. */
   fileHandlePriv->stream = stream;
   fileHandlePriv->streamAccess = TA_StreamAccessAlloc( stream );
   if( !fileHandlePriv->streamAccess )
   {
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }

   /* Success! Return the info to the caller. */
   *handle = (TA_FileHandle *)fileHandlePriv;
   TA_TRACE_RETURN( TA_SUCCESS );
}
示例#19
0
static TA_RetCode TA_SystemGlobalInit( void **globalToAlloc )
{
   TA_PROLOG
   TA_RetCode retCode;
   TA_SystemGlobal *global;

   TA_TRACE_BEGIN( TA_SystemGlobalInit );

   TA_ASSERT( globalToAlloc != NULL );

   *globalToAlloc = NULL;

   global = (TA_SystemGlobal *)TA_Malloc( sizeof( TA_SystemGlobal ) );
   if( !global )
   {
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }

   memset( global, 0, sizeof( TA_SystemGlobal ) );

   retCode = TA_StringCacheAlloc( &global->dirnameCache );
   if( retCode != TA_SUCCESS )
   {
      TA_Free( global );
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }

   retCode = TA_StringCacheAlloc( &global->filenameCache );
   if( retCode != TA_SUCCESS )
   {
      TA_StringCacheFree( global->dirnameCache );
      TA_Free( global );
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }

   /* Success! Return the global to the caller. */
   *globalToAlloc = global;
   TA_TRACE_RETURN( TA_SUCCESS );
}
示例#20
0
static TA_RetCode TA_SetReceiveTimeout( DWORD     newTimeout, /* milliseconds */
                                        HINTERNET hWebPage )
{
   BOOL status;

   /* Set the timeout who is going to affect calls to
    * InternetReadFile when retreiving data.
    */

   #if 0
   /* Code for debugging */
	unsigned char *optionString;
	DWORD optionStringLength = 0;
   DWORD receiveTimeout;

	status = InternetQueryOption( hWebPage, 
                                 INTERNET_OPTION_RECEIVE_TIMEOUT,
			                        NULL, &optionStringLength );
	optionString = TA_Malloc( optionStringLength + 1);
	optionString[optionStringLength] = 0;
	InternetQueryOption( hWebPage, INTERNET_OPTION_RECEIVE_TIMEOUT,
			               &receiveTimeout, &optionStringLength );
   /*printf("GET INTERNET_OPTION_RECEIVE_TIMEOUT = %u\n", receiveTimeout );*/
	TA_Free(  (void *) optionString );
   #endif

   status = InternetSetOption( hWebPage,
                               INTERNET_OPTION_RECEIVE_TIMEOUT,
                               &newTimeout,
                               sizeof(DWORD) );

	if( !status )
      return TA_INTERNET_SET_RX_TIMEOUT_FAILED;

   return TA_SUCCESS;
}
示例#21
0
static TA_RetCode TA_TraceGlobalInit( void **globalToAlloc )
{
   TA_TraceGlobal *global;
   #if !defined( TA_SINGLE_THREAD )
   TA_RetCode retCode;
   #endif

   if( !globalToAlloc )
      return TA_BAD_PARAM;

   *globalToAlloc = NULL;

   global = TA_Malloc( sizeof( TA_TraceGlobal ) );
   if( !global )
      return TA_ALLOC_ERR;

   memset( global, 0, sizeof( TA_TraceGlobal ) );

   #if !defined( TA_SINGLE_THREAD )
      /* Initialize the mutexes in a non-block state. */
      retCode = TA_SemaInit( &global->callSema, 1 );
      if( retCode != TA_SUCCESS )
      {
         TA_Free(  global );
         return retCode;
      }
      retCode = TA_SemaInit( &global->fatalSema, 1 );
      if( retCode != TA_SUCCESS )
      {
         TA_SemaDestroy( &global->callSema );
         TA_Free(  global );
         return retCode;
      }
   #endif

   #ifdef TA_DEBUG   
      #if defined( TA_SINGLE_THREAD )
         /* When single threaded, maintain a calling stack. */      

         global->callStack = TA_ListAlloc();
         if( !global->callStack )
         {
            TA_Free(  global );
            return TA_ALLOC_ERR;
         }
      #endif

      /* All function call and checkpoint are maintained in a dictionary. */
      global->functionCalled = TA_DictAlloc( TA_DICT_KEY_ONE_STRING, freeTracePosition );
      if( !global->functionCalled )
      {
         #if !defined( TA_SINGLE_THREAD )
            TA_SemaDestroy( &global->callSema );
            TA_SemaDestroy( &global->fatalSema );      
         #else
            TA_ListFree( global->callStack );
         #endif      
         TA_Free(  global );
         return TA_ALLOC_ERR;
      }
   #endif

   /* Success, return the allocated memory to the caller. */
   *globalToAlloc = global;

   return TA_SUCCESS;
}
示例#22
0
TA_RetCode TA_ParamHolderAlloc( const TA_FuncHandle *handle,
                                TA_ParamHolder **allocatedParams )
{
   
   TA_FuncDef *funcDef;
   unsigned int allocSize, i;
   TA_ParamHolderInput    *input;
   TA_ParamHolderOptInput *optInput;
   TA_ParamHolderOutput   *output;

   const TA_FuncInfo *funcInfo;
   TA_ParamHolder *newParams;
   TA_ParamHolderPriv *newParamsPriv;

   const TA_InputParameterInfo    **inputInfo;
   const TA_OptInputParameterInfo **optInputInfo;
   const TA_OutputParameterInfo   **outputInfo;

   /* Validate the parameters. */
   if( !handle || !allocatedParams)
   {
      return TA_BAD_PARAM;
   }

   /* Validate that this is a valid funcHandle. */
   funcDef = (TA_FuncDef *)handle;
   if( funcDef->magicNumber != TA_FUNC_DEF_MAGIC_NB )
   {
      *allocatedParams = NULL;
      return TA_INVALID_HANDLE;
   }

   /* Get the TA_FuncInfo. */
   funcInfo = funcDef->funcInfo;
   if( !funcInfo ) return TA_INVALID_HANDLE;

   /* Allocate the TA_ParamHolder. */
   newParams = (TA_ParamHolder *)TA_Malloc( sizeof(TA_ParamHolder) + sizeof(TA_ParamHolderPriv));
   if( !newParams )
   {
      *allocatedParams = NULL;
      return TA_ALLOC_ERR;
   }

   memset( newParams, 0, sizeof(TA_ParamHolder) + sizeof(TA_ParamHolderPriv) );
   newParamsPriv = (TA_ParamHolderPriv *)(((char *)newParams)+sizeof(TA_ParamHolder));
   newParamsPriv->magicNumber = TA_PARAM_HOLDER_PRIV_MAGIC_NB;
   newParams->hiddenData = newParamsPriv;

   /* From this point, TA_ParamHolderFree can be safely called. */

   /* Allocate the array of structure holding the info
    * for each parameter.
    */
   if( funcInfo->nbInput == 0 ) return TA_INTERNAL_ERROR(2);

   allocSize = (funcInfo->nbInput) * sizeof(TA_ParamHolderInput);
   input = (TA_ParamHolderInput *)TA_Malloc( allocSize );

   if( !input )
   {
      TA_ParamHolderFree( newParams );
      *allocatedParams = NULL;
      return TA_ALLOC_ERR;
   }
   memset( input, 0, allocSize );
   newParamsPriv->in = input;

   if( funcInfo->nbOptInput == 0 )
      optInput = NULL;
   else
   {
      allocSize = (funcInfo->nbOptInput) * sizeof(TA_ParamHolderOptInput);
      optInput = (TA_ParamHolderOptInput *)TA_Malloc( allocSize );

      if( !optInput )
      {
         TA_ParamHolderFree( newParams );
         *allocatedParams = NULL;
         return TA_ALLOC_ERR;
      }
      memset( optInput, 0, allocSize );
   }
   newParamsPriv->optIn = optInput;

   allocSize = (funcInfo->nbOutput) * sizeof(TA_ParamHolderOutput);
   output = (TA_ParamHolderOutput *)TA_Malloc( allocSize );
   if( !output )
   {
      TA_ParamHolderFree( newParams );
      *allocatedParams = NULL;
      return TA_ALLOC_ERR;
   }
   memset( output, 0, allocSize );
   newParamsPriv->out = output;

   newParamsPriv->funcInfo = funcInfo;

   inputInfo    = (const TA_InputParameterInfo **)funcDef->input;
   optInputInfo = (const TA_OptInputParameterInfo **)funcDef->optInput;
   outputInfo   = (const TA_OutputParameterInfo   **)funcDef->output;

   for( i=0; i < funcInfo->nbInput; i++ )
   {
      input[i].inputInfo = inputInfo[i];
      newParamsPriv->inBitmap <<= 1;
      newParamsPriv->inBitmap |= 1;
   }

   for( i=0; i < funcInfo->nbOptInput; i++ )
   {
      optInput[i].optInputInfo = optInputInfo[i];
      if( optInput[i].optInputInfo->type == TA_OptInput_RealRange )
         optInput[i].data.optInReal = optInputInfo[i]->defaultValue;
      else
         optInput[i].data.optInInteger = (TA_Integer)optInputInfo[i]->defaultValue;
   }

   for( i=0; i < funcInfo->nbOutput; i++ )
   {
      output[i].outputInfo = outputInfo[i];
      newParamsPriv->outBitmap <<= 1;
      newParamsPriv->outBitmap |= 1;
   }

   /* Succcess, return the result to the caller. */
   *allocatedParams = newParams;

   return TA_SUCCESS;
}
示例#23
0
TA_RetCode TA_FuncTableAlloc( const char *group, TA_StringTable **table )
{
   TA_RetCode retCode;
   unsigned int i;
   TA_StringTable *stringTable;
   unsigned int groupId; /* TA_GroupId */
   unsigned int groupSize;
   const char *stringPtr;
   TA_StringTablePriv *stringTablePriv;

   if( (group == NULL) || (table == NULL ) )
   {
      return TA_BAD_PARAM;
   }

   *table = NULL;
   stringPtr = NULL;

   /* Get information on the group. */
   retCode = getGroupId( group, &groupId );
   if( retCode != TA_SUCCESS )
   {
      return retCode;
   }

   retCode = getGroupSize( (TA_GroupId)groupId, &groupSize );
   if( retCode != TA_SUCCESS )
   {
      return retCode;
   }

   /* Allocate the table. */

   stringTable = (TA_StringTable *)TA_Malloc( sizeof(TA_StringTable) + sizeof(TA_StringTablePriv) );
   if( !stringTable )
   {
      *table = NULL;
      return TA_ALLOC_ERR;
   }

   memset( stringTable, 0, sizeof(TA_StringTable) + sizeof(TA_StringTablePriv) );
   stringTablePriv = (TA_StringTablePriv *)(((char *)stringTable)+sizeof(TA_StringTable));
   stringTablePriv->magicNumber = TA_STRING_TABLE_FUNC_MAGIC_NB;
   stringTable->hiddenData = stringTablePriv;

   /* From this point, TA_FuncTableFree can be safely called. */
   stringTable->size = groupSize;
   if( groupSize != 0 )
   {
      stringTable->string = (const char **)TA_Malloc( (stringTable->size) *
                                                      sizeof(const char *) );

      if( stringTable->string == NULL )
      {
         *table = NULL;
         TA_FuncTableFree( stringTable );
         return TA_ALLOC_ERR;
      }

      memset( (void *)stringTable->string, 0,
              (stringTable->size) * sizeof(const char *) );

      for( i=0; i < stringTable->size; i++ )
      {
         retCode = getFuncNameByIdx( (TA_GroupId)groupId, i, &stringPtr );

         if( retCode != TA_SUCCESS )
         {
            *table = NULL;
            TA_FuncTableFree( stringTable );
            return TA_ALLOC_ERR;
         }

         (stringTable->string)[i] = stringPtr;
      }
   }

   /* Return the table to the caller. */
   *table = stringTable;

   return TA_SUCCESS;
}
示例#24
0
TA_RetCode TA_ReadOp_Do( TA_FileHandle       *fileHandle,
                         const TA_ReadOpInfo *readOpInfo,
                         TA_Period            period,
                         const TA_Timestamp  *start,
                         const TA_Timestamp  *end,
                         unsigned int         minimumNbBar,
                         TA_Field             fieldToAlloc,
                         TA_ParamForAddData  *paramForAddData,
                         unsigned int        *nbBarAdded )
{
   TA_PROLOG
   TA_RetCode retCode;
   TA_EstimateInfo estimationInfo;

   unsigned int nbElementToAllocate;
   unsigned int memoryNeeded; /* Boolean */
   unsigned int timeNeeded;   /* Boolean */

   TA_Real    *arrayReal[TA_REAL_ARRAY_SIZE];
   TA_Integer *arrayInteger[TA_INTEGER_ARRAY_SIZE];
   TA_Timestamp *timestamp;

   TA_Real *openBeg, *highBeg, *lowBeg, *closeBeg;
   TA_Integer *volumeBeg, *openInterestBeg;
   TA_Timestamp *timestampBeg;
   TA_Timestamp tmpTimestamp;

   TA_ReadOp op;

   TA_Field fieldToProcess;
   unsigned int year, month, day, hour, min, sec;
   TA_Integer curOp;

   unsigned int nbTotalByteDone, nbTotalBarDone;
   unsigned int nbBarAddedInTheBlock;

   char monthChar[4];
   char cnvtArray[CNVT_ARRAY_SIZE];
   unsigned int  cnvtArrayIdx;

   unsigned int nbByteToAllocReal;
   unsigned int nbByteToAllocInteger;

   unsigned int fileSize;
   unsigned int skipField;
   unsigned int lineToSkip;

   unsigned int nbByteRead;
   unsigned int nbLetter;

   TA_Real lastValidClose;

   const char *car;

   register TA_Real tmpReal;
   register TA_Integer tmpInt;
   register unsigned int tmpIdx;
   register unsigned int nbCharToRead;

   unsigned int lastOpFieldIncremented;
   TA_TRACE_BEGIN( TA_PriceBarRead );

   /* Initialization of local variables. */
   openBeg = highBeg = lowBeg = closeBeg = NULL;
   timestampBeg = NULL;
   volumeBeg = openInterestBeg = NULL;
   timestamp = NULL;
   retCode = TA_SUCCESS;
   lastValidClose = 0.0;

   fieldToProcess = readOpInfo->fieldProvided & fieldToAlloc;
   if( (fieldToProcess & fieldToAlloc) != fieldToAlloc )
   {
      /* Nothing to read because not all the requested
       * fields are provided by this data source!
       */
      return TA_SUCCESS;
   }

   /* Estimate the initial amount of memory to allocate. */
   fileSize = TA_FileSize( fileHandle );
   retCode = TA_EstimateAllocInit( start, end, period,                                   
                                   minimumNbBar, 2048,
                                   &estimationInfo,
                                   &nbElementToAllocate );
   if( retCode != TA_SUCCESS )
   {
      TA_TRACE_RETURN( retCode );
   }

   if( nbElementToAllocate == 0 )
   {
      TA_TRACE_RETURN( TA_SUCCESS ); /* Nothing to read!? Just return... */
   }

   memset( arrayInteger, 0, sizeof( arrayInteger ) );
   memset( arrayReal,    0, sizeof( arrayReal ) );

   /* Set the date/time pointers to where the information will be stored. */
   arrayInteger[TA_HOUR_IDX]  = (TA_Integer *)&hour;
   arrayInteger[TA_MIN_IDX]   = (TA_Integer *)&min;
   arrayInteger[TA_SEC_IDX]   = (TA_Integer *)&sec;
   arrayInteger[TA_MONTH_IDX] = (TA_Integer *)&month;
   arrayInteger[TA_YEAR_IDX]  = (TA_Integer *)&year;
   arrayInteger[TA_DAY_IDX]   = (TA_Integer *)&day;

   /* Set default time/date. */
   year  = 1900;
   month = day = 1;
   hour  = 23;
   min   = sec = 59;

   /* Check if the processing of the time will be needed. */
   timeNeeded = isTimeNeeded( readOpInfo->arrayReadOp);

   /* 'car' always point to the character being currently handled. */
   nbByteRead = 0;
   car = TA_FileSeqRead( fileHandle, &nbByteRead );
   if( (car == NULL) || (nbByteRead == 0) )
      return TA_SUCCESS; /* End of file! */
   --nbByteRead;

   nbTotalByteDone = 0;
   nbTotalBarDone  = 0;
   nbBarAddedInTheBlock = 0;
   memoryNeeded    = 1;
   curOp           = 0;
   skipField       = 0;

   monthChar[3] = '\0';

   /* When requested, skip header lines. */
   lineToSkip = readOpInfo->nbHeaderLineToSkip;
   while( lineToSkip-- )
   {
      while( *car != '\n' )
      {
         GET_CHAR;
         if( car == NULL )
            goto exit_loops;
      }
   }

line_loop: /* Always jump here when end-of-line is found (EOL). */

      /* If curOp != 0, the last operations are canceled. */
      REVERT_OPERATIONS;
      curOp = 0;
      lastOpFieldIncremented = 0;

      /* Start over a new line. */

      if( memoryNeeded )
      {
         /* Allocate the memory. */
         nbByteToAllocReal = nbElementToAllocate * sizeof( TA_Real );
         nbByteToAllocInteger = nbElementToAllocate * sizeof( TA_Integer );

         timestamp = (TA_Timestamp *)TA_Malloc( nbElementToAllocate * sizeof( TA_Timestamp ) );
         timestampBeg = timestamp;

         if( !timestampBeg )
         {
            retCode = TA_ALLOC_ERR;
            goto exit_loops;
         }

         #define TA_ALLOC_MEM(upperc,lowerc,typepar) \
         { \
            if( fieldToProcess & TA_##upperc ) \
            { \
               lowerc##Beg = (TA_##typepar *)TA_Malloc( nbByteToAlloc##typepar ); \
               array##typepar[TA_##upperc##_IDX] = lowerc##Beg; \
               if( !lowerc##Beg ) \
               { \
                  retCode = TA_ALLOC_ERR; \
                  goto exit_loops; \
               } \
            } \
         }
         TA_ALLOC_MEM( OPEN,  open,  Real );
         TA_ALLOC_MEM( HIGH,  high,  Real );
         TA_ALLOC_MEM( LOW,   low,   Real );
         TA_ALLOC_MEM( CLOSE, close, Real );

         TA_ALLOC_MEM( VOLUME, volume, Integer );
         TA_ALLOC_MEM( OPENINTEREST, openInterest, Integer );
         #undef TA_ALLOC_MEM

         memoryNeeded = 0;
      }

op_loop: /* Jump here when ready to proceed with the next command. */

      op = readOpInfo->arrayReadOp[curOp];

      if( !(op&TA_CMD_READ_MONTH_CHAR) )
      {
         /* Skip leading non-numeric character. */
         SKIP_UNTIL_NUMERIC;
      }

      /* Shall we skip this field? */
      if( TA_IS_SKIP_SET(op) )
      {
         if( (op&(TA_CMD_READ_REAL|TA_CMD_READ_INTEGER)) == 0 )
         {
            tmpInt = TA_GET_NB_NUMERIC(op);
            curOp++;
            while( tmpInt-- )
            {
               GET_CHAR;
               CHECK_EOL_EOF;
            }
         }
         else
         {
            if( skipField == 0 )
            {
               skipField = TA_GET_NB_NUMERIC(op);
               TA_ASSERT( skipField > 0 );
            }

            if( --skipField == 0 )
               curOp++;

            SKIP_NUMERIC;
            if( (op&TA_CMD_READ_REAL) && (*car == '.') )
            {
               GET_CHAR;
               CHECK_EOL_EOF;
               SKIP_NUMERIC;
            }
         }
      }
      else
      {
         cnvtArrayIdx = 0;

         if( TA_IS_REAL_CMD(op) )
         {
            /* Extract a numeric into cnvtArray. */
            READ_IN_CNVT_ARRAY;

            /* This is a TA_Real. */
            if( car && (*car == '.') )
            {
               /* Read rest of the float after the '.' */
               READ_IN_CNVT_ARRAY;
            }
            cnvtArray[cnvtArrayIdx] = '\0';
            tmpReal = atof( &cnvtArray[0] );

            /* Write the TA_Real in memory. */
            tmpIdx = TA_GET_IDX(op);
            TA_ASSERT( tmpIdx < TA_REAL_ARRAY_SIZE );
            TA_ASSERT( arrayReal[tmpIdx] != NULL );
            if( tmpReal != 0.0 )
            {
               *(arrayReal[tmpIdx]) = tmpReal;
               if( tmpIdx == TA_CLOSE_IDX )
                  lastValidClose = tmpReal;
            }
            else if( TA_IS_REPLACE_ZERO(op) )
            {
               /* Replace this zero value with the last known close.
                * If there is no previous close, this line is ignored.
                */
               if( lastValidClose != 0.0 )
                  *(arrayReal[tmpIdx]) = lastValidClose;
               else
               {
                  SKIP_LINE;
               }
            }
            else
            {
               /* Zero are not expected, consider this as a failure
                * and ignore all further data from this file.
                */
               retCode = TA_PRICE_BAR_CONTAINS_ZERO;
               goto exit_loops;
            }

            arrayReal[tmpIdx]++;
            curOp++;
         }
         else
         {
            /* This is a TA_Integer. */
            if( !(op&TA_CMD_READ_MONTH_CHAR) )
            {
               nbCharToRead = TA_GET_NB_NUMERIC(op);
               if( nbCharToRead )
               {
                  READ_N_CHAR_IN_CNVT_ARRAY(nbCharToRead);
               }
               else
               {
                  READ_IN_CNVT_ARRAY;
               }

               cnvtArray[cnvtArrayIdx] = '\0';
               tmpInt = atoi( &cnvtArray[0] );
            }
            else
            {
               /* Try to find a 3 letters month string. 
                * Translate it to a [1..12] integer.
                */
               nbLetter = 1;
               do
               {
                  CHECK_EOL_EOF;
                  monthChar[nbLetter] = (char)toupper(*car);
                  GET_CHAR;
                  nbLetter++;
               } while( nbLetter != 3 );
               
               do
               {
                  CHECK_EOL_EOF;
                  monthChar[0] = monthChar[1];
                  monthChar[1] = monthChar[2];
                  monthChar[2] = (char)toupper(*car);
                  if( strncmp("JAN",monthChar,3) == 0 )
                     tmpInt = 1;
                  else if( strncmp("FEB",monthChar,3) == 0 )
                     tmpInt = 2;
                  else if( strncmp("MAR",monthChar,3) == 0 )
                     tmpInt = 3;
                  else if( strncmp("APR",monthChar,3) == 0 )
                     tmpInt = 4;
                  else if( strncmp("MAY",monthChar,3) == 0 )
                     tmpInt = 5;
                  else if( strncmp("JUN",monthChar,3) == 0 )
                     tmpInt = 6;
                  else if( strncmp("JUL",monthChar,3) == 0 )
                     tmpInt = 7;
                  else if( strncmp("AUG",monthChar,3) == 0 )
                     tmpInt = 8;
                  else if( strncmp("SEP",monthChar,3) == 0 )
                     tmpInt = 9;
                  else if( strncmp("OCT",monthChar,3) == 0 )
                     tmpInt = 10;
                  else if( strncmp("NOV",monthChar,3) == 0 )
                     tmpInt = 11;
                  else if( strncmp("DEC",monthChar,3) == 0 )
                     tmpInt = 12;
                  else
                     tmpInt = 0;

                  GET_CHAR;
               } while( tmpInt == 0 );
            }

            /* Write the TA_Integer in memory. */
            tmpIdx = TA_GET_IDX(op);
            TA_ASSERT( tmpIdx < TA_INTEGER_ARRAY_SIZE );
            TA_ASSERT( arrayInteger[tmpIdx] != NULL );
            *(arrayInteger[tmpIdx]) = tmpInt;

            if( tmpIdx > TA_YEAR_IDX )
               arrayInteger[tmpIdx]++;
            curOp++;

            if( TA_IS_TIMESTAMP_COMPLETE(op) )
            {
               /* Build the timestamp. */
               retCode = TA_SetDate( year, month, day, &tmpTimestamp );
               if( retCode != TA_SUCCESS )
                  goto exit_loops; /* Invalid date */

               if( !timeNeeded )
               {
                  /* Ignore time in comparison and use default to build the price bar. */
                  tmpTimestamp.time = 23595900; /* Default EOD time */
                  if( start && (tmpTimestamp.date < start->date) )
                  {
                     /* This price bar is not needed, jump to the next line. */
                     retCode = TA_SUCCESS;
                     SKIP_LINE;
                  }

                  if( end && (tmpTimestamp.date > end->date) )
                  {
                     /* This price bar is beyond the upper limit, just exit. */
                     goto exit_loops;
                  }
               }
               else
               {
                  retCode = TA_SetTime( hour, min, sec, &tmpTimestamp );
                  if( retCode != TA_SUCCESS )
                     goto exit_loops; /* Invalid time */
                  if( start && TA_TimestampLess(&tmpTimestamp,start) )
                  {
                     /* This price bar is not needed, jump to the next line. */
                     retCode = TA_SUCCESS;
                     SKIP_LINE;
                  }

                  if( end && TA_TimestampGreater(&tmpTimestamp, end) )
                  {
                     /* This price bar is beyond the upper limit, just exit. */
                     goto exit_loops;
                  }
               }

               /* Write the timestamp in memory. */
               *timestamp = tmpTimestamp;
            }
         }

         if( TA_IS_READ_STOP_FLAG_SET(op) )
         {
            #ifdef DEBUG_PRINTF
               printf( "(%d%d%d,%e,%e,%e,%e,%d)\n",
                  timestampBeg?TA_GetYear(&timestampBeg[nbBarAddedInTheBlock]):0,
                  timestampBeg?TA_GetMonth(&timestampBeg[nbBarAddedInTheBlock]):0,
                  timestampBeg?TA_GetDay(&timestampBeg[nbBarAddedInTheBlock]):0,
                  openBeg?openBeg[nbBarAddedInTheBlock]:0.0,
                  highBeg?highBeg[nbBarAddedInTheBlock]:0.0,
                  lowBeg?lowBeg[nbBarAddedInTheBlock]:0.0,
                  closeBeg?closeBeg[nbBarAddedInTheBlock]:0.0,
                  volumeBeg?volumeBeg[nbBarAddedInTheBlock]:0 );
            #endif

            /* At this point, the price bar is completely written in memory. */
            timestamp++;
            curOp = 0;
            nbBarAddedInTheBlock++;
            if( nbBarAddedInTheBlock < nbElementToAllocate )
            {
              /* Go to next line. */
              SKIP_LINE;
            }
            else
            {
               /* There is not enough memory for another bar, so re-allocate
                * some more.
                */
               retCode = TA_HistoryAddData( paramForAddData, nbBarAddedInTheBlock,
                                            period, timestampBeg,
                                            openBeg, highBeg, lowBeg, closeBeg,
                                            volumeBeg, openInterestBeg );

               /* TA_HistoryAddData is ALWAYS the owner of these memory block
                * when called. So we set these to NULL to make sure there will
                * be no attempt to free these from this function.
                */
               openBeg = highBeg = lowBeg = closeBeg = NULL;
               timestampBeg = NULL;
               volumeBeg = openInterestBeg = NULL;
               nbTotalBarDone += nbBarAddedInTheBlock;
               nbBarAddedInTheBlock = 0;

               if( retCode != TA_SUCCESS )
                  goto exit_loops;

               retCode = TA_EstimateAllocNext( &estimationInfo, &nbElementToAllocate );
               if( retCode != TA_SUCCESS )
                  goto exit_loops;

               memoryNeeded = 1;
               SKIP_LINE;
            }
         }
         else
         {
            /* Make sure we did not hit an EOL or EOF prematurly, if yes,
             * this line will be silently ignored.
             */
            CHECK_EOL_EOF;
         }
      }

      goto op_loop;

exit_loops: /* Jump here when the end-of-file is hit (or an error occured) */

   /* On succesful exit, process possibly remaining data. */
   if( (retCode == TA_SUCCESS) && (nbBarAddedInTheBlock != 0) )
   {
      retCode = TA_HistoryAddData( paramForAddData, nbBarAddedInTheBlock,
                                   period, timestampBeg,
                                   openBeg, highBeg, lowBeg, closeBeg,
                                   volumeBeg, openInterestBeg );

      openBeg = highBeg = lowBeg = closeBeg = NULL;
      timestampBeg = NULL;
      volumeBeg = openInterestBeg = NULL;
      nbTotalBarDone += nbBarAddedInTheBlock;
   }
   
   /* ALWAYS verify if locally allocated memory needs to be freed. ALWAYS. */
   FREE_IF_NOT_NULL( openBeg );
   FREE_IF_NOT_NULL( highBeg );
   FREE_IF_NOT_NULL( lowBeg );
   FREE_IF_NOT_NULL( closeBeg );
   FREE_IF_NOT_NULL( volumeBeg );
   FREE_IF_NOT_NULL( openInterestBeg );
   FREE_IF_NOT_NULL( timestampBeg );

   /* An indication that no more data needs to be provided is not a failure. */
   if( retCode == TA_ENOUGH_DATA )
      retCode = TA_SUCCESS;

   /* Return the number of added price bar to the caller. */
   if( nbBarAdded )
      *nbBarAdded = nbTotalBarDone;

   TA_TRACE_RETURN( retCode );
}
示例#25
0
/**** Global functions definitions.   ****/
TA_RetCode TA_GetHistoryDataFromWeb( TA_Libc *libHandle,
                                     TA_DataSourceHandle *handle,
                                     TA_CategoryHandle   *categoryHandle,
                                     TA_SymbolHandle     *symbolHandle,
                                     TA_Period            period,
                                     const TA_Timestamp  *start,
                                     const TA_Timestamp  *end,
                                     TA_Field             fieldToAlloc,
                                     TA_ParamForAddData  *paramForAddData )
{
   TA_PROLOG;

   TA_RetCode retCode;
   TA_StringCache *stringCache;
   TA_String *yahooName;
   TA_WebPage *webPage;
   TA_PrivateYahooHandle *yahooHandle;
   TA_DecodingParam localDecodingParam;
   const TA_DecodingParam *decodingParam;
   TA_FileHandle *fileHandle;
   TA_ReadOpInfo *readOpInfo;
   UIRSuffixParsing suffixParsing;
   TA_Timestamp firstBarTimestamp, lastBarTimestamp, prevEndDate;
   TA_InfoFromAddedData infoFromAddedData;
   TA_DayOfWeek dayOfWeek;

   int nbEstimateBar;
   int nbField;
   unsigned int nbBarAdded, nbTotalBarAdded;
   int again, firstTime, nbBatch;
   int zeroBarAddedAttempt;

   TA_TRACE_BEGIN( libHandle, TA_GetHistoryDataFromWeb );

   /* Initialize some local variables. */
   stringCache   = TA_GetGlobalStringCache( libHandle );
   yahooHandle   = (TA_PrivateYahooHandle *)handle->opaqueData;
   readOpInfo    = NULL;
   nbEstimateBar = 0;

   TA_ASSERT( libHandle, categoryHandle != NULL );
   TA_ASSERT( libHandle, symbolHandle != NULL );
   TA_ASSERT( libHandle, categoryHandle->string != NULL );
   TA_ASSERT( libHandle, symbolHandle->string != NULL );

   /* Set the initial first/last timestamp */
   if( start )
      TA_TimestampCopy( &firstBarTimestamp, start );
   else
   {
      TA_SetDate( 1950, 1, 1, &firstBarTimestamp );
      TA_SetTime( 0, 0, 0, &firstBarTimestamp );
   }

   if( end )
      TA_TimestampCopy( &lastBarTimestamp, end );
   else
   {
      TA_SetDateNow( &lastBarTimestamp );
      TA_SetTime( 0, 0, 0, &lastBarTimestamp );
   }

   /* Make sure that lastBarTimestamp is a week-day. */
   dayOfWeek = TA_GetDayOfTheWeek( &lastBarTimestamp );
   if( (dayOfWeek == TA_SUNDAY) || (dayOfWeek == TA_SATURDAY) )
      TA_PrevWeekday( &lastBarTimestamp );

   /* Map the TA-Lib name into the Yahoo! name. */
   retCode = TA_AllocStringFromLibName( libHandle,
                                        categoryHandle->string,
                                        symbolHandle->string,
                                        &yahooName );  
   if( retCode != TA_SUCCESS )
   {
      TA_TRACE_RETURN( retCode );
   }

   TA_ASSERT( libHandle, yahooName != NULL );
   TA_ASSERT( libHandle, yahooHandle != NULL );

   /* Get the decoding parameter for the CSV web page. */
   decodingParam = TA_YahooIdxDecodingParam( yahooHandle->index, TA_YAHOOIDX_CVS_PAGE );
   if( !decodingParam )
   {
      TA_StringFree( stringCache, yahooName );
      TA_TRACE_RETURN( TA_INTERNAL_ERROR(103) );
   }

   /* Use a local copy of the decoding param. 
    * This is because the uirSuffix is replaced with
    * an allocated buffer (so the date field can be
    * manipulated).
    */
   localDecodingParam = *decodingParam;

   /* Parse the uirSuffix so the start/end date can be changed. */
   if( !setUIRSuffixParsing( decodingParam->uirSuffix, &suffixParsing ) )
   {
      /* This should never happen unless the
       * Yahoo! index protocol has been broken.
       */
      /* Clean-up and exit */
      TA_StringFree( stringCache, yahooName );
      TA_TRACE_RETURN( TA_INTERNAL_ERROR(104) );
   }

   /* Replace the uirSuffix with a large local buffer. */
   localDecodingParam.uirSuffix = TA_Malloc( libHandle, suffixParsing.maxTotalLength );
   if( !localDecodingParam.uirSuffix )
   {
      /* Clean-up and exit */
      TA_StringFree( stringCache, yahooName );
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }

   /* Change the dates in the uirSuffix. */
   buildUIRSuffix( &suffixParsing,
                   &firstBarTimestamp, &lastBarTimestamp,
                   (char *)localDecodingParam.uirSuffix );

   /* nbBatch is a safety net to make sure that
    * TA-Lib won't stay forever in the while loop
    * in case Yahoo! changes their protocol.
    */
   nbBatch = 0; 

   /* Sometime Yahoo! return an empty csv file. Make
    * multiple attempts in that case.
    */
   zeroBarAddedAttempt = 0;

   again = 1;
   firstTime = 1;
   nbTotalBarAdded = 0;
   while( again && (++nbBatch < 100) && (zeroBarAddedAttempt < 10) )
   {  
    
      if( TA_TimestampLess(&lastBarTimestamp,&firstBarTimestamp) )
      {
          /* Get out of this loop if all the requested data
           * has been retreived already.
           */
         again = 0;
         break;
      }   

      retCode = TA_WebPageAllocFromYahooName( libHandle,
                                              &localDecodingParam,
                                              TA_StringToChar(yahooName),
                                              &webPage );
           
      if( retCode != TA_SUCCESS )
      {
         TA_StringFree( stringCache, yahooName );
         TA_Free( libHandle, (char *)localDecodingParam.uirSuffix );
         TA_TRACE_RETURN( retCode );
      }

      /* Disguise the webPage stream into a "file". That way the speed
       * optimized ASCII decoder can be re-used (TA_ReadOp stuff).
       */
      retCode = TA_FileSeqOpenFromStream( libHandle, webPage->content, &fileHandle );
      if( retCode != TA_SUCCESS )
      {
         /* Clean-up and exit */
         TA_StringFree( stringCache, yahooName );
         TA_WebPageFree( webPage );
         TA_Free( libHandle, (char *)localDecodingParam.uirSuffix );
         TA_TRACE_RETURN( retCode );
      }

      if( firstTime )
      {
         /* Make assumption of the data provided
          * base on the number of fields in the CSV file.
          */
         nbField = nbCommaField( webPage->content );
         switch( nbField )
         {
         case 2:
            readOpInfo = yahooHandle->readOp2Fields;
            break;
         case 5:
            readOpInfo = yahooHandle->readOp5Fields;
            break;
         default:
            readOpInfo = yahooHandle->readOp6Fields;
         }

         /* User asking for all the fields? */
         if( fieldToAlloc == TA_ALL )
         {
            switch( nbField )
            {
            case 2:
               fieldToAlloc = TA_CLOSE|TA_TIMESTAMP;
               break;
            case 5:
               fieldToAlloc = TA_OPEN|TA_HIGH|TA_LOW|TA_CLOSE|TA_TIMESTAMP;
               break;
            default:
               fieldToAlloc = TA_OPEN|TA_HIGH|TA_LOW|TA_CLOSE|TA_VOLUME|TA_TIMESTAMP;
            }
         }

         /* Optimize the read op for the requested data. */
         retCode = TA_ReadOp_Optimize( libHandle,
                                       readOpInfo,
                                       period,
                                       fieldToAlloc );
         if( retCode != TA_SUCCESS )
         {
            /* Clean-up and exit */
            TA_StringFree( stringCache, yahooName );
            TA_WebPageFree( webPage );
            TA_Free( libHandle, (char *)localDecodingParam.uirSuffix );
            TA_TRACE_RETURN( retCode );
         }

         /* Make an estimation of the number of price bar. */
         nbEstimateBar  = TA_StreamCountChar( webPage->content, '\n' ) + 1;
         if( nbEstimateBar < 100 )
            nbEstimateBar = 100;
      }

      /* Interpret the CSV data. */
      retCode = TA_ReadOp_Do( libHandle, fileHandle,                           
                              readOpInfo,
                              period, &firstBarTimestamp, &lastBarTimestamp,
                              nbEstimateBar, fieldToAlloc,
                              paramForAddData,
                              &nbBarAdded );

      TA_FileSeqClose( libHandle, fileHandle );
      TA_WebPageFree( webPage );

      nbTotalBarAdded += nbBarAdded;

      if( retCode != TA_SUCCESS )
      {
         /* Clean-up and exit */
         TA_StringFree( stringCache, yahooName );
         TA_Free( libHandle, (char *)localDecodingParam.uirSuffix );
         TA_TRACE_RETURN( retCode );
      }

      /* Yahoo! does not always return all the data it could, up to
       * the requested end date. It is important to detect these occurence
       * and cancel the usage of all data accumulated up to now. 
       */      
      TA_GetInfoFromAddedData( paramForAddData, &infoFromAddedData );
      if( infoFromAddedData.barAddedSinceLastCall )
      {
         /* Do some more checking by considering holidays, week-end etc... */
         if( !isGapAcceptable(&infoFromAddedData.highestTimestampAddedSinceLastCall, &lastBarTimestamp) )
         {
            /* Clean-up and exit */
            TA_StringFree( stringCache, yahooName );
            TA_Free( libHandle, (char *)localDecodingParam.uirSuffix );
            TA_TRACE_RETURN( TA_DATA_GAP );
         }
         
         TA_TimestampCopy( &lastBarTimestamp, &infoFromAddedData.lowestTimestamp );
      }

      #if DEBUG_PRINTF
      printf( "NB BAR ADDED=%d, TOTAL=%d\n", nbBarAdded, nbTotalBarAdded );
      #endif

      /* Verify if more data should be processed. 
       * Yahoo! sometimes slice their data, in 
       * batch of 200 price bars. 
       */
      if( firstTime && (nbBarAdded > 200) )
      {
         again = 0; /* Assume all the data extracted... exit the loop. */
      }
      else if( nbBarAdded == 0 )
      {
         /* Make multiple attempts when retreiving data succeed,
          * but somehow there is zero bar returned. 
          *
          * Sometimes this might be correct when there is truly no
          * more data available, so choosing an algorithm before
          * giving up is a comprimise between reliability and
          * usability. The data source is free... and you get
          * what you pay for after all ;)
          */
         if( (nbTotalBarAdded < 1000) && (zeroBarAddedAttempt >= 1) && (zeroBarAddedAttempt < 7) )
         {
            /* I did choose to add a delay when insufficient total data is returned. When
             * there is already ~5 years of data, most likely there is "Zero" returned
             * because there is NO more data available, so just do the retry without delay.
             */
            TA_Sleep(zeroBarAddedAttempt*2);
         }

         #if DEBUG_PRINTF
         printf( "Retry %d", zeroBarAddedAttempt );
         #endif

         zeroBarAddedAttempt++;
      }
      else
      {
         zeroBarAddedAttempt = 0;

         if( TA_TimestampEqual( &lastBarTimestamp, &prevEndDate ) )
         {
            /* prevEndDate is a "safety net" to
             * exit the loop early in case Yahoo! starts
             * to return always the same batch of data.
             * Just ignore the repetitive data and exit.
             */
            TA_Free( libHandle, (char *)localDecodingParam.uirSuffix );
            TA_StringFree( stringCache, yahooName );
            TA_TRACE_RETURN( TA_SUCCESS );
         }
         TA_TimestampCopy( &prevEndDate, &lastBarTimestamp );

         /* Request the data up to the day BEFORE
          * the last batch of data received.
          */
         TA_PrevDay( &lastBarTimestamp );

         /* Make sure that lastBarTimestamp is a week-day. */
         dayOfWeek = TA_GetDayOfTheWeek( &lastBarTimestamp );
         if( (dayOfWeek == TA_SUNDAY) || (dayOfWeek == TA_SATURDAY) )
            TA_PrevWeekday( &lastBarTimestamp );

         /* Change the dates in the uirSuffix. */
         buildUIRSuffix( &suffixParsing,
                         &firstBarTimestamp, &lastBarTimestamp,
                         (char *)localDecodingParam.uirSuffix );

         /* From that point, data is expected to be most likely
          * sent in batch of 200.
          */
         nbEstimateBar = 200;
      }

      firstTime = 0;
   }

   /* Clean-up and exit */
   TA_Free( libHandle, (char *)localDecodingParam.uirSuffix );
   TA_StringFree( stringCache, yahooName );
   TA_TRACE_RETURN( retCode );
}
示例#26
0
TA_RetCode TA_FileSeqOpen( const char *path, TA_FileHandle **handle )
{
   TA_PROLOG
   TA_FileHandlePriv *fileHandlePriv;

   TA_TRACE_BEGIN(  TA_FileSeqOpen );

   TA_ASSERT( path != NULL );
   TA_ASSERT( handle != NULL );

   fileHandlePriv = (TA_FileHandlePriv *)TA_Malloc( sizeof( TA_FileHandlePriv ) );
   if( !fileHandlePriv )
   {
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }
   memset( fileHandlePriv, 0, sizeof( TA_FileHandlePriv ) );

   #if defined( USE_WIN32_API )
   fileHandlePriv->handle = CreateFile( path, GENERIC_READ, FILE_SHARE_READ,
                                        NULL, OPEN_EXISTING,
                                        FILE_FLAG_NO_BUFFERING|FILE_FLAG_SEQUENTIAL_SCAN,
                                        NULL );

   if( fileHandlePriv->handle == INVALID_HANDLE_VALUE )
   {
      TA_FileSeqClose( (TA_FileHandle *)fileHandlePriv );
      TA_TRACE_RETURN( TA_ACCESS_FAILED );
   }
   #else
   /* For all non-win32 platform, use standard ANSI C I/O */
   fileHandlePriv->handle = fopen( path, "rb" );

   if( fileHandlePriv->handle == 0 )
   {
      TA_FileSeqClose( (TA_FileHandle *)fileHandlePriv );
      TA_TRACE_RETURN( TA_ACCESS_FAILED );
   }
   #endif

   /* Allocate buffer memory. */
   #if defined( USE_WIN32_API )
      fileHandlePriv->allocBuffer = allocDiskBuffer( path, &fileHandlePriv->allocBufferSize );
      if( !fileHandlePriv->allocBuffer || (fileHandlePriv->allocBufferSize == 0) )
      {
         TA_FileSeqClose( (TA_FileHandle *)fileHandlePriv );
         TA_TRACE_RETURN( TA_ACCESS_FAILED );
      }
   #else
      fileHandlePriv->allocBuffer = TA_Malloc( FILE_BUFFER_SIZE );
      fileHandlePriv->allocBufferSize = FILE_BUFFER_SIZE;
      if( !fileHandlePriv->allocBuffer )
      {
         TA_FileSeqClose( (TA_FileHandle *)fileHandlePriv );
         TA_TRACE_RETURN( TA_ACCESS_FAILED );
      }
   #endif

   /* Keep a ptr on the path. */
   fileHandlePriv->path = path;

   /* Success! Return the info to the caller. */
   *handle = (TA_FileHandle *)fileHandlePriv;
   TA_TRACE_RETURN( TA_SUCCESS );
}
示例#27
0
TA_RetCode TA_DirectoryAlloc( const char *path,
                              TA_Directory **directory )
{
   #if defined( USE_WIN32_API )
   HANDLE handle;
   WIN32_FIND_DATA data;
   DWORD win32Error;
   #endif

   #if defined( USE_OSLAYER )
   DIRST dirHandle;
   const char *filePattern;
   char *basePath;
   #endif

   unsigned pathLength;

   int findNextRetCode;

   TA_Directory *dir;
   TA_String *string;
   TA_RetCode retCode;
   TA_SystemGlobal *global;

   const char   *entryName;
   unsigned int  entryIsDirectory;

   *directory = NULL;

   if( (path == NULL) || (directory == NULL) )
      return TA_BAD_PARAM;

   retCode = TA_GetGlobal(  &TA_SystemGlobalControl, (void **)&global );
   if( retCode != TA_SUCCESS )
      return retCode;

   dir = (TA_Directory *)TA_Malloc( sizeof( TA_Directory ) );

   if( dir == NULL )
      return TA_ALLOC_ERR;

   dir->nbFile = 0;
   dir->nbDirectory = 0;

   dir->listOfFile = TA_ListAlloc();
   dir->listOfDirectory = TA_ListAlloc();

   if( (dir->listOfFile == NULL) || (dir->listOfDirectory == NULL) )
   {
      TA_DirectoryFree( dir );
      return TA_ALLOC_ERR;
   }

   /* Verify that the path is valid. */
   pathLength = strlen( path );

   if( (pathLength == 0) || (pathLength >= MAX_PATH) )
   {
      TA_DirectoryFree( dir );
      return TA_BAD_PARAM;
   }

   /* Now get the directory from the operating system. */
   #if defined( USE_WIN32_API )

   handle = FindFirstFile( path, &data );
   if( handle == INVALID_HANDLE_VALUE )
   {
      win32Error = GetLastError();
      global->lastError = win32Error;

      if( (win32Error != ERROR_FILE_NOT_FOUND) &&
          (win32Error != ERROR_PATH_NOT_FOUND) )
      {
         TA_DirectoryFree( dir );
         return TA_ACCESS_FAILED;
      }

      /* No files or directory... but still have to pass the result
       * to the caller.
       */
      *directory = dir;

      return TA_SUCCESS;
   }

   entryName = data.cFileName;
   entryIsDirectory = data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
   #endif

   #if defined( USE_OSLAYER )
   /* Split the path into the basePath and the filePattern. */
   basePath = TA_Malloc( pathLength+1 ); 
   memcpy( basePath, path, pathLength+1 );
   filePattern = split_path_and_file( basePath );

   if( !filePattern )
   {
      /* With no filePattern, no file can be found...
       * so return an empty directory to the caller.
       */
      *directory = dir;
      TA_Free(  basePath );
      return TA_SUCCESS;
   }

   /* Look for last separetor. */
   if( !open_dir(&dirHandle, basePath ) )
   {
      /* Errors, or no files or no directory... but
       * still have to pass the result to the caller.
       */      
      TA_Free(  basePath );
      *directory = dir;
      return TA_SUCCESS;
   }

   entryName = dirHandle.file_name;
   entryIsDirectory = dirHandle.file_attrs & ATTR_SUBDIR;
   #endif

   do
   {
      #if defined( USE_OSLAYER )
      if( file_matches( entryName, filePattern ) )
      {
      #endif
         if( entryIsDirectory )
         {
            if( entryName[0] != '.' )
            {
               string = TA_StringAlloc( global->dirnameCache, entryName );

               if( string == NULL )
               {
                  #if defined( USE_OSLAYER )
                     close_dir(&dirHandle);
                     TA_Free(  basePath );
                  #endif
                  TA_DirectoryFree( dir );
                  return TA_ALLOC_ERR;
               }

               retCode = TA_ListAddTail( dir->listOfDirectory, (void *)string );

               if( retCode != TA_SUCCESS )
               {
                  #if defined( USE_OSLAYER )
                     close_dir(&dirHandle);
                     TA_Free(  basePath );
                  #endif
                  TA_DirectoryFree( dir );
                  return retCode;
               }
               dir->nbDirectory++;
            }
         }
         else
         {
            string = TA_StringAlloc( global->filenameCache, entryName );

            if( string == NULL )
            {
               #if defined( USE_OSLAYER )
                  close_dir(&dirHandle);
                  TA_Free(  basePath );
               #endif
               TA_DirectoryFree( dir );
               return TA_ALLOC_ERR;
            }

            retCode = TA_ListAddTail( dir->listOfFile, (void *)string );

            if( retCode != TA_SUCCESS )
            {
               #if defined( USE_OSLAYER )
                  close_dir(&dirHandle);
                  TA_Free(  basePath );
               #endif
               TA_DirectoryFree( dir );
               return retCode;
            }
            dir->nbFile++;
         }
      #if defined( USE_OSLAYER )
      }
      #endif
      
      #if defined( USE_WIN32_API )
      findNextRetCode = FindNextFile( handle, &data );
      entryName = data.cFileName;
      entryIsDirectory = data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
      #endif

      #if defined( USE_OSLAYER )
      findNextRetCode = read_dir( &dirHandle );
      entryName = dirHandle.file_name;
      entryIsDirectory = dirHandle.file_attrs & ATTR_SUBDIR;
      #endif
   }
   while( findNextRetCode == TRUE );


   #if defined( USE_OSLAYER )
   TA_Free(  basePath );
   if( !close_dir(&dirHandle) )
   {
      TA_DirectoryFree( dir );
      return TA_INTERNAL_ERROR(11);
   }
   #endif

   #if defined( USE_WIN32_API )   
   if( FindClose( handle ) != TRUE )
   {
      global->lastError = GetLastError();
      TA_DirectoryFree( dir );
      return TA_INTERNAL_ERROR(12);
   }
   #endif

   /* Pass the result to the caller. */
   *directory = dir;

   return TA_SUCCESS;
}
示例#28
0
/**** Global functions definitions.   ****/
TA_RetCode TA_FileIndexParsePath( TA_FileIndexPriv *fileIndexPriv, TA_String *path )
{
   typedef enum { INIT_PROCESSING,
                  FIX_PROCESSING,
                  FIELD_PROCESSING,
                  WILD_PROCESSING,
                  SEP_PROCESSING } State;

   TA_PROLOG
   State currentState;
   const char *currentTokenStart;
   unsigned int length;
   char *str;
   char *pos;
   char sepTmp[2];
   TA_RetCode retCode;
   unsigned int tokenSize;
   TA_TokenId tokenId;
   const char *sourcePattern;

   TA_TRACE_BEGIN(  TA_FileIndexParsePath );

   TA_ASSERT( path != NULL );

   sepTmp[1] = '\0';
   sourcePattern = TA_StringToChar( path );

   /* The following macro should help for the readability of the parsing logic.
    * These macro are used only inside this function.
    */
   #define RETURN(y) {TA_Free(str); TA_TRACE_RETURN( y );}
   #define REJECT_STATE(x,y) { if(currentState==x)RETURN(y);  }
   #define CHANGE_STATE(x) {currentState=x; currentTokenStart=pos+1;}

   #define ADD_TOKEN(id,value) \
   { \
      retCode = addToken(fileIndexPriv,id,value); \
      if( retCode != TA_SUCCESS) RETURN(retCode); \
   }

   #define FLUSH_FIX() \
   { \
      retCode = flushFixPart(fileIndexPriv,currentTokenStart,pos); \
      if( retCode != TA_SUCCESS ) RETURN(retCode); \
   }

   /* This function build a list representing the tokens
    * of the sourcePattern.
    *
    * Example:  "C:\a\*AZD?\[S]\data.txt" becomes
    *
    *            TokenId      Value
    *            TA_TOK_FIX       "C:"
    *            TA_TOK_SEP       "\"
    *            TA_TOK_FIX       "a"
    *            TA_TOK_SEP       "\"
    *            TA_TOK_WILD      "*"
    *            TA_TOK_FIX       "AZD"
    *            TA_TOK_WILD_CHAR "?"
    *            TA_TOK_SEP       "\"
    *            TA_TOK_S         "?*"
    *            TA_TOK_SEP       "\"
    *            TA_TOK_FIX       "data.txt"
    *            TA_TOK_END       (null)
    *
    *        In the values, the '?' and '*' character represent MS-DOS kind
    *        of wildcards:
    *             '?' is any character (but only one).
    *             '*' zero or more of any character
    */
   if( sourcePattern == NULL )
      return TA_INVALID_PATH;

   length = strlen( sourcePattern ) + 1;

   if( (length <= 1) || (length > 2048) )
      return TA_INVALID_PATH;

   str = (char *)TA_Malloc( length );
   strcpy( str, sourcePattern );

   pos = str;
   currentState = INIT_PROCESSING;
   currentTokenStart = pos;

   while( *pos != '\0' )
   {

      if( (*pos == '\\') || (*pos == '/') )
      {
         /* Handle directories separator character. */
         REJECT_STATE( FIELD_PROCESSING, TA_INVALID_FIELD );
         REJECT_STATE( SEP_PROCESSING, TA_INVALID_PATH );

         FLUSH_FIX();

#if 0
!!! Needed?
         /* Check that the string prior to the separator
          * does not terminate with a dot '.'
          */
         if( currentState != INIT_PROCESSING )
         {
            if( *(pos-1) == '.' )
               RETURN( TA_INVALID_PATH );
         }
#endif
         /* Transform into the directory delimiter
          * used on the host file system.
          */
         sepTmp[0] = (char)TA_SeparatorASCII();
         ADD_TOKEN( TA_TOK_SEP, sepTmp );

         CHANGE_STATE( SEP_PROCESSING );
      }
      else switch( *pos )
示例#29
0
/**** Local functions definitions.     ****/
static TA_RetCode rangeTestFunction( TA_Integer    startIdx,
                                     TA_Integer    endIdx,
                                     TA_Real      *outputBuffer,
                                     TA_Integer   *outputBufferInt,
                                     TA_Integer   *outBegIdx,
                                     TA_Integer   *outNbElement,
                                     TA_Integer   *lookback,
                                     void         *opaqueData,
                                     unsigned int  outputNb,
                                     unsigned int *isOutputInteger )
{
   TA_RetCode retCode;
   TA_RangeTestParam *testParam;
   double *dummyBuffer;

   (void)outputNb;
   (void)outputBufferInt;
  
   *isOutputInteger = 0;

   testParam = (TA_RangeTestParam *)opaqueData;   

   /* Allocate a buffer for the output who is going
    * to be ignored (make it slightly larger to play
    * safe)
    */
   dummyBuffer = TA_Malloc( sizeof(double) * (endIdx-startIdx+100) );
   switch( testParam->test->theFunction )
   {
   case TA_AROON_UP_TEST:
      retCode = TA_AROON( startIdx,
                          endIdx,
                          testParam->high,
                          testParam->low,
                          testParam->test->optInTimePeriod,
                          outBegIdx,
                          outNbElement,                          
                          &dummyBuffer[20],
                          outputBuffer );

      *lookback = TA_AROON_Lookback( testParam->test->optInTimePeriod );
      break;
   case TA_AROON_DOWN_TEST:
      retCode = TA_AROON( startIdx,
                          endIdx,
                          testParam->high,
                          testParam->low,
                          testParam->test->optInTimePeriod,
                          outBegIdx,
                          outNbElement,
                          outputBuffer,
                          &dummyBuffer[20]
                        );
      *lookback = TA_AROON_Lookback( testParam->test->optInTimePeriod );
      break;
   case TA_AROONOSC_TEST:
      retCode = TA_AROONOSC( startIdx,
                             endIdx,
                             testParam->high,
                             testParam->low,
                             testParam->test->optInTimePeriod,
                             outBegIdx,
                             outNbElement,
                             outputBuffer );
      *lookback = TA_AROONOSC_Lookback( testParam->test->optInTimePeriod );
      break;
   case TA_CORREL_TEST:
      retCode = TA_CORREL( startIdx,
                           endIdx,
                           testParam->high,
                           testParam->low,
                           testParam->test->optInTimePeriod,
                           outBegIdx,
                           outNbElement,
                           outputBuffer );
      *lookback = TA_CORREL_Lookback( testParam->test->optInTimePeriod );
      break;

   default:
      retCode = TA_INTERNAL_ERROR(132);
   }

   TA_Free( dummyBuffer );

   return retCode;
}
示例#30
0
/**** Local functions definitions.     ****/
static TA_RetCode rangeTestFunction( TA_Libc *libHandle, 
                              TA_Integer startIdx,
                              TA_Integer endIdx,
                              TA_Real *outputBuffer,
                              TA_Integer *outBegIdx,
                              TA_Integer *outNbElement,
                              TA_Integer *lookback,
                              void *opaqueData,
                              unsigned int outputNb )
{
  TA_RetCode retCode;
  TA_RangeTestParam *testParam;
  TA_Real *dummyOutput;
  
  testParam = (TA_RangeTestParam *)opaqueData;   


  dummyOutput = TA_Malloc( libHandle, (endIdx-startIdx+1) * sizeof(TA_Real) );

  if( outputNb == 0 )
  {
     retCode = TA_STOCH( libHandle,
                         startIdx,
                         endIdx,
                         testParam->high,
                         testParam->low,
                         testParam->close,
                         testParam->test->optInKPeriod_0,
                         testParam->test->optInKSlowPeriod_1,
                         testParam->test->optInDPeriod_2,
                         testParam->test->optInMethod_3,                       
                         outBegIdx, outNbElement,
                         outputBuffer,
                         dummyOutput );

   }
   else
   {
     retCode = TA_STOCH( libHandle,
                         startIdx,
                         endIdx,
                         testParam->high,
                         testParam->low,
                         testParam->close,
                         testParam->test->optInKPeriod_0,
                         testParam->test->optInKSlowPeriod_1,
                         testParam->test->optInDPeriod_2,
                         testParam->test->optInMethod_3,                                                
                         outBegIdx, outNbElement,
                         dummyOutput, 
                         outputBuffer );
   }

   TA_Free( libHandle, dummyOutput );

   *lookback = TA_STOCH_Lookback( testParam->test->optInKPeriod_0,
                         testParam->test->optInKSlowPeriod_1,
                         testParam->test->optInDPeriod_2,
                         testParam->test->optInMethod_3 );

   return retCode;
}