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