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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2