(file) Return to SCMOStreamer.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

  1 thilo.boehm 1.2 //%LICENSE////////////////////////////////////////////////////////////////
  2                 //
  3                 // Licensed to The Open Group (TOG) under one or more contributor license
  4                 // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
  5                 // this work for additional information regarding copyright ownership.
  6                 // Each contributor licenses this file to you under the OpenPegasus Open
  7                 // Source License; you may not use this file except in compliance with the
  8                 // License.
  9                 //
 10                 // Permission is hereby granted, free of charge, to any person obtaining a
 11                 // copy of this software and associated documentation files (the "Software"),
 12                 // to deal in the Software without restriction, including without limitation
 13                 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 14                 // and/or sell copies of the Software, and to permit persons to whom the
 15                 // Software is furnished to do so, subject to the following conditions:
 16                 //
 17                 // The above copyright notice and this permission notice shall be included
 18                 // in all copies or substantial portions of the Software.
 19                 //
 20                 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 21                 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 22 thilo.boehm 1.2 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 23                 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 24                 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 25                 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 26                 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27                 //
 28                 //////////////////////////////////////////////////////////////////////////
 29                 //
 30 marek       1.7 // This code implements part of PEP#348 - The CMPI infrastructure using SCMO
 31                 // (Single Chunk Memory Objects).
 32                 // The design document can be found on the OpenPegasus website openpegasus.org
 33                 // at https://collaboration.opengroup.org/pegasus/pp/documents/21210/PEP_348.pdf
 34                 //
 35 thilo.boehm 1.2 //%/////////////////////////////////////////////////////////////////////////////
 36                 
 37                 #include <Pegasus/Common/Config.h>
 38                 #include <cstdlib>
 39                 #include <cstdio>
 40                 #include <Pegasus/Common/SCMOStreamer.h>
 41                 #include <Pegasus/Common/ArrayIterator.h>
 42                 #include <Pegasus/Common/Tracer.h>
 43                 
 44                 PEGASUS_USING_STD;
 45                 
 46                 PEGASUS_NAMESPACE_BEGIN
 47                 
 48                 
 49                 #define PEGASUS_ARRAY_T SCMOResolutionTable
 50                 # include <Pegasus/Common/ArrayImpl.h>
 51                 #undef PEGASUS_ARRAY_T
 52                 
 53                 SCMOStreamer::SCMOStreamer(CIMBuffer& out, Array<SCMOInstance>& x) :
 54                     _buf(out),
 55 dl.meetei   1.5     _scmoInstances(x)
 56 thilo.boehm 1.2 {
 57                 };
 58                 
 59                 // Writes a single SCMOClass to the given CIMBuffer
 60                 void SCMOStreamer::serializeClass(CIMBuffer& out, const SCMOClass& scmoClass)
 61                 {
 62                     PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::serializeClass");
 63                 
 64                     Array<SCMBClass_Main*> classTable;
 65                     classTable.append(scmoClass.cls.hdr);
 66                 
 67                     _putClasses(out, classTable);
 68                 
 69                     PEG_METHOD_EXIT();
 70                 };
 71                 
 72                 // Reads a single SCMOClass from the given CIMBuffer
 73                 bool SCMOStreamer::deserializeClass(CIMBuffer& in, SCMOClass& scmoClass)
 74                 {
 75                     PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::deserializeClass");
 76                 
 77 thilo.boehm 1.2     Array<SCMBClass_Main*> classTable;
 78                     if(!_getClasses(in, classTable))
 79                     {
 80                         PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
 81                             "Failed to get Class!");
 82                         PEG_METHOD_EXIT();
 83                         return false;
 84                     }
 85                 
 86                     if (classTable.size() > 0)
 87                     {
 88                         scmoClass = SCMOClass(classTable[0]);
 89                     }
 90                 
 91                     PEG_METHOD_EXIT();
 92                     return true;
 93                 };
 94                 
 95                 // Writes the list of SCMOInstances stored in this instance of SCMOStreamer
 96                 // to the output buffer, including their referenced Classes and Instances
 97                 void SCMOStreamer::serialize()
 98 thilo.boehm 1.2 {
 99                     PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::serialize");
100                 
101                     PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL3,
102                         "Serializing %d instances\n",
103                         _scmoInstances.size()));
104                 
105                     ConstArrayIterator<SCMOInstance> iterator(_scmoInstances);
106                 
107                     // First build the tables for references classes and instances
108                     for (Uint32 i = 0; i < iterator.size(); i++)
109                     {
110                         const SCMOInstance& inst = iterator[i];
111                 
112                         _appendToResolverTables(inst);
113                     }
114                 
115                     _putClasses(_buf,_classTable);
116                 
117                     _putInstances();
118                 
119 thilo.boehm 1.2     //dumpTables();
120                 
121                     PEG_METHOD_EXIT();
122                 }
123                 
124                 // Reads a list of SCMOInstances from the input buffer and stores them in this
125                 // instance of SCMOStreamer, including their referenced Classes and Instances
126                 bool SCMOStreamer::deserialize()
127                 {
128                     PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::deserialize");
129                 
130                     if(!_getClasses(_buf,_classTable))
131                     {
132                         PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
133                             "Failed to get Classes!");
134                         PEG_METHOD_EXIT();
135                         return false;
136                     }
137                 
138                     if(!_getInstances())
139                     {
140 thilo.boehm 1.2         PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
141                             "Failed to get Instances!");
142                         PEG_METHOD_EXIT();
143                         return false;
144                     }
145                 
146                     //dumpTables();
147                 
148                     PEG_METHOD_EXIT();
149                     return true;
150                 }
151                 
152                 // This function takes and instance and adds all of its external
153                 // references (SCMOClass and SCMOInstances) to the index tables
154                 // For referenced SCMOInstances, the function recusively calls itself.
155                 //
156                 // Returns the index position at which the class for this instance was inserted
157                 // in the class resolver table.
158                 Uint32 SCMOStreamer::_appendToResolverTables(const SCMOInstance& inst)
159                 {
160                     // First handle the external references to other SCMOInstances
161 thilo.boehm 1.2     Uint32 numExtRefs = inst.numberExtRef();
162                     for (Uint32 x=0; x < numExtRefs; x++)
163                     {
164                         SCMOInstance* extRef = inst.getExtRef(x);
165                 
166                         Uint32 idx = _appendToResolverTables(*extRef);
167                         _appendToInstResolverTable(*extRef,idx);
168                     }
169                 
170                     // Add the instance to the class resolution table
171                     // (Also adds the class to the class table when neccessary)
172                     return _appendToClassResolverTable(inst);
173                 }
174                 
175                 
176                 // This function adds the given instance to the instance resolver table,
177                 // which stores the connections between instances and their external
178                 // references.
179                 //
180                 // Returns the index position at which the instance was inserted in the
181                 // instance resolver table.
182 thilo.boehm 1.2 Uint32 SCMOStreamer::_appendToInstResolverTable(
183 marek       1.6     SCMOInstance& inst,
184 thilo.boehm 1.2     Uint32 idx)
185                 {
186 marek       1.6     SCMOResolutionTable tableEntry;
187                     tableEntry.scmbptr.scmoInst = &inst;
188                     tableEntry.index = idx;
189                 
190 thilo.boehm 1.2     _instResolverTable.append(tableEntry);
191                 
192                     // The number of elements in the array minus 1 is the index position
193                     // at which the instance was added.
194                     return _instResolverTable.size() - 1;
195                 }
196                 
197                 
198                 // Adds an instance to the class resolution table.
199                 // Also adds the class to the class table when neccessary
200                 //
201                 // Returns the index position at which the instance was inserted in the
202                 // instance resolver table.
203                 Uint32 SCMOStreamer::_appendToClassResolverTable(const SCMOInstance& inst)
204                 {
205                     // Add the SCMOClass for this instance to the class table,
206                     // or give us the index at which the class resides in the table
207                     Uint32 clsIdx = _appendToClassTable(inst);
208                 
209                 
210                     // Now build a new entry for the class resolution table
211 marek       1.6     SCMOResolutionTable tableEntry;
212                     tableEntry.scmbptr.scmbMain = inst.inst.hdr;
213                     tableEntry.index = clsIdx;
214 thilo.boehm 1.2     _clsResolverTable.append(tableEntry);
215                 
216                     // The number of elements in the array minus 1 is the index position
217                     // at which the instance was added.
218                     return _clsResolverTable.size() - 1;
219                 }
220                 
221                 
222                 // Add the SCMOClass for the given instance to the class table.
223                 // If the class already exists in the table, it returns the index position
224                 // for this class, otherwise appends the class at the end of the table
225                 // and returns the new index position of the class.
226                 Uint32 SCMOStreamer::_appendToClassTable(const SCMOInstance& inst)
227                 {
228                     Uint32 clsTableSize = _classTable.size();
229                     SCMBClass_Main* clsPtr = inst.inst.hdr->theClass.ptr->cls.hdr;
230                 
231                     const SCMBClass_Main* const* clsArray = _classTable.getData();
232                 
233                     // Search through the table for the index of the class
234                     for (Uint32 x=0; x < clsTableSize; x++)
235 thilo.boehm 1.2     {
236                         if (clsArray[x] == clsPtr)
237                         {
238                             return x;
239                         }
240                     }
241                 
242                     // Class is not yet listed in the table, therefore append it at the end ...
243                     _classTable.append(clsPtr);
244                 
245                     // ... and return the new size off the array minus one as the index
246                     return _classTable.size()-1;
247                 }
248                 
249                 #ifdef PEGASUS_DEBUG
250                 void SCMOStreamer::_dumpTables()
251                 {
252                     fprintf(stderr,"=====================================================\n");
253                     fprintf(stderr,"Dump of SCMOStreamer Tables:\n");
254                     fprintf(stderr,"CLASSES:\n");
255                     for (Uint32 x=0; x < _classTable.size(); x++)
256 thilo.boehm 1.2     {
257                         fprintf(stderr,"\t[%2d] %p %s\n",x, _classTable[x],
258                                 _getCharString(_classTable[x]->className,
259                                                (const char*)_classTable[x]));
260                     }
261                 
262                     fprintf(stderr,"INSTANCES:\n");
263                     for (Uint32 x=0; x < _clsResolverTable.size(); x++)
264                     {
265 sahana.prabhakar 1.4         fprintf(stderr,"\t[%2d] I = %llx - cls = %2lld\n",
266 thilo.boehm      1.2                 x,
267 marek            1.6                 _clsResolverTable[x].scmbptr.uint64,
268 thilo.boehm      1.2                 _clsResolverTable[x].index);
269                          }
270                      
271                          fprintf(stderr,"INSTANCE REFERENCES:\n");
272                          for (Uint32 x=0; x < _instResolverTable.size(); x++)
273                          {
274 sahana.prabhakar 1.4         fprintf(stderr,"\t[%2d] R = %llx - I = %2lld\n",
275 thilo.boehm      1.2                 x,
276 marek            1.6                 _instResolverTable[x].scmbptr.uint64,
277 thilo.boehm      1.2                 _instResolverTable[x].index);
278                          }
279                          fprintf(stderr,"=====================================================\n");
280                      }
281                      #endif
282                      
283                      
284                      // Adds the list of SCMOClasses from the ClassTable to the output buffer
285                      void SCMOStreamer::_putClasses(
286                          CIMBuffer& out,
287                          Array<SCMBClass_Main*>& classTable)
288                      {
289                          Uint32 numClasses = classTable.size();
290                          const SCMBClass_Main* const* clsArray = classTable.getData();
291                      
292                          // Number of classes
293                          out.putUint32(numClasses);
294                      
295                          // SCMOClasses, one by one
296                          for (Uint32 x=0; x < numClasses; x++)
297                          {
298 thilo.boehm      1.2         // Calculate the in-use size of the SCMOClass data
299                              Uint64 size =
300                                  clsArray[x]->header.totalSize - clsArray[x]->header.freeBytes;
301                              out.putUint64(size);
302                      
303                              // Write class data
304                              out.putBytes(clsArray[x],(size_t)size);
305                          }
306                      
307                      }
308                      
309                      // Reads a list of SCMOClasses from the input buffer
310                      bool SCMOStreamer::_getClasses(
311                          CIMBuffer& in,
312                          Array<SCMBClass_Main*>& classTable)
313                      {
314                          // Number of classes
315                          Uint32 numClasses;
316                          if(! in.getUint32(numClasses) )
317                          {
318                              return false;
319 thilo.boehm      1.2     }
320                      
321                          // SCMOClasses, one by one
322                          for (Uint32 x=0; x < numClasses; x++)
323                          {
324                              Uint64 size;
325                              if (!in.getUint64(size))
326                              {
327                                  return false;
328                              }
329                      
330                              // Read class data
331                              SCMBClass_Main* scmbClassPtr = (SCMBClass_Main*)malloc((size_t)size);
332                              if (0 == scmbClassPtr)
333                              {
334                                  // Not enough memory!
335                                  throw PEGASUS_STD(bad_alloc)();
336                              }
337                      
338                              if (!in.getBytes(scmbClassPtr,(size_t)size))
339                              {
340 thilo.boehm      1.2             return false;
341                              }
342                      
343                      
344                              // Resolve the class
345                              scmbClassPtr->header.totalSize = size;
346                              scmbClassPtr->header.freeBytes = 0;
347                              scmbClassPtr->refCount.set(0);
348                      
349                              classTable.append(scmbClassPtr);
350                          }
351                      
352                          return true;
353                      }
354                      
355                      // Adds the list of SCMO Instances from the _clsResolverTable to the
356                      // output buffer
357                      void SCMOStreamer::_putInstances()
358                      {
359                          Uint32 numInst = _clsResolverTable.size();
360                          const SCMOResolutionTable* instArray = _clsResolverTable.getData();
361 thilo.boehm      1.2 
362                          // Number of instances
363                          _buf.putUint32(numInst);
364                      
365                          // Instance to class resolution table
366                          _buf.putBytes(instArray, numInst*sizeof(SCMOResolutionTable));
367                      
368                      
369                          Uint32 numExtRefs = _instResolverTable.size();
370                          const SCMOResolutionTable* extRefArray = _instResolverTable.getData();
371                      
372                          // Number of references
373                          _buf.putUint32(numExtRefs);
374                      
375                          // Instance references resolution table
376                          _buf.putBytes(extRefArray, numExtRefs*sizeof(SCMOResolutionTable));
377                      
378                      
379                          // SCMOInstances, one by one
380                          for (Uint32 x=0; x < numInst; x++)
381                          {
382 thilo.boehm      1.2         // Calculate the in-use size of the SCMOInstance data
383 marek            1.6         SCMBInstance_Main* instPtr = instArray[x].scmbptr.scmbMain;
384 thilo.boehm      1.2         Uint64 size = instPtr->header.totalSize - instPtr->header.freeBytes;
385                              _buf.putUint64(size);
386                      
387                              // Write class data
388                              _buf.putBytes(instPtr,(size_t)size);
389                          }
390                      }
391                      
392                      
393                      // Reads a list of SCMO Instances from the input buffer.
394                      // Resolves the pointers to the SCMOClass and external references via the
395                      // Class and Instance resolver tables.
396                      bool SCMOStreamer::_getInstances()
397                      {
398                          // Number of instances
399                          Uint32 numInst;
400                          if(!_buf.getUint32(numInst))
401                          {
402                              return false;
403                          }
404                      
405 thilo.boehm      1.2     // Instance to class resolution table
406                          SCMOResolutionTable *instArray = new SCMOResolutionTable[numInst];
407                          if(!_buf.getBytes(instArray, numInst*sizeof(SCMOResolutionTable)))
408                          {
409                              return false;
410                          }
411                      
412                          // Number of references
413                          Uint32 numExtRefs;
414                          if(!_buf.getUint32(numExtRefs))
415                          {
416                              return false;
417                          }
418                      
419                          // Instance references resolution table
420                          SCMOResolutionTable *extRefArray = new SCMOResolutionTable[numExtRefs];
421                          if (numExtRefs > 0)
422                          {
423                              if(!_buf.getBytes(extRefArray, numExtRefs*sizeof(SCMOResolutionTable)))
424                              {
425                                  return false;
426 thilo.boehm      1.2         }
427                          }
428                      
429                          // Use simple array for access to class pointers
430                          const SCMBClass_Main* const* clsArray = _classTable.getData();
431                      
432                          // SCMOInstances, one by one
433                          for (Uint32 x=0; x < numInst; x++)
434                          {
435                              Uint64 size;
436                              if(!_buf.getUint64(size))
437                              {
438                                  return false;
439                              }
440                      
441                              // Reserve 64 bytes more of storage to allow for hostname and namespace
442                              // updates without reallocation
443                      
444                              // Read instance data
445                              SCMBInstance_Main* scmbInstPtr =
446                                  (SCMBInstance_Main*)malloc((size_t)size+64);
447 thilo.boehm      1.2         if (0 == scmbInstPtr)
448                              {
449                                  // Not enough memory!
450                                  throw PEGASUS_STD(bad_alloc)();
451                              }
452                      
453                              if(!_buf.getBytes(scmbInstPtr,(size_t)size))
454                              {
455                                  return false;
456                              }
457                      
458                              // Resolve the instance
459                              scmbInstPtr->header.totalSize = size+64;
460                              scmbInstPtr->header.freeBytes = 64;
461                              scmbInstPtr->refCount.set(0);
462                              scmbInstPtr->theClass.ptr =
463                                   new SCMOClass((SCMBClass_Main*)clsArray[instArray[x].index]);
464                      
465                              SCMOInstance* scmoInstPtr = new SCMOInstance(scmbInstPtr);
466                      
467 marek            1.6         instArray[x].scmbptr.scmoInst = scmoInstPtr;
468 thilo.boehm      1.2 
469                      #ifdef PEGASUS_DEBUG
470                              _clsResolverTable.append(instArray[x]);
471                      #endif
472                          }
473                      
474 jsafrane         1.8     // resolve all references in all instances
475                          if (numExtRefs > 0)
476                          {
477                              for (Uint32 x = 0; x < numInst; x++)
478                              {
479                                  SCMOInstance* inst = (SCMOInstance*)instArray[x].scmbptr.scmoInst;
480                                  // resolve all references in this instance
481                                  for (Uint32 ref = 0; ref < inst->numberExtRef(); ref++)
482                                  {
483                                      SCMOInstance* oldPtr = inst->getExtRef(ref);
484                                      /* find the instance for given reference*/
485                                      for (Uint32 y = 0; y < numExtRefs; y++)
486                                      {
487                                          if (extRefArray[y].scmbptr.scmoInst == oldPtr) {
488                                              Uint64 i = extRefArray[y].index;
489                                              SCMOInstance *newPtr = instArray[i].scmbptr.scmoInst;
490                                              inst->putExtRef(ref, newPtr);
491                                              // consume the instance
492                                              instArray[i].scmbptr.uint64 = 0;
493                                              break;
494                                          }
495 jsafrane         1.8                 }
496                                  }
497                              }
498                          }
499                      
500 thilo.boehm      1.2     // Append all non-referenced instances to output array
501                          for (Uint32 x=0; x < numInst; x++)
502                          {
503 marek            1.6         if (0 != instArray[x].scmbptr.scmoInst)
504 thilo.boehm      1.2         {
505 marek            1.6             _scmoInstances.append(*(instArray[x].scmbptr.scmoInst));
506                                  delete instArray[x].scmbptr.scmoInst;
507 thilo.boehm      1.2         }
508                          }
509                          delete [] instArray;
510                          delete [] extRefArray;
511                      
512                          return true;
513                      }
514                      
515                      PEGASUS_NAMESPACE_END
516                      

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2