version 1.1.2.1, 2009/11/16 17:07:31
|
version 1.7, 2013/02/13 11:39:58
|
|
|
// | // |
////////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////////// |
// | // |
|
// This code implements part of PEP#348 - The CMPI infrastructure using SCMO |
|
// (Single Chunk Memory Objects). |
|
// The design document can be found on the OpenPegasus website openpegasus.org |
|
// at https://collaboration.opengroup.org/pegasus/pp/documents/21210/PEP_348.pdf |
|
// |
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
#include <Pegasus/Common/Config.h> | #include <Pegasus/Common/Config.h> |
|
|
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
| |
|
#define PEGASUS_ARRAY_T SCMOResolutionTable |
|
# include <Pegasus/Common/ArrayImpl.h> |
|
#undef PEGASUS_ARRAY_T |
|
|
SCMOStreamer::SCMOStreamer(CIMBuffer& out, Array<SCMOInstance>& x) : | SCMOStreamer::SCMOStreamer(CIMBuffer& out, Array<SCMOInstance>& x) : |
_buf(out), | _buf(out), |
_scmoInstances(x), |
_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 | // Writes the list of SCMOInstances stored in this instance of SCMOStreamer |
// to the output buffer, including their referenced Classes and Instances | // to the output buffer, including their referenced Classes and Instances |
|
|
_appendToResolverTables(inst); | _appendToResolverTables(inst); |
} | } |
| |
_putClasses(); |
_putClasses(_buf,_classTable); |
| |
_putInstances(); | _putInstances(); |
| |
|
|
// instance of SCMOStreamer, including their referenced Classes and Instances | // instance of SCMOStreamer, including their referenced Classes and Instances |
bool SCMOStreamer::deserialize() | bool SCMOStreamer::deserialize() |
{ | { |
PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::serialize"); |
PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::deserialize"); |
| |
if(!_getClasses()) |
if(!_getClasses(_buf,_classTable)) |
{ | { |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, | PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, |
"Failed to get Classes!"); | "Failed to get Classes!"); |
|
|
// Returns the index position at which the instance was inserted in the | // Returns the index position at which the instance was inserted in the |
// instance resolver table. | // instance resolver table. |
Uint32 SCMOStreamer::_appendToInstResolverTable( | Uint32 SCMOStreamer::_appendToInstResolverTable( |
const SCMOInstance& inst, |
SCMOInstance& inst, |
Uint32 idx) | Uint32 idx) |
{ | { |
SCMOResultionTable tableEntry; |
SCMOResolutionTable tableEntry; |
|
tableEntry.scmbptr.scmoInst = &inst; |
tableEntry.scmbptr = (void*)&inst; |
|
tableEntry.index = idx; | tableEntry.index = idx; |
| |
_instResolverTable.append(tableEntry); | _instResolverTable.append(tableEntry); |
|
|
| |
| |
// Now build a new entry for the class resolution table | // Now build a new entry for the class resolution table |
SCMOResultionTable tableEntry; |
SCMOResolutionTable tableEntry; |
|
tableEntry.scmbptr.scmbMain = inst.inst.hdr; |
tableEntry.scmbptr = (void*)inst.inst.hdr; |
|
tableEntry.index = clsIdx; | tableEntry.index = clsIdx; |
|
|
_clsResolverTable.append(tableEntry); | _clsResolverTable.append(tableEntry); |
| |
// The number of elements in the array minus 1 is the index position | // The number of elements in the array minus 1 is the index position |
|
|
Uint32 SCMOStreamer::_appendToClassTable(const SCMOInstance& inst) | Uint32 SCMOStreamer::_appendToClassTable(const SCMOInstance& inst) |
{ | { |
Uint32 clsTableSize = _classTable.size(); | Uint32 clsTableSize = _classTable.size(); |
const SCMBClass_Main* clsPtr = inst.inst.hdr->theClass->cls.hdr; |
SCMBClass_Main* clsPtr = inst.inst.hdr->theClass.ptr->cls.hdr; |
| |
const SCMBClass_Main* const* clsArray = _classTable.getData(); | const SCMBClass_Main* const* clsArray = _classTable.getData(); |
| |
|
|
fprintf(stderr,"INSTANCES:\n"); | fprintf(stderr,"INSTANCES:\n"); |
for (Uint32 x=0; x < _clsResolverTable.size(); x++) | for (Uint32 x=0; x < _clsResolverTable.size(); x++) |
{ | { |
fprintf(stderr,"\t[%2d] I = %p - cls = %2d\n", |
fprintf(stderr,"\t[%2d] I = %llx - cls = %2lld\n", |
x, | x, |
_clsResolverTable[x].scmbptr, |
_clsResolverTable[x].scmbptr.uint64, |
_clsResolverTable[x].index); | _clsResolverTable[x].index); |
} | } |
| |
fprintf(stderr,"INSTANCE REFERENCES:\n"); | fprintf(stderr,"INSTANCE REFERENCES:\n"); |
for (Uint32 x=0; x < _instResolverTable.size(); x++) | for (Uint32 x=0; x < _instResolverTable.size(); x++) |
{ | { |
fprintf(stderr,"\t[%2d] R = %p - I = %2d\n", |
fprintf(stderr,"\t[%2d] R = %llx - I = %2lld\n", |
x, | x, |
_instResolverTable[x].scmbptr, |
_instResolverTable[x].scmbptr.uint64, |
_instResolverTable[x].index); | _instResolverTable[x].index); |
} | } |
fprintf(stderr,"=====================================================\n"); | fprintf(stderr,"=====================================================\n"); |
|
|
| |
| |
// Adds the list of SCMOClasses from the ClassTable to the output buffer | // Adds the list of SCMOClasses from the ClassTable to the output buffer |
void SCMOStreamer::_putClasses() |
void SCMOStreamer::_putClasses( |
|
CIMBuffer& out, |
|
Array<SCMBClass_Main*>& classTable) |
{ | { |
Uint32 numClasses = _classTable.size(); |
Uint32 numClasses = classTable.size(); |
const SCMBClass_Main* const* clsArray = _classTable.getData(); |
const SCMBClass_Main* const* clsArray = classTable.getData(); |
| |
// Number of classes | // Number of classes |
_buf.putUint32(numClasses); |
out.putUint32(numClasses); |
| |
// SCMOClasses, one by one | // SCMOClasses, one by one |
for (Uint32 x=0; x < numClasses; x++) | for (Uint32 x=0; x < numClasses; x++) |
|
|
// Calculate the in-use size of the SCMOClass data | // Calculate the in-use size of the SCMOClass data |
Uint64 size = | Uint64 size = |
clsArray[x]->header.totalSize - clsArray[x]->header.freeBytes; | clsArray[x]->header.totalSize - clsArray[x]->header.freeBytes; |
_buf.putUint64(size); |
out.putUint64(size); |
| |
// Write class data | // Write class data |
_buf.putBytes(clsArray[x],size); |
out.putBytes(clsArray[x],(size_t)size); |
} | } |
| |
} | } |
| |
// Reads a list of SCMOClasses from the input buffer | // Reads a list of SCMOClasses from the input buffer |
bool SCMOStreamer::_getClasses() |
bool SCMOStreamer::_getClasses( |
|
CIMBuffer& in, |
|
Array<SCMBClass_Main*>& classTable) |
{ | { |
// Number of classes | // Number of classes |
Uint32 numClasses; | Uint32 numClasses; |
if(! _buf.getUint32(numClasses) ) |
if(! in.getUint32(numClasses) ) |
{ | { |
return false; | return false; |
} | } |
|
|
for (Uint32 x=0; x < numClasses; x++) | for (Uint32 x=0; x < numClasses; x++) |
{ | { |
Uint64 size; | Uint64 size; |
if (!_buf.getUint64(size)) |
if (!in.getUint64(size)) |
{ | { |
return false; | return false; |
} | } |
| |
// Read class data | // Read class data |
SCMBClass_Main* scmbClassPtr = (SCMBClass_Main*)malloc(size); |
SCMBClass_Main* scmbClassPtr = (SCMBClass_Main*)malloc((size_t)size); |
if (0 == scmbClassPtr) | if (0 == scmbClassPtr) |
{ | { |
// Not enough memory! | // Not enough memory! |
throw PEGASUS_STD(bad_alloc)(); | throw PEGASUS_STD(bad_alloc)(); |
} | } |
| |
if (!_buf.getBytes(scmbClassPtr,size)) |
if (!in.getBytes(scmbClassPtr,(size_t)size)) |
{ | { |
return false; | return false; |
} | } |
|
|
scmbClassPtr->header.freeBytes = 0; | scmbClassPtr->header.freeBytes = 0; |
scmbClassPtr->refCount.set(0); | scmbClassPtr->refCount.set(0); |
| |
_classTable.append(scmbClassPtr); |
classTable.append(scmbClassPtr); |
} | } |
| |
return true; | return true; |
|
|
void SCMOStreamer::_putInstances() | void SCMOStreamer::_putInstances() |
{ | { |
Uint32 numInst = _clsResolverTable.size(); | Uint32 numInst = _clsResolverTable.size(); |
const SCMOResultionTable* instArray = _clsResolverTable.getData(); |
const SCMOResolutionTable* instArray = _clsResolverTable.getData(); |
| |
// Number of instances | // Number of instances |
_buf.putUint32(numInst); | _buf.putUint32(numInst); |
| |
// Instance to class resolution table | // Instance to class resolution table |
_buf.putBytes(instArray, numInst*sizeof(SCMOResultionTable)); |
_buf.putBytes(instArray, numInst*sizeof(SCMOResolutionTable)); |
| |
| |
Uint32 numExtRefs = _instResolverTable.size(); | Uint32 numExtRefs = _instResolverTable.size(); |
const SCMOResultionTable* extRefArray = _instResolverTable.getData(); |
const SCMOResolutionTable* extRefArray = _instResolverTable.getData(); |
| |
// Number of references | // Number of references |
_buf.putUint32(numExtRefs); | _buf.putUint32(numExtRefs); |
| |
// Instance references resolution table | // Instance references resolution table |
_buf.putBytes(extRefArray, numExtRefs*sizeof(SCMOResultionTable)); |
_buf.putBytes(extRefArray, numExtRefs*sizeof(SCMOResolutionTable)); |
| |
| |
// SCMOInstances, one by one | // SCMOInstances, one by one |
for (Uint32 x=0; x < numInst; x++) | for (Uint32 x=0; x < numInst; x++) |
{ | { |
// Calculate the in-use size of the SCMOInstance data | // Calculate the in-use size of the SCMOInstance data |
SCMBInstance_Main* instPtr = (SCMBInstance_Main*)instArray[x].scmbptr; |
SCMBInstance_Main* instPtr = instArray[x].scmbptr.scmbMain; |
Uint64 size = instPtr->header.totalSize - instPtr->header.freeBytes; | Uint64 size = instPtr->header.totalSize - instPtr->header.freeBytes; |
_buf.putUint64(size); | _buf.putUint64(size); |
| |
// Write class data | // Write class data |
_buf.putBytes(instPtr,size); |
_buf.putBytes(instPtr,(size_t)size); |
} | } |
} | } |
| |
|
|
} | } |
| |
// Instance to class resolution table | // Instance to class resolution table |
SCMOResultionTable instArray[numInst]; |
SCMOResolutionTable *instArray = new SCMOResolutionTable[numInst]; |
if(!_buf.getBytes(&instArray, numInst*sizeof(SCMOResultionTable))) |
if(!_buf.getBytes(instArray, numInst*sizeof(SCMOResolutionTable))) |
{ | { |
return false; | return false; |
} | } |
|
|
} | } |
| |
// Instance references resolution table | // Instance references resolution table |
SCMOResultionTable extRefArray[numExtRefs]; |
SCMOResolutionTable *extRefArray = new SCMOResolutionTable[numExtRefs]; |
Uint32 extRefIndex=0; | Uint32 extRefIndex=0; |
if (numExtRefs > 0) | if (numExtRefs > 0) |
{ | { |
if(!_buf.getBytes(&extRefArray, numExtRefs*sizeof(SCMOResultionTable))) |
if(!_buf.getBytes(extRefArray, numExtRefs*sizeof(SCMOResolutionTable))) |
{ | { |
return false; | return false; |
} | } |
|
|
// updates without reallocation | // updates without reallocation |
| |
// Read instance data | // Read instance data |
SCMBInstance_Main* scmbInstPtr = (SCMBInstance_Main*)malloc(size+64); |
SCMBInstance_Main* scmbInstPtr = |
|
(SCMBInstance_Main*)malloc((size_t)size+64); |
if (0 == scmbInstPtr) | if (0 == scmbInstPtr) |
{ | { |
// Not enough memory! | // Not enough memory! |
throw PEGASUS_STD(bad_alloc)(); | throw PEGASUS_STD(bad_alloc)(); |
} | } |
| |
if(!_buf.getBytes(scmbInstPtr,size)) |
if(!_buf.getBytes(scmbInstPtr,(size_t)size)) |
{ | { |
return false; | return false; |
} | } |
|
|
scmbInstPtr->header.totalSize = size+64; | scmbInstPtr->header.totalSize = size+64; |
scmbInstPtr->header.freeBytes = 64; | scmbInstPtr->header.freeBytes = 64; |
scmbInstPtr->refCount.set(0); | scmbInstPtr->refCount.set(0); |
scmbInstPtr->theClass = |
scmbInstPtr->theClass.ptr = |
new SCMOClass((SCMBClass_Main*)clsArray[instArray[x].index]); | new SCMOClass((SCMBClass_Main*)clsArray[instArray[x].index]); |
| |
SCMOInstance* scmoInstPtr = new SCMOInstance(scmbInstPtr); | SCMOInstance* scmoInstPtr = new SCMOInstance(scmbInstPtr); |
|
|
for (Uint32 i=0; i < numExtRefs; i++) | for (Uint32 i=0; i < numExtRefs; i++) |
{ | { |
Uint32 extRefPos = extRefArray[extRefIndex].index; | Uint32 extRefPos = extRefArray[extRefIndex].index; |
SCMOInstance* extRefPtr = |
SCMOInstance* extRefPtr = instArray[extRefPos].scmbptr.scmoInst; |
(SCMOInstance*)instArray[extRefPos].scmbptr; |
|
scmoInstPtr->putExtRef(i,extRefPtr); | scmoInstPtr->putExtRef(i,extRefPtr); |
| |
// Mark instance as already consumed | // Mark instance as already consumed |
instArray[extRefPos].scmbptr = 0; |
instArray[extRefPos].scmbptr.uint64 = 0; |
| |
extRefIndex++; | extRefIndex++; |
} | } |
} | } |
| |
instArray[x].scmbptr = (void*)scmoInstPtr; |
instArray[x].scmbptr.scmoInst = scmoInstPtr; |
| |
#ifdef PEGASUS_DEBUG | #ifdef PEGASUS_DEBUG |
_clsResolverTable.append(instArray[x]); | _clsResolverTable.append(instArray[x]); |
|
|
// Append all non-referenced instances to output array | // Append all non-referenced instances to output array |
for (Uint32 x=0; x < numInst; x++) | for (Uint32 x=0; x < numInst; x++) |
{ | { |
if (instArray[x].scmbptr) |
if (0 != instArray[x].scmbptr.scmoInst) |
{ | { |
_scmoInstances.append(*((SCMOInstance*)instArray[x].scmbptr)); |
_scmoInstances.append(*(instArray[x].scmbptr.scmoInst)); |
delete (SCMOInstance*)instArray[x].scmbptr; |
delete instArray[x].scmbptr.scmoInst; |
} | } |
} | } |
|
delete [] instArray; |
|
delete [] extRefArray; |
| |
return true; | return true; |
} | } |