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