(file) Return to instance.cpp CVS log (file) (dir) Up to [OMI] / omi / micxx

  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

ViewCVS 0.9.2