1 /***********************************************************************/
2 /* Open Visualization Data Explorer                                    */
3 /* (C) Copyright IBM Corp. 1989,1999                                   */
4 /* ALL RIGHTS RESERVED                                                 */
5 /* This code licensed under the                                        */
6 /*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
7 /***********************************************************************/
8 
9 #include <dxconfig.h>
10 
11 #if defined(HAVE_STRING_H)
12 #include <string.h>
13 #endif
14 
15 #include "dx/dx.h"
16 #include "cat.h"
17 
18 static Error traverse( Object *, Object * );
19 static Error doLeaf( Object *, Object * );
20 static Error init_lookup( lookupinfo *ls );
21 static Error do_lookup( lookupinfo *ls );
22 static int get_int( catinfo *cp, char *s );
23 
24 Error
m_Lookup(Object * in,Object * out)25 m_Lookup( Object *in, Object *out )
26 {
27     int i;
28 
29     out[ 0 ] = NULL;
30 
31     if ( in[ 0 ] == NULL ) {
32         DXSetError( ERROR_MISSING_DATA, "\"input\" must be specified" );
33         return ERROR;
34     }
35 
36     out[ 0 ] = DXCopy( ( Object ) in[ 0 ], COPY_STRUCTURE );
37 
38     if ( !traverse( in, out ) )
39         goto error;
40 
41     return OK;
42 
43 error:
44     for ( i = 0; i < 1; i++ ) {
45         if ( in[ i ] != out[ i ] )
46             DXDelete( out[ i ] );
47 
48         out[ i ] = NULL;
49     }
50 
51     return ERROR;
52 }
53 
54 
55 static Error
traverse(Object * in,Object * out)56 traverse( Object *in, Object *out )
57 {
58     switch ( DXGetObjectClass( in[ 0 ] ) ) {
59     case CLASS_FIELD:
60     case CLASS_ARRAY:
61     case CLASS_STRING:
62 
63         if ( ! doLeaf( in, out ) )
64             return ERROR;
65 
66         return OK;
67 
68     case CLASS_GROUP: {
69             int i;
70             int memknt;
71             Category c;
72             Type t;
73             int rank;
74             int shape[ 32 ];
75             Class groupClass = DXGetGroupClass( ( Group ) in[ 0 ] );
76 
77             DXGetMemberCount( ( Group ) in[ 0 ], &memknt );
78 
79             for ( i = 0; i < memknt; i++ ) {
80                 Object new_in[ 8 ], new_out[ 1 ];
81 
82                 if ( in[ 0 ] )
83                     new_in[ 0 ] = DXGetEnumeratedMember( ( Group ) in[ 0 ], i, NULL );
84                 else
85                     new_in[ 0 ] = NULL;
86 
87                 new_in[ 1 ] = in[ 1 ];
88 
89                 new_in[ 2 ] = in[ 2 ];
90 
91                 new_in[ 3 ] = in[ 3 ];
92 
93                 new_in[ 4 ] = in[ 4 ];
94 
95                 new_in[ 5 ] = in[ 5 ];
96 
97                 new_in[ 6 ] = in[ 6 ];
98 
99                 new_in[ 7 ] = in[ 7 ];
100 
101                 if ( groupClass != CLASS_GROUP ) {
102                     if ( i == 0 ) {
103                         DXDelete( ( Object ) out[ 0 ] );
104 
105                         switch ( groupClass ) {
106                         case CLASS_SERIES: out[ 0 ] = ( Object ) DXNewSeries(); break;
107                         case CLASS_MULTIGRID: out[ 0 ] = ( Object ) DXNewMultiGrid(); break;
108                         case CLASS_COMPOSITEFIELD: out[ 0 ] = ( Object ) DXNewCompositeField(); break;
109                         default: return ERROR;
110                         }
111                     }
112 
113                     new_out[ 0 ] = DXCopy( ( Object ) new_in[ 0 ], COPY_STRUCTURE );
114 
115                     if ( ! traverse( new_in, new_out ) )
116                         return ERROR;
117 
118                     if ( i == 0 ) {
119                         if ( ! DXGetType( ( Object ) new_out[ 0 ], &t, &c, &rank, shape ) )
120                             return ERROR;
121 
122                         if ( ! DXSetGroupTypeV( ( Group ) out[ 0 ], t, c, rank, shape ) )
123                             return ERROR;
124                     }
125                 }
126 
127                 else {
128                     new_out[ 0 ] = DXGetEnumeratedMember( ( Group ) out[ 0 ], i, NULL );
129 
130                     if ( ! traverse( new_in, new_out ) )
131                         return ERROR;
132                 }
133 
134 
135                 if ( ! DXSetEnumeratedMember( ( Group ) out[ 0 ], i, new_out[ 0 ] ) )
136                     return ERROR;
137 
138             }
139 
140             return OK;
141         }
142 
143     case CLASS_XFORM: {
144             Object new_in[ 8 ], new_out[ 1 ];
145 
146             if ( in[ 0 ] )
147                 DXGetXformInfo( ( Xform ) in[ 0 ], &new_in[ 0 ], NULL );
148             else
149                 new_in[ 0 ] = NULL;
150 
151             new_in[ 1 ] = in[ 1 ];
152 
153             new_in[ 2 ] = in[ 2 ];
154 
155             new_in[ 3 ] = in[ 3 ];
156 
157             new_in[ 4 ] = in[ 4 ];
158 
159             new_in[ 5 ] = in[ 5 ];
160 
161             new_in[ 6 ] = in[ 6 ];
162 
163             new_in[ 7 ] = in[ 7 ];
164 
165             DXGetXformInfo( ( Xform ) out[ 0 ], &new_out[ 0 ], NULL );
166 
167             if ( ! traverse( new_in, new_out ) )
168                 return ERROR;
169 
170             DXSetXformObject( ( Xform ) out[ 0 ], new_out[ 0 ] );
171 
172             return OK;
173         }
174 
175     case CLASS_CLIPPED: {
176             Object new_in[ 8 ], new_out[ 1 ];
177 
178 
179             if ( in[ 0 ] )
180                 DXGetClippedInfo( ( Clipped ) in[ 0 ], &new_in[ 0 ], NULL );
181             else
182                 new_in[ 0 ] = NULL;
183 
184             new_in[ 1 ] = in[ 1 ];
185 
186             new_in[ 2 ] = in[ 2 ];
187 
188             new_in[ 3 ] = in[ 3 ];
189 
190             new_in[ 4 ] = in[ 4 ];
191 
192             new_in[ 5 ] = in[ 5 ];
193 
194             new_in[ 6 ] = in[ 6 ];
195 
196             new_in[ 7 ] = in[ 7 ];
197 
198             DXGetClippedInfo( ( Clipped ) out[ 0 ], &new_out[ 0 ], NULL );
199 
200             if ( ! traverse( new_in, new_out ) )
201                 return ERROR;
202 
203             DXSetClippedObjects( ( Clipped ) out[ 0 ], new_out[ 0 ], NULL );
204 
205             return OK;
206         }
207 
208     default:
209         break;
210     }
211 
212     DXSetError( ERROR_BAD_CLASS, "input must be Field or Group" );
213     return ERROR;
214 }
215 
216 static int
doLeaf(Object * in,Object * out)217 doLeaf( Object *in, Object *out )
218 {
219     int i, result = 0;
220     Field field;
221     int rank, shape[ 30 ];
222     Category category;
223     char *data_comp;
224     char *lookup_comp;
225     char *value_comp;
226     char *dest_comp;
227     char *table_comp;
228     Array input_array = NULL;
229     Array lookup_array = NULL;
230     Array value_array = NULL;
231     int data_knt;
232     Type data_type;
233     char value_str[ 200 ];
234     catinfo cat_data;
235     catinfo cat_lookup;
236     catinfo cat_value;
237     catinfo cat_dest;
238     lookupinfo look;
239     char *ignore;
240     int free_value = 0;
241     int free_input = 0;
242     Class in_class;
243     Class in_data_class;
244     char *str;
245 
246     /* Support user-supplied return value for unfounds */
247     Object nfObj = NULL;
248     int delNfObj = 0;
249     int nfKnt = 0;
250     Category nfCat;
251     Type nfType;
252     int nfRank;
253     int nfShape[30];
254     int  nfSize = 0;
255 
256     memset( &cat_data, 0, sizeof( catinfo ) );
257     memset( &cat_lookup, 0, sizeof( catinfo ) );
258     memset( &cat_value, 0, sizeof( catinfo ) );
259     memset( &cat_dest, 0, sizeof( catinfo ) );
260     memset( &look, 0, sizeof( lookupinfo ) );
261     look.data = &cat_data;
262     look.lookup = &cat_lookup;
263     look.value = &cat_value;
264     look.dest = &cat_dest;
265 
266     in_class = DXGetObjectClass( ( Object ) in[ 0 ] );
267 
268     if ( in_class == CLASS_FIELD ) {
269         field = ( Field ) in[ 0 ];
270 
271         if ( DXEmptyField( field ) )
272             return OK;
273     }
274 
275     if ( !DXExtractString( ( Object ) in[ 2 ], &data_comp ) )
276         data_comp = STR_DATA;
277 
278     if ( !DXExtractString( ( Object ) in[ 3 ], &lookup_comp ) )
279         lookup_comp = STR_POSITIONS;
280 
281     if ( !DXExtractString( ( Object ) in[ 4 ], &value_comp ) ) {
282         value_comp = STR_DATA;
283     }
284 
285     if ( !DXExtractString( ( Object ) in[ 5 ], &dest_comp ) )
286         dest_comp = "lookedup";
287 
288     for ( i = 0; DXExtractNthString( ( Object ) in[ 6 ], i, &ignore ); i++ ) {
289         if ( !strcmp( ignore, "none" ) ) {}
290         else if ( !strcmp( ignore, "case" ) ) {
291             look.ignore |= CAT_I_CASE;
292         }
293 
294         else if ( !strcmp( ignore, "space" ) ) {
295             look.ignore |= CAT_I_SPACE;
296         }
297 
298         else if ( !strcmp( ignore, "lspace" ) ) {
299             look.ignore |= CAT_I_LSPACE;
300         }
301 
302         else if ( !strcmp( ignore, "rspace" ) ) {
303             look.ignore |= CAT_I_RSPACE;
304         }
305 
306         else if ( !strcmp( ignore, "lrspace" ) ) {
307             look.ignore |= CAT_I_LRSPACE;
308         }
309 
310         else if ( !strcmp( ignore, "punctuation" ) ) {
311             look.ignore |= CAT_I_PUNCT;
312         }
313 
314         else {
315             DXSetError( ERROR_BAD_PARAMETER, "ignore value \"%s\" must be one of"
316                         "none, case, space, lspace, rspace, lrspace, punctuation", ignore );
317             goto error;
318         }
319     }
320 
321     nfObj = in[7];
322     if( nfObj ) {
323 	switch(DXGetObjectClass(nfObj)){
324 	case CLASS_STRING:
325 	    /* turn string into array */
326 	    delNfObj = 1;
327 	    nfObj = (Object) DXMakeStringList(1, DXGetString((String)nfObj));
328 	    /* fall thru...*/
329 	case CLASS_ARRAY:
330 	    DXGetArrayInfo( (Array) nfObj,&nfKnt,&nfType,&nfCat,&nfRank,nfShape );
331 	    break;
332 	default:
333 	    DXSetError( ERROR_BAD_PARAMETER, "notFound must be a string or value" );
334 	    goto error;
335 	}
336     }
337 
338     if ( look.ignore & CAT_I_SPACE )
339         look.ignore &= ~( CAT_I_LSPACE | CAT_I_RSPACE | CAT_I_LRSPACE );
340 
341     if ( ( look.ignore & CAT_I_LSPACE ) && ( look.ignore & CAT_I_RSPACE ) )
342         look.ignore |= CAT_I_LRSPACE;
343 
344     if ( look.ignore & CAT_I_LRSPACE )
345         look.ignore &= ~( CAT_I_LSPACE | CAT_I_RSPACE );
346 
347     if ( in_class == CLASS_STRING ) {
348         DXExtractString( ( Object ) in[ 0 ], &str );
349         input_array = DXNewArray( TYPE_STRING, CATEGORY_REAL, 1, strlen( str ) + 1 );
350         DXAddArrayData( input_array, 0, 1, str );
351         in_class = CLASS_ARRAY;
352         free_input = 1;
353     }
354 
355     else if ( in_class == CLASS_ARRAY ) {
356         input_array = ( Array ) in[ 0 ];
357     }
358 
359     else {
360         input_array = ( Array ) DXGetComponentValue( ( Field ) in[ 0 ], data_comp );
361     }
362 
363     if ( ! input_array ) {
364         DXSetError( ERROR_MISSING_DATA, "\"input\" has no \"%s\" component", data_comp );
365         goto error;
366     }
367 
368     in_data_class = DXGetObjectClass( ( Object ) input_array );
369 
370     if ( in_data_class != CLASS_ARRAY && in_data_class != CLASS_STRING ) {
371         DXSetError( ERROR_BAD_CLASS, "component \"%s\" of \"input\" must be an array", data_comp );
372         goto error;
373     }
374 
375     if ( in[ 1 ] == NULL ) {
376         if ( in_class != CLASS_FIELD ) {
377             DXSetError( ERROR_BAD_PARAMETER, "table compononent must be supplied if input is an array" );
378             goto error;
379         }
380 
381         if ( !strcmp( lookup_comp, STR_POSITIONS ) ) {
382             sprintf( value_str, "%s lookup", data_comp );
383             value_comp = value_str;
384             value_array = ( Array ) DXGetComponentValue( ( Field ) in[ 0 ], value_comp );
385 
386             if ( !value_array ) {
387                 DXSetError( ERROR_BAD_PARAMETER, "table component \"%s\" not found in input", value_str );
388                 goto error;
389             }
390         }
391 
392         else {
393             sprintf( value_str, "%s lookup", data_comp );
394             value_comp = value_str;
395             lookup_array = ( Array ) DXGetComponentValue( ( Field ) in[ 0 ], value_comp );
396 
397             if ( !lookup_array ) {
398                 DXSetError( ERROR_BAD_PARAMETER, "table component \"%s\" not found in input", value_str );
399                 goto error;
400             }
401         }
402     }
403 
404     else if ( DXExtractString( ( Object ) in[ 1 ], &table_comp ) ) {
405         if ( in_class != CLASS_FIELD ) {
406             DXSetError( ERROR_BAD_PARAMETER, "table compononent must be supplied if input is an array" );
407             goto error;
408         }
409 
410         if ( !strcmp( lookup_comp, STR_POSITIONS ) ) {
411             value_array = ( Array ) DXGetComponentValue( ( Field ) in[ 0 ], table_comp );
412 
413             if ( !value_array ) {
414                 DXSetError( ERROR_BAD_PARAMETER, "table component \"%s\" not found in input", table_comp );
415                 goto error;
416             }
417         }
418 
419         else {
420             lookup_array = ( Array ) DXGetComponentValue( ( Field ) in[ 0 ], table_comp );
421 
422             if ( !lookup_array ) {
423                 DXSetError( ERROR_BAD_PARAMETER, "table component \"%s\" not found in input", table_comp );
424                 goto error;
425             }
426         }
427     }
428 
429     else if ( DXGetObjectClass( ( Object ) in[ 1 ] ) == CLASS_ARRAY ) {
430         if ( !strcmp( value_comp, STR_DATA ) )
431             value_array = ( Array ) in[ 1 ];
432         else
433             lookup_array = ( Array ) in[ 1 ];
434     }
435 
436     else if ( DXGetObjectClass( ( Object ) in[ 1 ] ) == CLASS_FIELD ) {
437         value_array = ( Array ) DXGetComponentValue( ( Field ) in[ 1 ], value_comp );
438 
439         if ( !value_array ) {
440             DXSetError( ERROR_BAD_PARAMETER, "value component \"%s\" not found in input", value_comp );
441             goto error;
442         }
443 
444         lookup_array = ( Array ) DXGetComponentValue( ( Field ) in[ 1 ], lookup_comp );
445 
446         if ( !lookup_array ) {
447             DXSetError( ERROR_BAD_PARAMETER, "lookup component \"%s\" not found in input", lookup_comp );
448             goto error;
449         }
450     }
451 
452     /* if lookup_array not present, doing implicit lookup */
453     if ( !lookup_array ) {
454         DXGetArrayInfo( input_array, &data_knt, &data_type, &category, &rank, shape );
455 
456         if ( ( data_type != TYPE_BYTE && data_type != TYPE_UBYTE &&
457                 data_type != TYPE_INT && data_type != TYPE_UINT && data_type != TYPE_FLOAT )
458                 || category != CATEGORY_REAL || !( ( rank == 0 )
459                                                    || ( ( rank == 1 ) && ( shape[ 0 ] == 1 ) ) ) ) {
460             DXSetError( ERROR_DATA_INVALID, "data component \"%s\" must be scalar integer or float "
461                         "if lookup is based on implicit index", data_comp );
462             goto error;
463         }
464     }
465 
466     look.data->o = ( Object ) input_array;
467     _dxf_cat_FindCompType( look.data );
468 
469     if ( lookup_array ) {
470         look.lookup->o = ( Object ) lookup_array;
471         _dxf_cat_FindCompType( look.lookup );
472     }
473 
474     else {
475         /* if no lookup_array, we already know data is an integer type */
476         memcpy( look.lookup, look.data, sizeof( catinfo ) );
477     }
478 
479     if ( value_array ) {
480         look.value->o = ( Object ) value_array;
481         _dxf_cat_FindCompType( look.value );
482     }
483 
484     else {
485         int i;
486         int *p;
487         look.value->o = ( Object ) DXNewArray( TYPE_INT, CATEGORY_REAL, 0 );
488         value_array = ( Array ) look.value->o;
489         look.value->num = look.lookup->num;
490         DXAddArrayData( ( Array ) look.value->o, 0, look.value->num, NULL );
491         p = ( int * ) DXGetArrayData( ( Array ) look.value->o );
492 
493         for ( i = 0; i < look.value->num; i++ )
494             p[ i ] = i;
495 
496         _dxf_cat_FindCompType( look.value );
497 
498         free_value = 1;
499     }
500 
501     if ( ( look.data->cat_type != look.lookup->cat_type )
502             ||
503             ( ( look.data->cat_type != CAT_STRING )
504               &&
505               ( ( look.data->obj_size != look.lookup->obj_size ) && ( look.data->cat_type != CAT_SCALAR ) ) ) ) {
506         DXSetError( ERROR_DATA_INVALID, "data component type does not match lookup component" );
507         goto error;
508     }
509 
510     memcpy( look.dest, look.value, sizeof( catinfo ) );
511 
512     DXGetArrayInfo( value_array, &data_knt, &data_type, &category, &rank, shape );
513 
514     if( nfObj ){
515       if(data_type == TYPE_STRING){
516 	/* check type, and be sure result shape is max of value
517 	 * and not-found value's shape.
518 	 */
519         if( nfType != TYPE_STRING ) {
520           DXSetError( ERROR_DATA_INVALID, "notFound type does not match value type" );
521           goto error;
522 	}
523 	if( nfShape[0] > shape[0] )
524 		shape[0] = nfShape[0];
525       }
526       else {
527         /* convert supplied not-found value to same type as value component */
528         Array tmp;
529         if(! (tmp = DXArrayConvertV( (Array)nfObj, data_type, category, rank, shape ))){
530           DXSetError( ERROR_DATA_INVALID, "notFound type does not match value type" );
531           goto error;
532         }
533         if( delNfObj )
534 	  DXDelete( nfObj );
535         nfObj = (Object) tmp;
536         delNfObj = 1;
537       }
538       look.nfValue = (Pointer) DXGetArrayData((Array)nfObj);
539       look.nfLen   = DXGetItemSize((Array)nfObj);
540     }
541 
542     look.dest->comp_array = ( Array ) DXNewArrayV( data_type, category, rank, shape );
543     DXAddArrayData( look.dest->comp_array, 0, look.data->num, NULL );
544     look.dest->comp_data = DXGetArrayData( ( Array ) ( look.dest->comp_array ) );
545     DXCopyAttributes( ( Object ) look.dest->comp_array, ( Object ) input_array );
546 
547     if ( lookup_array )
548         look.lut = ( table_entry * ) DXAllocate( look.value->num * sizeof( table_entry ) );
549 
550     init_lookup( &look );
551 
552     result = do_lookup( &look );
553 
554     if ( ! result ) {
555         if ( DXGetError() == ERROR_NONE )
556             DXSetError( ERROR_INTERNAL, "error return from user routine" );
557 
558         goto error;
559     }
560 
561     if( delNfObj)
562 	    DXDelete( nfObj );
563 
564     if ( free_input ) {
565         DXDelete( ( Object ) input_array );
566         input_array = NULL;
567     }
568 
569     if ( free_value ) {
570         DXDelete( ( Object ) look.value->o );
571         look.value->o = NULL;
572     }
573 
574     if ( look.ignore && look.data->free_data && look.data->comp_data )
575         DXFree( look.data->comp_data );
576 
577     look.data->comp_data = NULL;
578 
579     if ( look.ignore && look.lookup->free_data && look.lookup->comp_data )
580         DXFree( look.lookup->comp_data );
581 
582     look.data->comp_data = NULL;
583 
584     if ( !out[ 0 ] ) {
585         out[ 0 ] = DXCopy( in[ 0 ], COPY_STRUCTURE );
586     }
587 
588     if ( DXGetObjectClass( ( Object ) in[ 0 ] ) == CLASS_FIELD ) {
589         if ( DXGetComponentValue( ( Field ) out[ 0 ], dest_comp ) )
590             DXDeleteComponent( ( Field ) out[ 0 ], dest_comp );
591 
592         if ( ! DXSetComponentValue( ( Field ) out[ 0 ], dest_comp, ( Object ) look.dest->comp_array ) )
593             goto error;
594 
595         DXChangedComponentValues( ( Field ) out[ 0 ], dest_comp );
596 
597         result = DXEndField( ( Field ) out[ 0 ] ) != NULL;
598     }
599 
600     else {
601         out[ 0 ] = ( Object ) look.dest->comp_array;
602         result = OK;
603     }
604 
605     return result;
606 
607 error:
608 
609     if ( free_input )
610         DXDelete( ( Object ) input_array );
611 
612     if ( free_value )
613         DXDelete( ( Object ) look.value->o );
614 
615     if( delNfObj)
616 	    DXDelete( nfObj );
617 
618     if ( look.dest->comp_array )
619         DXDelete( ( Object ) look.dest->comp_array );
620 
621     look.dest->comp_array = NULL;
622 
623     if ( look.ignore && look.data->free_data && look.data->comp_data )
624         DXFree( look.data->comp_data );
625 
626     look.data->comp_data = NULL;
627 
628     if ( look.ignore && look.lookup->free_data && look.lookup->comp_data )
629         DXFree( look.lookup->comp_data );
630 
631     look.data->comp_data = NULL;
632 
633     return result;
634 }
635 
lookupcmp(const void * e1,const void * e2)636 static int lookupcmp( const void *e1, const void *e2 )
637 {
638     return ((table_entry *)e1)->cp->cmpcat( ((table_entry *)e1)->cp,
639     		((table_entry *)e1)->lookup, ((table_entry *)e2)->lookup );
640 }
641 
searchcmp(const void * e1,const void * e2)642 static int searchcmp( const void *e1, const void *e2 )
643 {
644     return ((table_entry *)e2)->cp->cmpcat(
645     			((table_entry*)e2)->cp, (char *)e1, ((table_entry *)e2)->lookup );
646 }
647 
get_int(catinfo * cp,char * s)648 static int get_int( catinfo *cp, char *s )
649 {
650     switch ( cp->comp_type ) {
651     case TYPE_INT: return ( int ) ( *( ( int * ) s ) );
652     case TYPE_UBYTE: return ( int ) ( *( ( ubyte * ) s ) );
653     case TYPE_FLOAT: return ( int ) ( *( ( float * ) s ) + 0.5 );
654     case TYPE_BYTE: return ( int ) ( *s );
655     case TYPE_SHORT: return ( int ) ( *( ( short * ) s ) );
656     case TYPE_USHORT: return ( int ) ( *( ( ushort * ) s ) );
657     case TYPE_UINT: return ( int ) ( *( ( uint * ) s ) );
658     case TYPE_DOUBLE: return ( int ) ( *( ( double * ) s ) + 0.5 );
659     default: return ( int ) ( *( ( int * ) s ) );
660     }
661 }
662 
get_float(catinfo * cp,char * s)663 static float get_float( catinfo *cp, char *s )
664 {
665     switch ( cp->comp_type ) {
666     case TYPE_INT: return ( float ) ( *( ( int * ) s ) );
667     case TYPE_UBYTE: return ( float ) ( *( ( ubyte * ) s ) );
668     case TYPE_FLOAT: return ( float ) ( *( ( float * ) s ) );
669     case TYPE_BYTE: return ( float ) ( *s );
670     case TYPE_SHORT: return ( float ) ( *( ( short * ) s ) );
671     case TYPE_USHORT: return ( float ) ( *( ( ushort * ) s ) );
672     case TYPE_UINT: return ( float ) ( *( ( uint * ) s ) );
673     case TYPE_DOUBLE: return ( float ) ( *( ( double * ) s ) );
674     default: return ( float ) ( *( ( int * ) s ) );
675     }
676 }
677 
init_lookup(lookupinfo * l)678 static Error init_lookup( lookupinfo *l )
679 {
680     int i;
681     char *s, *t;
682     table_entry *lut;
683     char *d;
684     float *f;
685     int *p;
686     int size;
687     int num;
688 
689     if ( !l->lut )
690         return OK;
691 
692     if ( l->ignore && l->data->cat_type == CAT_STRING ) {
693         d = ( char * ) l->data->comp_data;
694         l->data->comp_data = ( Pointer ) DXAllocate( l->data->obj_size * l->data->num );
695         l->data->free_data = 1;
696         size = l->data->obj_size;
697         num = l->data->num;
698 
699         for ( i = 0, s = d, t = ( char * ) l->data->comp_data; i < num; i++, s += size, t += size ) {
700             memcpy( t, s, size );
701             _dxf_cat_ignore( t, l->ignore );
702         }
703 
704         d = ( char * ) l->lookup->comp_data;
705         l->lookup->comp_data = ( Pointer ) DXAllocate( l->lookup->obj_size * l->lookup->num );
706         l->lookup->free_data = 1;
707         size = l->lookup->obj_size;
708         num = l->lookup->num;
709 
710         for ( i = 0, s = d, t = ( char * ) l->lookup->comp_data; i < num; i++, s += size, t += size ) {
711             memcpy( t, s, size );
712             _dxf_cat_ignore( t, l->ignore );
713         }
714     }
715 
716     if ( l->data->cat_type == CAT_SCALAR && l->data->comp_type != l->lookup->comp_type ) {
717         if ( l->data->comp_type == TYPE_FLOAT || l->lookup->comp_type == TYPE_FLOAT ) {
718             if ( l->data->comp_type == TYPE_FLOAT ) {
719                 d = ( char * ) l->lookup->comp_data;
720                 l->lookup->comp_data = ( Pointer ) DXAllocate( sizeof( float ) * l->lookup->num );
721                 l->lookup->free_data = 1;
722                 f = ( float * ) l->lookup->comp_data;
723                 size = l->lookup->obj_size;
724                 num = l->lookup->num;
725 
726                 for ( i = 0; i < num; i++, f++, d += size )
727                     * f = get_float( l->lookup, d );
728 
729                 l->lookup->comp_type = TYPE_FLOAT;
730 
731                 l->lookup->obj_size = sizeof( float );
732             }
733 
734             else {
735                 d = ( char * ) l->data->comp_data;
736                 l->data->comp_data = ( Pointer ) DXAllocate( sizeof( float ) * l->data->num );
737                 l->data->free_data = 1;
738                 f = ( float * ) l->data->comp_data;
739                 size = l->data->obj_size;
740                 num = l->data->num;
741 
742                 for ( i = 0; i < num; i++, f++, d += size )
743                     * f = get_float( l->data, d );
744 
745                 l->data->comp_type = TYPE_FLOAT;
746 
747                 l->data->obj_size = sizeof( float );
748             }
749         }
750 
751         else {
752             if ( l->lookup->comp_type != TYPE_INT ) {
753                 d = ( char * ) l->lookup->comp_data;
754                 l->lookup->comp_data = ( Pointer ) DXAllocate( sizeof( int ) * l->lookup->num );
755                 l->lookup->free_data = 1;
756                 p = ( int * ) l->lookup->comp_data;
757                 size = l->lookup->obj_size;
758                 num = l->lookup->num;
759 
760                 for ( i = 0; i < num; i++, p++, d += size )
761                     * p = get_int( l->lookup, d );
762 
763                 l->lookup->comp_type = TYPE_INT;
764 
765                 l->lookup->obj_size = sizeof( int );
766             }
767 
768             if ( l->data->comp_type != TYPE_INT ) {
769                 d = ( char * ) l->data->comp_data;
770                 l->data->comp_data = ( Pointer ) DXAllocate( sizeof( int ) * l->data->num );
771                 l->data->free_data = 1;
772                 p = ( int * ) l->data->comp_data;
773                 size = l->data->obj_size;
774                 num = l->data->num;
775 
776                 for ( i = 0; i < num; i++, p++, d += size )
777                     * p = get_int( l->data, d );
778 
779                 l->data->comp_type = TYPE_INT;
780 
781                 l->data->obj_size = sizeof( int );
782             }
783         }
784     }
785 
786     s = ( char * ) l->lookup->comp_data;
787     t = ( char * ) l->value->comp_data;
788 
789     for ( i = 0, lut = l->lut; i < l->lookup->num; i++, lut++ ) {
790         lut->lookup = ( Pointer ) s;
791         lut->value = ( Pointer ) t;
792         lut->cp = l->lookup;
793         s += l->lookup->obj_size;
794         t += l->value->obj_size;
795     }
796 
797     qsort( l->lut, l->value->num, sizeof( table_entry ), lookupcmp );
798 
799     return OK;
800 }
801 
do_lookup(lookupinfo * l)802 static Error do_lookup( lookupinfo *l )
803 {
804     int i;
805     char *s, *v;
806     table_entry *found;
807     int num = l->data->num;
808     int size = l->value->obj_size;
809     int datasize = l->data->obj_size;
810     int n;
811 
812     s = ( char * ) l->data->comp_data;
813     v = ( char * ) l->dest->comp_data;
814 
815     if ( l->lut ) {
816         for ( i = 0; i < num; i++, s += datasize, v += size ) {
817             found = ( table_entry * ) bsearch( s, l->lut, l->lookup->num,
818                                                sizeof( table_entry ), searchcmp );
819 
820             if ( found ) {
821                 memcpy( v, ( char * ) found->value, size );
822             }
823 
824 	    else if (l->nfValue) {
825                 memcpy( v, ( char * ) l->nfValue, l->nfLen );
826 	    }
827 
828             else {
829                 memset( v, 0, size );
830             }
831         }
832     }
833 
834     else {
835         for ( i = 0; i < num; i++, s += datasize, v += size ) {
836             n = get_int( l->data, s );
837 
838             if ( n >= 0 && n < l->value->num ) {
839                 memcpy( v, ( char * ) ( &( ( ( char * ) ( l->value->comp_data ) ) [ n * size ] ) ), size );
840             }
841 
842 	    else if (l->nfValue) {
843                 memcpy( v, ( char * ) l->nfValue, l->nfLen );
844 	    }
845 
846             else {
847                 memset( v, 0, size );
848             }
849         }
850     }
851 
852     return OK;
853 }
854