133 mike 1.1 static MI_PropertyDecl* _ClonePropertyDecl(
134 const MI_PropertyDecl* pd,
135 Batch* batch)
136 {
137 MI_PropertyDecl* p;
138
139 p = (MI_PropertyDecl*)BCalloc(batch, sizeof(MI_PropertyDecl), CALLSITE);
140
141 if (!p)
142 return NULL;
143
144 if (pd->name)
145 {
146 p->name = BStrdup(batch, pd->name, CALLSITE);
147 if (!p->name)
148 return NULL;
149 }
150
151 p->flags = pd->flags;
152 p->code = pd->code;
153 p->type = pd->type;
154 mike 1.1 p->offset = pd->offset;
155
156 return p;
157 }
158
159 static MI_PropertyDecl** _ClonePropertyDecls(
160 MI_PropertyDecl** properties,
161 MI_Uint32 size,
162 Batch* batch)
163 {
164 MI_PropertyDecl** data;
165 MI_Uint32 i;
166
167 /* Allocate at least _CAPACITY properties */
168 MI_Uint32 cap = (size < _CAPACITY) ? _CAPACITY : size;
169
170 /* Allocate properties array */
171 data = (MI_PropertyDecl**)BAlloc(batch, sizeof(MI_PropertyDecl*) * cap,
172 CALLSITE);
173 if (!data)
174 return NULL;
175 mike 1.1
176 /* Copy each property */
177 for (i = 0; i < size; i++)
178 {
179 MI_PropertyDecl* pd = _ClonePropertyDecl(properties[i], batch);
180 if (!pd)
181 return NULL;
182
183 data[i] = pd;
184 }
185
186 return data;
187 }
188
189 static MI_ClassDecl* _CloneClassDecl(
190 const MI_ClassDecl* cd,
191 Batch* batch)
192 {
193 MI_ClassDecl* p;
194
195 /* Instance.classDecl */
196 mike 1.1 p = (MI_ClassDecl*)BCalloc(batch, sizeof(MI_ClassDecl), CALLSITE);
197 if (!p)
198 return NULL;
199
200 /* Instance.name */
201 if (cd->name)
202 {
203 p->name = BStrdup(batch, cd->name, CALLSITE);
204 if (!p->name)
205 return NULL;
206 }
207
208 /* Instance.size */
209 p->size = cd->size;
210
211 /* Instance.properties */
212 {
213 p->properties = _ClonePropertyDecls(cd->properties, cd->numProperties,
214 batch);
215
216 if (!p->properties)
217 mike 1.1 return NULL;
218
219 p->numProperties = cd->numProperties;
220 }
221
222 return p;
223 }
224
225 MI_INLINE InstanceHeader* _HeaderOf(Instance* self)
226 {
227 return self ? ((InstanceHeader*)self - 1) : NULL;
228 }
229
230 MI_INLINE Instance* _InstanceOf(InstanceHeader* self)
231 {
232 return self ? (Instance*)(self + 1) : NULL;
233 }
234
235 static Instance* _AllocInstance(Batch* batch, size_t size)
236 {
237 InstanceHeader* h = (InstanceHeader*)BCalloc(
238 mike 1.1 batch,
239 sizeof(InstanceHeader) + size,
240 CALLSITE);
241
242 if (!h)
243 return NULL;
244
245 h->magic = _MAGIC;
246 h->u.refs = 1;
247 return _InstanceOf(h);
248 }
249
250 static Instance* _ReallocInstance(
251 Batch* batch,
252 Instance* self,
253 size_t oldSize,
254 size_t newSize)
255 {
256 InstanceHeader* h = (InstanceHeader*)BRealloc(
257 batch,
258 _HeaderOf(self),
259 mike 1.1 sizeof(InstanceHeader) + oldSize,
260 sizeof(InstanceHeader) + newSize,
261 CALLSITE);
262
263 if (!h)
264 return NULL;
265
266 h->magic = _MAGIC;
267 h->u.refs = 1;
268
269 return _InstanceOf(h);
270 }
271
272 static void _FreeInstance(
273 Batch* batch,
274 Instance* self)
275 {
276 InstanceHeader* h = _HeaderOf(self);
277
278 if (h)
279 {
280 mike 1.1 DEBUG_ASSERT(h->magic == _MAGIC);
281 #if defined(CONFIG_ENABLE_DEBUG)
282 memset(h, 0xDD, sizeof(InstanceHeader) + sizeof(Instance));
283 #endif
284 BFree(batch, h, CALLSITE);
285 }
286 }
287
288 /*
289 * Each dynamic instance is 'wrapped' inside another instance (referred to
290 * by the self field). This requiredment is imposed by the
291 * MI_Instance_AddElement() function, which does not allow the address of
292 * the instance to change. Hence, indirection is required to allow the inner
293 * instance to be relocated in memory as new properties are added. The
294 * resulting layout is depicted below.
295 *
296 * (Wrapper)
297 * +-------------+
298 * | MI_Instance |
299 * +---------+---+
300 * | | | (Inner)
301 mike 1.1 * +---------+---+ +-------------+
302 * | self | ------> | MI_Instance |
303 * +---------+---+ +---------+---+
304 * | | |
305 * +---------+---+
306 * | | |
307 * +---------+---+
308 *
309 * All methods of the instance type, must resolve the self pointer using
310 * _SelfOf(), which either returns the sole parameter itself (for static
311 * instances) or the self field (for dynamic instances).
312 *
313 */
314 static Instance* _WrapInstance(
315 Instance* self,
316 Batch* batch)
317 {
318 Instance* wrapper;
319
320 if (!self)
321 return NULL;
322 mike 1.1
323 /* Allocate space for outer wrapper instance */
324 wrapper = (Instance*)_AllocInstance(batch, sizeof(MI_Instance));
325 if (!wrapper)
326 return NULL;
327
328 /* Copy fields from inner instance to outer instance */
329 *wrapper = *self;
330
331 /* Set outer instance self to point to inner instance */
332 wrapper->self = self;
333
334 return wrapper;
335 }
336
337 MI_Uint32 _CountKeys(
338 const Instance* self)
339 {
340 MI_Uint32 n = 0;
341 const MI_ClassDecl* cd = self->classDecl;
342 MI_Uint32 i;
343 mike 1.1
344 for (i = 0; i < cd->numProperties; i++)
345 {
346 if (cd->properties[i]->flags & MI_FLAG_KEY)
347 n++;
348 }
349
350 return n;
351 }
352
353 /*
354 **==============================================================================
355 **
356 ** Public definitions
357 **
358 **==============================================================================
359 */
360
361 MI_Result MI_CALL Instance_Construct(
362 MI_Instance* self_,
363 const MI_ClassDecl* classDecl,
364 mike 1.1 Batch* batch_)
365 {
366 Instance* self = (Instance*)self_;
367 MI_ClassDecl* cd = (MI_ClassDecl*)classDecl;
368 Batch* batch = batch_;
369
370 /* Check for null arguments */
371 if (!self || !cd)
372 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
373
374 /* Create a new batch */
375 if (!batch)
376 {
377 batch = Batch_New(_NUM_PAGES);
378 if (!batch)
379 return MI_RESULT_FAILED;
380 }
381
382 /* Zero-fill the object */
383 memset(self, 0, cd->size);
384
385 mike 1.1 /* MI_Instance.ft */
386 self->ft = &__mi_instanceFT;
387
388 /* MI_Instance.self */
389 self->self = self;
390
391 /* MI_Instance.classDecl */
392 self->classDecl = cd;
393
394 /* MI_Instance.batch */
395 self->batch = batch;
396
397 /* Flags */
398 self->releaseBatch = batch == batch_ ? MI_FALSE : MI_TRUE;
399
400 MI_RETURN(MI_RESULT_OK);
401 }
402
403 MI_Result Instance_New(
404 MI_Instance** selfOut,
405 const MI_ClassDecl* classDecl,
406 mike 1.1 Batch* batch_)
407 {
408 Instance* self;
409 Batch* batch = batch_;
410 MI_Result r;
411
412 /* Check for null arguments */
413 if (!selfOut || !classDecl || !batch)
414 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
415
416 /* Null out selfOut */
417 *selfOut = NULL;
418
419 /* Create a new batch */
420 if (!batch)
421 {
422 batch = Batch_New(_NUM_PAGES);
423 if (!batch)
424 return MI_RESULT_FAILED;
425 }
426
427 mike 1.1 /* Allocate structure */
428 self = _AllocInstance(batch, classDecl->size);
429 if (!self)
430 {
431 r = MI_RESULT_FAILED;
432 goto failed;
433 }
434
435 /* Initialize the object */
436 r = Instance_Construct((MI_Instance*)self, classDecl, batch);
437 if (r != MI_RESULT_OK)
438 goto failed;
439
440 /* Arrange to release batch if we created it */
441 self->releaseBatch = batch == batch_ ? MI_FALSE : MI_TRUE;
442
443 *selfOut = (MI_Instance*)self;
444 MI_RETURN(MI_RESULT_OK);
445
446 failed:
447 if (batch != batch_)
448 mike 1.1 Batch_Delete(batch);
449 return r;
450 }
451
452 MI_Result MI_CALL Instance_InitConvert(
453 MI_Instance* self_,
454 const MI_ClassDecl* cd1,
455 const MI_Instance* inst_,
456 MI_Boolean keysOnly,
457 MI_Boolean allowKeylessInst,
458 MI_Boolean copy,
459 Batch* batch_)
460 {
461 Instance* self;
462 const Instance* inst = _SelfOf(inst_);
463 MI_Uint32 i;
464 MI_Result r;
465 const MI_ClassDecl* cd2;
466 const MI_SchemaDecl* sd1;
467 Batch* batch = batch_;
468
469 mike 1.1 /* Resolve the schema declaration (based on type) */
470 if (cd1->flags & MI_FLAG_METHOD)
471 sd1 = ((MI_MethodDecl*)cd1)->schema;
472 else if (cd1->flags & MI_FLAG_CLASS)
473 sd1 = cd1->schema;
474 else
|
704 mike 1.1 }
705
706 if (r != MI_RESULT_OK)
707 {
708 __MI_Instance_Delete(tmpInst);
709 r = MI_RESULT_TYPE_MISMATCH;
710 goto failed;
711 }
712 }
713 else if (pd2->type == MI_INSTANCEA || pd2->type == MI_REFERENCEA)
714 {
715 MI_Value v;
716 MI_Uint32 j;
717
718 v.instancea.size = ((MI_Value*)field)->instancea.size;
719 v.instancea.data = BAlloc(batch,
720 v.instancea.size * sizeof(void*), CALLSITE);
721
722 if (!v.instancea.data)
723 {
724 r = MI_RESULT_FAILED;
725 mike 1.1 goto failed;
726 }
727
728 for (j = 0; j < v.instancea.size; j++)
729 {
730 MI_Instance* tmpInst;
731 MI_ClassDecl* tmpCd;
732
733 /* Find the schema declaration */
734 tmpCd = SchemaDecl_FindClassDecl(sd1, _SelfOf(((
735 MI_Value*)field)->instancea.data[j])->classDecl->name);
736
737 if (!tmpCd)
738 {
739 r = MI_RESULT_FAILED;
740 goto failed;
741 }
742
743 /* Allocate the instance for the provider */
744 if (Instance_New(&tmpInst,tmpCd,batch) != MI_RESULT_OK)
745 {
746 mike 1.1 r = MI_RESULT_FAILED;
747 goto failed;
748 }
749
750 r = Instance_InitConvert(tmpInst, tmpCd,
751 ((MI_Value*)field)->instancea.data[j], keysOnly, MI_FALSE, copy,
752 ((Instance*)tmpInst)->batch);
753
754 if (r != MI_RESULT_OK)
755 {
756 MI_Uint32 k;
757
758 for (k = 0; k < j; k++)
759 __MI_Instance_Delete(v.instancea.data[k]);
760
761 r = MI_RESULT_TYPE_MISMATCH;
762 goto failed;
763 }
764
765 v.instancea.data[j] = tmpInst;
766 }
767 mike 1.1
768 /* Set the value */
769 r = __MI_Instance_SetElement(self_, pd2->name, &v, pd2->type,
770 MI_FLAG_ADOPT);
771
772 if (r != MI_RESULT_OK)
773 {
774 for (j = 0; j < v.instancea.size; j++)
775 __MI_Instance_Delete(v.instancea.data[j]);
776
777 r = MI_RESULT_TYPE_MISMATCH;
778 goto failed;
779 }
780 }
781 else
782 {
783 MI_Uint32 tmpFlags = copy ? 0 : MI_FLAG_BORROW;
784
785 /* Set the value */
786 r = __MI_Instance_SetElement(self_, pd2->name, (MI_Value*)field,
787 pd2->type, tmpFlags);
788 mike 1.1
789 if (r != MI_RESULT_OK)
790 {
791 r = MI_RESULT_TYPE_MISMATCH;
792 goto failed;
793 }
794 }
795 }
796 }
797
798 failed:
799 if (batch != batch_)
800 Batch_Delete(batch);
801 return r;
802 }
803
804 MI_Result MI_CALL Instance_Clone(
805 const MI_Instance* self_,
806 MI_Instance** instOut,
807 Batch* batch_)
808 {
809 mike 1.1 const Instance* self = _SelfOf(self_);
810 Batch* batch = batch_;
811 Instance* inst;
812 MI_Uint32 i;
813 MI_Result r;
814
815 /* Check for a null parameter */
816 if (!self || !instOut)
817 {
818 r = MI_RESULT_FAILED;
819 goto failed;
820 }
821
822 /* Create new batch? */
823 if (!batch)
824 {
825 batch = Batch_New(_NUM_PAGES);
826 if (!batch)
827 return MI_RESULT_FAILED;
828 }
829
830 mike 1.1 /* Allocate the new instance */
831 {
832 MI_Uint32 cap = sizeof(MI_Instance) + _CAPACITY * sizeof(Field);
833
834 if (self->classDecl->size > cap)
835 cap = self->classDecl->size;
836
837 inst = _AllocInstance(batch, cap);
838 if (!inst)
839 {
840 r = MI_RESULT_FAILED;
841 goto failed;
842 }
843 }
844
845 /* Instance.self */
846 inst->self = inst;
847
848 /* Instance.flags */
849 if (batch != batch_)
850 {
851 mike 1.1 inst->releaseBatch = MI_TRUE;
852 }
853
854 /* Set Instance.batch */
855 inst->batch = batch;
856
857 /* Set MI_Instance.ft */
858 inst->ft = &__mi_instanceFT;
859
860 /* Instance.nameSpace */
861 if (self->nameSpace)
862 {
863 inst->nameSpace = BStrdup(batch, self->nameSpace, CALLSITE);
864
865 if (!inst->nameSpace)
866 {
867 r = MI_RESULT_FAILED;
868 goto failed;
869 }
870 }
871
872 mike 1.1 /* Instance.serverName */
873 if (self->serverName)
874 {
875 inst->serverName = BStrdup(batch, self->serverName, CALLSITE);
876
877 if (!inst->serverName)
878 {
879 r = MI_RESULT_FAILED;
880 goto failed;
881 }
882 }
883
884 /* Set Instance.classDecl */
885 if ((void*)self != (void*)self_)
886 {
887 inst->classDecl = _CloneClassDecl(self->classDecl, batch);
888
889 if (!inst->classDecl)
890 {
891 r = MI_RESULT_FAILED;
892 goto failed;
893 mike 1.1 }
894 }
895 else
896 inst->classDecl = self->classDecl;
897
898 /* Clone each of the fields */
899 for (i = 0; i < self->classDecl->numProperties; i++)
900 {
901 const MI_PropertyDecl* pd = self->classDecl->properties[i];
902
903 r = Field_Copy(
904 (Field*)((char*)inst + pd->offset),
905 pd->type,
906 (Field*)((char*)self + pd->offset),
907 batch);
908
909 if (r != MI_RESULT_OK)
910 {
911 r = MI_RESULT_FAILED;
912 goto failed;
913 }
914 mike 1.1 }
915
916 /* Wrapper dynamic instances */
917 if ((void*)self != (void*)self_)
918 {
919 inst = _WrapInstance(inst, batch);
920 if (!inst)
921 {
922 r = MI_RESULT_FAILED;
923 goto failed;
924 }
925 }
926
927 *instOut = (MI_Instance*)inst;
928 return MI_RESULT_OK;
929
930 failed:
931 if (batch != batch_)
932 Batch_Delete(batch);
933 return r;
934 }
935 mike 1.1
936 MI_Result MI_CALL Instance_SetClassName(
937 MI_Instance* self_,
938 const MI_Char* className)
939 {
940 Instance* self = _SelfOf(self_);
941 MI_Char* oldClassName;
942
943 /* Check parameters */
944 if (!self || !className)
945 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
946
947 /* Save old className */
948 oldClassName = self->classDecl->name;
949
950 /* Set new className */
951 {
952 MI_Char* tmp = BStrdup(self->batch, className, CALLSITE);
953
954 if (!tmp)
955 MI_RETURN(MI_RESULT_FAILED);
956 mike 1.1
957 self->classDecl->name = tmp;
958 }
959
960 /* Free old className */
961 if (oldClassName)
962 BFree(self->batch, oldClassName, CALLSITE);
963
964 MI_RETURN(MI_RESULT_OK);
965 }
966
967 MI_Result MI_CALL Instance_NewDynamic(
968 MI_Instance** selfOut,
969 const MI_Char* className,
970 MI_Uint32 metaType,
971 Batch* batch_)
972 {
973 Instance* self = NULL;
974 Batch* batch = batch_;
975 MI_Result r;
976
977 mike 1.1 /* Reject null arguments */
978 if (!selfOut || !className)
979 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
980
981 /* Null output self pointer */
982 *selfOut = NULL;
983
984 /* Create batch if necessary */
985 if (!batch)
986 {
987 batch = Batch_New(_NUM_PAGES);
988 if (!batch)
989 return MI_RESULT_FAILED;
990 }
991
992 /* Check that 'className' parameter is a legal CIM className */
993 if (!LegalName(className))
994 {
995 r = MI_RESULT_INVALID_PARAMETER;
996 goto failed;
997 }
998 mike 1.1
999 /* Allocate instance and reserve room for properties */
1000 {
1001 self = _AllocInstance(batch,
1002 sizeof(MI_Instance) + _CAPACITY * sizeof(Field));
1003
1004 if (!self)
1005 {
1006 r = MI_RESULT_FAILED;
1007 goto failed;
1008 }
1009
1010 self->self = self;
1011 }
1012
1013 /* Set Instance.classDecl */
1014 {
1015 MI_ClassDecl* cd;
1016
1017 /* Allocate and set Instance.classDecl */
1018 {
1019 mike 1.1 cd = (MI_ClassDecl*)BCalloc(batch, sizeof(MI_ClassDecl), CALLSITE);
1020
1021 if (!cd)
1022 {
1023 r = MI_RESULT_FAILED;
1024 goto failed;
1025 }
1026
1027 self->classDecl = cd;
1028 }
1029
1030 /* MI_ClassDecl.flags: */
1031 if (metaType & MI_FLAG_ASSOCIATION)
1032 cd->flags |= MI_FLAG_ASSOCIATION;
1033 else if (metaType & MI_FLAG_INDICATION)
1034 cd->flags |= MI_FLAG_INDICATION;
1035 else if (metaType & MI_FLAG_METHOD)
1036 cd->flags |= MI_FLAG_METHOD;
1037 else if (metaType & MI_FLAG_CLASS)
1038 cd->flags |= MI_FLAG_CLASS;
1039 else
1040 mike 1.1 cd->flags |= MI_FLAG_CLASS;
1041
1042 /* MI_ClassDecl.name: */
1043 {
1044 cd->name = BStrdup(batch, className, CALLSITE);
1045
1046 if (!cd->name)
1047 {
1048 r = MI_RESULT_FAILED;
1049 goto failed;
1050 }
1051 }
1052
1053 /* MI_ClassDecl.code: */
1054 cd->code = Hash(className);
1055
1056 /* MI_ClassDecl.properties: */
1057 {
1058 MI_PropertyDecl** data;
1059
1060 data = (MI_PropertyDecl**)BAlloc(batch,
1061 mike 1.1 _CAPACITY * sizeof(MI_PropertyDecl), CALLSITE);
1062
1063 if (!data)
1064 {
1065 r = MI_RESULT_FAILED;
1066 goto failed;
1067 }
1068
1069 cd->properties = data;
1070 cd->numProperties = 0;
1071 }
1072
1073 /* MI_ClassDecl.size: */
1074 cd->size = sizeof(MI_Instance);
1075 }
1076
1077 /* Set batch: */
1078 self->batch = batch;
1079
1080 /* Set flags */
1081 if (batch_)
1082 mike 1.1 self->releaseBatch = MI_FALSE;
1083 else
1084 self->releaseBatch = MI_TRUE;
1085
1086 /* Set MI_Instance.ft: */
1087 self->ft = &__mi_instanceFT;
1088
1089 /* Set the self pointer */
1090 self->self = self;
1091
1092 /* Set output instance (creating a wrapper for it) */
1093 self = _WrapInstance(self, batch);
1094 if (!self)
1095 {
1096 r = MI_RESULT_FAILED;
1097 goto failed;
1098 }
1099
1100 *selfOut = (MI_Instance*)self;
1101 MI_RETURN(MI_RESULT_OK);
1102
1103 mike 1.1 failed:
1104 if (batch != batch_)
1105 Batch_Delete(batch);
1106 return r;
1107 }
1108
1109 MI_Boolean Instance_MatchKeys(
1110 const MI_Instance* self_,
1111 const MI_Instance* inst_)
1112 {
1113 Instance* self;
1114 Instance* inst;
1115
1116 /* Check parameters */
1117 if (!self_ || !inst_)
1118 {
1119 return MI_FALSE;
1120 }
1121
1122 self = _SelfOf(self_);
1123 inst = _SelfOf(inst_);
1124 mike 1.1
1125 /* Check parameters */
1126 if (!self || !inst)
1127 {
1128 return MI_FALSE;
1129 }
1130
1131 /* Verify they have the same number of keys (one or more) */
1132 {
1133 MI_Uint32 n = _CountKeys(self);
1134
1135 if (n == 0 || n != _CountKeys(inst))
1136 {
1137 return MI_FALSE;
1138 }
1139 }
1140
1141 /* Verify that key fields are identical */
1142 {
1143 const MI_ClassDecl* cd1 = self->classDecl;
1144 const MI_ClassDecl* cd2 = inst->classDecl;
1145 mike 1.1 MI_Uint32 i;
1146
1147 for (i = 0; i < cd1->numProperties; i++)
1148 {
1149 const MI_PropertyDecl* pd1 = cd1->properties[i];
1150 const MI_PropertyDecl* pd2;
1151 Field* f1;
1152 Field* f2;
1153 MI_Uint32 index;
1154
1155 if (pd1->flags & MI_FLAG_KEY)
1156 {
1157 index = _FindPropertyDecl(cd2, pd1->name);
1158
1159 if (index == (MI_Uint32)-1)
1160 {
1161 return MI_FALSE;
1162 }
1163
1164 pd2 = cd2->properties[index];
1165
1166 mike 1.1 if (!(pd2->flags & MI_FLAG_KEY))
1167 {
1168 return MI_FALSE;
1169 }
1170
1171 if (pd1->type != pd2->type)
1172 return MI_FALSE;
1173
1174 f1 = (Field*)((char*)self + pd1->offset);
1175 f2 = (Field*)((char*)inst + pd2->offset);
1176
1177 if (!Field_MatchKey(f1, f2, pd1->type))
1178 {
1179 return MI_FALSE;
1180 }
1181 }
1182 }
1183 }
1184
1185 return MI_TRUE;
1186 }
1187 mike 1.1
1188 /*
1189 **==============================================================================
1190 **
1191 ** MI_Instance function table and functions
1192 **
1193 **==============================================================================
1194 */
1195
1196 void __MI_Instance_Ref(MI_Instance* self)
1197 {
1198 InstanceHeader* h = _HeaderOf((Instance*)self);
1199
1200 if (h)
1201 AtomicInc(&h->u.refs);
1202 }
1203
1204 void __MI_Instance_Unref(MI_Instance* self)
1205 {
1206 InstanceHeader* h = _HeaderOf((Instance*)self);
1207
1208 mike 1.1 if (h && AtomicDec(&h->u.refs))
1209 __MI_Instance_Delete((MI_Instance*)self);
1210 }
1211
1212 MI_Result MI_CALL __MI_Instance_Clone(
1213 const MI_Instance* self,
1214 MI_Instance** inst)
1215 {
1216 return Instance_Clone(self, inst, NULL);
1217 }
1218
1219 MI_Result MI_CALL __MI_Instance_Destruct(
1220 MI_Instance* self_)
1221 {
1222 Instance* self = _SelfOf(self_);
1223 Batch* batch;
1224 MI_Uint32 i;
1225
1226 /* Check for null parameter */
1227 if (!self)
1228 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1229 mike 1.1
1230 /* Save pointer to batch */
1231 batch = self->batch;
1232 if (!batch)
1233 MI_RETURN(MI_RESULT_FAILED);
1234
1235 /* Release serverName */
1236 if (self->serverName)
1237 BFree(batch, self->serverName, CALLSITE);
1238
1239 /* Release nameSpace */
1240 if (self->nameSpace)
1241 BFree(batch, self->nameSpace, CALLSITE);
1242
1243 /* Release all memory used by properties */
1244 for (i = 0; i < self->classDecl->numProperties; i++)
1245 {
1246 const MI_PropertyDecl* pd = self->classDecl->properties[i];
1247 Field* field = (Field*)((char*)self + pd->offset);
1248 Field_Destruct(field, pd->type, batch);
1249 }
1250 mike 1.1
1251 /* Free dynamic instance part (if any) */
1252 if ((void*)self != (void*)self_)
1253 {
1254 for (i = 0; i < self->classDecl->numProperties; i++)
1255 {
1256 MI_PropertyDecl* pd = self->classDecl->properties[i];
1257 BFree(batch, pd->name, CALLSITE);
1258 BFree(batch, pd, CALLSITE);
1259 }
1260
1261 BFree(batch, self->classDecl->name, CALLSITE);
1262 BFree(batch, self->classDecl->properties, CALLSITE);
1263 BFree(batch, self->classDecl, CALLSITE);
1264
1265 if ((void*)self != (void*)self_)
1266 _FreeInstance(batch, self);
1267 }
1268
1269 MI_RETURN(MI_RESULT_OK);
1270 }
1271 mike 1.1
1272 MI_Result MI_CALL __MI_Instance_Delete(
1273 MI_Instance* self_)
1274 {
1275 Instance* self = _SelfOf(self_);
1276 MI_Result r;
1277 Batch* batch;
1278 MI_Boolean releaseBatch;
1279
1280 /* Check for null parameter */
1281 if (!self)
1282 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1283
1284 /* Save pointer to batch */
1285 batch = self->batch;
1286 if (!batch)
1287 MI_RETURN(MI_RESULT_FAILED);
1288
1289 /* Save */
1290 releaseBatch = self->releaseBatch;
1291
1292 mike 1.1 /* Destruct */
1293 r = __MI_Instance_Destruct(self_);
1294 if (r != MI_RESULT_OK)
1295 MI_RETURN(r);
1296
1297 /* Release self pointer */
1298 _FreeInstance(batch, (Instance*)self_);
1299
1300 /* Release the batch */
1301 if (releaseBatch)
1302 Batch_Delete(batch);
1303
1304 return r;
1305 }
1306
1307 MI_Result MI_CALL __MI_Instance_IsA(
1308 const MI_Instance* self_,
1309 const MI_ClassDecl* classDecl,
1310 MI_Boolean* resultOut)
1311 {
1312 Instance* self = _SelfOf(self_);
1313 mike 1.1 const MI_ClassDecl* p;
1314
1315 if (!self || !classDecl)
1316 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1317
1318 for (p = self->classDecl; p; p = p->superClassDecl)
1319 {
1320 if (p == classDecl)
1321 {
1322 if (resultOut)
1323 *resultOut = MI_TRUE;
1324 MI_RETURN(MI_RESULT_OK);
1325 }
1326 }
1327
1328 if (resultOut)
1329 *resultOut = MI_FALSE;
1330
1331 MI_RETURN(MI_RESULT_OK);
1332 }
1333
1334 mike 1.1 MI_Result MI_CALL __MI_Instance_GetClassName(
1335 const MI_Instance* self_,
1336 const MI_Char** classNameOut)
1337 {
1338 Instance* self = _SelfOf(self_);
1339
1340 if (!self)
1341 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1342
1343 if (classNameOut)
1344 *classNameOut = self->classDecl->name;
1345
1346 MI_RETURN(MI_RESULT_OK);
1347 }
1348
1349 MI_Result MI_CALL __MI_Instance_SetNameSpace(
1350 MI_Instance* self_,
1351 const MI_Char* nameSpace)
1352 {
1353 Instance* self = _SelfOf(self_);
1354 MI_Char* oldNameSpace;
1355 mike 1.1
1356 /* Check parameters */
1357 if (!self)
1358 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1359
1360 /* Save old namespace */
1361 oldNameSpace = self->nameSpace;
1362
1363 /* Set new namespace */
1364 if (nameSpace)
1365 {
1366 MI_Char* tmp = BStrdup(self->batch, nameSpace, CALLSITE);
1367
1368 if (!tmp)
1369 MI_RETURN(MI_RESULT_FAILED);
1370
1371 self->nameSpace = tmp;
1372 }
1373 else
1374 self->nameSpace = NULL;
1375
1376 mike 1.1 /* Free old namespace */
1377 if (oldNameSpace)
1378 BFree(self->batch, oldNameSpace, CALLSITE);
1379
1380 MI_RETURN(MI_RESULT_OK);
1381 }
1382
1383 MI_Result MI_CALL __MI_Instance_GetNameSpace(
1384 const MI_Instance* self_,
1385 const MI_Char** nameSpaceOut)
1386 {
1387 Instance* self = _SelfOf(self_);
1388
1389 if (!self)
1390 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1391
1392 if (nameSpaceOut)
1393 *nameSpaceOut = self->nameSpace;
1394
1395 MI_RETURN(MI_RESULT_OK);
1396 }
1397 mike 1.1
1398 MI_Result MI_CALL __MI_Instance_GetElementCount(
1399 const MI_Instance* self_,
1400 MI_Uint32* countOut)
1401 {
1402 Instance* self = _SelfOf(self_);
1403
1404 if (!self)
1405 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1406
1407 if (countOut)
1408 *countOut = self->classDecl->numProperties;
1409
1410 MI_RETURN(MI_RESULT_OK);
1411 }
1412
1413 MI_Result MI_CALL __MI_Instance_AddElement(
1414 MI_Instance* self_,
1415 const MI_Char* name,
1416 const MI_Value* value,
1417 MI_Type type,
1418 mike 1.1 MI_Uint32 flags)
1419 {
1420 Instance* self = _SelfOf(self_);
1421 MI_Uint32 index;
1422 MI_ClassDecl* cd;
1423 MI_Uint32 tflags = 0;
1424
1425 if (flags & MI_FLAG_BORROW)
1426 tflags |= MI_FLAG_BORROW;
1427
1428 if (flags & MI_FLAG_NULL)
1429 tflags |= MI_FLAG_NULL;
1430
1431 /* Check for null arguments */
1432 if (!self || !name)
1433 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1434
1435 /* Reject attempts to extend a non-dynamic instances */
1436 if ((void*)self == (void*)self_)
1437 MI_RETURN(MI_RESULT_FAILED);
1438
1439 mike 1.1 /* Check that 'name' parameter is a legal CIM name */
1440 if (!LegalName(name))
1441 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1442
1443 /* Find the property with this name */
1444 index = _FindPropertyDecl(self->classDecl, name);
1445
1446 if (index != (MI_Uint32)-1)
1447 MI_RETURN(MI_RESULT_ALREADY_EXISTS);
1448
1449 /* Get pointer to class declaration */
1450 cd = (MI_ClassDecl*)self->classDecl;
1451
1452 /* Extend size of instance and properties array as needed */
1453 if (cd->numProperties == _FindCapacity(cd->numProperties))
1454 {
1455 MI_Uint32 cap;
1456 MI_PropertyDecl** data;
1457
1458 /* Double old capacity */
1459 cap = 2 * cd->numProperties;
1460 mike 1.1
1461 /* Reallocate properties array */
1462 data = (MI_PropertyDecl**)BRealloc(
1463 self->batch,
1464 cd->properties,
1465 cd->numProperties * sizeof(MI_PropertyDecl),
1466 cap * sizeof(MI_PropertyDecl),
1467 CALLSITE);
1468
1469 if (!data)
1470 MI_RETURN(MI_RESULT_FAILED);
1471
1472 cd->properties = data;
1473
1474 /* Reallocate instance */
1475 self = _ReallocInstance(
1476 self->batch,
1477 self,
1478 sizeof(MI_Instance) + cd->numProperties * sizeof(Field),
1479 sizeof(MI_Instance) + cap * sizeof(Field));
1480 if (!self)
1481 mike 1.1 MI_RETURN(MI_RESULT_FAILED);
1482
1483 /* Set new self */
1484 self->self = self;
1485 }
1486
1487 /* Create and add new property */
1488 {
1489 MI_PropertyDecl* pd;
1490
1491 /* Allocate new peroperty declaration */
1492 pd = (MI_PropertyDecl*)BCalloc(
1493 self->batch, sizeof(MI_PropertyDecl), CALLSITE);
1494
1495 if (!pd)
1496 MI_RETURN(MI_RESULT_FAILED);
1497
1498 /* MI_PropertyDecl.flags */
1499 pd->flags = flags;
1500
1501 /* MI_PropertyDecl.code */
1502 mike 1.1 pd->code = Hash(name);
1503
1504 /* MI_PropertyDecl.name */
1505 pd->name = BStrdup(self->batch, name, CALLSITE);
1506
1507 if (!pd->name)
1508 MI_RETURN(MI_RESULT_FAILED);
1509
1510 /* MI_PropertyDecl.type */
1511 pd->type = type;
1512
1513 /* MI_PropertyDecl.offset */
1514 pd->offset = sizeof(MI_Instance) + cd->numProperties*sizeof(Field);
1515
1516 /* Add property to array */
1517 cd->properties[cd->numProperties++] = pd;
1518
1519 /* Clear the new field */
1520 memset((char*)self + pd->offset, 0, sizeof(Field));
1521
1522 /* Adjust size */
1523 mike 1.1 cd->size += sizeof(Field);
1524 }
1525
1526 /* Reassign 'self' field (it may have changed) */
1527 ((Instance*)self_)->self = self;
1528
1529 /* Copy self of self wrapper */
1530 memcpy(self_, self, sizeof(MI_Instance));
1531
1532 /* Set the last property */
1533 MI_RETURN(__MI_Instance_SetElementAt(
1534 self_, cd->numProperties - 1, value, type, tflags));
1535 }
1536
1537 MI_Result MI_CALL __MI_Instance_SetElement(
1538 MI_Instance* self_,
1539 const MI_Char* name,
1540 const MI_Value* value,
1541 MI_Type type,
1542 MI_Uint32 flags)
1543 {
1544 mike 1.1 Instance* self = _SelfOf(self_);
1545 MI_Uint32 index;
1546
1547 /* Check for null arguments */
1548 if (!self || !name)
1549 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1550
1551 /* Find the property with this name */
1552 index = _FindPropertyDecl(self->classDecl, name);
1553
1554 if (index == (MI_Uint32)-1)
1555 MI_RETURN(MI_RESULT_NO_SUCH_PROPERTY);
1556
1557 MI_RETURN(__MI_Instance_SetElementAt(self_, index, value, type, flags));
1558 }
1559
1560 MI_Result MI_CALL __MI_Instance_SetElementAt(
1561 MI_Instance* self_,
1562 MI_Uint32 index,
1563 const MI_Value* value,
1564 MI_Type type,
1565 mike 1.1 MI_Uint32 flags)
1566 {
1567 Instance* self = _SelfOf(self_);
1568 const MI_PropertyDecl* pd;
1569 char* field;
1570
1571 /* Check for null arguments */
1572 if (!self)
1573 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1574
1575 /* Check whether index is in range */
1576 if (index > self->classDecl->numProperties)
1577 MI_RETURN(MI_RESULT_FAILED);
1578
1579 /* Get pointer to properties declaration */
1580 pd = self->classDecl->properties[index];
1581
1582 /* Check the type */
1583 if (type != (MI_Type)pd->type)
1584 MI_RETURN(MI_RESULT_TYPE_MISMATCH);
1585
1586 mike 1.1 /* Get pointer to field */
1587 field = (char*)self + pd->offset;
1588
1589 /* Set the value */
1590 {
1591 MI_Result r = Field_Set(
1592 (Field*)((char*)self + pd->offset),
1593 pd->type,
1594 value,
1595 flags,
1596 self->batch);
1597
1598 if (r != MI_RESULT_OK)
1599 return r;
1600 }
1601
1602 MI_RETURN(MI_RESULT_OK);
1603 }
1604
1605 MI_Result MI_CALL __MI_Instance_GetElement(
1606 const MI_Instance* self_,
1607 mike 1.1 const MI_Char* name,
1608 MI_Value* valueOut,
1609 MI_Type* typeOut,
1610 MI_Uint32* flagsOut,
1611 MI_Uint32* indexOut)
1612 {
1613 Instance* self = _SelfOf(self_);
1614 MI_Uint32 index;
1615 MI_Result r;
1616
1617 /* Check for null arguments */
1618 if (!self || !name)
1619 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1620
1621 /* Find the property with this name */
1622 index = _FindPropertyDecl(self->classDecl, name);
1623
1624 if (index == (MI_Uint32)-1)
1625 MI_RETURN(MI_RESULT_NO_SUCH_PROPERTY);
1626
1627 r = __MI_Instance_GetElementAt(
1628 mike 1.1 self_, index, NULL, valueOut, typeOut, flagsOut);
1629
1630 if (r != MI_RESULT_OK)
1631 MI_RETURN(r);
1632
1633 if (indexOut)
1634 *indexOut = index;
1635
1636 MI_RETURN(MI_RESULT_OK);
1637 }
1638
1639 MI_Result MI_CALL __MI_Instance_GetElementAt(
1640 const MI_Instance* self_,
1641 MI_Uint32 index,
1642 const MI_Char** nameOut,
1643 MI_Value* valueOut,
1644 MI_Type* typeOut,
1645 MI_Uint32* flagsOut)
1646 {
1647 Instance* self = _SelfOf(self_);
1648 const MI_PropertyDecl* pd;
1649 mike 1.1 const Field* field;
1650
1651 /* Check for null arguments */
1652 if (!self)
1653 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1654
1655 /* Check for bounds error */
1656 if (index >= self->classDecl->numProperties)
1657 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1658
1659 pd = self->classDecl->properties[index];
1660
1661 /* Get pointer to field */
1662 field = (Field*)((char*)self + pd->offset);
1663
1664 /* set nameOut */
1665 if (nameOut)
1666 *nameOut = pd->name;
1667
1668 /* set valueOut */
1669 if (valueOut)
1670 mike 1.1 memcpy(valueOut, field, Type_SizeOf((MI_Type)pd->type));
1671
1672 /* Set existsOut */
1673 if (flagsOut)
1674 {
1675 *flagsOut = pd->flags;
1676
1677 if (!Field_GetExists(field, (MI_Type)pd->type))
1678 *flagsOut |= MI_FLAG_NULL;
1679 }
1680
1681 /* Set typeOut */
1682 if (typeOut)
1683 *typeOut = (MI_Type)pd->type;
1684
1685 MI_RETURN(MI_RESULT_OK);
1686 }
1687
1688 MI_Result MI_CALL __MI_Instance_ClearElement(
1689 MI_Instance* self_,
1690 const MI_Char* name)
1691 mike 1.1 {
1692 Instance* self = _SelfOf(self_);
1693 MI_Uint32 index;
1694
1695 /* Check for null arguments */
1696 if (!self || !name)
1697 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1698
1699 /* Find the property with this name */
1700 index = _FindPropertyDecl(self->classDecl, name);
1701
1702 if (index == (MI_Uint32)-1)
1703 MI_RETURN(MI_RESULT_NO_SUCH_PROPERTY);
1704
1705 MI_RETURN(__MI_Instance_ClearElementAt(self_, index));
1706 }
1707
1708 MI_Result MI_CALL __MI_Instance_ClearElementAt(
1709 MI_Instance* self_,
1710 MI_Uint32 index)
1711 {
1712 mike 1.1 Instance* self = _SelfOf(self_);
1713 const MI_PropertyDecl* pd;
1714 char* field;
1715
1716 /* Check for null arguments */
1717 if (!self)
1718 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1719
1720 /* Check whether index is in range */
1721 if (index > self->classDecl->numProperties)
1722 MI_RETURN(MI_RESULT_FAILED);
1723
1724 /* Get pointer to properties declaration */
1725 pd = self->classDecl->properties[index];
1726
1727 /* Get pointer to field */
1728 field = (char*)self + pd->offset;
1729
1730 /* Clear the value */
1731 Field_Clear((Field*)((char*)self + pd->offset), pd->type,
1732 self->batch);
1733 mike 1.1
1734 MI_RETURN(MI_RESULT_OK);
1735 }
1736
1737 MI_Result MI_CALL Instance_Print(
1738 const MI_Instance* self_,
1739 FILE* os,
1740 MI_Uint32 level,
1741 MI_Boolean showNulls)
1742 {
1743 Instance* self = _SelfOf(self_);
1744 const MI_ClassDecl* cd = self->classDecl;
1745 MI_Uint32 i;
1746
1747 /* Check for null arguments */
1748 if (!self)
1749 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1750
1751 /* Print nameSpace and className */
1752 if (self->nameSpace)
1753 {
1754 mike 1.1 Indent(os, level);
1755 Fzprintf(os, T("instance of %s:%s\n"), self->nameSpace, cd->name);
1756 }
1757 else
1758 {
1759 Indent(os, level);
1760 Fzprintf(os, T("instance of %s\n"), cd->name);
1761 }
1762
1763 Indent(os, level);
1764 Fzprintf(os, T("{\n"));
1765 level++;
1766
1767 /* Print the properties */
1768 for (i = 0; i < cd->numProperties; i++)
1769 {
1770 const MI_PropertyDecl* pd = cd->properties[i];
1771 const Field* field = (Field*)((char*)self + pd->offset);
1772
1773 if (showNulls || Field_GetExists(field, pd->type))
1774 {
1775 mike 1.1 Indent(os, level);
1776
1777 if (pd->flags & MI_FLAG_KEY)
1778 Fzprintf(os, T("[Key] "));
1779
1780 Fzprintf(os, T("%s="), pd->name);
1781
1782 Field_Print(field, os, pd->type, level);
1783
1784 if (pd->type == MI_INSTANCE || pd->type == MI_REFERENCE)
1785 {
1786 if (!field->instance.value)
1787 fputc('\n', os);
1788 }
1789 else
1790 fputc('\n', os);
1791 }
1792 }
1793
1794 level--;
1795 Indent(os, level);
1796 mike 1.1
1797 Fzprintf(os, T("}\n"));
1798
1799 MI_RETURN(MI_RESULT_OK);
1800 }
1801
1802 MI_Result MI_CALL __MI_Instance_GetServerName(
1803 const MI_Instance* self,
1804 const MI_Char** name)
1805 {
1806 MI_RETURN(MI_RESULT_NOT_SUPPORTED);
1807 }
1808
1809 MI_Result MI_CALL __MI_Instance_SetServerName(
1810 _Inout_ MI_Instance* self,
1811 _In_z_ const MI_Char* name)
1812 {
1813 MI_RETURN(MI_RESULT_NOT_SUPPORTED);
1814 }
1815
1816 MI_Result MI_CALL __MI_Instance_GetClass(
1817 mike 1.1 _In_ const MI_Instance* self,
1818 _Outptr_ MI_Class** instanceClass)
1819 {
1820 MI_RETURN(MI_RESULT_NOT_SUPPORTED);
1821 }
1822
1823 MI_Result MI_CALL __MI_Instance_Print(
1824 const MI_Instance* self,
1825 FILE* os,
1826 MI_Uint32 level)
1827 {
1828 return Instance_Print(self, os, level, MI_TRUE);
1829 }
1830
1831 MI_InstanceFT __mi_instanceFT =
1832 {
1833 __MI_Instance_Clone,
1834 __MI_Instance_Destruct,
1835 __MI_Instance_Delete,
1836 __MI_Instance_IsA,
1837 __MI_Instance_GetClassName,
1838 mike 1.1 __MI_Instance_SetNameSpace,
1839 __MI_Instance_GetNameSpace,
1840 __MI_Instance_GetElementCount,
1841 __MI_Instance_AddElement,
1842 __MI_Instance_SetElement,
1843 __MI_Instance_SetElementAt,
1844 __MI_Instance_GetElement,
1845 __MI_Instance_GetElementAt,
1846 __MI_Instance_ClearElement,
1847 __MI_Instance_ClearElementAt,
1848 __MI_Instance_GetServerName,
1849 __MI_Instance_SetServerName,
1850 __MI_Instance_GetClass,
1851 __MI_Instance_Print,
1852 };
|