static TA_RetCode freeListAndElement( TA_Libc *libHandle, TA_List *list, TA_RetCode (*freeFunc)( TA_Libc *libHandle, void *toBeFreed ) )
{
   TA_PROLOG;
   TA_RetCode retCode;
   void *node;

   TA_TRACE_BEGIN( libHandle, freeListAndElement );

   if( list != NULL )
   {
      while( (node = TA_ListRemoveTail( list )) != NULL )
      {
         retCode = freeFunc( libHandle, node );
         if( retCode != TA_SUCCESS )
         {
            TA_FATAL( libHandle, NULL, node, retCode );
            TA_TRACE_RETURN( TA_ALLOC_ERR );
         }
      }

      retCode = TA_ListFree( list );
      if( retCode != TA_SUCCESS )
      {
         TA_FATAL( libHandle, NULL, list, retCode );
         TA_TRACE_RETURN( TA_ALLOC_ERR );
      }
   }

   TA_TRACE_RETURN( TA_SUCCESS );
}
Beispiel #2
0
TA_RetCode TA_FileSeqClose( TA_FileHandle *handle )
{
   TA_PROLOG
   TA_RetCode retCode;
   TA_FileHandlePriv *fileHandlePriv;
   TA_SystemGlobal *global;
   #if defined( USE_WIN32_API )
   DWORD win32Error;
   BOOL retValue;
   #endif

   TA_TRACE_BEGIN(  TA_FileSeqClose );

   retCode = TA_GetGlobal(  &TA_SystemGlobalControl, (void **)&global );
   if( retCode != TA_SUCCESS )
   {
      TA_TRACE_RETURN( retCode );
   }

   TA_ASSERT( handle != NULL );

   fileHandlePriv = (TA_FileHandlePriv *)handle;

   if( fileHandlePriv )
   {
      #if defined( USE_WIN32_API )
         if( fileHandlePriv->handle != INVALID_HANDLE_VALUE )
         {
            retValue = CloseHandle( fileHandlePriv->handle );
            if( retValue == 0 )
            {
               win32Error = GetLastError();
               global->lastError = win32Error;
               TA_FATAL(  NULL, 0, win32Error );
            }
         }
         if( fileHandlePriv->allocBuffer )
         {
            freeDiskBuffer( fileHandlePriv->allocBuffer,
                            fileHandlePriv->allocBufferSize );
         }
      #endif

      #if defined( USE_OSLAYER )
         if( fileHandlePriv->handle != NULL )
            fclose( fileHandlePriv->handle );
         if( fileHandlePriv->allocBuffer )
            TA_Free(  fileHandlePriv->allocBuffer );
      #endif

      if( fileHandlePriv->streamAccess )
      {
         TA_StreamAccessFree( fileHandlePriv->streamAccess );
      }

      TA_Free(  fileHandlePriv );
   }

   TA_TRACE_RETURN( TA_SUCCESS );
}
TA_RetCode TA_FileIndexMoveToPrevToken( TA_FileIndexPriv *data )
{
   TA_PROLOG;
   TA_Libc *libHandle;
   TA_RetCode retCode;

   if( !data )
      return TA_UNKNOWN_ERR;

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

   if( data->curToken == NULL )
   {
      /* Iterator variable not initialize. Simply position everything on the
       * first token.
       */
      retCode = TA_FileIndexMoveToNextToken( data );
      TA_TRACE_RETURN( retCode ); 
   }
   else if( data->prevToken == NULL )
   {
      /* Can't go further back. Simply return. */
      TA_TRACE_RETURN( TA_SUCCESS );
   }
   else
   {
      if( data->curDirectionForward == 1 )
      {
         if( data->nextToken != NULL )
            TA_ListAccessPrev( data->listLocationToken );
         else
            TA_ListAccessTail( data->listLocationToken );

         TA_ListAccessPrev( data->listLocationToken );
         data->curDirectionForward = 0;
      }

      data->nextToken = data->curToken;
      data->curToken = data->prevToken;
      data->prevToken = (TA_TokenInfo *)TA_ListAccessPrev( data->listLocationToken );

      /* Parano test: Should never happen since the code assume that
       * the 'listLocationToken' is always terminated by TA_END.
       */
      if( !data->curToken )
      {
         TA_FATAL( data->libHandle, NULL, data->curToken->id, data->curTokenDepth );
      }
   }
   data->curTokenDepth--;

   TA_TRACE_RETURN( TA_SUCCESS );
}
Beispiel #4
0
static TA_RetCode freeDiskBuffer( LPVOID buffer, DWORD nbByteAlloc )
{
   TA_PROLOG
   BOOL retValue;
   DWORD win32Error;
   TA_RetCode retCode;
   TA_SystemGlobal *global;

   TA_TRACE_BEGIN(  freeDiskBuffer );

   retCode = TA_GetGlobal(  &TA_SystemGlobalControl, (void **)&global );
   if( retCode != TA_SUCCESS )
   {
      TA_TRACE_RETURN( retCode );
   }

   /* Uncommit all pages. */
   retValue = VirtualFree( buffer, nbByteAlloc, MEM_DECOMMIT );
   if( retValue == 0 )
   {
      win32Error = GetLastError();
      global->lastError = win32Error;
      TA_FATAL(  "Win32 Cannot free paged mem", nbByteAlloc, win32Error );
   }

   /* Unreserve all pages. */
   retValue = VirtualFree( buffer, 0, MEM_RELEASE );
   if( retValue == 0 )
   {
      win32Error = GetLastError();
      global->lastError = win32Error;
      TA_FATAL(  "Win32 Cannot free paged mem", 0, win32Error );
   }

   TA_TRACE_RETURN( TA_SUCCESS );
}
Beispiel #5
0
TA_RetCode TA_ReadOpInfoAlloc( const char *sourceInfo,
                               TA_ReadOpInfo **allocatedInfo,
                               unsigned int readOpFlags )
{
   TA_PROLOG
   TA_RetCode retCode;

   TA_ReadOp readOp;
   TA_ReadOp *arrayReadOp;
   TA_ReadOpInfo *newReadOpInfo;
   TA_Field fieldMask, fieldProvided;
   unsigned int timeframeIdx;
   unsigned int intraDayIncPeriod;
   TA_TokenId   intraDayIncToken;
   TA_TokenId   tempToken;
   unsigned int tempInt;
   unsigned int period;
   unsigned int errorOccurred;

   const char *pos;
   unsigned int inField;
   unsigned int nbField;
   unsigned int nbCharInField;
   unsigned int skipNonDigitLine;
   const char *ptrFirstCarInField;

   unsigned char localBuf[10];
   unsigned int bufIdx, opIdx, i;

   register unsigned int flagSet;
   register TA_ReadOp *ptrReadOp;
   
   TA_TRACE_BEGIN(  TA_BuildArrayReadOp );

   newReadOpInfo = (TA_ReadOpInfo *)TA_Malloc( sizeof( TA_ReadOpInfo ) );

   /* These variables are resolved within this function. */
   memset( newReadOpInfo, 0, sizeof( TA_ReadOpInfo ) );

   /* At this point, TA_ReadOpInfoFree can be safely called. */

   /* Keep track of some user provided parameter. */
   newReadOpInfo->sourceInfo = sourceInfo;
   newReadOpInfo->readOpFlags = readOpFlags;

   /* Initialize some defaults. */
   newReadOpInfo->openInterestMult = 100;
   newReadOpInfo->volumeMult       = 100;

   nbField = 0;
   intraDayIncPeriod = 0;
   intraDayIncToken = TA_TOK_END;

   pos = newReadOpInfo->sourceInfo;
   if( !pos || (*pos == '\0') )
   {
      TA_ReadOpInfoFree( newReadOpInfo );
      TA_TRACE_RETURN( TA_MISSING_FIELD );
   }

   /* Find how many fields are defined and check some syntax
    * at the same time.
    */
   if( *pos != '[' )
   {
      TA_ReadOpInfoFree( newReadOpInfo );
      TA_TRACE_RETURN( TA_INVALID_FIELD );
   }

   inField = 0;
   nbCharInField = 0;
   skipNonDigitLine = 0;
   ptrFirstCarInField = NULL;
   while( *pos != '\0' )
   {
      switch( *pos )
      {
      case '[':
         if( inField )
         {
            TA_ReadOpInfoFree( newReadOpInfo );
            TA_TRACE_RETURN( TA_INVALID_FIELD );
         }
         inField = 1;
         break;
      case ']':
         if( (!inField) || (nbCharInField == 0) )
         {
            TA_ReadOpInfoFree( newReadOpInfo );
            TA_TRACE_RETURN( TA_INVALID_FIELD );
         }

         nbField++;

         /* Exclude fields not generating a TA_ReadOp.
          * For the time being that means only the -H and -NDL field.
          */
         if( nbCharInField >= 2 )
         {
            TA_ASSERT( ptrFirstCarInField != NULL );
            if( ptrFirstCarInField[0] == '-' ) 
            {
               if( toupper(ptrFirstCarInField[1]) == 'H' )
                  nbField--;
               else if( (toupper(ptrFirstCarInField[1]) == 'N') &&
                        (toupper(ptrFirstCarInField[2]) == 'D') &&
                        (toupper(ptrFirstCarInField[3]) == 'L') )
               {
                  skipNonDigitLine = 1;
                  nbField--;
               }               
             }
         }

         inField = 0;
         nbCharInField = 0;
         ptrFirstCarInField = NULL;
         break;
      default:
         if( !inField )
         {
            TA_ReadOpInfoFree( newReadOpInfo );
            TA_TRACE_RETURN( TA_INVALID_FIELD );
         }

         if( nbCharInField == 0 )
            ptrFirstCarInField = pos;
         nbCharInField++;
         break;
      }

      pos++;
   }

   if( inField || *(pos-1) != ']' )
   {
      TA_ReadOpInfoFree( newReadOpInfo );
      TA_TRACE_RETURN( TA_INVALID_FIELD );
   }

   /* Build the TA_ReadOp array */
   arrayReadOp = (TA_ReadOp *)TA_Malloc( sizeof( TA_ReadOp ) * nbField );

   if( !arrayReadOp )
   {
      TA_ReadOpInfoFree( newReadOpInfo );
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }

   newReadOpInfo->arrayReadOp = arrayReadOp;

   pos = TA_StringToChar(newReadOpInfo->sourceInfo);

   bufIdx = 0;
   opIdx = 0;
   while( *pos != '\0' && (opIdx < nbField) )
   {
      switch( *pos )
      {
      case '[':
        break;

      case ']':
        localBuf[bufIdx] ='\0';
        bufIdx = 0;

        /* Identify the field and build the TA_ReadOp. */
        tempInt = 0;
        retCode = buildReadOp( newReadOpInfo,
                               (const char *)&localBuf[0],
                               &arrayReadOp[opIdx],
                               &tempToken, &tempInt );
        if( retCode != TA_SUCCESS )
        {
           TA_ReadOpInfoFree( newReadOpInfo );
           TA_TRACE_RETURN( retCode );
        }

        if( arrayReadOp[opIdx] != 0 )
        {
           /* Set the replace zero flag as needed */
           if( TA_IS_REPLACE_ZERO(readOpFlags) && TA_IS_REAL_CMD(arrayReadOp[opIdx]) )
           {
              TA_SET_REPLACE_ZERO(arrayReadOp[opIdx]);
           }

           /* Set the skipNonDigitLine flag as needed. */
           if( skipNonDigitLine == 1 )
           {
              TA_SET_SKIP_NDL_FLAG(arrayReadOp[opIdx]);
           }

           /* Ooof... this readOp is now all build! */
           opIdx++;
        }

        /* If this is a time token, make sure this
         * is not in contradiction with an already
         * specified increment.
         */
        if( intraDayIncPeriod )
        {
           errorOccurred = 0;
           switch( tempToken )
           {
           case TA_TOK_SEC:
           case TA_TOK_SS:
              if( (intraDayIncToken == TA_TOK_MIN) ||
                  (intraDayIncToken == TA_TOK_MN) )
                 errorOccurred = 1;
              /* no break */
           case TA_TOK_MIN:
           case TA_TOK_MN:
              if( (intraDayIncToken == TA_TOK_HOUR) ||
                  (intraDayIncToken == TA_TOK_HH) )
                 errorOccurred = 1;
              break;
           case TA_TOK_HOUR:
           case TA_TOK_HH:
              errorOccurred = 1;
              break;
           default:
              /* Do nothing */
              break;
           }

           if( errorOccurred )
           {
              TA_ReadOpInfoFree( newReadOpInfo );
              TA_TRACE_RETURN( TA_INVALID_FIELD );
           }
        }

        /* Check if a period increment is specified. */
        if( (tempInt != 0) && (tempInt != 1) )
        {
           if( intraDayIncPeriod != 0 )
           {
              TA_ReadOpInfoFree( newReadOpInfo );
              TA_TRACE_RETURN( TA_INVALID_FIELD );
           }

           intraDayIncPeriod = tempInt;
           intraDayIncToken  = tempToken;
        }
        break;

      default:
        if( bufIdx >= sizeof(localBuf)-1 )
        {
           TA_ReadOpInfoFree( newReadOpInfo );
           TA_TRACE_RETURN( TA_INVALID_FIELD );
        }

        localBuf[bufIdx++] = *pos;
        break;
      }

      pos++;
   }

   if( opIdx != nbField )
   {
      TA_ReadOpInfoFree( newReadOpInfo );
      TA_TRACE_RETURN( TA_INTERNAL_ERROR(89) );
   }

   arrayReadOp[opIdx-1] |= TA_CMD_LAST_FLAG;

   /* Build the mask representing the fields provided. */
   fieldProvided = 0;
   timeframeIdx = TA_INTEGER_ARRAY_SIZE;

   for( opIdx=0; opIdx < nbField; opIdx++ )
   {
      readOp = arrayReadOp[opIdx];

      TA_ASSERT( readOp != 0 ); /* Parano test */

      if( !TA_IS_PERMANENT_SKIP_SET(readOp) )
      {
         /* Make sure this field was not specified twice. */
         for( i=opIdx+1; i < nbField; i++ )
         {
            if( (TA_IS_REAL_CMD(readOp) && TA_IS_REAL_CMD(arrayReadOp[i])) ||
                (TA_IS_INTEGER_CMD(readOp) && TA_IS_INTEGER_CMD(arrayReadOp[i])) )
            {
               if( (TA_GET_IDX(readOp) == TA_GET_IDX(arrayReadOp[i])) &&
                   !TA_IS_PERMANENT_SKIP_SET(arrayReadOp[i]) )
               {
                  TA_ReadOpInfoFree( newReadOpInfo );
                  TA_TRACE_RETURN( TA_REDUNDANT_FIELD );
               }
            }
         }

         /* Parano test: Double-check redundant field in a different way. */
         fieldMask = TA_ReadOpToField( readOp );
         TA_ASSERT( fieldMask != 0 );
         if( !(fieldMask & TA_TIMESTAMP) && (fieldProvided & fieldMask) )
         {
            TA_ReadOpInfoFree( newReadOpInfo );
            TA_TRACE_RETURN( TA_REDUNDANT_FIELD );
         }

         /* Set the field. */
         fieldProvided |= fieldMask;

         /* Keep track of the smallest granularity of the timestamp. */
         if( fieldMask & TA_TIMESTAMP )
         {
            if( (timeframeIdx == TA_INTEGER_ARRAY_SIZE) ||
                (TA_GET_IDX(readOp) < timeframeIdx) )
               timeframeIdx = TA_GET_IDX(readOp);
         }
      }
   }


   /* No date/time reference provided!? This is considered an error
    * in the current implementation.
    */
   if( timeframeIdx == TA_INTEGER_ARRAY_SIZE )
   {
      TA_ReadOpInfoFree( newReadOpInfo );
      TA_TRACE_RETURN( TA_MISSING_DATE_OR_TIME_FIELD );
   }

   /* Determine at which point the timestamp is completed. */
   flagSet = 0;
   for( opIdx=nbField; opIdx > 0; opIdx-- )
   {
      ptrReadOp = &arrayReadOp[opIdx-1];
      readOp = *ptrReadOp;

      if( !flagSet                          && 
          TA_IS_INTEGER_CMD(readOp)         && 
          (TA_GET_IDX(readOp)<=TA_YEAR_IDX) && 
          !TA_IS_PERMANENT_SKIP_SET(readOp) )
      {
         TA_SET_TIMESTAMP_COMPLETE(*ptrReadOp);
         flagSet = 1;
      }
      else
      {
         TA_CLR_TIMESTAMP_COMPLETE(*ptrReadOp);
      }
   }

   /* Validate and identify the period. */
   period = 0;
   if( intraDayIncPeriod )
   {
      errorOccurred = 0;
      switch( timeframeIdx )
      {
      case TA_YEAR_IDX:
      case TA_MONTH_IDX:
      case TA_DAY_IDX:
         errorOccurred = 1;
         break;
      case TA_HOUR_IDX:
         if( (intraDayIncPeriod < TA_1HOUR) || (intraDayIncPeriod >= TA_DAILY) )
            errorOccurred = 1;
         break;
      case TA_MIN_IDX:
         if( (intraDayIncPeriod < TA_1MIN) || (intraDayIncPeriod >= TA_1HOUR) )
            errorOccurred = 1;
         break;
      case TA_SEC_IDX:
         if( (intraDayIncPeriod < TA_1SEC) || (intraDayIncPeriod >= TA_1MIN) )
            errorOccurred = 1;
         break;
      default:
         TA_ReadOpInfoFree( newReadOpInfo );
         TA_FATAL(  NULL, timeframeIdx, fieldProvided );
      }

      if( errorOccurred )
      {
         TA_ReadOpInfoFree( newReadOpInfo );
         TA_TRACE_RETURN( TA_INVALID_FIELD );
      }
            
      period = intraDayIncPeriod;
   }
   else
   {
      switch( timeframeIdx )
      {
      case TA_YEAR_IDX:
         period = TA_YEARLY;
         break;
      case TA_MONTH_IDX:
         period = TA_MONTHLY;
         break;
      case TA_DAY_IDX:
         period = TA_DAILY;
         break;
      case TA_HOUR_IDX:
         period = TA_1HOUR;
         break;
      case TA_MIN_IDX:
         period = TA_1MIN;
         break;
      case TA_SEC_IDX:
         period = TA_1SEC;
         break;
      default:
         TA_FATAL(  NULL, timeframeIdx, fieldProvided );
      }
   }

   /* A last check... */
   if( period == 0 )
   {
      TA_ReadOpInfoFree( newReadOpInfo );
      TA_TRACE_RETURN( TA_INVALID_FIELD );
   }
         
   /* Everything is fine, let's return the information. */
   newReadOpInfo->arrayReadOp = arrayReadOp;
   newReadOpInfo->fieldProvided = fieldProvided;
   newReadOpInfo->nbReadOp = nbField;
   newReadOpInfo->period = period;

   *allocatedInfo = newReadOpInfo;

   TA_TRACE_RETURN( TA_SUCCESS );
}
TA_RetCode TA_FileIndexMoveToNextToken( TA_FileIndexPriv *data )
{
   TA_PROLOG;
   TA_Libc *libHandle;

   if( !data )
      return TA_UNKNOWN_ERR;


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

   if( data->curToken == NULL )
   {
      /* First time this function get called for this 'data' */
      data->curTokenDepth = 0;
      data->curDirectionForward = 1;
      data->curToken = (TA_TokenInfo *)TA_ListAccessHead( data->listLocationToken );
      data->prevToken = NULL;
      data->nextToken = (TA_TokenInfo *)TA_ListAccessNext( data->listLocationToken );

      if( !data->curToken || !data->nextToken )
      {
         TA_FATAL( data->libHandle, NULL, data->curToken, data->nextToken );
      }
   }
   else if( data->nextToken == NULL )
   {
      /* Can't go further, simply return. */
      TA_TRACE_RETURN( TA_SUCCESS );
   }
   else
   {
      if( data->curDirectionForward == 0 )
      {
         if( data->prevToken != NULL )
            TA_ListAccessNext( data->listLocationToken );
         else
            TA_ListAccessHead( data->listLocationToken );

         TA_ListAccessNext( data->listLocationToken );
         data->curDirectionForward = 1;
      }

      data->prevToken = data->curToken;
      data->curToken = data->nextToken;
      data->nextToken = (TA_TokenInfo *)TA_ListAccessNext( data->listLocationToken );

      /* Parano test: Should never happen since the code assume that
       * the 'listLocationToken' is always terminated by TA_END.
       */
      if( !data->curToken )
      {
         TA_FATAL( data->libHandle, NULL, data->curToken->id, data->curTokenDepth );
      }
   }

   data->curTokenDepth++;

   TA_TRACE_RETURN( TA_SUCCESS );
}