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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2