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