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 ); }
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 ); }
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 ); }
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 ); }