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 #include "../base/defines.h"
11
12 #include "DXStrings.h"
13 #include "List.h"
14 #include "ListIterator.h"
15 #include "DXType.h"
16 #include "DXValue.h"
17
18
19 boolean DXType::DXTypeClassInitialized = FALSE;
20 List *DXType::TypeList;
21 //
22 // Forces initialization so that we can call static member functions
23 // without creating an instance of class DXType.
24 //
25 DXType *__force_init__ = new DXType;
26
27 static
28 DXTypeName _baseType[] =
29 {
30 { 0, "undefined", DXType::UndefinedType },
31 { 0, "value", DXType::ValueType },
32 { 0, "scalar", DXType::ScalarType },
33 { 0, "integer", DXType::IntegerType },
34 { 0, "flag", DXType::FlagType },
35 { 0, "tensor", DXType::TensorType },
36 { 0, "matrix", DXType::TensorType },
37 { 0, "vector", DXType::VectorType },
38 { 0, "value list", DXType::ValueType | DXType::ListType },
39 { 0, "scalar list", DXType::ScalarType | DXType::ListType },
40 { 0, "integer list", DXType::IntegerType | DXType::ListType },
41 { 0, "flag list", DXType::FlagType | DXType::ListType },
42 { 0, "tensor list", DXType::TensorType | DXType::ListType },
43 { 0, "matrix list", DXType::TensorType | DXType::ListType },
44 { 0, "vector list", DXType::VectorType | DXType::ListType },
45 { 0, "string", DXType::StringType },
46 { 0, "string list", DXType::StringType | DXType::ListType },
47 { 0, "camera", DXType::CameraType },
48 { 0, "light", DXType::LightType },
49 { 0, "field", DXType::FieldType },
50 { 0, "geometry field", DXType::GeometryFieldType },
51 { 0, "color field", DXType::ColorFieldType },
52 { 0, "scalar field", DXType::ScalarFieldType },
53 { 0, "vector field", DXType::VectorFieldType },
54 { 0, "data field", DXType::DataFieldType },
55 { 0, "series", DXType::SeriesType },
56 { 0, "field series", DXType::FieldSeriesType },
57 { 0, "image", DXType::ImageType },
58 { 0, "image series", DXType::ImageType | DXType::SeriesType },
59 { 0, "vector field series", DXType::VectorFieldType | DXType::SeriesType },
60 { 0, "group", DXType::GroupType },
61 { 0, "value group", DXType::ValueGroupType },
62 { 0, "value list group", DXType::ValueListGroupType },
63 { 0, "field group", DXType::FieldGroupType },
64 { 0, "image group", DXType::ImageType | DXType::GroupType },
65 { 0, "list", DXType::ListType },
66 { 0, "object", DXType::ObjectType },
67 #if !defined(DONT_DEFINE_WINDOW_TYPE)
68 { 0, "window", DXType::WhereType },
69 #endif
70 };
71
72
73 static
74 long _numBaseTypes = sizeof(_baseType) / sizeof(DXTypeName);
75
76
InitializeClass()77 inline void DXType::InitializeClass()
78 {
79 if (NOT DXType::DXTypeClassInitialized)
80 {
81 //
82 // Create and initialize the type list with the base types.
83 //
84 DXType::TypeList = new List;
85 for (int i = 0; i < _numBaseTypes; i++)
86 {
87 DXType::TypeList->appendElement(&_baseType[i]);
88 }
89
90 DXType::DXTypeClassInitialized = TRUE;
91 }
92 }
93
94
AddUserType(const Type type,const char * name)95 boolean DXType::AddUserType(const Type type,
96 const char* name)
97 {
98 DXTypeName* userType;
99
100 //
101 // Create a new type record and initialize it.
102 //
103 userType = new DXTypeName;
104
105 userType->userDefined = TRUE;
106 userType->type = type;
107 userType->name = DuplicateString(name);
108
109 //
110 // Append the new type to the end of the list.
111 //
112 return DXType::TypeList->appendElement(userType);
113 }
114
115 //
116 // Determine if the given value matches any of the DXTypes contained
117 // in the typelist.
118 // Return the first type found to match, otherwise DXType::UndefinedType.
119 //
FindTypeMatch(const char * value,List * typelist)120 Type DXType::FindTypeMatch(const char *value,
121 List *typelist)
122 {
123 ListIterator iterator(*typelist);
124 DXType *dxtype;
125 Type t;
126
127 ASSERT(typelist->getSize() > 0);
128
129 for (dxtype = (DXType*)iterator.getNext();
130 dxtype != NUL(DXType*);
131 dxtype = (DXType*)iterator.getNext())
132 {
133 t = dxtype->getType();
134 if (DXValue::IsValidValue(value,t))
135 return t;
136 }
137
138 return DXType::UndefinedType;
139
140 }
141
DeleteType(const Type type)142 boolean DXType::DeleteType(const Type type)
143 {
144 ListIterator iterator(*DXType::TypeList);
145 DXTypeName* knownType;
146 int position;
147
148 //
149 // Iterate through the type list and look for a matching type.
150 // If found, delete the type from the list, deallocate the
151 // the name string and the type record if user-defined, and
152 // return TRUE.
153 //
154 for (knownType = (DXTypeName*)iterator.getNext(), position = 1;
155 knownType != NUL(DXTypeName*);
156 knownType = (DXTypeName*)iterator.getNext(), position++)
157 {
158 if (type == knownType->type)
159 {
160 DXType::TypeList->deleteElement(position);
161 if (knownType->userDefined)
162 {
163 delete knownType->name;
164 delete knownType;
165 }
166 }
167 return TRUE;
168 }
169
170 //
171 // No match...return FALSE.
172 //
173 return FALSE;
174 }
175
176
DeleteType(const char * name)177 boolean DXType::DeleteType(const char* name)
178 {
179 ListIterator iterator(*DXType::TypeList);
180 DXTypeName* knownType;
181 int position;
182
183 //
184 // Iterate through the type list and look for a matching type.
185 // If found, delete the type from the list, deallocate the
186 // the name string and the type record if user-defined, and
187 // return TRUE.
188 //
189 for (knownType = (DXTypeName*)iterator.getNext(), position = 1;
190 knownType != NUL(DXTypeName*);
191 knownType = (DXTypeName*)iterator.getNext(), position++)
192 {
193 if (EqualString(name, knownType->name))
194 {
195 DXType::TypeList->deleteElement(position);
196 if (knownType->userDefined)
197 {
198 delete knownType->name;
199 delete knownType;
200 }
201 }
202 return TRUE;
203 }
204
205 //
206 // No match...return FALSE.
207 //
208 return FALSE;
209 }
210
211
TypeToString(const Type type)212 const char* DXType::TypeToString(const Type type)
213 {
214 ListIterator iterator(*DXType::TypeList);
215 DXTypeName* knownType;
216
217 //
218 // Iterate through the type list. If a matching type is
219 // found, return the corresponding string value; otherwise,
220 // return NULL.
221 //
222 while ((knownType=(DXTypeName*)iterator.getNext()))
223 {
224 if (type == knownType->type)
225 {
226 return knownType->name;
227 }
228 }
229
230 return NUL(const char*);
231 }
232
233
StringToType(const char * string)234 Type DXType::StringToType(const char* string)
235 {
236 ListIterator iterator(*DXType::TypeList);
237 DXTypeName* knownType;
238
239 ASSERT(string);
240
241 //
242 // Iterate through the type list. If a matching string is
243 // found, return the corresponding type value; otherwise,
244 // return undefined type.
245 //
246 while ((knownType=(DXTypeName*)iterator.getNext()))
247 {
248 if (EqualString(string, knownType->name))
249 {
250 return knownType->type;
251 }
252 }
253
254 return DXType::UndefinedType;
255 }
256
257
MatchType(const Type source,const Type destination)258 boolean DXType::MatchType(const Type source,
259 const Type destination)
260 {
261 Type intersection;
262 Type baseSource;
263 Type baseDestination;
264
265 //
266 // Get the intersection of source and destination types.
267 //
268 intersection = source & destination;
269
270 //
271 // If there is no intersection...
272 //
273 if (NOT intersection OR intersection == DXType::ListType)
274 {
275 return FALSE;
276 }
277
278 //
279 // If the source/destination type is Object type...
280 //
281 if (source == DXType::ObjectType OR
282 destination == DXType::ObjectType)
283 {
284 return TRUE;
285 }
286
287 //
288 // If the source type is a list while the destination type
289 // is not a list, no match...
290 //
291 if ((source & DXType::ListType) AND (NOT (destination & DXType::ListType)))
292 {
293 return FALSE;
294 }
295
296 //
297 // Strip off list attribute from the source and destination
298 // types at this point.
299 //
300 baseSource = source & DXType::ListTypeMask;
301 baseDestination = destination & DXType::ListTypeMask;
302
303 //
304 // Scalar source type cannot match flag/integer destination type.
305 //
306 if (baseSource == DXType::ScalarType AND
307 (baseDestination == DXType::FlagType OR
308 baseDestination == DXType::IntegerType))
309 {
310 return FALSE;
311 }
312
313 #ifdef OH_YES_THEY_CAN
314 //
315 // Flag source type cannot match integer destination type.
316 //
317 if (baseSource == DXType::FlagType AND
318 baseDestination == DXType::IntegerType)
319 {
320 return FALSE;
321 }
322 #endif
323
324 //
325 // Passed all the tests... return successfully.
326 //
327 return TRUE;
328 }
329
330
MatchType(DXType & source,DXType & destination)331 boolean DXType::MatchType(DXType& source,
332 DXType& destination)
333 {
334 return DXType::MatchType(source.getType(), destination.getType());
335 }
336
337
MatchTypeLists(List & source,List & destination)338 boolean DXType::MatchTypeLists(List& source,
339 List& destination)
340 {
341 ListIterator sourceIterator(source);
342 ListIterator destinationIterator(destination);
343 DXType* sourceType;
344 DXType* destinationType;
345
346 //
347 // Compare each type in the source list against each type in
348 // the destination list.
349 //
350 while ((sourceType=(DXType*)sourceIterator.getNext()))
351 {
352 while ((destinationType=(DXType*)destinationIterator.getNext()))
353 {
354 if (MatchType(*sourceType, *destinationType))
355 {
356 //
357 // Match found... return successfully.
358 //
359 return TRUE;
360 }
361 }
362
363 //
364 // Rewind the destination list...
365 //
366 destinationIterator.setPosition(1);
367 }
368
369 //
370 // No match... return unsuccessfully.
371 //
372 return FALSE;
373 }
374
375
IntersectTypeLists(List & first,List & second)376 List* DXType::IntersectTypeLists(List& first,
377 List& second)
378 {
379 List* thirdList;
380 ListIterator firstIterator(first);
381 ListIterator secondIterator(second);
382 ListIterator thirdIterator;
383 ListIterator typeListIterator(*DXType::TypeList);;
384 DXType* firstType;
385 DXType* secondType;
386 DXType* thirdType;
387 DXTypeName* typeName;
388 long intersection;
389 boolean found;
390
391 typeListIterator.setList(*DXType::TypeList);
392
393 //
394 // Create the intersection list.
395 //
396 thirdList = new List;
397 thirdIterator.setList(*thirdList);
398
399 //
400 // Generate the new type list, which is an intersection of
401 // the two type lists.
402 //
403 while((firstType=(DXType*)firstIterator.getNext()))
404 {
405 secondIterator.setPosition(1);
406 while((secondType=(DXType*)secondIterator.getNext()))
407 {
408 intersection = firstType->getType() & secondType->getType();
409
410 if (intersection AND intersection != DXType::ListType)
411 {
412 //
413 // Make sure that the intersection type is a valid type.
414 //
415 found = FALSE;
416 typeListIterator.setPosition(1);
417 while((typeName=(DXTypeName*)typeListIterator.getNext()))
418 {
419 if (intersection == typeName->type)
420 {
421 found = TRUE;
422 break;
423 }
424 }
425 ASSERT(found);
426
427 //
428 // If type intersection found, search the new list for the
429 // same type.
430 //
431 found = FALSE;
432 thirdIterator.setPosition(1);
433 while((thirdType=(DXType*)thirdIterator.getNext()))
434 {
435 if (intersection == thirdType->getType())
436 {
437 found = TRUE;
438 break;
439 }
440 }
441
442 //
443 // If the new type does not already exist in the list,
444 // add to it.
445 //
446 if (NOT found)
447 {
448 thirdList->appendElement(new DXType(intersection));
449 }
450 }
451 }
452 }
453
454 //
455 // Return the intersection list.
456 //
457 return thirdList;
458 }
459
460
461
DXType()462 DXType::DXType()
463 {
464 //
465 // Initialize class.
466 //
467 DXType::InitializeClass();
468
469 //
470 // Initialize instance data.
471 //
472 this->type = DXType::UndefinedType;
473 this->name = NUL(const char*);
474 }
475
476
DXType(const Type type)477 DXType::DXType(const Type type)
478 {
479 //
480 // Initialize class.
481 //
482 DXType::InitializeClass();
483
484 //
485 // Initialize to be undefined.
486 //
487 this->type = DXType::UndefinedType;
488 this->name = NUL(const char*);
489
490 //
491 // Next, set the type value.
492 //
493 (void)this->setType(type);
494 }
495
496
setType(const Type type)497 boolean DXType::setType(const Type type)
498 {
499 ListIterator iterator(*DXType::TypeList);
500 DXTypeName* knownType;
501
502 //
503 // Iterate through the type list and look for a matching type.
504 // If found, set the instance type and name and return TRUE.
505 //
506 while ((knownType=(DXTypeName*)iterator.getNext()))
507 {
508 if (type == knownType->type)
509 {
510 this->type = type;
511 this->name = (const char*)knownType->name;
512 return TRUE;
513 }
514 }
515
516 //
517 // If not found, return FALSE.
518 //
519 return FALSE;
520 }
521 #if 0
522 //
523 // Give a value contained in the value string, determine its type.
524 // Returns the Type of the value and DXType::UndefinedType if no
525 // match is found.
526 //
527 Type DXType::ValueToType(const char *value)
528 {
529
530 ListIterator iterator(*DXType::TypeList);
531 DXTypeName* knownType;
532
533 //
534 // Iterate through the type list and look for a matching type.
535 // If found, set the instance type and name and return TRUE.
536 //
537 while (knownType = (DXTypeName*)iterator.getNext())
538 {
539 if (DXValue::IsValidValue(value,knownType->type))
540 return knownType->type;
541 }
542
543 //
544 // If not found, return FALSE.
545 //
546 return DXType::UndefinedType;
547
548
549 }
550 #endif // 0
551
552 //
553 // Give a value contained in the value string, determine its type.
554 // Returns the number of types found that match the value.
555 //
ValueToType(const char * value,List & typelist)556 boolean DXType::ValueToType(const char *value, List& typelist)
557 {
558
559 ListIterator iterator(*DXType::TypeList);
560 DXTypeName* knownType;
561 int in_size = typelist.getSize();
562
563 //
564 // Iterate through the type list and look for a matching type.
565 // If found, set the instance type and name and return TRUE.
566 //
567 while ((knownType=(DXTypeName*)iterator.getNext()))
568 {
569 if (DXValue::IsValidValue(value,knownType->type))
570 typelist.appendElement(knownType);
571 }
572
573 //
574 //
575 //
576 return (typelist.getSize() > in_size);
577 }
578
579 //
580 // Type masks as defined in version 1.0.0 .net files.
581 //
582 #define MT_VALUE 0x0000003d
583 #define MT_STRING 0x00000040
584 #define MT_CAMERA 0x00000080
585 #define MT_LIGHT 0x00000100
586 #define MT_FIELD 0x00000800
587 #define MT_GEOMETRY_FIELD 0x01001800
588 #define MT_IMAGE 0x00002800
589 #define MT_COLOR_FIELD 0x00004800
590 #define MT_SCALAR_FIELD 0x00008800
591 #define MT_VECTOR_FIELD 0x00010800
592 #define MT_DATA_FIELD 0x00020800
593 #define MT_SERIES 0x00100800
594 #define MT_FIELD_SERIES 0x00300800
595 #define MT_GROUP 0x01000800
596 #define MT_VALUE_GROUP 0x03000800
597 #define MT_VALUE_LIST_GROUP 0x05000800
598 #define MT_FIELD_GROUP 0x09000800
599 #define MT_LIST 0x10000000
600 #define MT_OBJECT 0x3fffffff
601 #define MT_DESCRIPTION 0x40000000
602 //
603 // Convert a version 1.0 (DX/6000 version 1.2 11/92) type to new UI types.
604 //
ConvertVersionType(Type t)605 Type DXType::ConvertVersionType(Type t)
606 {
607 Type r;
608 boolean waslist = FALSE;
609
610 if (t & MT_LIST) {
611 waslist = TRUE;
612 t &= ~MT_LIST;
613 }
614
615 switch (t) {
616 case MT_VALUE: r = DXType::ValueType; break;
617 case MT_STRING: r = DXType::StringType; break;
618 case MT_CAMERA: r = DXType::CameraType; break;
619 case MT_LIGHT: r = DXType::LightType; break;
620 case MT_GEOMETRY_FIELD: r = DXType::GeometryFieldType; break;
621 case MT_COLOR_FIELD: r = DXType::ColorFieldType; break;
622 case MT_SCALAR_FIELD: r = DXType::ScalarType; break;
623 case MT_VECTOR_FIELD: r = DXType::VectorType; break;
624 case MT_DATA_FIELD: r = DXType::DataFieldType; break;
625 case MT_IMAGE: r = DXType::ImageType; break;
626 case MT_SERIES: r = DXType::SeriesType; break;
627 case MT_FIELD_SERIES: r = DXType::FieldType; break;
628 case MT_GROUP: r = DXType::GroupType; break;
629 case MT_VALUE_GROUP: r = DXType::ValueGroupType; break;
630 case MT_VALUE_LIST_GROUP: r = DXType::ValueListGroupType; break;
631 case MT_FIELD_GROUP: r = DXType::FieldType; break;
632 case MT_OBJECT: r = DXType::ObjectType; break;
633 case MT_DESCRIPTION: r = DXType::DescriptionType; break;
634 default:
635 r = t;
636 }
637
638 if (waslist)
639 r |= DXType::ListType;
640
641 return r;
642 }
643
644 //
645 // Determine the types of the items in a list.
646 // If there are mixed types then the returned type is DXType::ValueType.
647 // If there are not mixed types than the type of each item is returned.
648 // If an unrecognized list item is found, DXType::UndefinedType is returned.
649 //
DetermineListItemType(const char * val)650 Type DXType::DetermineListItemType(const char *val)
651 {
652 char *s1 = NULL, *s2 = NULL;
653 int count = 0, index = -1;
654 char buf1[512];
655 char buf2[512];
656 Type ctype, type = DXType::UndefinedType;
657 boolean quitting = FALSE;
658
659 if (EqualString(val,"NULL") || EqualString(val,"null"))
660 return DXType::ValueType;
661
662 while (!quitting &&
663 ((s1=DXValue::NextListItem(val,&index, DXType::ValueListType,buf1,512 )) ||
664 (s2=DXValue::NextListItem(val,&index, DXType::StringListType,buf2,512)))) {
665 if (s2) {
666 ctype = DXType::StringType;
667 } else if (DXValue::IsValidValue(s1,DXType::IntegerType)) {
668 if (type == DXType::ScalarType)
669 ctype = DXType::ScalarType;
670 else
671 ctype = DXType::IntegerType;
672 } else if (DXValue::IsValidValue(s1,DXType::ScalarType)) {
673 ctype = DXType::ScalarType;
674 if (type == DXType::IntegerType)
675 type = DXType::ScalarType;
676 } else if (DXValue::IsValidValue(s1,DXType::VectorType)) {
677 ctype = DXType::VectorType;
678 } else if (DXValue::IsValidValue(s1,DXType::TensorType)) {
679 ctype = DXType::TensorType;
680 } else if (DXValue::IsValidValue(s1,DXType::ValueType)) {
681 ctype = DXType::ValueType;
682 } else
683 ctype = DXType::UndefinedType;
684
685 if (type == DXType::UndefinedType)
686 type = ctype;
687
688 if (ctype == DXType::UndefinedType) {
689 type = DXType::UndefinedType;
690 quitting = TRUE;
691 } else if (type != ctype) {
692 type = DXType::ValueType;
693 }
694 if (type == DXType::ValueType)
695 quitting = TRUE;
696 count++;
697 if ((s1)&&(s1!=buf1)) {
698 delete s1;
699 s1 = NULL;
700 }
701 if ((s2)&&(s2!=buf2)) {
702 delete s2;
703 s2 = NULL;
704 }
705 }
706
707 #if 0 // 6/1/93
708 if (count == 0)
709 type = DXType::ValueType;
710 #endif
711
712 return type;
713 }
714 //
715 // Copy the instance data from this to newt. If newt is null allocate
716 // a new DXType. newt is returned.
717 //
duplicate(DXType * newt)718 DXType *DXType::duplicate(DXType *newt)
719 {
720 if (!newt)
721 newt = new DXType();
722 *newt = *this;
723
724 return newt;
725 }
726