IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 12287


Ignore:
Timestamp:
Mar 6, 2007, 4:42:22 PM (19 years ago)
Author:
Paul Price
Message:

Flushing out a lot of code that could be done more simply another way. Adding assertions.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/types/psLookupTable.c

    r11710 r12287  
    77*  @author Ross Harman, MHPCC
    88*
    9 *  @version $Revision: 1.48 $ $Name: not supported by cvs2svn $
    10 *  @date $Date: 2007-02-08 21:57:02 $
     9*  @version $Revision: 1.49 $ $Name: not supported by cvs2svn $
     10*  @date $Date: 2007-03-07 02:42:22 $
    1111*
    1212*  Copyright 2004-2005 Maui High Performance Computing Center, Univ. of Hawaii
     
    2727#include <inttypes.h>
    2828
     29#include "psAbort.h"
    2930#include "psMemory.h"
    3031#include "psString.h"
     
    6768static char *cleanString(char *inString, int sLen);
    6869static char* getToken(char **inString, char *delimiter, psParseErrorType *status);
    69 static psS32 parseS32(char *inString, psParseErrorType *status);
    70 static psS64 parseS64(char *inString, psParseErrorType *status);
    71 static psF32 parseF32(char *inString, psParseErrorType *status);
    72 static psF64 parseF64(char *inString, psParseErrorType *status);
    7370static void parseValue(psVector *vec, psU64 index, char* strValue, psParseErrorType *status);
    7471static void lookupTableFree(psLookupTable* table);
     
    7875static bool ignoreLine(char *inString)
    7976{
    80     while(*inString!='\0' && *inString!='#') {
    81         if(!isspace(*inString)) {
     77    while (*inString!='\0' && *inString!='#') {
     78        if (!isspace(*inString)) {
    8279            return false;
    8380        }
     
    106103    // Skip over trailing whitespace, null terminators, and # characters
    107104    ptrE = inString + sLen;
    108     while(isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') {
     105    while (isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') {
    109106        ptrE--;
    110107    }
     
    131128
    132129    // Skip over leading whitespace
    133     while(isspace(**inString)) {
     130    while (isspace(**inString)) {
    134131        (*inString)++;
    135132    }
     
    137134    // Length of token, not including delimiter
    138135    sLen = strcspn(*inString, delimiter);
    139     if(sLen) {
     136    if (sLen) {
    140137
    141138        // Create new, cleaned, and null terminated token
     
    145142        (*inString) += sLen;
    146143    }
    147     /*    else if(**inString!='\0' && sLen==0) {
     144    /*    else if (**inString!='\0' && sLen==0) {
    148145            *status = PS_PARSE_ERROR_GENERAL;
    149146        }
     
    152149}
    153150
    154 /* Returns single parsed value as a psS32. The input string must be cleaned and
    155    null terminated. */
    156 static psS32 parseS32(char *inString,
    157                       psParseErrorType *status)
    158 {
    159     char *end = NULL;
    160     psS32 value = 0.0;
    161 
    162 
    163     value = (psS32)strtol(inString, &end, 0);
    164     if(*end != '\0' && !isspace(*end)) {
    165         *status = PS_PARSE_ERROR_VALUE;
    166     }
    167     /*    else if(inString==end) {
    168             *status = PS_PARSE_ERROR_VALUE;
    169         }
    170     */
    171     return value;
    172 }
    173 
    174 /* Returns single parsed value as a psS64. The input string must be cleaned and
    175    null terminated. */
    176 static psS64 parseS64(char *inString,
    177                       psParseErrorType *status)
    178 {
    179     char *end = NULL;
    180     psS64 value = 0.0;
    181 
    182     value = (psS64)strtoll(inString, &end, 0);
    183     if(*end != '\0' && !isspace(*end)) {
    184         *status = PS_PARSE_ERROR_VALUE;
    185     }
    186     /*    else if(inString==end) {
    187             *status = PS_PARSE_ERROR_VALUE;
    188         }
    189     */
    190     return value;
    191 }
    192 
    193 /* Returns single parsed value as a psF32. The input string must be cleaned and
    194    null terminated. */
    195 static psF32 parseF32(char *inString,
    196                       psParseErrorType *status)
    197 {
    198     char *end = NULL;
    199     psF32 value = 0.0;
    200 
    201     value = (psF32)strtof(inString, &end);
    202     if(*end != '\0' && !isspace(*end)) {
    203         *status = PS_PARSE_ERROR_VALUE;
    204     }
    205     /*    else if(inString==end) {
    206             *status = PS_PARSE_ERROR_VALUE;
    207         }
    208     */
    209     return value;
    210 }
    211 
    212 /* Returns single parsed value as a psF64. The input string must be cleaned and
    213    null terminated. */
    214 static psF64 parseF64(char *inString,
    215                       psParseErrorType *status)
    216 {
    217     char *end = NULL;
    218     psF64 value = 0.0;
    219 
    220     value = (psF64)strtod(inString, &end);
    221     if(*end != '\0' && !isspace(*end)) {
    222         *status = PS_PARSE_ERROR_VALUE;
    223     }
    224     /*    else if(inString==end) {
    225             *status = PS_PARSE_ERROR_VALUE;
    226         }
    227     */
    228     return value;
    229 }
     151#define PARSE_VALUE_INT_CASE(TYPE, FUNC) \
     152    case PS_TYPE_##TYPE: { \
     153        char *end = NULL; \
     154        ps##TYPE value = FUNC(strValue, &end, 0); \
     155        if (*end != '\0' && !isspace(*end)) { \
     156            *status = PS_PARSE_ERROR_VALUE; \
     157        } \
     158        vec->data.TYPE[index] = value; \
     159        return; \
     160    }
     161
     162#define PARSE_VALUE_FLOAT_CASE(TYPE, FUNC) \
     163    case PS_TYPE_##TYPE: { \
     164        char *end = NULL; \
     165        ps##TYPE value = FUNC(strValue, &end); \
     166        if (*end != '\0' && !isspace(*end)) { \
     167            *status = PS_PARSE_ERROR_VALUE; \
     168        } \
     169        vec->data.TYPE[index] = value; \
     170        return; \
     171    }
     172
    230173
    231174/* Returns single parsed value as a double precision number. The input string must be
     
    236179                       psParseErrorType *status)
    237180{
    238     psElemType type;
    239 
    240 
    241     /*    if(vec == NULL) {
    242             *status = 1;
    243             return;
    244         }
    245     */
    246     type = vec->type.type;
    247 
    248     switch(type) {
    249     case PS_TYPE_S32:
    250         vec->data.S32[index] = parseS32(strValue, status);
    251         break;
    252     case PS_TYPE_S64:
    253         vec->data.S64[index] = parseS64(strValue, status);
    254         break;
    255     case PS_TYPE_F32:
    256         vec->data.F32[index] = parseF32(strValue, status);
    257         break;
    258     case PS_TYPE_F64:
    259     default:
    260         vec->data.F64[index] = parseF64(strValue, status);
    261         break;
    262         //    default:
    263         //        *status = PS_PARSE_ERROR_TYPE;
    264     }
    265 
     181    switch (vec->type.type) {
     182        PARSE_VALUE_INT_CASE(S32, strtol);
     183        PARSE_VALUE_INT_CASE(S64, strtoll);
     184        PARSE_VALUE_FLOAT_CASE(F32, strtof);
     185        PARSE_VALUE_FLOAT_CASE(F64, strtod);
     186      default:
     187        psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Bad type for vector: %x.\n", vec->type.type);
     188        *status = PS_PARSE_ERROR_TYPE;
     189    }
    266190    return;
    267191}
     
    269193static void lookupTableFree(psLookupTable* table)
    270194{
     195    assert(table);
    271196    psFree(table->values);
    272     psFree((void *)table->filename);
    273     psFree((void *)table->format);
     197    psFree(table->filename);
     198    psFree(table->format);
    274199}
    275200
     
    292217                                    long indexCol)
    293218{
    294     // Can't read table if you don't know its name
    295     PS_ASSERT_PTR_NON_NULL(filename,NULL);
    296 
    297     // Can't read table if you don't know its format
    298     PS_ASSERT_PTR_NON_NULL(format,NULL);
    299 
    300     psLookupTable *outTable = NULL;
    301 
    302     // Allocate lookup table
    303     outTable = (psLookupTable*)p_psAlloc(file, lineno, func, sizeof(psLookupTable));
     219    PS_ASSERT_STRING_NON_EMPTY(filename,NULL);
     220    PS_ASSERT_STRING_NON_EMPTY(format,NULL);
     221
     222    psLookupTable *outTable = p_psAlloc(file, lineno, func, sizeof(psLookupTable));
    304223
    305224    // Set deallocator
     
    324243}
    325244
    326 #define UPDATE_VALID_TO_FROM(TABLE)                                             \
    327 switch (TABLE->index->type.type) {                                              \
    328 case PS_TYPE_U8:                                                                \
    329     *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.U8[0];                         \
    330     *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.U8[TABLE->index->n-1];         \
    331     break;                                                                      \
    332 case PS_TYPE_S8:                                                                \
    333     *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.S8[0];                         \
    334     *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.S8[TABLE->index->n-1];         \
    335     break;                                                                      \
    336 case PS_TYPE_U16:                                                               \
    337     *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.U16[0];                        \
    338     *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.U16[TABLE->index->n-1];        \
    339     break;                                                                      \
    340 case PS_TYPE_S16:                                                               \
    341     *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.S16[0];                        \
    342     *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.S16[TABLE->index->n-1];        \
    343     break;                                                                      \
    344 case PS_TYPE_U32:                                                               \
    345     *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.U32[0];                        \
    346     *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.U32[TABLE->index->n-1];        \
    347     break;                                                                      \
    348 case PS_TYPE_S32:                                                               \
    349     *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.S32[0];                        \
    350     *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.S32[TABLE->index->n-1];        \
    351     break;                                                                      \
    352 case PS_TYPE_U64:                                                               \
    353     *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.U64[0];                        \
    354     *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.U64[TABLE->index->n-1];        \
    355     break;                                                                      \
    356 case PS_TYPE_S64:                                                               \
    357     *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.S64[0];                        \
    358     *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.S64[TABLE->index->n-1];        \
    359     break;                                                                      \
    360 case PS_TYPE_F32:                                                               \
    361     *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.F32[0];                        \
    362     *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.F32[TABLE->index->n-1];        \
    363     break;                                                                      \
    364 case PS_TYPE_F64:                                                               \
    365     *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.F64[0];                        \
    366     *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.F64[TABLE->index->n-1];        \
    367     break;                                                                      \
    368 default:                                                                        \
    369     *(double *)&TABLE->validFrom = (psF64)0;                                                \
    370     *(double *)&TABLE->validTo   = (psF64)0;                                                \
    371     break;                                                                      \
    372 }
    373 
    374 #define COPY_VECTOR_VALUES(VEC_OUT,INDEX_OUT,VEC_IN,INDEX_IN)                              \
    375 switch(((psVector*)(VEC_IN))->type.type) {                                                 \
    376 case PS_TYPE_U8:                                                                           \
    377     ((psVector*)VEC_OUT)->data.U8[INDEX_OUT] = ((psVector*)VEC_IN)->data.U8[INDEX_IN];     \
    378     break;                                                                                 \
    379 case PS_TYPE_U16:                                                                          \
    380     ((psVector*)VEC_OUT)->data.U16[INDEX_OUT] = ((psVector*)VEC_IN)->data.U16[INDEX_IN];   \
    381     break;                                                                                 \
    382 case PS_TYPE_U32:                                                                          \
    383     ((psVector*)VEC_OUT)->data.U32[INDEX_OUT] = ((psVector*)VEC_IN)->data.U32[INDEX_IN];   \
    384     break;                                                                                 \
    385 case PS_TYPE_U64:                                                                          \
    386     ((psVector*)VEC_OUT)->data.U64[INDEX_OUT] = ((psVector*)VEC_IN)->data.U64[INDEX_IN];   \
    387     break;                                                                                 \
    388 case PS_TYPE_S8:                                                                           \
    389     ((psVector*)VEC_OUT)->data.S8[INDEX_OUT] = ((psVector*)VEC_IN)->data.S8[INDEX_IN];     \
    390     break;                                                                                 \
    391 case PS_TYPE_S16:                                                                          \
    392     ((psVector*)VEC_OUT)->data.S16[INDEX_OUT] = ((psVector*)VEC_IN)->data.S16[INDEX_IN];   \
    393     break;                                                                                 \
    394 case PS_TYPE_S32:                                                                          \
    395     ((psVector*)VEC_OUT)->data.S32[INDEX_OUT] = ((psVector*)VEC_IN)->data.S32[INDEX_IN];   \
    396     if(INDEX_OUT == 0) {                                                                   \
    397         validFrom = ((psVector*)VEC_OUT)->data.S32[INDEX_OUT];                             \
    398     }                                                                                      \
    399     if(INDEX_OUT == ((psVector*)VEC_OUT)->n-1 ) {                                          \
    400         validTo = ((psVector*)VEC_OUT)->data.S32[INDEX_OUT];                               \
    401     }                                                                                      \
    402     break;                                                                                 \
    403 case PS_TYPE_S64:                                                                          \
    404     ((psVector*)VEC_OUT)->data.S64[INDEX_OUT] = ((psVector*)VEC_IN)->data.S64[INDEX_IN];   \
    405     if(INDEX_OUT == 0) {                                                                   \
    406         validFrom = ((psVector*)VEC_OUT)->data.S64[INDEX_OUT];                             \
    407     }                                                                                      \
    408     if(INDEX_OUT == ((psVector*)VEC_OUT)->n-1 ) {                                          \
    409         validTo = ((psVector*)VEC_OUT)->data.S64[INDEX_OUT];                               \
    410     }                                                                                      \
    411     break;                                                                                 \
    412 case PS_TYPE_F32:                                                                          \
    413     ((psVector*)VEC_OUT)->data.F32[INDEX_OUT] = ((psVector*)VEC_IN)->data.F32[INDEX_IN];   \
    414     if(INDEX_OUT == 0) {                                                                   \
    415         validFrom = ((psVector*)VEC_OUT)->data.F32[INDEX_OUT];                             \
    416     }                                                                                      \
    417     if(INDEX_OUT == ((psVector*)VEC_OUT)->n-1 ) {                                          \
    418         validTo = ((psVector*)VEC_OUT)->data.F32[INDEX_OUT];                               \
    419     }                                                                                      \
    420     break;                                                                                 \
    421 case PS_TYPE_F64:                                                                          \
    422     ((psVector*)VEC_OUT)->data.F64[INDEX_OUT] = ((psVector*)VEC_IN)->data.F64[INDEX_IN];   \
    423     if(INDEX_OUT == 0) {                                                                   \
    424         validFrom = ((psVector*)VEC_OUT)->data.F64[INDEX_OUT];                             \
    425     }                                                                                      \
    426     if(INDEX_OUT == ((psVector*)VEC_OUT)->n-1 ) {                                          \
    427         validTo = ((psVector*)VEC_OUT)->data.F64[INDEX_OUT];                               \
    428     }                                                                                      \
    429     break;                                                                                 \
    430 default:                                                                                   \
    431     break;                                                                                 \
    432 }
    433 
    434245psArray *psVectorsReadFromFile(const char *filename,
    435246                               const char *format)
    436247{
     248    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
     249    PS_ASSERT_STRING_NON_EMPTY(format, NULL);
     250
    437251    psArray*          outputArray = NULL;
    438252    psVector*         colVector   = NULL;
     
    447261    psParseErrorType  parseStatus = PS_PARSE_SUCCESS;
    448262
    449     // Check for nul file name
    450     PS_ASSERT_PTR_NON_NULL(filename,NULL);
    451 
    452     // Parse format string for valid string
    453     PS_ASSERT_PTR_NON_NULL(format,NULL);
    454 
    455263    // Create temp pointer which can then be used several times
    456264    tempFormat = format;
     
    461269    // Parse the format string to determine how many vectors
    462270    // and whether the format string is valid
    463     while((strValue=getToken((char**)&tempFormat," \t",&parseStatus))) {
     271    while ((strValue = getToken((char**)&tempFormat, " \t", &parseStatus))) {
    464272
    465273        // Check for %d format sub string
    466         if(strcmp(strValue,"\%d") == 0 ) {
     274        if (strcmp(strValue,"\%d") == 0 ) {
    467275            numCols++;
    468276            colVector = psVectorAlloc(1,PS_TYPE_S32);
     
    498306    // If the format string was parsed successfully and return numCols the
    499307    // prepare to open file and read values
    500     if(numCols > 0) {
     308    if (numCols > 0) {
    501309
    502310        // Open specified file
    503         if((fp=fopen(filename, "r")) == NULL) {
     311        if ((fp=fopen(filename, "r")) == NULL) {
    504312            psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed to open file %s."),
    505313                    filename);
     
    514322
    515323            // Loop through file to get numRows, numCols, and column data types
    516             while((fgets(line, MAX_STRING_LENGTH, fp) != NULL) &&
     324            while ((fgets(line, MAX_STRING_LENGTH, fp) != NULL) &&
    517325                    (parseStatus == PS_PARSE_SUCCESS))   {
    518326
     
    521329
    522330                // If line is not a comment or blank, then extract data
    523                 if(!ignoreLine(linePtr)) {
     331                if (!ignoreLine(linePtr)) {
    524332                    numRows++;
    525333
     
    530338
    531339                    // Loop through format and line strings to get values in text table file
    532                     while((strValue=getToken((char**)&tempFormat," \t",&parseStatus))
     340                    while ((strValue=getToken((char**)&tempFormat," \t",&parseStatus))
    533341                            && (strNum=getToken((char**)&linePtr," \t",&parseStatus)) ) {
    534342                        // Set column vector
     
    536344
    537345                        // Set column entries based on format string defining the type
    538                         if(strcmp(strValue,"\%d") == 0 ) {
     346                        if (strcmp(strValue,"\%d") == 0 ) {
    539347                            colVector = psVectorRecycle(colVector, numRows,
    540348                                                        colVector->type.type);
     
    564372                        // If the file line was not parsed successful report
    565373                        // error and return NULL
    566                         if(parseStatus != PS_PARSE_SUCCESS) {
     374                        if (parseStatus != PS_PARSE_SUCCESS) {
    567375                            psError(PS_ERR_UNKNOWN, true,
    568376                                    "Parsing text file failed.");
     
    615423                                     const char *func,
    616424                                     psLookupTable *table,
    617                                      const psArray *vectors,
     425                                     psArray *vectors,
    618426                                     long indexCol)
    619427{
    620     psLookupTable* outputTable = NULL;
    621     bool         sortNeeded  = false;
    622     psF64          validTo     = 0;
    623     psF64          validFrom   = 0;
    624 
    625     // Check for NULL input table
    626     // XXX table/outputtable should be allocated if NULL
    627     PS_ASSERT_PTR_NON_NULL(table,NULL);
    628 
    629     // Check for NULL vectors
    630     PS_ASSERT_PTR_NON_NULL(vectors,NULL);
    631 
    632     // Check for invalid index column
    633     if(indexCol < 0 ) {
    634         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    635                 "Index column cannot be less than zero");
    636         return NULL;
    637     }
    638 
     428    PS_ASSERT_LOOKUPTABLE_NON_NULL(table, NULL);
     429    PS_ASSERT_ARRAY_NON_NULL(vectors, NULL);
    639430    if (indexCol >= vectors->n) {
    640431        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Index column, %ld, is larger"
     
    643434    }
    644435
    645     psVector* indexColumnVector = vectors->data[indexCol];
    646     psS32  numRows = indexColumnVector->n;
    647     psS32  numCols = vectors->n;
     436    psVector *indexVector = vectors->data[indexCol]; // The vector that provides the index
     437    long numRows = indexVector->n;      // Number of rows in table
     438    long numCols = vectors->n;          // Number of columns in table
     439
     440#define CHECK_SORT_CASE(TYPE) \
     441    case PS_TYPE_##TYPE: \
     442        for (long i = 1; i < numRows; i++) { \
     443             if (indexVector->data.TYPE[i] < indexVector->data.TYPE[i - 1]) { \
     444                 sortNeeded = true; \
     445                 break; \
     446             } \
     447         } \
     448         break;
    648449
    649450    // Check if array is sorted on the index column
    650     psVector* sortedIndex = psVectorAlloc(numRows,PS_TYPE_U32);
    651     sortedIndex = psVectorSortIndex(sortedIndex,indexColumnVector);
    652     for(psS32 i = 0; i < numRows; i++ ) {
    653         if(sortedIndex->data.U32[i] != i) {
    654             sortNeeded = true;
    655             break;
    656         }
    657     }
    658 
    659     // Check if it is necessary to sort value vectors
    660     if(sortNeeded) {
    661         // Allocate new array to contain sorted vectors
    662         psArray* newValueArray = psArrayAlloc(numCols);
    663         for(psS32 j = 0; j < numCols; j++) {
    664             psS32 type = ((psVector*)(vectors->data[j]))->type.type;
    665             newValueArray->data[j] = psVectorAlloc(numRows,type);
    666         }
    667 
    668         // Populate new array/vectors with sorted values
    669         for(psS32 i = 0; i < numRows; i++) {
    670             // Populate new index vector
    671             psU32 sortIndex = sortedIndex->data.U32[i];
    672             // For every column populate new value vectors
    673             for(psS32 j=0; j < numCols; j++) {
    674                 COPY_VECTOR_VALUES(newValueArray->data[j],i,vectors->data[j], sortIndex)
     451    bool sortNeeded  = false;           // Do we need to sort?
     452    switch (indexVector->type.type) {
     453        CHECK_SORT_CASE(U8);
     454        CHECK_SORT_CASE(U16);
     455        CHECK_SORT_CASE(U32);
     456        CHECK_SORT_CASE(U64);
     457        CHECK_SORT_CASE(S8);
     458        CHECK_SORT_CASE(S16);
     459        CHECK_SORT_CASE(S32);
     460        CHECK_SORT_CASE(S64);
     461        CHECK_SORT_CASE(F32);
     462        CHECK_SORT_CASE(F64);
     463      default:
     464        psAbort("Should never get here: bad type.");
     465    }
     466
     467    if (sortNeeded) {
     468        psVector *sortedIndex = psVectorSortIndex(NULL, indexVector); // Indices for sorting
     469        psArray *newValues = psArrayAlloc(numCols);
     470        for (long i = 0; i < numCols; i++) {
     471            psVector *oldVector = vectors->data[i]; // Vector of interest
     472            psVector *newVector = psVectorAlloc(numRows, oldVector->type.type);
     473            newValues->data[i] = newVector;
     474
     475#define REARRANGE_CASE(TYPE) \
     476    case PS_TYPE_##TYPE: \
     477        for (long j = 0; j < numRows; j++) { \
     478            newVector->data.TYPE[j] = oldVector->data.TYPE[sortedIndex->data.S32[j]]; \
     479        } \
     480        break;
     481
     482            switch (oldVector->type.type) {
     483                REARRANGE_CASE(U8);
     484                REARRANGE_CASE(U16);
     485                REARRANGE_CASE(U32);
     486                REARRANGE_CASE(U64);
     487                REARRANGE_CASE(S8);
     488                REARRANGE_CASE(S16);
     489                REARRANGE_CASE(S32);
     490                REARRANGE_CASE(S64);
     491                REARRANGE_CASE(F32);
     492                REARRANGE_CASE(F64);
     493              default:
     494                psAbort("Should never get here: bad type.");
    675495            }
    676496        }
    677         // Assign new vector value to table
    678         table->index = newValueArray->data[indexCol];
    679         // Assign new value vectors to table array
    680         table->values = newValueArray;
    681         // Assign indexCol
    682         table->indexCol = indexCol;
    683         // Assign validTo and validFrom values
    684         UPDATE_VALID_TO_FROM(table)
    685 
    686         // Set return value
    687         outputTable = table;
    688 
     497
     498        psFree(sortedIndex);
     499        table->values = newValues;
    689500    } else {
    690         // Index vector is already sorted
    691         // Assign array vector specified by indexCol to table index vector
    692         // and increment memory ref
    693         table->index = vectors->data[indexCol];
    694         table->values = (psArray*)vectors;
    695         psMemIncrRefCounter((psArray*)vectors);
    696 
    697         // Assign indexCol
    698         table->indexCol = indexCol;
    699         // Assign validTo and validFrom values
    700         UPDATE_VALID_TO_FROM(table);
    701 
    702         // Set return value
    703         outputTable = table;
    704     }
    705 
    706     // Free sort vector
    707     psFree(sortedIndex);
    708 
    709     return outputTable;
     501        table->values = psMemIncrRefCounter(vectors);
     502    }
     503
     504    table->index = psMemIncrRefCounter(table->values->data[indexCol]);
     505    table->indexCol = indexCol;
     506
     507#define SET_VALID_CASE(TYPE) \
     508    case PS_TYPE_##TYPE: \
     509        *(double*)&table->validFrom = table->index->data.TYPE[0]; \
     510        *(double*)&table->validTo   = table->index->data.TYPE[numRows - 1]; \
     511        break;
     512
     513    switch (table->index->type.type) {
     514        SET_VALID_CASE(U8);
     515        SET_VALID_CASE(U16);
     516        SET_VALID_CASE(U32);
     517        SET_VALID_CASE(U64);
     518        SET_VALID_CASE(S8);
     519        SET_VALID_CASE(S16);
     520        SET_VALID_CASE(S32);
     521        SET_VALID_CASE(S64);
     522        SET_VALID_CASE(F32);
     523        SET_VALID_CASE(F64);
     524      default:
     525        psAbort("Should never get here: bad type.");
     526    }
     527
     528    return table;
    710529}
    711530
    712531long psLookupTableRead(psLookupTable* table)
    713532{
     533    PS_ASSERT_LOOKUPTABLE_NON_NULL(table, 0);
     534
    714535    long            numRows  = 0;
    715536    psArray*        vectors  = NULL;
    716537    psLookupTable*  outTable = NULL;
    717538
    718     // Check if the input table is NULL then return 0
    719     PS_ASSERT_PTR_NON_NULL(table,0);
    720 
    721539    // Read vectors from file specified in table
    722540    vectors = psVectorsReadFromFile(table->filename, table->format);
    723541
    724542    // Check for valid array after reading from file
    725     if(vectors != NULL) {
     543    if (vectors != NULL) {
    726544
    727545        // Import vector into table
     
    731549
    732550        // Update the number of rows read if outTable is not NULL
    733         if(outTable != NULL) {
     551        if (outTable != NULL) {
    734552            numRows = table->index->n;
    735553        }
     
    780598switch (TABLE->index->type.type) {                                      \
    781599case PS_TYPE_S32:                                                       \
    782     if( (psS32)index < TABLE->index->data.S32[0] ) {                    \
     600    if ( (psS32)index < TABLE->index->data.S32[0] ) {                    \
    783601        return NAN;                                                     \
    784602    }                                                                   \
    785     if( (psS32)index > TABLE->index->data.S32[numRows-1] ) {            \
     603    if ( (psS32)index > TABLE->index->data.S32[numRows-1] ) {            \
    786604        return NAN;                                                     \
    787605    }                                                                   \
    788606    break;                                                              \
    789607case PS_TYPE_S64:                                                       \
    790     if( (psS64)index < TABLE->index->data.S64[0] ) {                    \
     608    if ( (psS64)index < TABLE->index->data.S64[0] ) {                    \
    791609        return NAN;                                                     \
    792610    }                                                                   \
    793     if( (psS64)index > TABLE->index->data.S64[numRows-1] ) {            \
     611    if ( (psS64)index > TABLE->index->data.S64[numRows-1] ) {            \
    794612        return NAN;                                                     \
    795613    }                                                                   \
    796614    break;                                                              \
    797615case PS_TYPE_F32:                                                       \
    798     if( (psF32)index < TABLE->index->data.F32[0] ) {                    \
     616    if ( (psF32)index < TABLE->index->data.F32[0] ) {                    \
    799617        return NAN;                                                     \
    800618    }                                                                   \
    801     if( (psF32)index > TABLE->index->data.F32[numRows-1] ) {            \
     619    if ( (psF32)index > TABLE->index->data.F32[numRows-1] ) {            \
    802620        return NAN;                                                     \
    803621    }                                                                   \
    804622    break;                                                              \
    805623case PS_TYPE_F64:                                                       \
    806     if( index < TABLE->index->data.F64[0] ) {                           \
     624    if ( index < TABLE->index->data.F64[0] ) {                           \
    807625        return NAN;                                                     \
    808626    }                                                                   \
    809     if( index > TABLE->index->data.F64[numRows-1] ) {                   \
     627    if ( index > TABLE->index->data.F64[numRows-1] ) {                   \
    810628        return NAN;                                                     \
    811629    }                                                                   \
     
    820638                                long column)
    821639{
     640    PS_ASSERT_LOOKUPTABLE_NON_NULL(table, NAN);
     641    // Ensuring information exists
     642    PS_ASSERT_VECTOR_NON_NULL(table->index, NAN);
     643    PS_ASSERT_ARRAY_NON_NULL(table->values, NAN);
     644    PS_ASSERT_INT_WITHIN_RANGE(column, 0, (int)table->values->n - 1, NAN);
     645    PS_ASSERT_VECTOR_NON_NULL((psVector*)table->values->data[column], NAN);
     646
    822647    psU64 hiIdx = 0;
    823648    psU64 loIdx = 0;
     
    832657    psArray *values = NULL;
    833658
    834     // Check for NULL table
    835     PS_ASSERT_PTR_NON_NULL(table,NAN);
    836 
    837659    indexVec = table->index;
    838660    values = table->values;
    839661    numRows = table->index->n;
    840662    numCols = table->values->n;
    841     PS_ASSERT_PTR_NON_NULL(indexVec,NAN);
    842     PS_ASSERT_PTR_NON_NULL(values,NAN);
    843     PS_ASSERT_INT_UNEQUAL(numRows, 0,NAN);
    844     PS_ASSERT_INT_UNEQUAL(numCols, 0,NAN);
    845     PS_ASSERT_INT_WITHIN_RANGE(column, 0, (int)(numCols-1), NAN);
    846 
    847663    valuesVec = (psVector*)values->data[column];
    848     PS_ASSERT_PTR_NON_NULL(indexVec,NAN);
    849664
    850665    // Verify the index is within the bounds of the table
     
    853668    // Find location in table where specified index is between to entries
    854669    CONVERT_VALUE_TO_F64(indexVec, 0, convertVal)
    855     while(index > convertVal ) {
     670    while (index > convertVal ) {
    856671        hiIdx++;
    857672        /*  XXX:  following is unreachable.
    858                 if(hiIdx >= numRows) {
     673                if (hiIdx >= numRows) {
    859674                    psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    860675                            _("High index too big, %" PRIu64 "."), hiIdx);
     
    867682    // Check for negative low index and generate error
    868683    loIdx = hiIdx--;
    869     if(loIdx < 0) {
     684    if (loIdx < 0) {
    870685        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    871686                _("Low index too small, %" PRIu64 "."), loIdx);
     
    877692    CONVERT_VALUE_TO_F64(indexVec, loIdx, convertVal);
    878693    denom -= convertVal;
    879     if(fabs(denom) < FLT_EPSILON) {
     694    if (fabs(denom) < FLT_EPSILON) {
    880695        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    881696                _("Divide by zero error during interpolation."));
     
    897712                                      double index)
    898713{
    899     long numCols = 0;
    900     psVector *outVector = NULL;
    901 
    902     // Error checks
    903     PS_ASSERT_PTR_NON_NULL(table,NULL);
    904     PS_ASSERT_PTR_NON_NULL(table->values,NULL);
    905     numCols = table->values->n;
    906     PS_ASSERT_INT_UNEQUAL(numCols, 0,NULL);
    907 
    908     // Create output vector
    909     outVector = psVectorAlloc(numCols, PS_TYPE_F64);
     714    PS_ASSERT_LOOKUPTABLE_NON_NULL(table, NULL);
     715    // Ensuring information exists
     716    PS_ASSERT_VECTOR_NON_NULL(table->index, NULL);
     717    PS_ASSERT_ARRAY_NON_NULL(table->values, NULL);
     718
     719    long numCols = table->values->n;
     720    psVector *outVector = psVectorAlloc(numCols, PS_TYPE_F64);
    910721
    911722    // Fill vectors with results and status of results
    912     for(psU64 i=0; i<numCols; i++) {
     723    // XXX: This algorithm must be changed to something more efficient!
     724    for (long i = 0; i < numCols; i++) {
    913725        outVector->data.F64[i] = psLookupTableInterpolate(table, index, i);
    914         if(isnan(outVector->data.F64[i])) {
     726        if (isnan(outVector->data.F64[i])) {
    915727            // Free allocated vector
    916728            psFree(outVector);
Note: See TracChangeset for help on using the changeset viewer.