IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 19778


Ignore:
Timestamp:
Sep 28, 2008, 10:06:37 AM (18 years ago)
Author:
eugene
Message:

adding boolean expressions to psMetadataItemCompare (in template comment)

File:
1 edited

Legend:

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

    r16645 r19778  
    44
    55#include <stdio.h>
     6#include <ctype.h>
    67#include <string.h>
    78#include <strings.h>
     
    1415#include "psMetadataItemCompare.h"
    1516
     17typedef enum {
     18    PS_MD_OP_EQ,
     19    PS_MD_OP_LT,
     20    PS_MD_OP_LE,
     21    PS_MD_OP_GT,
     22    PS_MD_OP_GE,
     23    PS_MD_OP_NE
     24} psMetadataItemCompareOp;
     25
     26/* determine boolean operator specified in comment: @OP: X@ (default is ==) */
     27psMetadataItemCompareOp p_psMetadataItemCompareGetOp (const psMetadataItem *item) {
     28
     29    if (!item->comment) return PS_MD_OP_EQ;
     30
     31    char *p1 = strstr (item->comment, "@OP:");
     32    if (!p1) return PS_MD_OP_EQ;
     33    p1 += 4; // point to first char after @OP:
     34    while (isblank(p1[0])) p1++;
     35
     36    char *p2 = strchr (p1, '@');
     37    if (!p2) return PS_MD_OP_EQ;
     38
     39    // the string starting at p1 and p2 must contain one of the following:
     40    // == or = PS_MD_OP_EQ,
     41    // < PS_MD_OP_LT,
     42    // <= PS_MD_OP_LE,
     43    // > PS_MD_OP_GT,
     44    // >= PS_MD_OP_GE,
     45    // ! PS_MD_OP_NE
     46   
     47    // XXX a bit crude: does not catch the case of invalid chars after boolean op
     48    if (!strncmp (p1, "==", 2)) return PS_MD_OP_EQ;
     49    if (!strncmp (p1, "=",  1)) return PS_MD_OP_EQ;
     50    if (!strncmp (p1, "<=", 2)) return PS_MD_OP_LE;
     51    if (!strncmp (p1, "<",  1)) return PS_MD_OP_LT;
     52    if (!strncmp (p1, ">=", 2)) return PS_MD_OP_GE;
     53    if (!strncmp (p1, ">",  1)) return PS_MD_OP_GT;
     54
     55    return PS_MD_OP_EQ;
     56}
     57
     58// XXX better value for tolerance?
     59# define EQ_TOL 1e-6
     60
     61# define COMPARE_CASE(TEMPLATENAME, TEMPLATETYPE, COMPARENAME, COMPARETYPENAME) \
     62  case PS_TYPE_##COMPARETYPENAME: {                                      \
     63      TEMPLATETYPE valueC = (TEMPLATETYPE)compare->data.COMPARENAME;     \
     64      TEMPLATETYPE valueT = (TEMPLATETYPE)template->data.TEMPLATENAME;                    \
     65      /* XXX check the validiy of the type casting? */                 \
     66      if (valueC != compare->data.COMPARENAME) {                         \
     67          return false;                                          \
     68      }                                                          \
     69      /* does template specify a boolean operation in comment? */ \
     70      psMetadataItemCompareOp op = p_psMetadataItemCompareGetOp (template);  \
     71      switch (op) { \
     72        case PS_MD_OP_EQ: \
     73          if ((template->type == PS_TYPE_F32) || (template->type == PS_TYPE_F64)) { \
     74              result = fabs(valueT - valueC) < EQ_TOL; \
     75          } else { \
     76              result = valueT == valueC; \
     77          } \
     78          break; \
     79        case PS_MD_OP_LT: \
     80          result = valueC < valueT; \
     81          break; \
     82        case PS_MD_OP_LE: \
     83          result = valueC <= valueT; \
     84          break; \
     85        case PS_MD_OP_GT: \
     86          result = valueC > valueT; \
     87          break; \
     88        case PS_MD_OP_GE: \
     89          result = valueC >= valueT; \
     90          break; \
     91        case PS_MD_OP_NE: \
     92          result = valueC != valueT; \
     93          break; \
     94        default: \
     95          psAbort ("all cases should have been handled..."); \
     96      } \
     97      return (result); \
     98    }
     99
     100#define TEMPLATE_CASE(TYPENAME, NAME, TYPE)                             \
     101    case PS_TYPE_##TYPENAME:                                            \
     102    switch(compare->type) {                                             \
     103        COMPARE_CASE(NAME, TYPE, B  , BOOL);                            \
     104        COMPARE_CASE(NAME, TYPE, U8 , U8 );                             \
     105        COMPARE_CASE(NAME, TYPE, U16, U16);                             \
     106        COMPARE_CASE(NAME, TYPE, U32, U32);                             \
     107        COMPARE_CASE(NAME, TYPE, S8 , S8 );                             \
     108        COMPARE_CASE(NAME, TYPE, S16, S16);                             \
     109        COMPARE_CASE(NAME, TYPE, S32, S32);                             \
     110        COMPARE_CASE(NAME, TYPE, F32, F32);                             \
     111        COMPARE_CASE(NAME, TYPE, F64, F64);                             \
     112      default:                                                          \
     113        psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Don't know how to compare types %x and %x\n", \
     114                compare->type, template->type);                         \
     115        return false;                                                   \
     116    }
     117
     118
    16119bool psMetadataItemCompare(const psMetadataItem *compare, // Item to compare to the template
    17120                           const psMetadataItem *template) // The template
    18121{
    19122
    20     // First order checks
     123    // First order checks:
     124
     125    // both items must exist
    21126    if (! compare || ! template) {
    22127        return false;
    23128    }
    24     if (strcmp(compare->name, template->name)
    25             != 0) {
     129
     130    // the names of both items must match
     131    if (strcmp(compare->name, template->name)) {
    26132        return false;
    27133    }
    28134
    29 
    30     #define COMPARE_CASE(TEMPLATENAME, TEMPLATETYPE, COMPARENAME, COMPARETYPENAME) \
    31 case PS_TYPE_##COMPARETYPENAME: { \
    32         TEMPLATETYPE value = (TEMPLATETYPE)compare->data.COMPARENAME; \
    33         if (value != compare->data.COMPARENAME) { \
    34             return false; \
    35         } \
    36         return (template->data.TEMPLATENAME == value) ? true : false; \
    37     }
    38 
    39     #define TEMPLATE_CASE(TYPENAME, NAME, TYPE) \
    40 case PS_TYPE_##TYPENAME: \
    41     switch(compare->type) { \
    42         COMPARE_CASE(NAME, TYPE, B  , BOOL); \
    43         COMPARE_CASE(NAME, TYPE, U8 , U8 ); \
    44         COMPARE_CASE(NAME, TYPE, U16, U16); \
    45         COMPARE_CASE(NAME, TYPE, U32, U32); \
    46         COMPARE_CASE(NAME, TYPE, S8 , S8 ); \
    47         COMPARE_CASE(NAME, TYPE, S16, S16); \
    48         COMPARE_CASE(NAME, TYPE, S32, S32); \
    49         COMPARE_CASE(NAME, TYPE, F32, F32); \
    50         COMPARE_CASE(NAME, TYPE, F64, F64); \
    51     default: \
    52         psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Don't know how to compare types %x and %x\n", \
    53                 compare->type, template->type); \
    54         return false; \
    55     }
    56 
     135    bool result = false;
    57136
    58137    switch (template->type) {
    59         TEMPLATE_CASE(BOOL, B,   bool)
    60         ;
     138        TEMPLATE_CASE(BOOL, B,   bool) ;
    61139        TEMPLATE_CASE(U8,   U8,  psU8 );
    62140        TEMPLATE_CASE(U16,  U16, psU16);
     
    67145        TEMPLATE_CASE(F32,  F32, psF32);
    68146        TEMPLATE_CASE(F64,  F64, psF64);
     147
    69148    case PS_DATA_STRING:
    70149
Note: See TracChangeset for help on using the changeset viewer.