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 <cstring>
26 #include <cassert>
27 #include <cstdlib>
28 #include <base/instance.h>
29 #include "instance.h"
30
31 MI_BEGIN_NAMESPACE
32
33 Instance::Instance(
34 const MI_ClassDecl* clDecl)
35 {
36 m_instance = Create(clDecl);
37 AddRef(m_instance);
38 }
39
40 Instance::Instance(
41 const MI_MethodDecl* methodDecl)
42 {
43 mike 1.1 const MI_ClassDecl* clDecl =
44 reinterpret_cast<const MI_ClassDecl*>(methodDecl);
45 m_instance = Create(clDecl);
46 AddRef(m_instance);
47 }
48
49 // returns new instance
50 MI_Instance* Instance::Create(const MI_ClassDecl* clDecl)
51 {
52 size_t instance_size = sizeof(Header) + clDecl->size;
53 Header* chunk = reinterpret_cast<Header*>(operator new(instance_size));
54
55 // init
56 memset(chunk,0,instance_size);
57
58 chunk++;
59
60 ((MI_Instance*)chunk)->classDecl = clDecl;
61 return reinterpret_cast<MI_Instance*>(chunk);
62 }
63
64 mike 1.1 void Instance::Initialize(
65 const MI_ClassDecl* clDecl,
66 const MI_Instance* instance,
67 bool keysOnly)
68 {
69 MI_Instance* chunk = Create(clDecl);
70 m_instance = 0;
71
72 AddRef(chunk);
73
74 if (NULL == instance)
75 {
76 m_instance = chunk;
77 return ;
78 }
79
80 // copy relevant data
81 memcpy(chunk, instance, clDecl->size);
82
83 // Clear reserved part.
84 chunk->reserved[0] = 0;
85 mike 1.1 chunk->reserved[1] = 0;
86 chunk->reserved[2] = 0;
87 chunk->reserved[3] = 0;
88
89 // namespace
90 new(&((MI_Instance*)chunk)->nameSpace) String(
91 ((MI_Instance*)instance)->nameSpace);
92
93 // some types require extra care (arrays, strings, refs)
94
95 for (size_t i = 0; i < clDecl->numProperties; i++)
96 {
97 MI_Uint32 offset = clDecl->properties[i]->offset;
98 char* p = (char*)chunk + offset;
99 const char* q = (const char*)instance + offset;
100
101 switch(clDecl->properties[i]->type)
102 {
103 case MI_BOOLEAN:
104 case MI_UINT8:
105 case MI_SINT8:
106 mike 1.1 case MI_UINT16:
107 case MI_SINT16:
108 case MI_UINT32:
109 case MI_SINT32:
110 case MI_UINT64:
111 case MI_SINT64:
112 case MI_REAL32:
113 case MI_REAL64:
114 case MI_CHAR16:
115 case MI_DATETIME:
116 break; // nothing to do
117
118 case MI_STRING:
119 {
120 // copy string from instance to the dest
121 new(p) String(*(const MI_Char**)(q));
122 break;
123 }
124 case MI_REFERENCE:
125 case MI_INSTANCE:
126 {
127 mike 1.1 const MI_Instance* ref = *(const MI_Instance**)(q);
128
129 if (ref)
130 {
131 // copy instance from 'c' instance pointer
132 new(p) Instance(((MI_Instance*)ref)->classDecl, ref,
133 keysOnly);
134 }
135 break;
136 }
137 case MI_BOOLEANA :
138 case MI_UINT8A :
139 case MI_SINT8A :
140 {
141 const MI_BooleanA * item = (const MI_BooleanA*)(q);
142 new(p) BooleanA(item->data, item->size);
143 break;
144 }
145 case MI_UINT16A :
146 case MI_SINT16A :
147 case MI_CHAR16A :
148 mike 1.1 {
149 const MI_Uint16A * item = (const MI_Uint16A*)(q);
150 new(p) Uint16A(item->data, item->size);
151 break;
152 }
153
154 case MI_UINT32A :
155 case MI_SINT32A :
156 case MI_REAL32A :
157 {
158 const MI_Uint32A * item = (const MI_Uint32A*)(q);
159 new(p) Uint32A(item->data, item->size);
160 break;
161 }
162 case MI_UINT64A :
163 case MI_SINT64A :
164 case MI_REAL64A :
165 {
166 const MI_Uint64A * item = (const MI_Uint64A*)(q);
167 new(p) Uint64A(item->data, item->size);
168 break;
169 mike 1.1 }
170 case MI_STRINGA :
171 {
172 const MI_StringA * item = (const MI_StringA*)(q);
173 new(p) StringA();
174
175 reinterpret_cast<StringA*>(p)->Resize(item->size);
176
177 for(Uint32 counter = 0; counter < item->size; counter++)
178 {
179 reinterpret_cast<StringA*>(p)->operator[](counter)
180 = String(item->data[counter]);
181 }
182 break;
183 }
184 case MI_DATETIMEA :
185 {
186 const MI_DatetimeA* item = (const MI_DatetimeA*)(q);
187 new(p) DatetimeA((const Datetime*)item->data, item->size);
188 break;
189 }
190 mike 1.1 case MI_REFERENCEA :
191 case MI_INSTANCEA :
192 {
193 const MI_InstanceA * item = (const MI_InstanceA*)(q);
194 new(p) InstanceA();
195 reinterpret_cast<InstanceA*>(p)->Resize(item->size);
196
197 for(Uint32 counter = 0; counter < item->size; counter++)
198 {
199 reinterpret_cast<InstanceA*>(p)->operator[](counter) =
200 Instance(((MI_Instance*)item->data[counter])->
201 classDecl, item->data[counter], false);
202 }
203 break;
204 }
205 default:
206 assert(0); // want to find it!
207 }
208 }
209
210 m_instance = chunk;
211 mike 1.1 }
212
213 Instance::Instance(
214 const MI_ClassDecl* clDecl,
215 const MI_Instance* instance,
216 bool keysOnly)
217 {
218 Initialize(clDecl, instance, keysOnly);
219 }
220
221 Instance::Instance(
222 const MI_MethodDecl* methodDecl,
223 const MI_Instance* instance,
224 bool keysOnly)
225 {
226 const MI_ClassDecl* clDecl =
227 reinterpret_cast<const MI_ClassDecl*>(methodDecl);
228 Initialize(clDecl, instance, keysOnly);
229 }
230
231 MI_Instance* Instance::Clone() const
232 mike 1.1 {
233 const MI_ClassDecl* clDecl = ((MI_Instance*)m_instance)->classDecl;
234 MI_Instance* new_inst = Create(clDecl);
235
236 // most of the data can be copied from 'this'
237 memcpy(new_inst, m_instance, clDecl->size);
238
239 new(&((MI_Instance*)new_inst)->nameSpace) String(
240 *((const String*)(&((MI_Instance*)m_instance)->nameSpace)));
241
242 char* inst_start = ((char*)new_inst);
243
244 for (size_t i = 0; i < clDecl->numProperties; i++)
245 {
246 MI_Uint32 offset = clDecl->properties[i]->offset;
247 char* p = inst_start + offset;
248 const char* q = (((const char*)m_instance) + offset);
249
250 switch(clDecl->properties[i]->type)
251 {
252 case MI_BOOLEAN:
253 mike 1.1 case MI_UINT8:
254 case MI_SINT8:
255 case MI_UINT16:
256 case MI_SINT16:
257 case MI_UINT32:
258 case MI_SINT32:
259 case MI_UINT64:
260 case MI_SINT64:
261 case MI_REAL32:
262 case MI_REAL64:
263 case MI_CHAR16:
264 case MI_DATETIME:
265 break; // nothing to do
266 case MI_STRING:
267 {
268 // copy string from instance to the dest
269 new(p) String(*(const String*)(q));
270 break;
271 }
272 case MI_REFERENCE:
273 case MI_INSTANCE:
274 mike 1.1 {
275 // copy instance from 'c' instance pointer
276 MI_Instance* ref = *(MI_Instance**)(q);
277 if (ref)
278 AddRef(ref);
279 break;
280 }
281 case MI_BOOLEANA :
282 case MI_UINT8A :
283 case MI_SINT8A :
284 new(p) BooleanA(*(const BooleanA*)(q));
285 break;
286
287 case MI_UINT16A :
288 case MI_SINT16A :
289 case MI_CHAR16A :
290 new(p) Uint16A(*(const Uint16A*)(q));
291 break;
292
293 case MI_UINT32A :
294 case MI_SINT32A :
295 mike 1.1 case MI_REAL32A :
296 new(p) Uint32A(*(const Uint32A*)q);
297 break;
298
299 case MI_UINT64A :
300 case MI_SINT64A :
301 case MI_REAL64A :
302 new(p) Uint64A(*(const Uint64A*)(q));
303 break;
304
305 case MI_STRINGA :
306 new(p) StringA(*(const StringA*)(q));
307 break;
308
309 case MI_DATETIMEA :
310 new(p) DatetimeA(*(const DatetimeA*)(q));
311 break;
312
313 case MI_REFERENCEA :
314 case MI_INSTANCEA :
315 new(p) InstanceA(*(const InstanceA*)(q));
316 mike 1.1 break;
317
318 default:
319 assert(0); // want to find it!
320 }
321 }
322
323 return new_inst;
324 }
325
326 void Instance::Release(MI_Instance* instance)
327 {
328 if (instance && AtomicDec(GetHeader(instance)->u.s.m_refCounter))
329 {
330 const MI_ClassDecl* clDecl = ((MI_Instance*)instance)->classDecl;
331
332 // namespace
333 ((const String*)(&((MI_Instance*)instance)->nameSpace))->~String();
334
335 // destroy objects!!!
336 char* inst_start = ((char*)(instance));
337 mike 1.1
338 for (size_t i = 0; i < clDecl->numProperties; i++)
339 {
340 char* p = inst_start + clDecl->properties[i]->offset;
341
342 switch(clDecl->properties[i]->type)
343 {
344 case MI_BOOLEAN:
345 case MI_UINT8:
346 case MI_SINT8:
347 case MI_UINT16:
348 case MI_SINT16:
349 case MI_UINT32:
350 case MI_SINT32:
351 case MI_UINT64:
352 case MI_SINT64:
353 case MI_REAL32:
354 case MI_REAL64:
355 case MI_CHAR16:
356 case MI_DATETIME:
357 break; // nothing to do
358 mike 1.1
359 case MI_STRING:
360 // copy string from instance to the dest
361 reinterpret_cast<String*>(p)->~String();
362 break;
363
364 case MI_REFERENCE:
365 case MI_INSTANCE:
366 reinterpret_cast<Instance*>(p)->~Instance();
367 break;
368
369 case MI_BOOLEANA :
370 case MI_UINT8A :
371 case MI_SINT8A :
372 reinterpret_cast<BooleanA*>(p)->~BooleanA();
373 break;
374
375 case MI_UINT16A :
376 case MI_SINT16A :
377 case MI_CHAR16A :
378 reinterpret_cast<Uint16A*>(p)->~Uint16A();
379 mike 1.1 break;
380
381 case MI_UINT32A :
382 case MI_SINT32A :
383 case MI_REAL32A :
384 reinterpret_cast<Uint32A*>(p)->~Uint32A();
385 break;
386
387 case MI_UINT64A :
388 case MI_SINT64A :
389 case MI_REAL64A :
390 reinterpret_cast<Uint64A*>(p)->~Uint64A();
391 break;
392
393 case MI_STRINGA :
394 reinterpret_cast<StringA*>(p)->~StringA();
395 break;
396
397 case MI_DATETIMEA :
398 reinterpret_cast<DatetimeA*>(p)->~DatetimeA();
399 break;
400 mike 1.1
401 case MI_REFERENCEA :
402 case MI_INSTANCEA :
403 reinterpret_cast<InstanceA*>(p)->~InstanceA();
404 break;
405
406 default:
407 assert(0); // want to find it!
408 }
409 }
410
411 operator delete(GetHeader(instance));
412 }
413 }
414
415 // namespace support
416 String Instance::GetNamespace() const
417 {
418 return *((const String*)(&((MI_Instance*)m_instance)->nameSpace));
419 }
420
421 mike 1.1 void Instance::SetNamespace(const String& ns)
422 {
423 *((String*)(&((MI_Instance*)m_instance)->nameSpace)) = ns;
424 }
425
426 void Instance::CopyRef(
427 const Instance& x)
428 {
429 if (x.m_instance != m_instance)
430 {
431 Release(m_instance);
432
433 m_instance = x.m_instance;
434
435 if (m_instance)
436 AddRef(m_instance);
437 }
438 }
439
440 void Instance::Print(FILE* os, MI_Uint32 level) const
441 {
442 mike 1.1 if (!m_instance)
443 return;
444
445 __MI_Instance_Print(m_instance, os, level);
446 }
447
448 const MI_ClassDecl* Instance::GetClassDecl()
449 {
450 static MI_ClassDecl _classDecl =
451 {
452 MI_FLAG_CLASS, /* flags */
453 0, /* code */
454 (MI_Char*)MI_T("Instance"), /* name */
455 NULL, /* qualifiers */
456 0, /* numQualifiers */
457 NULL, /* properties */
458 0, /* numProperties */
459 sizeof(MI_Instance), /* size */
460 NULL, /* superClass */
461 NULL, /* superClassDecl */
462 NULL, /* methods */
463 mike 1.1 0, /* numMethods */
464 NULL, /* schema */
465 NULL, /* functions */
466 };
467
468 return &_classDecl;
469 }
470
471 bool __IsA(const MI_ClassDecl* classDecl, const Instance* instance)
472 {
473 if (classDecl == Instance::GetClassDecl())
474 return true;
475
476 if (!instance)
477 return false;
478
479 const MI_Instance* inst = instance->m_instance;
480
481 for (const MI_ClassDecl *p = inst->classDecl; p; p = p->superClassDecl)
482 {
483 if (p == classDecl)
484 mike 1.1 return true;
485 }
486
487 return false;
488 }
489
490 MI_END_NAMESPACE
|