|
ocssw
1.0
|
00001 #ifdef IRIX 00002 #include <ieeefp.h> 00003 #endif 00004 00005 #include <math.h> 00006 #include "fmt_check.h" 00007 00008 extern int fmt_status; /* format checking status, see fmt_check */ 00009 00010 int get_attr( int32 fid, attr_str attr, u_data *value, int *d_count ) 00011 /******************************************************************* 00012 00013 get_attr 00014 00015 purpose: for a particular attribute, check the existance of it 00016 in the dataset and make sure it has the specified 00017 attribute name, number type and count. If so, 00018 read the attribute into the data area 00019 00020 Returns type: int - 0 if all went well, 00021 -1 can't find the attribute 00022 -2 bad match with name, number type or count 00023 -3 unable to read the data 00024 00025 Parameters: (in calling order) 00026 Type Name I/O Description 00027 ---- ---- --- ----------- 00028 int32 fid I file id or sds id 00029 attr_str attr I attribute description 00030 structure. 00031 u_data * value O returned data structure 00032 int* d_count O data item count read 00033 00034 Modification history: 00035 Programmer Date Description of change 00036 ---------- ---- --------------------- 00037 W. Robinson 27-Jan-1995 Original development 00038 W. Robinson 30-Jun-1995 assure that only 3000 bytes of 00039 attribute data are read 00040 W. Robinson 30-Jun-1995 set fmt_status if problems 00041 W. Robinson 4-Oct-1995 save actual count (a_count) for 00042 printing 00043 W. Robinson 20-Nov-1995 add check for strings so they have 00044 only 1 null at the end (str_chk) 00045 L. Kumar 19-Dec-1995 after gets back from str_chk, if the 00046 string lack a null, place a null at 00047 the end of string 00048 W. Robinson 17-Sep-1996 increase the string handeling 00049 capability to 66000 bytes (enough 00050 for HDF 4.0) 00051 W. Robinson 26-Sep-1996 enable attribute range checking 00052 W. Robinson 31-Oct-1996 upgrade to handle float64 data type 00053 W. Robinson 31-May-2000 check the floats for NaN if read and 00054 the doubles to be finite 00055 W. Robinson 15-Mar-2001 update for a linux array size change 00056 (hope it always works) 00057 W. Robinson 3 Feb 2010 allow a small range in float attrib 00058 value checking 00059 00060 *******************************************************************/ 00061 00062 { 00063 int i, iatr; 00064 int32 attr_index, gain1[8], index, sds_id; 00065 char att_info_name[200], a_name[200], *temp; 00066 int32 att_info_numtyp, att_info_count, a_n_type, a_count; 00067 00068 void chk_str( attr_str, char *, int32 ); 00069 00070 if( ( attr_index = SDfindattr( fid, attr.access_nm ) ) 00071 == -1 ) 00072 { 00073 printf( "**** object: '%s', Error trying to get attribute '%s'\n", 00074 attr.obj_nm, attr.access_nm ); 00075 fmt_status = fmt_status | 2; 00076 return -1; 00077 } 00078 /* 00079 * Call SDattrinfo to get the info on this attribute 00080 */ 00081 if( SDattrinfo( fid, attr_index, a_name, &a_n_type, &a_count ) 00082 == -1 ) 00083 { 00084 printf( "**** Error in SDattrinfo for object: '%s', attribute: '%s'\n", 00085 attr.obj_nm, attr.access_nm ); 00086 fmt_status = fmt_status | 2; 00087 return -4; 00088 } 00089 /* 00090 * put actual count in output variable 00091 */ 00092 *d_count = a_count; 00093 00094 /* 00095 * Check the name, number type and count 00096 */ 00097 i = 0; 00098 if( strcmp( a_name, attr.int_nm ) != 0 ) 00099 { 00100 printf( 00101 "**** object: '%s', attribute: '%s', difference in attribute name found\n", 00102 attr.obj_nm, attr.access_nm ); 00103 printf( "expected: '%s', read: '%s'\n", attr.int_nm, a_name ); 00104 fmt_status = fmt_status | 2; 00105 i = 1; 00106 } 00107 if( a_n_type != attr.type ) 00108 { 00109 printf( 00110 "**** object: '%s', attribute: '%s', difference in number type found\n", 00111 attr.obj_nm, attr.access_nm ); 00112 printf( "expected: %d, read: %d\n", attr.type, a_n_type ); 00113 fmt_status = fmt_status | 2; 00114 i = 1; 00115 } 00116 if( attr.count > 0 && a_count != attr.count ) 00117 { 00118 printf( "**** object: '%s', attribute: '%s', difference in count found\n", 00119 attr.obj_nm, attr.access_nm ); 00120 printf( "expected: %d, read: %d\n", attr.count, a_count ); 00121 fmt_status = fmt_status | 2; 00122 i = 1; 00123 } 00124 if( i != 0 ) return -2; 00125 /* 00126 * read in the attribute 00127 */ 00128 if( attr.read != ATT_RD_NOREAD ) 00129 { 00130 /* 00131 * in the event the attribute gets larger than the # bytes 00132 * in value (a generous 66000 bytes!), allocate a temp read area 00133 * and transfer the first 66000 bytes 00134 * ** Use variable FMT_8BLEN for the 66000 ** 00135 */ 00136 if( a_count * DFKNTsize( a_n_type ) >= FMT_8BLEN * 8 ) 00137 { 00138 printf( "**** object: '%s', attribute: '%s' has excessive count of \n", 00139 attr.obj_nm, attr.access_nm ); 00140 printf( "%d items. Truncated list of bytes will be used\n", 00141 a_count ); 00142 /* remove this as a problem 00143 fmt_status = fmt_status | 2; 00144 */ 00145 00146 temp = (char *) malloc( a_count * DFKNTsize( a_n_type ) ); 00147 if( SDreadattr( fid, attr_index, temp ) == -1 ) 00148 { 00149 printf( "**** object: '%s', attribute: '%s', Error reading data\n", 00150 attr.obj_nm, attr.access_nm); 00151 return -3; 00152 fmt_status = fmt_status | 2; 00153 } 00154 /* 00155 * check for null at end only 00156 */ 00157 chk_str( attr, temp, a_count ); 00158 00159 memcpy( value->chr, temp, FMT_8BLEN ); 00160 free( temp ); 00161 } 00162 else 00163 { 00164 if( SDreadattr( fid, attr_index, value->chr ) == -1 ) 00165 { 00166 printf( "**** object: '%s', attribute: '%s', Error reading data\n", 00167 attr.obj_nm, attr.access_nm); 00168 fmt_status = fmt_status | 2; 00169 return -3; 00170 } 00171 /* 00172 * check for null at end only 00173 */ 00174 chk_str( attr, value->chr, a_count ); 00175 } 00176 /* 00177 * any read-in floats can be checked for NaN status and the doubles can 00178 * be checked for finite status 00179 */ 00180 switch ( attr.type ) 00181 { 00182 case DFNT_FLOAT32: 00183 for( i = 0; i < attr.count; i++ ) 00184 { 00185 if( isnan( value->f32[i] ) ) 00186 { 00187 printf( 00188 "**** object: '%s', attribute '%s'[%d]\n", 00189 attr.obj_nm, attr.access_nm, i ); 00190 printf( "is not a number (NaN)\n" ); 00191 fmt_status = fmt_status | 2; 00192 } 00193 } 00194 break; 00195 case DFNT_FLOAT64: 00196 for( i = 0; i < attr.count; i++ ) 00197 { 00198 if( !finite( attr.data.f64[i] ) ) 00199 { 00200 printf( 00201 "**** object: '%s', attribute '%s'[%d]\n", 00202 attr.obj_nm, attr.access_nm, i ); 00203 printf( "is not a number (NaN) or not finite\n" ); 00204 fmt_status = fmt_status | 2; 00205 } 00206 } 00207 break; 00208 } 00209 /* 00210 * Check the constant attribute values (read = READ_ONE_VAL) 00211 * and handle variables in a range to calling routine 00212 */ 00213 if( attr.read == ATT_RD_READ_ONE_VAL ) 00214 { 00215 switch ( attr.type ) 00216 { 00217 case DFNT_CHAR: 00218 if( value->chr[a_count-1] != 0 ) /* LK */ 00219 value->chr[a_count] = 0; /* LK */ 00220 if( strcmp( value->chr, attr.data.chr ) != 0 ) 00221 { 00222 printf( "**** object: '%s', difference in attribute '%s'\n", 00223 attr.obj_nm, attr.access_nm ); 00224 printf( "expected value: '%s'\nread value : '%s'\n", 00225 attr.data.chr, value->chr ); 00226 fmt_status = fmt_status | 2; 00227 } 00228 break; 00229 case DFNT_FLOAT32: 00230 for( i = 0; i < attr.count; i++ ) 00231 { 00232 if( ( value->f32[i] < attr.data.f32[i] - 00233 fabsf( attr.data.f32[i] ) * ERR_FRAC_F32 ) || 00234 ( value->f32[i] > attr.data.f32[i] + 00235 fabsf( attr.data.f32[i] ) * ERR_FRAC_F32 ) ) 00236 { 00237 printf( 00238 "**** object: '%s', difference in attribute '%s'[%d]\n", 00239 attr.obj_nm, attr.access_nm, i ); 00240 printf( "expected value: %f\nread value: %f\n", 00241 attr.data.f32[i], value->f32[i] ); 00242 fmt_status = fmt_status | 2; 00243 } 00244 } 00245 break; 00246 case DFNT_FLOAT64: 00247 for( i = 0; i < attr.count; i++ ) 00248 { 00249 if( ( value->f64[i] < attr.data.f64[i] - 00250 fabs( attr.data.f64[i] ) * ERR_FRAC_F64 ) || 00251 ( value->f64[i] > attr.data.f64[i] + 00252 fabs( attr.data.f64[i] ) * ERR_FRAC_F64 ) ) 00253 { 00254 printf( 00255 "**** object: '%s', difference in attribute '%s'[%d]\n", attr.obj_nm, attr.access_nm, i ); 00256 printf( "expected value: %f\nread value: %f\n", 00257 attr.data.f64[i], value->f64[i] ); 00258 fmt_status = fmt_status | 2; 00259 } 00260 } 00261 break; 00262 case DFNT_INT8: 00263 for( i = 0; i < attr.count; i++ ) 00264 { 00265 if( value->i8[i] != attr.data.i8[i] ) 00266 { 00267 printf( 00268 "**** object: '%s', difference in attribute '%s'[%d]\n", attr.obj_nm, attr.access_nm, i ); 00269 printf( "expected value: %d\nread value: %d\n", 00270 attr.data.i8[i], value->i8[i] ); 00271 fmt_status = fmt_status | 2; 00272 } 00273 } 00274 break; 00275 case DFNT_UINT8: 00276 for( i = 0; i < attr.count; i++ ) 00277 { 00278 if( value->ui8[i] != attr.data.ui8[i] ) 00279 { 00280 printf( 00281 "**** object: '%s', difference in attribute '%s'[%d]\n", attr.obj_nm, attr.access_nm, i ); 00282 printf( "expected value: %d\nread value: %d\n", 00283 attr.data.ui8[i], value->ui8[i] ); 00284 fmt_status = fmt_status | 2; 00285 } 00286 } 00287 break; 00288 case DFNT_INT16: 00289 for( i = 0; i < attr.count; i++ ) 00290 { 00291 if( value->i16[i] != attr.data.i16[i] ) 00292 { 00293 printf( 00294 "**** object: '%s', difference in attribute '%s'[%d]\n", 00295 attr.obj_nm, attr.access_nm, i ); 00296 printf( "expected value: %d\nread value: %d\n", 00297 attr.data.i16[i], value->i16[i] ); 00298 fmt_status = fmt_status | 2; 00299 } 00300 } 00301 break; 00302 case DFNT_INT32: 00303 for( i = 0; i < attr.count; i++ ) 00304 { 00305 if( value->i32[i] != attr.data.i32[i] ) 00306 { 00307 printf( 00308 "**** object: '%s', difference in attribute '%s'[%d]\n", 00309 attr.obj_nm, attr.access_nm, i ); 00310 printf( "expected value: %d\nread value: %d\n", 00311 attr.data.i32[i], value->i32[i] ); 00312 fmt_status = fmt_status | 2; 00313 } 00314 } 00315 break; 00316 default: 00317 printf( "************* DEFAULT CASE OF VALUE CHECKING\n" ); 00318 printf( "Program error\n" ); 00319 fmt_status = fmt_status | 1; 00320 break; 00321 } 00322 } 00323 else if( attr.read == ATT_RD_READ_INCLUSIVE ) 00324 { 00325 switch ( attr.type ) 00326 { 00327 case DFNT_CHAR: 00328 if( value->chr[a_count-1] != 0 ) /* LK */ 00329 value->chr[a_count] = 0; /* LK */ 00330 if( strcmp( value->chr, attr.data.chr ) != 0 ) 00331 { 00332 printf( "**** object: '%s', difference in attribute '%s'\n", 00333 attr.obj_nm, attr.access_nm ); 00334 printf( "expected value: '%s'\nread value : '%s'\n", 00335 attr.data.chr, value->chr ); 00336 fmt_status = fmt_status | 2; 00337 } 00338 break; 00339 case DFNT_FLOAT32: 00340 for( i = 0; i < attr.count; i++ ) 00341 { 00342 if( value->f32[i] < attr.data.f32[0] || 00343 value->f32[i] > attr.data.f32[1] ) 00344 { 00345 printf( 00346 "**** object: '%s', outside range in attribute '%s'[%d]\n", 00347 attr.obj_nm, attr.access_nm, i ); 00348 printf( "valid range: %f - %f\nread value: %f\n", 00349 attr.data.f32[0], attr.data.f32[1], value->f32[i] ); 00350 fmt_status = fmt_status | 2; 00351 } 00352 } 00353 break; 00354 case DFNT_FLOAT64: 00355 for( i = 0; i < attr.count; i++ ) 00356 { 00357 if( value->f64[i] < attr.data.f64[0] || 00358 value->f64[i] > attr.data.f64[1] ) 00359 { 00360 printf( 00361 "**** object: '%s', outside range in attribute '%s'[%d]\n", attr.obj_nm, attr.access_nm, i ); 00362 printf( "valid range: %f - %f\nread value: %f\n", 00363 attr.data.f64[0], attr.data.f64[1], value->f64[i] ); 00364 fmt_status = fmt_status | 2; 00365 } 00366 } 00367 break; 00368 case DFNT_INT8: 00369 for( i = 0; i < attr.count; i++ ) 00370 { 00371 if( value->i8[i] < attr.data.i8[0] || 00372 value->i8[i] > attr.data.i8[1] ) 00373 { 00374 printf( 00375 "**** object: '%s', outside range in attribute '%s'[%d]\n", attr.obj_nm, attr.access_nm, i ); 00376 printf( "valid range: %d - %d\nread value: %d\n", 00377 attr.data.i8[0], attr.data.i8[1], value->i8[i] ); 00378 fmt_status = fmt_status | 2; 00379 } 00380 } 00381 break; 00382 case DFNT_UINT8: 00383 for( i = 0; i < attr.count; i++ ) 00384 { 00385 if( value->ui8[i] < attr.data.ui8[0] || 00386 value->ui8[i] > attr.data.ui8[1] ) 00387 { 00388 printf( 00389 "**** object: '%s', outside range in attribute '%s'[%d]\n", attr.obj_nm, attr.access_nm, i ); 00390 printf( "valid range: %d - %d\nread value: %d\n", 00391 attr.data.ui8[0], attr.data.ui8[1], value->ui8[i] ); 00392 fmt_status = fmt_status | 2; 00393 } 00394 } 00395 break; 00396 case DFNT_INT16: 00397 for( i = 0; i < attr.count; i++ ) 00398 { 00399 if( value->i16[i] < attr.data.i16[0] || 00400 value->i16[i] > attr.data.i16[1] ) 00401 { 00402 printf( 00403 "**** object: '%s', outside range in attribute '%s'[%d]\n", 00404 attr.obj_nm, attr.access_nm, i ); 00405 printf( "valid range: %d - %d\nread value: %d\n", 00406 attr.data.i16[0], attr.data.i16[1], value->i16[i] ); 00407 fmt_status = fmt_status | 2; 00408 } 00409 } 00410 break; 00411 case DFNT_INT32: 00412 for( i = 0; i < attr.count; i++ ) 00413 { 00414 if( value->i32[i] < attr.data.i32[0] || 00415 value->i32[i] > attr.data.i32[1] ) 00416 { 00417 printf( 00418 "**** object: '%s', outside range in attribute '%s'[%d]\n", 00419 attr.obj_nm, attr.access_nm, i ); 00420 printf( "valid range: %d - %d\nread value: %d\n", 00421 attr.data.i32[0], attr.data.i32[1], value->i32[i] ); 00422 fmt_status = fmt_status | 2; 00423 } 00424 } 00425 break; 00426 default: 00427 printf( "************* DEFAULT CASE OF VALUE CHECKING\n" ); 00428 printf( "Program error\n" ); 00429 fmt_status = fmt_status | 1; 00430 break; 00431 } 00432 } 00433 } 00434 return 0; 00435 }
1.7.6.1