(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 karl        1.4.4.1 // 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 karl        1.4.4.1     _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 karl        1.4.4.1     SCMOInstance& inst,
184 thilo.boehm 1.2         Uint32 idx)
185                     {
186 karl        1.4.4.1     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 karl        1.4.4.1     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 karl             1.4.4.1                 _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 karl             1.4.4.1                 _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 karl             1.4.4.1         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                              Uint32 extRefIndex=0;
422                              if (numExtRefs > 0)
423                              {
424                                  if(!_buf.getBytes(extRefArray, numExtRefs*sizeof(SCMOResolutionTable)))
425                                  {
426 thilo.boehm      1.2                 return false;
427                                  }
428                              }
429                          
430                              // Use simple array for access to class pointers
431                              const SCMBClass_Main* const* clsArray = _classTable.getData();
432                          
433                              // SCMOInstances, one by one
434                              for (Uint32 x=0; x < numInst; x++)
435                              {
436                                  Uint64 size;
437                                  if(!_buf.getUint64(size))
438                                  {
439                                      return false;
440                                  }
441                          
442                                  // Reserve 64 bytes more of storage to allow for hostname and namespace
443                                  // updates without reallocation
444                          
445                                  // Read instance data
446                                  SCMBInstance_Main* scmbInstPtr =
447 thilo.boehm      1.2                 (SCMBInstance_Main*)malloc((size_t)size+64);
448                                  if (0 == scmbInstPtr)
449                                  {
450                                      // Not enough memory!
451                                      throw PEGASUS_STD(bad_alloc)();
452                                  }
453                          
454                                  if(!_buf.getBytes(scmbInstPtr,(size_t)size))
455                                  {
456                                      return false;
457                                  }
458                          
459                                  // Resolve the instance
460                                  scmbInstPtr->header.totalSize = size+64;
461                                  scmbInstPtr->header.freeBytes = 64;
462                                  scmbInstPtr->refCount.set(0);
463                                  scmbInstPtr->theClass.ptr =
464                                       new SCMOClass((SCMBClass_Main*)clsArray[instArray[x].index]);
465                          
466                                  SCMOInstance* scmoInstPtr = new SCMOInstance(scmbInstPtr);
467                          
468 thilo.boehm      1.2             if (numExtRefs > 0)
469                                  {
470                                      // Handle the external references to other SCMOInstances
471                                      Uint32 numExtRefs = scmoInstPtr->numberExtRef();
472                                      for (Uint32 i=0; i < numExtRefs; i++)
473                                      {
474                                          Uint32 extRefPos = extRefArray[extRefIndex].index;
475 karl             1.4.4.1                 SCMOInstance* extRefPtr = instArray[extRefPos].scmbptr.scmoInst;
476 thilo.boehm      1.2                     scmoInstPtr->putExtRef(i,extRefPtr);
477                          
478                                          // Mark instance as already consumed
479 karl             1.4.4.1                 instArray[extRefPos].scmbptr.uint64 = 0;
480 thilo.boehm      1.2     
481                                          extRefIndex++;
482                                      }
483                                  }
484                          
485 karl             1.4.4.1         instArray[x].scmbptr.scmoInst = scmoInstPtr;
486 thilo.boehm      1.2     
487                          #ifdef PEGASUS_DEBUG
488                                  _clsResolverTable.append(instArray[x]);
489                          #endif
490                              }
491                          
492                              // Append all non-referenced instances to output array
493                              for (Uint32 x=0; x < numInst; x++)
494                              {
495 karl             1.4.4.1         if (0 != instArray[x].scmbptr.scmoInst)
496 thilo.boehm      1.2             {
497 karl             1.4.4.1             _scmoInstances.append(*(instArray[x].scmbptr.scmoInst));
498                                      delete instArray[x].scmbptr.scmoInst;
499 thilo.boehm      1.2             }
500                              }
501                              delete [] instArray;
502                              delete [] extRefArray;
503                          
504                              return true;
505                          }
506                          
507                          PEGASUS_NAMESPACE_END
508                          

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2