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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2