1 mike 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 mike 1.1 **==============================================================================
23 */
24
25 #include "field.h"
26 #include "types.h"
27 #include "alloc.h"
28 #include "instance.h"
29 #include "return.h"
30 #include "types.h"
31 #include "indent.h"
32 #include "strings.h"
33 #include "io.h"
34 #include "helpers.h"
35
36 #define T MI_T
37 #define _BORROW 0x01
38
39 /*
40 **==============================================================================
41 **
42 ** Local definitions
43 mike 1.1 **
44 **==============================================================================
45 */
46
47 static unsigned char _fieldSizes[] =
48 {
49 sizeof(MI_BooleanField),
50 sizeof(MI_Uint8Field),
51 sizeof(MI_Sint8Field),
52 sizeof(MI_Uint16Field),
53 sizeof(MI_Sint16Field),
54 sizeof(MI_Uint32Field),
55 sizeof(MI_Sint32Field),
56 sizeof(MI_Uint64Field),
57 sizeof(MI_Sint64Field),
58 sizeof(MI_Real32Field),
59 sizeof(MI_Real64Field),
60 sizeof(MI_Char16Field),
61 sizeof(MI_DatetimeField),
62 sizeof(MI_StringField),
63 sizeof(MI_ReferenceField),
64 mike 1.1 sizeof(MI_InstanceField),
65 sizeof(MI_BooleanAField),
66 sizeof(MI_Uint8AField),
67 sizeof(MI_Sint8AField),
68 sizeof(MI_Uint16AField),
69 sizeof(MI_Sint16AField),
70 sizeof(MI_Uint32AField),
71 sizeof(MI_Sint32AField),
72 sizeof(MI_Uint64AField),
73 sizeof(MI_Sint64AField),
74 sizeof(MI_Real32AField),
75 sizeof(MI_Real64AField),
76 sizeof(MI_Char16AField),
77 sizeof(MI_DatetimeAField),
78 sizeof(MI_StringAField),
79 sizeof(MI_ReferenceAField),
80 sizeof(MI_InstanceAField),
81 };
82
83 static void* _CloneSimpleArray(
84 const void* data,
85 mike 1.1 MI_Uint32 size,
86 MI_Uint32 type,
87 Batch* batch)
88 {
89 void* array;
90 size_t m;
91
92 /* Handle empty arrays up front */
93 if (!data || size == 0)
94 return NULL;
95
96 /* Get element size in bytes */
97 m = Type_SizeOf(Type_ScalarOf((MI_Type)type));
98
99 /* Allocate memory for array elements */
100 array = BAlloc(batch, size * m, CALLSITE);
101 if (!array)
102 return NULL;
103
104 /* Copy elements to the new array */
105 memcpy(array, data, m * size);
106 mike 1.1
107 return array;
108 }
109
110 static MI_Char** _CloneStringArray(
111 const MI_Char** data,
112 MI_Uint32 size,
113 Batch* batch)
114 {
115 size_t n;
116 MI_Uint32 i;
117 MI_Char* ptr;
118 MI_Char** array;
119
120 /* Empty arrays are represented by NULL */
121 if (!data || size == 0)
122 return NULL;
123
124 /* Calculate space for pointer array */
125 n = size * sizeof(MI_Char*);
126
127 mike 1.1 /* Calculate space for strings (add space for zero terminators) */
128 for (i = 0; i < size; i++)
129 {
130 if (!data[i])
131 {
132 /* Null elements are illegal */
133 return NULL;
134 }
135
136 n += (Zlen(data[i]) + 1) * sizeof(MI_Char);
137 }
138
139 /* Allocate memory */
140 array = (MI_Char**)BAlloc(batch, n, CALLSITE);
141
142 if (!array)
143 return NULL;
144
145 ptr = (MI_Char*)&array[size];
146
147 /* Copy the strings */
148 mike 1.1 for (i = 0; i < size; i++)
149 {
150 size_t count = Zlen(data[i]) + 1;
151 memcpy(ptr, data[i], count * sizeof(MI_Char));
152 array[i] = ptr;
153 ptr += count;
154 }
155
156 return array;
157 }
158
159 static void* _CloneInstanceArray(
160 const void* data_,
161 MI_Uint32 size,
162 Batch* batch)
163 {
164 const MI_Instance** data = (const MI_Instance**)data_;
165 MI_Instance** array;
166 MI_Uint32 i;
167
168 /* Handle empty arrays up front */
169 mike 1.1 if (!data || size == 0)
170 return NULL;
171
172 /* validate entries */
173 for (i = 0; i < size; i++ )
174 {
175 if (!data[i])
176 {
177 /* Null elements are illegal */
178 return NULL;
179 }
180 }
181
182 /* Allocate memory for the new array */
183 array = BCalloc(batch, size * sizeof(MI_Instance*), CALLSITE);
184 if (!array)
185 return NULL;
186
187 /* Clone each reference (or instance) */
188 for (i = 0; i < size; i++)
189 {
190 mike 1.1 MI_Result r = Instance_Clone(data[i], &array[i], batch);
191 if (r != MI_RESULT_OK)
192 return NULL;
193 }
194
195 return array;
196 }
197
198 INLINE void _Copy(
199 Field* dest,
200 const Field* src,
201 MI_Type type)
202 {
203 memcpy(dest, src, _fieldSizes[(int)type]);
204 }
205
206 static void _Swap(
207 Field* field1,
208 Field* field2,
209 MI_Type type)
210 {
211 mike 1.1 Field tmp;
212 _Copy(&tmp, field1, type);
213 _Copy(field1, field2, type);
214 _Copy(field2, &tmp, type);
215 }
216
217 static void _Fill(
218 Field* self,
219 MI_Type type,
220 MI_Uint8 x)
221 {
222 memset(self, x, _fieldSizes[(int)type]);
223 }
224
225 /*
226 **==============================================================================
227 **
228 ** Public definitions
229 **
230 **==============================================================================
231 */
232 mike 1.1
233 MI_Result Field_Construct(
234 Field* self,
235 MI_Type type,
236 const MI_Value* value,
237 MI_Uint32 flags,
238 Batch* batch)
239 {
240 MI_Result r;
241
242 /* Zero out self */
243 _Fill(self, type, 0);
244
245 /* Handle null case up front */
246 if (flags & MI_FLAG_NULL)
247 MI_RETURN(MI_RESULT_OK);
248
249 /* Reject null values */
250 /* ATTN: Tolerate this for now */
251 if (!value)
252 MI_RETURN(MI_RESULT_OK);
253 mike 1.1
254 switch (type)
255 {
256 case MI_BOOLEAN:
257 {
258 self->boolean.value = value->boolean;
259 self->boolean.exists = MI_TRUE;
260 break;
261 }
262 case MI_UINT8:
263 {
264 self->uint8.value = value->uint8;
265 self->uint8.exists = MI_TRUE;
266 break;
267 }
268 case MI_SINT8:
269 {
270 self->sint8.value = value->sint8;
271 self->sint8.exists = MI_TRUE;
272 break;
273 }
274 mike 1.1 case MI_UINT16:
275 {
276 self->uint16.value = value->uint16;
277 self->uint16.exists = MI_TRUE;
278 break;
279 }
280 case MI_SINT16:
281 {
282 self->sint16.value = value->sint16;
283 self->sint16.exists = MI_TRUE;
284 break;
285 }
286 case MI_UINT32:
287 {
288 self->uint32.value = value->uint32;
289 self->uint32.exists = MI_TRUE;
290 break;
291 }
292 case MI_SINT32:
293 {
294 self->sint32.value = value->sint32;
295 mike 1.1 self->sint32.exists = MI_TRUE;
296 break;
297 }
298 case MI_UINT64:
299 {
300 self->uint64.value = value->uint64;
301 self->uint64.exists = MI_TRUE;
302 break;
303 }
304 case MI_SINT64:
305 {
306 self->sint64.value = value->sint64;
307 self->sint64.exists = MI_TRUE;
308 break;
309 }
310 case MI_REAL32:
311 {
312 self->real32.value = value->real32;
313 self->real32.exists = MI_TRUE;
314 break;
315 }
316 mike 1.1 case MI_REAL64:
317 {
318 self->real64.value = value->real64;
319 self->real64.exists = MI_TRUE;
320 break;
321 }
322 case MI_CHAR16:
323 {
324 self->char16.value = value->char16;
325 self->char16.exists = MI_TRUE;
326 break;
327 }
328 case MI_DATETIME:
329 {
330 self->datetime.value = value->datetime;
331 self->datetime.exists = MI_TRUE;
332 break;
333 }
334 case MI_STRING:
335 {
336 if (value->string)
337 mike 1.1 {
338 MI_Char* str;
339
340 if (flags & MI_FLAG_BORROW)
341 {
342 self->string.value = value->string;
343 self->string.exists = MI_TRUE;
344 self->string.flags = _BORROW;
345 break;
346 }
347
348 str = BStrdup(batch, value->string, CALLSITE);
349 if (!str)
350 MI_RETURN(MI_RESULT_FAILED);
351
352 self->string.value = str;
353 self->string.exists = MI_TRUE;
354 }
355 else
356 {
357 self->string.value = NULL;
358 mike 1.1 self->string.exists = MI_FALSE;
359 self->string.flags = 0;
360 }
361 break;
362 }
363 case MI_INSTANCE:
364 case MI_REFERENCE:
365 {
366 if (value->instance)
367 {
368 MI_Instance* instance;
369
370 if (flags & MI_FLAG_BORROW)
371 {
372 self->instance.value = value->instance;
373 self->instance.exists = MI_TRUE;
374 self->instance.flags = _BORROW;
375 break;
376 }
377
378 r = Instance_Clone(value->instance, &instance, batch);
379 mike 1.1 if (r != MI_RESULT_OK)
380 MI_RETURN(r);
381
382 self->instance.value = instance;
383 self->instance.exists = MI_TRUE;
384 }
385 else
386 {
387 self->instance.value = NULL;
388 self->instance.exists = MI_FALSE;
389 self->instance.flags = 0;
390 }
391 break;
392 }
393 case MI_BOOLEANA:
394 case MI_UINT8A:
395 case MI_SINT8A:
396 case MI_UINT16A:
397 case MI_SINT16A:
398 case MI_UINT32A:
399 case MI_SINT32A:
400 mike 1.1 case MI_UINT64A:
401 case MI_SINT64A:
402 case MI_REAL32A:
403 case MI_REAL64A:
404 case MI_CHAR16A:
405 case MI_DATETIMEA:
406 {
407 if (value->array.data)
408 {
409 void* data;
410
411 if (flags & MI_FLAG_BORROW)
412 {
413 self->array.value = value->array;
414 self->array.exists = MI_TRUE;
415 self->array.flags = _BORROW;;
416 break;
417 }
418
419 data = _CloneSimpleArray(
420 value->array.data, value->array.size, type, batch);
421 mike 1.1 if (!data)
422 MI_RETURN(MI_RESULT_FAILED);
423
424 self->array.value.data = data;
425 self->array.value.size = value->array.size;
426 self->array.exists = MI_TRUE;
427 }
428 else
429 {
430 self->array.value.data = NULL;
431 self->array.value.size = 0;
432 self->array.exists = MI_FALSE;
433 }
434 break;
435 }
436 case MI_STRINGA:
437 {
438 MI_Char** data;
439
440 if (value->array.data)
441 {
442 mike 1.1 if (flags & MI_FLAG_BORROW)
443 {
444 self->stringa.value = value->stringa;
445 self->stringa.exists = MI_TRUE;
446 self->stringa.flags = _BORROW;;
447 break;
448 }
449
450 data = _CloneStringArray((const MI_Char**)value->stringa.data,
451 value->stringa.size, batch);
452 if (!data)
453 MI_RETURN(MI_RESULT_FAILED);
454
455 self->stringa.value.data = data;
456 self->stringa.value.size = value->array.size;
457 self->stringa.exists = MI_TRUE;
458 }
459 else
460 {
461 self->stringa.value.data = NULL;
462 self->stringa.value.size = 0;
463 mike 1.1 self->stringa.exists = MI_FALSE;
464 }
465 break;
466 }
467 case MI_INSTANCEA:
468 case MI_REFERENCEA:
469 {
470 if (value->instancea.data)
471 {
472 MI_Instance** data;
473
474 if (flags & MI_FLAG_BORROW)
475 {
476 self->instancea.value = value->instancea;
477 self->instancea.exists = MI_TRUE;
478 self->instancea.flags = _BORROW;;
479 break;
480 }
481
482 data = _CloneInstanceArray(value->instancea.data,
483 value->instancea.size, batch);
484 mike 1.1 if (!data)
485 MI_RETURN(MI_RESULT_FAILED);
486
487 self->instancea.value.data = data;
488 self->instancea.value.size = value->array.size;
489 self->instancea.exists = MI_TRUE;
490 }
491 else
492 {
493 self->instancea.value.data = NULL;
494 self->instancea.value.size = 0;
495 self->instancea.exists = MI_FALSE;
496 }
497 break;
498 }
499 }
500
501 return MI_RESULT_OK;
502 }
503
504 void Field_Destruct(
505 mike 1.1 Field* self,
506 MI_Type type,
507 Batch* batch)
508 {
509 switch (type)
510 {
511 case MI_STRING:
512 {
513 MI_StringField* f = &self->string;
514
515 if (!(f->flags & _BORROW) && f->value)
516 BFree(batch, f->value, CALLSITE);
517 break;
518 }
519 case MI_BOOLEANA:
520 case MI_SINT8A:
521 case MI_UINT8A:
522 case MI_SINT16A:
523 case MI_UINT16A:
524 case MI_SINT32A:
525 case MI_UINT32A:
526 mike 1.1 case MI_SINT64A:
527 case MI_UINT64A:
528 case MI_REAL32A:
529 case MI_REAL64A:
530 case MI_CHAR16A:
531 case MI_DATETIMEA:
532 case MI_STRINGA:
533 {
534 MI_ArrayField* f = &self->array;
535
536 if (!(f->flags & _BORROW) && f->value.data)
537 BFree(batch, f->value.data, CALLSITE);
538 break;
539 }
540 case MI_INSTANCE:
541 case MI_REFERENCE:
542 {
543 MI_InstanceField* f = &self->instance;
544
545 if (!(f->flags & _BORROW) && f->value)
546 MI_Instance_Delete(f->value);
547 mike 1.1 break;
548 }
549 case MI_INSTANCEA:
550 case MI_REFERENCEA:
551 {
552 MI_InstanceAField* f = &self->instancea;
553
554 if (!(f->flags & _BORROW) && f->value.data)
555 {
556 MI_Uint32 j;
557
558 for (j = 0; j < f->value.size; j++ )
559 MI_Instance_Delete(f->value.data[j]);
560
561 BFree(batch, f->value.data, CALLSITE);
562 }
563 break;
564 }
565 default:
566 break;
567 }
568 mike 1.1
569 /* Fill with illegal character */
570 _Fill(self, type, 0xDD);
571 }
572
573 MI_Result Field_Set(
574 Field* self,
575 MI_Type type,
576 const MI_Value* value,
577 MI_Uint32 flags,
578 Batch* batch)
579 {
580 Field field;
581 MI_Result r;
582
583 /* Initialize new field */
584 r = Field_Construct(&field, type, value, flags, batch);
585 if (r != MI_RESULT_OK)
586 MI_RETURN(r);
587
588 /* Destroy self */
589 mike 1.1 Field_Destruct(self, type, batch);
590
591 /* Swap new field with self */
592 _Swap(self, &field, type);
593
594 return MI_RESULT_OK;
595 }
596
597 MI_Result Field_Copy(
598 Field* self,
599 MI_Type type,
600 const Field* field,
601 Batch* batch)
602 {
603 MI_Value value;
604 MI_Boolean exists;
605 MI_Uint8 flags;
606 MI_Uint32 tflags = 0;
607 MI_Result r;
608
609 Field_Extract(field, type, &value, &exists, &flags);
610 mike 1.1
611 if (!exists)
612 tflags |= MI_FLAG_NULL;
613
614 r = Field_Construct(self, type, &value, tflags, batch);
615
616 return r;
617 }
618
619 void Field_Clear(
620 Field* self,
621 MI_Type type,
622 Batch* batch)
623 {
624 Field_Destruct(self, type, batch);
625 _Fill(self, type, 0);
626 }
627
628 void Field_Extract(
629 const Field* self,
630 MI_Type type,
631 mike 1.1 MI_Value* valueOut,
632 MI_Boolean* existsOut,
633 MI_Uint8* flagsOut)
634 {
635 size_t size = Type_SizeOf(type);
636 memcpy(valueOut, self, size);
637 *existsOut = *(MI_Boolean*)((char*)self + size);
638 *flagsOut = *(MI_Uint8*)((char*)self + size + sizeof(MI_Boolean));
639 }
640
641 void Field_Print(
642 const Field* self,
643 FILE* os,
644 MI_Type type,
645 MI_Uint32 level)
646 {
647 MI_Value v;
648 MI_Boolean e;
649 MI_Uint8 f;
650 Field_Extract(self, type, &v, &e, &f);
651
652 mike 1.1 if (!e)
653 {
654 fprintf(os, "NULL");
655 return;
656 }
657 else
658 {
659 switch (type)
660 {
661 case MI_BOOLEAN:
662 {
663 const MI_Boolean* p = (const MI_Boolean*)&v;
664 fprintf(os, "%s", *p ? "true" : "false");
665 break;
666 }
667 case MI_SINT8:
668 {
669 fprintf(os, "%d", *((const MI_Sint8*)&v));
670 break;
671 }
672 case MI_UINT8:
673 mike 1.1 {
674 fprintf(os, "%u", *((const MI_Uint8*)&v));
675 break;
676 }
677 case MI_SINT16:
678 {
679 fprintf(os, "%d", *((const MI_Sint16*)&v));
680 break;
681 }
682 case MI_UINT16:
683 {
684 fprintf(os, "%u", *((const MI_Uint16*)&v));
685 break;
686 }
687 case MI_SINT32:
688 {
689 fprintf(os, "%d", *((const MI_Sint32*)&v));
690 break;
691 }
692 case MI_UINT32:
693 {
694 mike 1.1 fprintf(os, "%u", *((const MI_Uint32*)&v));
695 break;
696 }
697 case MI_SINT64:
698 {
699 fprintf(os, SINT64_FMT, *((const MI_Sint64*)&v));
700 break;
701 }
702 case MI_UINT64:
703 {
704 fprintf(os, UINT64_FMT, *((const MI_Uint64*)&v));
705 break;
706 }
707 case MI_REAL32:
708 {
709 fprintf(os, "%g", *((const MI_Real32*)&v));
710 break;
711 }
712 case MI_REAL64:
713 {
714 fprintf(os, "%g", *((const MI_Real64*)&v));
715 mike 1.1 break;
716 }
717 case MI_CHAR16:
718 {
719 fprintf(os, "%u", *((const MI_Char16*)&v));
720 break;
721 }
722 case MI_DATETIME:
723 {
724 MI_Char buf[26];
725 DatetimeToStr((const MI_Datetime*)&v, buf);
726 Fzprintf(os, T("%s"), buf);
727 break;
728 }
729 case MI_STRING:
730 {
731 Fzprintf(os, T("%s"), *((MI_Char**)&v));
732 break;
733 }
734 case MI_BOOLEANA:
735 case MI_SINT8A:
736 mike 1.1 case MI_UINT8A:
737 case MI_SINT16A:
738 case MI_UINT16A:
739 case MI_SINT32A:
740 case MI_UINT32A:
741 case MI_SINT64A:
742 case MI_UINT64A:
743 case MI_REAL32A:
744 case MI_REAL64A:
745 case MI_CHAR16A:
746 case MI_DATETIMEA:
747 {
748 MI_BooleanA* arr = (MI_BooleanA*)&v;
749 char* ptr = (char*)arr->data;
750 MI_Uint32 i;
751
752 fprintf(os, "{");
753
754 for (i = 0; i < arr->size; i++)
755 {
756 MI_Type stype = Type_ScalarOf(type);
757 mike 1.1 MI_Type ssize = Type_SizeOf(stype);
758 Field field;
759
760 /* Build dummy field */
761 memcpy(&field, ptr, ssize);
762 *(MI_Boolean*)((char*)&field + ssize) = MI_TRUE;
763 *(MI_Uint8*)((char*)&field + ssize + 1) = 0;
764
765 /* Print dummy field */
766 Field_Print(&field, os, stype, level);
767 ptr += ssize;
768
769 if (i + 1 != arr->size)
770 fprintf(os, ", ");
771 }
772
773 fprintf(os, "}");
774 break;
775 }
776 case MI_STRINGA:
777 {
778 mike 1.1 MI_StringA* arr = (MI_StringA*)&v;
779 MI_Uint32 i;
780
781 fprintf(os, "{");
782
783 for (i = 0; i < arr->size; i++)
784 {
785 Fzprintf(os, T("%s"), arr->data[i]);
786
787 if (i + 1 != arr->size)
788 fprintf(os, ", ");
789 }
790
791 fprintf(os, "}");
792 break;
793 }
794 case MI_INSTANCE:
795 case MI_REFERENCE:
796 {
797 MI_Instance* inst = *((MI_Instance**)&v);
798
799 mike 1.1 if ( type == MI_REFERENCE)
800 fprintf(os, " REF ");
801
802 __MI_Instance_Print(inst, os, level);
803 break;
804 }
805 case MI_INSTANCEA:
806 case MI_REFERENCEA:
807 {
808 MI_InstanceA* inst = ((MI_InstanceA*)&v);
809 MI_Uint32 i;
810
811 if ( type == MI_REFERENCEA)
812 fprintf(os, " REF ");
813
814 #if 0
815 fprintf(os, "[%d]\n", (int)inst->size);
816 #endif
817 fprintf(os, "\n");
818
819 Indent(os, level);
820 mike 1.1 fprintf(os, "{\n");
821
822 for (i = 0; i < inst->size; i++)
823 {
824 __MI_Instance_Print(inst->data[i], os, level + 1);
825 }
826
827 Indent(os, level);
828 fprintf(os, "}");
829
830 break;
831 }
832 default:
833 break;
834 }
835 }
836 }
837
838 static MI_Boolean _MatchDatetime(
839 const MI_Datetime* x,
840 const MI_Datetime* y)
841 mike 1.1 {
842 if (x->isTimestamp)
843 {
844 if (!y->isTimestamp)
845 return MI_FALSE;
846
847 return
848 x->u.timestamp.year == y->u.timestamp.year &&
849 x->u.timestamp.month == y->u.timestamp.month &&
850 x->u.timestamp.day == y->u.timestamp.day &&
851 x->u.timestamp.hour == y->u.timestamp.hour &&
852 x->u.timestamp.minute == y->u.timestamp.minute &&
853 x->u.timestamp.second == y->u.timestamp.second &&
854 x->u.timestamp.microseconds == y->u.timestamp.microseconds &&
855 x->u.timestamp.utc == y->u.timestamp.utc;
856 }
857 else
858 {
859 if (y->isTimestamp)
860 return MI_FALSE;
861
862 mike 1.1 return
863 x->u.interval.days == y->u.interval.days &&
864 x->u.interval.hours == y->u.interval.hours &&
865 x->u.interval.minutes == y->u.interval.minutes &&
866 x->u.interval.seconds == y->u.interval.seconds &&
867 x->u.interval.microseconds == y->u.interval.microseconds;
868 }
869 }
870
871 MI_Boolean Field_MatchKey(
872 const Field* f1,
873 const Field* f2,
874 MI_Type type)
875 {
876 MI_Boolean e1 = Field_GetExists(f1, type);
877 MI_Boolean e2 = Field_GetExists(f2, type);
878 int f = MI_FALSE;
879
880 if ((e1 && !e2) || (e2 && !e1))
881 return MI_FALSE;
882
883 mike 1.1 switch (type)
884 {
885 case MI_BOOLEAN:
886 f = f1->boolean.value == f2->boolean.value;
887 break;
888 case MI_UINT8:
889 f = f1->uint8.value == f2->uint8.value;
890 break;
891 case MI_SINT8:
892 f = f1->sint8.value == f2->sint8.value;
893 break;
894 case MI_UINT16:
895 f = f1->uint16.value == f2->uint16.value;
896 break;
897 case MI_SINT16:
898 f = f1->sint16.value == f2->sint16.value;
899 break;
900 case MI_UINT32:
901 f = f1->uint32.value == f2->uint32.value;
902 break;
903 case MI_SINT32:
904 mike 1.1 f = f1->sint32.value == f2->sint32.value;
905 break;
906 case MI_UINT64:
907 f = f1->uint64.value == f2->uint64.value;
908 break;
909 case MI_SINT64:
910 f = f1->sint64.value == f2->sint64.value;
911 break;
912 case MI_REAL32:
913 f = f1->real32.value == f2->real32.value;
914 break;
915 case MI_REAL64:
916 f = f1->real64.value == f2->real64.value;
917 break;
918 case MI_CHAR16:
919 f = f1->char16.value == f2->char16.value;
920 break;
921 case MI_DATETIME:
922 f = _MatchDatetime(&f1->datetime.value, &f2->datetime.value);
923 break;
924 case MI_STRING:
925 mike 1.1 f = Zcmp(f1->string.value, f2->string.value) == 0;
926 break;
927 case MI_REFERENCE:
928 {
929 if (!f1->reference.value && !f2->reference.value)
930 return MI_TRUE;
931
932 f = Instance_MatchKeys(f1->reference.value, f2->reference.value);
933 break;
934 }
935 case MI_INSTANCE:
936 /* Instances cannot be keys */
937 f = MI_FALSE;
938 break;
939 default:
940 /* Arrays cannot be keys */
941 f = MI_FALSE;
942 break;
943 }
944
945 return f ? MI_TRUE : MI_FALSE;
946 mike 1.1 }
|