Changeset 19778
- Timestamp:
- Sep 28, 2008, 10:06:37 AM (18 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/types/psMetadataItemCompare.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/types/psMetadataItemCompare.c
r16645 r19778 4 4 5 5 #include <stdio.h> 6 #include <ctype.h> 6 7 #include <string.h> 7 8 #include <strings.h> … … 14 15 #include "psMetadataItemCompare.h" 15 16 17 typedef 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 ==) */ 27 psMetadataItemCompareOp 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 16 119 bool psMetadataItemCompare(const psMetadataItem *compare, // Item to compare to the template 17 120 const psMetadataItem *template) // The template 18 121 { 19 122 20 // First order checks 123 // First order checks: 124 125 // both items must exist 21 126 if (! compare || ! template) { 22 127 return false; 23 128 } 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)) { 26 132 return false; 27 133 } 28 134 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; 57 136 58 137 switch (template->type) { 59 TEMPLATE_CASE(BOOL, B, bool) 60 ; 138 TEMPLATE_CASE(BOOL, B, bool) ; 61 139 TEMPLATE_CASE(U8, U8, psU8 ); 62 140 TEMPLATE_CASE(U16, U16, psU16); … … 67 145 TEMPLATE_CASE(F32, F32, psF32); 68 146 TEMPLATE_CASE(F64, F64, psF64); 147 69 148 case PS_DATA_STRING: 70 149
Note:
See TracChangeset
for help on using the changeset viewer.
