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

Diff for /pegasus/src/Pegasus/Common/SCMOStreamer.cpp between version 1.1 and 1.1.2.7

version 1.1, 2009/11/16 17:07:31 version 1.1.2.7, 2009/12/07 11:03:08
Line 0 
Line 1 
   //%LICENSE////////////////////////////////////////////////////////////////
   //
   // Licensed to The Open Group (TOG) under one or more contributor license
   // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
   // this work for additional information regarding copyright ownership.
   // Each contributor licenses this file to you under the OpenPegasus Open
   // Source License; you may not use this file except in compliance with the
   // License.
   //
   // Permission is hereby granted, free of charge, to any person obtaining a
   // copy of this software and associated documentation files (the "Software"),
   // to deal in the Software without restriction, including without limitation
   // the rights to use, copy, modify, merge, publish, distribute, sublicense,
   // and/or sell copies of the Software, and to permit persons to whom the
   // Software is furnished to do so, subject to the following conditions:
   //
   // The above copyright notice and this permission notice shall be included
   // in all copies or substantial portions of the Software.
   //
   // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   //
   //////////////////////////////////////////////////////////////////////////
   //
   //%/////////////////////////////////////////////////////////////////////////////
   
   #include <Pegasus/Common/Config.h>
   #include <cstdlib>
   #include <cstdio>
   #include <Pegasus/Common/SCMOStreamer.h>
   #include <Pegasus/Common/ArrayIterator.h>
   #include <Pegasus/Common/Tracer.h>
   
   PEGASUS_USING_STD;
   
   PEGASUS_NAMESPACE_BEGIN
   
   
   #define PEGASUS_ARRAY_T SCMOResolutionTable
   # include <Pegasus/Common/ArrayImpl.h>
   #undef PEGASUS_ARRAY_T
   
   SCMOStreamer::SCMOStreamer(CIMBuffer& out, Array<SCMOInstance>& x) :
       _buf(out),
       _scmoInstances(x),
       _ttlNumInstances(0),
       _ttlNumClasses(0)
   {
   };
   
   // Writes a single SCMOClass to the given CIMBuffer
   void SCMOStreamer::serializeClass(CIMBuffer& out, const SCMOClass& scmoClass)
   {
       PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::serializeClass");
   
       Array<SCMBClass_Main*> classTable;
       classTable.append(scmoClass.cls.hdr);
   
       _putClasses(out, classTable);
   
       PEG_METHOD_EXIT();
   };
   
   // Reads a single SCMOClass from the given CIMBuffer
   bool SCMOStreamer::deserializeClass(CIMBuffer& in, SCMOClass& scmoClass)
   {
       PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::deserializeClass");
   
       Array<SCMBClass_Main*> classTable;
       if(!_getClasses(in, classTable))
       {
           PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
               "Failed to get Class!");
           PEG_METHOD_EXIT();
           return false;
       }
   
       if (classTable.size() > 0)
       {
           scmoClass = SCMOClass(classTable[0]);
       }
   
       PEG_METHOD_EXIT();
       return true;
   };
   
   // Writes the list of SCMOInstances stored in this instance of SCMOStreamer
   // to the output buffer, including their referenced Classes and Instances
   void SCMOStreamer::serialize()
   {
       PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::serialize");
   
       PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL3,
           "Serializing %d instances\n",
           _scmoInstances.size()));
   
       ConstArrayIterator<SCMOInstance> iterator(_scmoInstances);
   
       // First build the tables for references classes and instances
       for (Uint32 i = 0; i < iterator.size(); i++)
       {
           const SCMOInstance& inst = iterator[i];
   
           _appendToResolverTables(inst);
       }
   
       _putClasses(_buf,_classTable);
   
       _putInstances();
   
       //dumpTables();
   
       PEG_METHOD_EXIT();
   }
   
   // Reads a list of SCMOInstances from the input buffer and stores them in this
   // instance of SCMOStreamer, including their referenced Classes and Instances
   bool SCMOStreamer::deserialize()
   {
       PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::deserialize");
   
       if(!_getClasses(_buf,_classTable))
       {
           PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
               "Failed to get Classes!");
           PEG_METHOD_EXIT();
           return false;
       }
   
       if(!_getInstances())
       {
           PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
               "Failed to get Instances!");
           PEG_METHOD_EXIT();
           return false;
       }
   
       //dumpTables();
   
       PEG_METHOD_EXIT();
       return true;
   }
   
   // This function takes and instance and adds all of its external
   // references (SCMOClass and SCMOInstances) to the index tables
   // For referenced SCMOInstances, the function recusively calls itself.
   //
   // Returns the index position at which the class for this instance was inserted
   // in the class resolver table.
   Uint32 SCMOStreamer::_appendToResolverTables(const SCMOInstance& inst)
   {
       // First handle the external references to other SCMOInstances
       Uint32 numExtRefs = inst.numberExtRef();
       for (Uint32 x=0; x < numExtRefs; x++)
       {
           SCMOInstance* extRef = inst.getExtRef(x);
   
           Uint32 idx = _appendToResolverTables(*extRef);
           _appendToInstResolverTable(*extRef,idx);
       }
   
       // Add the instance to the class resolution table
       // (Also adds the class to the class table when neccessary)
       return _appendToClassResolverTable(inst);
   }
   
   
   // This function adds the given instance to the instance resolver table,
   // which stores the connections between instances and their external
   // references.
   //
   // Returns the index position at which the instance was inserted in the
   // instance resolver table.
   Uint32 SCMOStreamer::_appendToInstResolverTable(
       const SCMOInstance& inst,
       Uint32 idx)
   {
       SCMOResolutionTable tableEntry;
   
       tableEntry.scmbptr = (Uint64)(void*)&inst;
       tableEntry.index = idx;
   
       _instResolverTable.append(tableEntry);
   
       // The number of elements in the array minus 1 is the index position
       // at which the instance was added.
       return _instResolverTable.size() - 1;
   }
   
   
   // Adds an instance to the class resolution table.
   // Also adds the class to the class table when neccessary
   //
   // Returns the index position at which the instance was inserted in the
   // instance resolver table.
   Uint32 SCMOStreamer::_appendToClassResolverTable(const SCMOInstance& inst)
   {
       // Add the SCMOClass for this instance to the class table,
       // or give us the index at which the class resides in the table
       Uint32 clsIdx = _appendToClassTable(inst);
   
   
       // Now build a new entry for the class resolution table
       SCMOResolutionTable tableEntry;
   
       tableEntry.scmbptr = (Uint64)(void*)inst.inst.hdr;
       tableEntry.index = clsIdx;
   
       _clsResolverTable.append(tableEntry);
   
       // The number of elements in the array minus 1 is the index position
       // at which the instance was added.
       return _clsResolverTable.size() - 1;
   }
   
   
   // Add the SCMOClass for the given instance to the class table.
   // If the class already exists in the table, it returns the index position
   // for this class, otherwise appends the class at the end of the table
   // and returns the new index position of the class.
   Uint32 SCMOStreamer::_appendToClassTable(const SCMOInstance& inst)
   {
       Uint32 clsTableSize = _classTable.size();
       SCMBClass_Main* clsPtr = inst.inst.hdr->theClass.ptr->cls.hdr;
   
       const SCMBClass_Main* const* clsArray = _classTable.getData();
   
       // Search through the table for the index of the class
       for (Uint32 x=0; x < clsTableSize; x++)
       {
           if (clsArray[x] == clsPtr)
           {
               return x;
           }
       }
   
       // Class is not yet listed in the table, therefore append it at the end ...
       _classTable.append(clsPtr);
   
       // ... and return the new size off the array minus one as the index
       return _classTable.size()-1;
   }
   
   #ifdef PEGASUS_DEBUG
   void SCMOStreamer::_dumpTables()
   {
       fprintf(stderr,"=====================================================\n");
       fprintf(stderr,"Dump of SCMOStreamer Tables:\n");
       fprintf(stderr,"CLASSES:\n");
       for (Uint32 x=0; x < _classTable.size(); x++)
       {
           fprintf(stderr,"\t[%2d] %p %s\n",x, _classTable[x],
                   _getCharString(_classTable[x]->className,
                                  (const char*)_classTable[x]));
       }
   
       fprintf(stderr,"INSTANCES:\n");
       for (Uint32 x=0; x < _clsResolverTable.size(); x++)
       {
           fprintf(stderr,"\t[%2d] I = %p - cls = %2d\n",
                   x,
                   _clsResolverTable[x].scmbptr,
                   _clsResolverTable[x].index);
       }
   
       fprintf(stderr,"INSTANCE REFERENCES:\n");
       for (Uint32 x=0; x < _instResolverTable.size(); x++)
       {
           fprintf(stderr,"\t[%2d] R = %p - I = %2d\n",
                   x,
                   _instResolverTable[x].scmbptr,
                   _instResolverTable[x].index);
       }
       fprintf(stderr,"=====================================================\n");
   }
   #endif
   
   
   // Adds the list of SCMOClasses from the ClassTable to the output buffer
   void SCMOStreamer::_putClasses(
       CIMBuffer& out,
       Array<SCMBClass_Main*>& classTable)
   {
       Uint32 numClasses = classTable.size();
       const SCMBClass_Main* const* clsArray = classTable.getData();
   
       // Number of classes
       out.putUint32(numClasses);
   
       // SCMOClasses, one by one
       for (Uint32 x=0; x < numClasses; x++)
       {
           // Calculate the in-use size of the SCMOClass data
           Uint64 size =
               clsArray[x]->header.totalSize - clsArray[x]->header.freeBytes;
           out.putUint64(size);
   
           // Write class data
           out.putBytes(clsArray[x],size);
       }
   
   }
   
   // Reads a list of SCMOClasses from the input buffer
   bool SCMOStreamer::_getClasses(
       CIMBuffer& in,
       Array<SCMBClass_Main*>& classTable)
   {
       // Number of classes
       Uint32 numClasses;
       if(! in.getUint32(numClasses) )
       {
           return false;
       }
   
       // SCMOClasses, one by one
       for (Uint32 x=0; x < numClasses; x++)
       {
           Uint64 size;
           if (!in.getUint64(size))
           {
               return false;
           }
   
           // Read class data
           SCMBClass_Main* scmbClassPtr = (SCMBClass_Main*)malloc(size);
           if (0 == scmbClassPtr)
           {
               // Not enough memory!
               throw PEGASUS_STD(bad_alloc)();
           }
   
           if (!in.getBytes(scmbClassPtr,size))
           {
               return false;
           }
   
   
           // Resolve the class
           scmbClassPtr->header.totalSize = size;
           scmbClassPtr->header.freeBytes = 0;
           scmbClassPtr->refCount.set(0);
   
           classTable.append(scmbClassPtr);
       }
   
       return true;
   }
   
   // Adds the list of SCMO Instances from the _clsResolverTable to the
   // output buffer
   void SCMOStreamer::_putInstances()
   {
       Uint32 numInst = _clsResolverTable.size();
       const SCMOResolutionTable* instArray = _clsResolverTable.getData();
   
       // Number of instances
       _buf.putUint32(numInst);
   
       // Instance to class resolution table
       _buf.putBytes(instArray, numInst*sizeof(SCMOResolutionTable));
   
   
       Uint32 numExtRefs = _instResolverTable.size();
       const SCMOResolutionTable* extRefArray = _instResolverTable.getData();
   
       // Number of references
       _buf.putUint32(numExtRefs);
   
       // Instance references resolution table
       _buf.putBytes(extRefArray, numExtRefs*sizeof(SCMOResolutionTable));
   
   
       // SCMOInstances, one by one
       for (Uint32 x=0; x < numInst; x++)
       {
           // Calculate the in-use size of the SCMOInstance data
           SCMBInstance_Main* instPtr = (SCMBInstance_Main*)instArray[x].scmbptr;
           Uint64 size = instPtr->header.totalSize - instPtr->header.freeBytes;
           _buf.putUint64(size);
   
           // Write class data
           _buf.putBytes(instPtr,size);
       }
   }
   
   
   // Reads a list of SCMO Instances from the input buffer.
   // Resolves the pointers to the SCMOClass and external references via the
   // Class and Instance resolver tables.
   bool SCMOStreamer::_getInstances()
   {
       // Number of instances
       Uint32 numInst;
       if(!_buf.getUint32(numInst))
       {
           return false;
       }
   
       // Instance to class resolution table
       SCMOResolutionTable *instArray = new SCMOResolutionTable[numInst];
       if(!_buf.getBytes(instArray, numInst*sizeof(SCMOResolutionTable)))
       {
           return false;
       }
   
       // Number of references
       Uint32 numExtRefs;
       if(!_buf.getUint32(numExtRefs))
       {
           return false;
       }
   
       // Instance references resolution table
       SCMOResolutionTable *extRefArray = new SCMOResolutionTable[numExtRefs];
       Uint32 extRefIndex=0;
       if (numExtRefs > 0)
       {
           if(!_buf.getBytes(extRefArray, numExtRefs*sizeof(SCMOResolutionTable)))
           {
               return false;
           }
       }
   
       // Use simple array for access to class pointers
       const SCMBClass_Main* const* clsArray = _classTable.getData();
   
       // SCMOInstances, one by one
       for (Uint32 x=0; x < numInst; x++)
       {
           Uint64 size;
           if(!_buf.getUint64(size))
           {
               return false;
           }
   
           // Reserve 64 bytes more of storage to allow for hostname and namespace
           // updates without reallocation
   
           // Read instance data
           SCMBInstance_Main* scmbInstPtr = (SCMBInstance_Main*)malloc(size+64);
           if (0 == scmbInstPtr)
           {
               // Not enough memory!
               throw PEGASUS_STD(bad_alloc)();
           }
   
           if(!_buf.getBytes(scmbInstPtr,size))
           {
               return false;
           }
   
           // Resolve the instance
           scmbInstPtr->header.totalSize = size+64;
           scmbInstPtr->header.freeBytes = 64;
           scmbInstPtr->refCount.set(0);
           scmbInstPtr->theClass.ptr =
                new SCMOClass((SCMBClass_Main*)clsArray[instArray[x].index]);
   
           SCMOInstance* scmoInstPtr = new SCMOInstance(scmbInstPtr);
   
           if (numExtRefs > 0)
           {
               // Handle the external references to other SCMOInstances
               Uint32 numExtRefs = scmoInstPtr->numberExtRef();
               for (Uint32 i=0; i < numExtRefs; i++)
               {
                   Uint32 extRefPos = extRefArray[extRefIndex].index;
                   SCMOInstance* extRefPtr =
                       (SCMOInstance*)instArray[extRefPos].scmbptr;
                   scmoInstPtr->putExtRef(i,extRefPtr);
   
                   // Mark instance as already consumed
                   instArray[extRefPos].scmbptr = 0;
   
                   extRefIndex++;
               }
           }
   
           instArray[x].scmbptr = (Uint64)(void*)scmoInstPtr;
   
   #ifdef PEGASUS_DEBUG
           _clsResolverTable.append(instArray[x]);
   #endif
       }
   
       // Append all non-referenced instances to output array
       for (Uint32 x=0; x < numInst; x++)
       {
           if (instArray[x].scmbptr)
           {
               _scmoInstances.append(*((SCMOInstance*)instArray[x].scmbptr));
               delete (SCMOInstance*)instArray[x].scmbptr;
           }
       }
       delete [] instArray;
       delete [] extRefArray;
   
       return true;
   }
   
   PEGASUS_NAMESPACE_END
   


Legend:
Removed from v.1.1  
changed lines
  Added in v.1.1.2.7

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2