(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                 //%/////////////////////////////////////////////////////////////////////////////
 31                 
 32                 #include <Pegasus/Common/Config.h>
 33                 #include <cstdlib>
 34                 #include <cstdio>
 35                 #include <Pegasus/Common/SCMOStreamer.h>
 36                 #include <Pegasus/Common/ArrayIterator.h>
 37                 #include <Pegasus/Common/Tracer.h>
 38                 
 39                 PEGASUS_USING_STD;
 40                 
 41                 PEGASUS_NAMESPACE_BEGIN
 42                 
 43 thilo.boehm 1.2 
 44                 #define PEGASUS_ARRAY_T SCMOResolutionTable
 45                 # include <Pegasus/Common/ArrayImpl.h>
 46                 #undef PEGASUS_ARRAY_T
 47                 
 48                 SCMOStreamer::SCMOStreamer(CIMBuffer& out, Array<SCMOInstance>& x) :
 49                     _buf(out),
 50                     _scmoInstances(x),
 51                     _ttlNumInstances(0),
 52                     _ttlNumClasses(0)
 53                 {
 54                 };
 55                 
 56                 // Writes a single SCMOClass to the given CIMBuffer
 57                 void SCMOStreamer::serializeClass(CIMBuffer& out, const SCMOClass& scmoClass)
 58                 {
 59                     PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::serializeClass");
 60                 
 61                     Array<SCMBClass_Main*> classTable;
 62                     classTable.append(scmoClass.cls.hdr);
 63                 
 64 thilo.boehm 1.2     _putClasses(out, classTable);
 65                 
 66                     PEG_METHOD_EXIT();
 67                 };
 68                 
 69                 // Reads a single SCMOClass from the given CIMBuffer
 70                 bool SCMOStreamer::deserializeClass(CIMBuffer& in, SCMOClass& scmoClass)
 71                 {
 72                     PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::deserializeClass");
 73                 
 74                     Array<SCMBClass_Main*> classTable;
 75                     if(!_getClasses(in, classTable))
 76                     {
 77                         PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
 78                             "Failed to get Class!");
 79                         PEG_METHOD_EXIT();
 80                         return false;
 81                     }
 82                 
 83                     if (classTable.size() > 0)
 84                     {
 85 thilo.boehm 1.2         scmoClass = SCMOClass(classTable[0]);
 86                     }
 87                 
 88                     PEG_METHOD_EXIT();
 89                     return true;
 90                 };
 91                 
 92                 // Writes the list of SCMOInstances stored in this instance of SCMOStreamer
 93                 // to the output buffer, including their referenced Classes and Instances
 94                 void SCMOStreamer::serialize()
 95                 {
 96                     PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::serialize");
 97                 
 98                     PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL3,
 99                         "Serializing %d instances\n",
100                         _scmoInstances.size()));
101                 
102                     ConstArrayIterator<SCMOInstance> iterator(_scmoInstances);
103                 
104                     // First build the tables for references classes and instances
105                     for (Uint32 i = 0; i < iterator.size(); i++)
106 thilo.boehm 1.2     {
107                         const SCMOInstance& inst = iterator[i];
108                 
109                         _appendToResolverTables(inst);
110                     }
111                 
112                     _putClasses(_buf,_classTable);
113                 
114                     _putInstances();
115                 
116                     //dumpTables();
117                 
118                     PEG_METHOD_EXIT();
119                 }
120                 
121                 // Reads a list of SCMOInstances from the input buffer and stores them in this
122                 // instance of SCMOStreamer, including their referenced Classes and Instances
123                 bool SCMOStreamer::deserialize()
124                 {
125                     PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::deserialize");
126                 
127 thilo.boehm 1.2     if(!_getClasses(_buf,_classTable))
128                     {
129                         PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
130                             "Failed to get Classes!");
131                         PEG_METHOD_EXIT();
132                         return false;
133                     }
134                 
135                     if(!_getInstances())
136                     {
137                         PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
138                             "Failed to get Instances!");
139                         PEG_METHOD_EXIT();
140                         return false;
141                     }
142                 
143                     //dumpTables();
144                 
145                     PEG_METHOD_EXIT();
146                     return true;
147                 }
148 thilo.boehm 1.2 
149                 // This function takes and instance and adds all of its external
150                 // references (SCMOClass and SCMOInstances) to the index tables
151                 // For referenced SCMOInstances, the function recusively calls itself.
152                 //
153                 // Returns the index position at which the class for this instance was inserted
154                 // in the class resolver table.
155                 Uint32 SCMOStreamer::_appendToResolverTables(const SCMOInstance& inst)
156                 {
157                     // First handle the external references to other SCMOInstances
158                     Uint32 numExtRefs = inst.numberExtRef();
159                     for (Uint32 x=0; x < numExtRefs; x++)
160                     {
161                         SCMOInstance* extRef = inst.getExtRef(x);
162                 
163                         Uint32 idx = _appendToResolverTables(*extRef);
164                         _appendToInstResolverTable(*extRef,idx);
165                     }
166                 
167                     // Add the instance to the class resolution table
168                     // (Also adds the class to the class table when neccessary)
169 thilo.boehm 1.2     return _appendToClassResolverTable(inst);
170                 }
171                 
172                 
173                 // This function adds the given instance to the instance resolver table,
174                 // which stores the connections between instances and their external
175                 // references.
176                 //
177                 // Returns the index position at which the instance was inserted in the
178                 // instance resolver table.
179                 Uint32 SCMOStreamer::_appendToInstResolverTable(
180                     const SCMOInstance& inst,
181                     Uint32 idx)
182                 {
183 sahana.prabhakar 1.4     SCMOResolutionTable tableEntry = { (Uint64)(void*)&inst, idx};
184 thilo.boehm      1.2     _instResolverTable.append(tableEntry);
185                      
186                          // The number of elements in the array minus 1 is the index position
187                          // at which the instance was added.
188                          return _instResolverTable.size() - 1;
189                      }
190                      
191                      
192                      // Adds an instance to the class resolution table.
193                      // Also adds the class to the class table when neccessary
194                      //
195                      // Returns the index position at which the instance was inserted in the
196                      // instance resolver table.
197                      Uint32 SCMOStreamer::_appendToClassResolverTable(const SCMOInstance& inst)
198                      {
199                          // Add the SCMOClass for this instance to the class table,
200                          // or give us the index at which the class resides in the table
201                          Uint32 clsIdx = _appendToClassTable(inst);
202                      
203                      
204                          // Now build a new entry for the class resolution table
205 sahana.prabhakar 1.4     SCMOResolutionTable tableEntry = {(Uint64)(void*)inst.inst.hdr, clsIdx};
206 thilo.boehm      1.2     _clsResolverTable.append(tableEntry);
207                      
208                          // The number of elements in the array minus 1 is the index position
209                          // at which the instance was added.
210                          return _clsResolverTable.size() - 1;
211                      }
212                      
213                      
214                      // Add the SCMOClass for the given instance to the class table.
215                      // If the class already exists in the table, it returns the index position
216                      // for this class, otherwise appends the class at the end of the table
217                      // and returns the new index position of the class.
218                      Uint32 SCMOStreamer::_appendToClassTable(const SCMOInstance& inst)
219                      {
220                          Uint32 clsTableSize = _classTable.size();
221                          SCMBClass_Main* clsPtr = inst.inst.hdr->theClass.ptr->cls.hdr;
222                      
223                          const SCMBClass_Main* const* clsArray = _classTable.getData();
224                      
225                          // Search through the table for the index of the class
226                          for (Uint32 x=0; x < clsTableSize; x++)
227 thilo.boehm      1.2     {
228                              if (clsArray[x] == clsPtr)
229                              {
230                                  return x;
231                              }
232                          }
233                      
234                          // Class is not yet listed in the table, therefore append it at the end ...
235                          _classTable.append(clsPtr);
236                      
237                          // ... and return the new size off the array minus one as the index
238                          return _classTable.size()-1;
239                      }
240                      
241                      #ifdef PEGASUS_DEBUG
242                      void SCMOStreamer::_dumpTables()
243                      {
244                          fprintf(stderr,"=====================================================\n");
245                          fprintf(stderr,"Dump of SCMOStreamer Tables:\n");
246                          fprintf(stderr,"CLASSES:\n");
247                          for (Uint32 x=0; x < _classTable.size(); x++)
248 thilo.boehm      1.2     {
249                              fprintf(stderr,"\t[%2d] %p %s\n",x, _classTable[x],
250                                      _getCharString(_classTable[x]->className,
251                                                     (const char*)_classTable[x]));
252                          }
253                      
254                          fprintf(stderr,"INSTANCES:\n");
255                          for (Uint32 x=0; x < _clsResolverTable.size(); x++)
256                          {
257 sahana.prabhakar 1.4         fprintf(stderr,"\t[%2d] I = %llx - cls = %2lld\n",
258 thilo.boehm      1.2                 x,
259                                      _clsResolverTable[x].scmbptr,
260                                      _clsResolverTable[x].index);
261                          }
262                      
263                          fprintf(stderr,"INSTANCE REFERENCES:\n");
264                          for (Uint32 x=0; x < _instResolverTable.size(); x++)
265                          {
266 sahana.prabhakar 1.4         fprintf(stderr,"\t[%2d] R = %llx - I = %2lld\n",
267 thilo.boehm      1.2                 x,
268                                      _instResolverTable[x].scmbptr,
269                                      _instResolverTable[x].index);
270                          }
271                          fprintf(stderr,"=====================================================\n");
272                      }
273                      #endif
274                      
275                      
276                      // Adds the list of SCMOClasses from the ClassTable to the output buffer
277                      void SCMOStreamer::_putClasses(
278                          CIMBuffer& out,
279                          Array<SCMBClass_Main*>& classTable)
280                      {
281                          Uint32 numClasses = classTable.size();
282                          const SCMBClass_Main* const* clsArray = classTable.getData();
283                      
284                          // Number of classes
285                          out.putUint32(numClasses);
286                      
287                          // SCMOClasses, one by one
288 thilo.boehm      1.2     for (Uint32 x=0; x < numClasses; x++)
289                          {
290                              // Calculate the in-use size of the SCMOClass data
291                              Uint64 size =
292                                  clsArray[x]->header.totalSize - clsArray[x]->header.freeBytes;
293                              out.putUint64(size);
294                      
295                              // Write class data
296                              out.putBytes(clsArray[x],(size_t)size);
297                          }
298                      
299                      }
300                      
301                      // Reads a list of SCMOClasses from the input buffer
302                      bool SCMOStreamer::_getClasses(
303                          CIMBuffer& in,
304                          Array<SCMBClass_Main*>& classTable)
305                      {
306                          // Number of classes
307                          Uint32 numClasses;
308                          if(! in.getUint32(numClasses) )
309 thilo.boehm      1.2     {
310                              return false;
311                          }
312                      
313                          // SCMOClasses, one by one
314                          for (Uint32 x=0; x < numClasses; x++)
315                          {
316                              Uint64 size;
317                              if (!in.getUint64(size))
318                              {
319                                  return false;
320                              }
321                      
322                              // Read class data
323                              SCMBClass_Main* scmbClassPtr = (SCMBClass_Main*)malloc((size_t)size);
324                              if (0 == scmbClassPtr)
325                              {
326                                  // Not enough memory!
327                                  throw PEGASUS_STD(bad_alloc)();
328                              }
329                      
330 thilo.boehm      1.2         if (!in.getBytes(scmbClassPtr,(size_t)size))
331                              {
332                                  return false;
333                              }
334                      
335                      
336                              // Resolve the class
337                              scmbClassPtr->header.totalSize = size;
338                              scmbClassPtr->header.freeBytes = 0;
339                              scmbClassPtr->refCount.set(0);
340                      
341                              classTable.append(scmbClassPtr);
342                          }
343                      
344                          return true;
345                      }
346                      
347                      // Adds the list of SCMO Instances from the _clsResolverTable to the
348                      // output buffer
349                      void SCMOStreamer::_putInstances()
350                      {
351 thilo.boehm      1.2     Uint32 numInst = _clsResolverTable.size();
352                          const SCMOResolutionTable* instArray = _clsResolverTable.getData();
353                      
354                          // Number of instances
355                          _buf.putUint32(numInst);
356                      
357                          // Instance to class resolution table
358                          _buf.putBytes(instArray, numInst*sizeof(SCMOResolutionTable));
359                      
360                      
361                          Uint32 numExtRefs = _instResolverTable.size();
362                          const SCMOResolutionTable* extRefArray = _instResolverTable.getData();
363                      
364                          // Number of references
365                          _buf.putUint32(numExtRefs);
366                      
367                          // Instance references resolution table
368                          _buf.putBytes(extRefArray, numExtRefs*sizeof(SCMOResolutionTable));
369                      
370                      
371                          // SCMOInstances, one by one
372 thilo.boehm      1.2     for (Uint32 x=0; x < numInst; x++)
373                          {
374                              // Calculate the in-use size of the SCMOInstance data
375                              SCMBInstance_Main* instPtr = (SCMBInstance_Main*)instArray[x].scmbptr;
376                              Uint64 size = instPtr->header.totalSize - instPtr->header.freeBytes;
377                              _buf.putUint64(size);
378                      
379                              // Write class data
380                              _buf.putBytes(instPtr,(size_t)size);
381                          }
382                      }
383                      
384                      
385                      // Reads a list of SCMO Instances from the input buffer.
386                      // Resolves the pointers to the SCMOClass and external references via the
387                      // Class and Instance resolver tables.
388                      bool SCMOStreamer::_getInstances()
389                      {
390                          // Number of instances
391                          Uint32 numInst;
392                          if(!_buf.getUint32(numInst))
393 thilo.boehm      1.2     {
394                              return false;
395                          }
396                      
397                          // Instance to class resolution table
398                          SCMOResolutionTable *instArray = new SCMOResolutionTable[numInst];
399                          if(!_buf.getBytes(instArray, numInst*sizeof(SCMOResolutionTable)))
400                          {
401                              return false;
402                          }
403                      
404                          // Number of references
405                          Uint32 numExtRefs;
406                          if(!_buf.getUint32(numExtRefs))
407                          {
408                              return false;
409                          }
410                      
411                          // Instance references resolution table
412                          SCMOResolutionTable *extRefArray = new SCMOResolutionTable[numExtRefs];
413                          Uint32 extRefIndex=0;
414 thilo.boehm      1.2     if (numExtRefs > 0)
415                          {
416                              if(!_buf.getBytes(extRefArray, numExtRefs*sizeof(SCMOResolutionTable)))
417                              {
418                                  return false;
419                              }
420                          }
421                      
422                          // Use simple array for access to class pointers
423                          const SCMBClass_Main* const* clsArray = _classTable.getData();
424                      
425                          // SCMOInstances, one by one
426                          for (Uint32 x=0; x < numInst; x++)
427                          {
428                              Uint64 size;
429                              if(!_buf.getUint64(size))
430                              {
431                                  return false;
432                              }
433                      
434                              // Reserve 64 bytes more of storage to allow for hostname and namespace
435 thilo.boehm      1.2         // updates without reallocation
436                      
437                              // Read instance data
438                              SCMBInstance_Main* scmbInstPtr =
439                                  (SCMBInstance_Main*)malloc((size_t)size+64);
440                              if (0 == scmbInstPtr)
441                              {
442                                  // Not enough memory!
443                                  throw PEGASUS_STD(bad_alloc)();
444                              }
445                      
446                              if(!_buf.getBytes(scmbInstPtr,(size_t)size))
447                              {
448                                  return false;
449                              }
450                      
451                              // Resolve the instance
452                              scmbInstPtr->header.totalSize = size+64;
453                              scmbInstPtr->header.freeBytes = 64;
454                              scmbInstPtr->refCount.set(0);
455                              scmbInstPtr->theClass.ptr =
456 thilo.boehm      1.2              new SCMOClass((SCMBClass_Main*)clsArray[instArray[x].index]);
457                      
458                              SCMOInstance* scmoInstPtr = new SCMOInstance(scmbInstPtr);
459                      
460                              if (numExtRefs > 0)
461                              {
462                                  // Handle the external references to other SCMOInstances
463                                  Uint32 numExtRefs = scmoInstPtr->numberExtRef();
464                                  for (Uint32 i=0; i < numExtRefs; i++)
465                                  {
466                                      Uint32 extRefPos = extRefArray[extRefIndex].index;
467                                      SCMOInstance* extRefPtr =
468                                          (SCMOInstance*)instArray[extRefPos].scmbptr;
469                                      scmoInstPtr->putExtRef(i,extRefPtr);
470                      
471                                      // Mark instance as already consumed
472                                      instArray[extRefPos].scmbptr = 0;
473                      
474                                      extRefIndex++;
475                                  }
476                              }
477 thilo.boehm      1.2 
478                              instArray[x].scmbptr = (Uint64)(void*)scmoInstPtr;
479                      
480                      #ifdef PEGASUS_DEBUG
481                              _clsResolverTable.append(instArray[x]);
482                      #endif
483                          }
484                      
485                          // Append all non-referenced instances to output array
486                          for (Uint32 x=0; x < numInst; x++)
487                          {
488                              if (instArray[x].scmbptr)
489                              {
490                                  _scmoInstances.append(*((SCMOInstance*)instArray[x].scmbptr));
491                                  delete (SCMOInstance*)instArray[x].scmbptr;
492                              }
493                          }
494                          delete [] instArray;
495                          delete [] extRefArray;
496                      
497                          return true;
498 thilo.boehm      1.2 }
499                      
500                      PEGASUS_NAMESPACE_END
501                      

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2