(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 mike  1.2     // Set the class decl:
 84               chunk->classDecl = clDecl;
 85           
 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

ViewCVS 0.9.2