(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 krisbash 1.4 #include <base/miextras.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              
 84 mike     1.2     // Set the class decl:
 85                  chunk->classDecl = clDecl;
 86              
 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              
449 krisbash 1.4     MI_Instance_Print(m_instance, os, level);
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

ViewCVS 0.9.2