version 1.5, 2011/01/07 02:17:20
|
version 1.5.2.28, 2014/06/01 19:26:52
|
|
|
// | // |
////////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////////// |
// | // |
|
// Class CIMResponseData encapsulates the possible types of response data |
|
// representations and supplies conversion methods between these types. |
|
// PEP#348 - The CMPI infrastructure using SCMO (Single Chunk Memory Objects) |
|
// describes its usage in the server flow. |
|
// 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 "CIMResponseData.h" | #include "CIMResponseData.h" |
|
|
#include <Pegasus/Common/CIMInternalXmlEncoder.h> | #include <Pegasus/Common/CIMInternalXmlEncoder.h> |
#include <Pegasus/Common/SCMOInternalXmlEncoder.h> | #include <Pegasus/Common/SCMOInternalXmlEncoder.h> |
| |
|
|
PEGASUS_USING_STD; | PEGASUS_USING_STD; |
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
// C++ objects interface handling |
// Defines debug code in CIMResponseData. This under this |
|
// special compile flag so that it can be compiled independent of |
|
// PEGASUS_DEBUG flags. |
|
// #define CIMRESPONSEDATA_DEBUG |
|
|
|
#define LOCAL_MIN(a, b) ((a < b) ? a : b) |
|
|
|
/* |
|
Append an InstanceElement to the Buffer. This function accounts |
|
for the existence of a propertyList. |
|
*/ |
|
void CIMResponseData::_appendInstanceElement( |
|
Buffer& out, |
|
SCMOInstance _scmoInstance) |
|
{ |
|
if(_propertyList.isNull()) |
|
{ |
|
Array<Uint32> emptyNodes; |
|
SCMOXmlWriter::appendInstanceElement( |
|
out, |
|
_scmoInstance, |
|
false, |
|
emptyNodes); |
|
} |
|
else |
|
{ |
|
Array<propertyFilterNodesArray_t> propFilterNodesArrays; |
|
// This searches for an already created array of nodes, |
|
//if not found, creates it inside propFilterNodesArrays |
|
const Array<Uint32> & nodes= |
|
SCMOXmlWriter::getFilteredNodesArray( |
|
propFilterNodesArrays, |
|
_scmoInstance, |
|
_propertyList); |
|
SCMOXmlWriter::appendInstanceElement( |
|
out, |
|
_scmoInstance, |
|
true, |
|
nodes); |
|
} |
|
} |
| |
// Instance Names handling | // Instance Names handling |
Array<CIMObjectPath>& CIMResponseData::getInstanceNames() | Array<CIMObjectPath>& CIMResponseData::getInstanceNames() |
|
|
return _instanceNames; | return _instanceNames; |
} | } |
| |
// Instance handling |
// Get a single instance as a CIM instance. |
|
// This converts all of the objects in the response data to |
|
// CIM form as part of the conversion. |
|
// If there are no instances in the object, returns CIMInstance(), |
|
// an empty instance. |
CIMInstance& CIMResponseData::getInstance() | CIMInstance& CIMResponseData::getInstance() |
{ | { |
PEGASUS_DEBUG_ASSERT(_dataType == RESP_INSTANCE); | PEGASUS_DEBUG_ASSERT(_dataType == RESP_INSTANCE); |
|
|
return _instances; | return _instances; |
} | } |
| |
|
// Instances handling specifically for the client where the call may |
|
// get either instances or objects and must convert them to instances |
|
// NOTE: This is a temporary solution to satisfy the BinaryCodec passing |
|
// of data to the client where the data could be either instances or |
|
// objects. The correct solution is to convert back when the provider, etc. |
|
// returns the data to the server. We must convert to that solution but |
|
// this keeps it working for the moment. |
|
Array<CIMInstance>& CIMResponseData::getInstancesFromInstancesOrObjects() |
|
{ |
|
if (_dataType == RESP_INSTANCES) |
|
{ |
|
_resolveToCIM(); |
|
return _instances; |
|
} |
|
else if (_dataType == RESP_OBJECTS) |
|
{ |
|
_resolveToCIM(); |
|
for (Uint32 i = 0 ; i < _objects.size() ; i++) |
|
{ |
|
_instances.append((CIMInstance)_objects[i]); |
|
} |
|
return _instances; |
|
|
|
} |
|
PEGASUS_ASSERT(false); |
|
} |
|
|
// Objects handling | // Objects handling |
Array<CIMObject>& CIMResponseData::getObjects() | Array<CIMObject>& CIMResponseData::getObjects() |
{ | { |
|
PEG_METHOD_ENTER(TRC_DISPATCHER, "CIMResponseData::getObjects"); |
PEGASUS_DEBUG_ASSERT(_dataType == RESP_OBJECTS); | PEGASUS_DEBUG_ASSERT(_dataType == RESP_OBJECTS); |
_resolveToCIM(); | _resolveToCIM(); |
|
PEG_METHOD_EXIT(); |
return _objects; | return _objects; |
} | } |
| |
// SCMO representation, single instance stored as one element array | // SCMO representation, single instance stored as one element array |
// object paths are represented as SCMOInstance | // object paths are represented as SCMOInstance |
|
// Resolve all of the information in the CIMResponseData container to |
|
// SCMO and return all scmoInstances. |
|
// Note that since the SCMO representation, |
|
// a is single instance stored as one element array and object paths are |
|
// represented as SCMOInstance this returns array of SCMOInstance. |
Array<SCMOInstance>& CIMResponseData::getSCMO() | Array<SCMOInstance>& CIMResponseData::getSCMO() |
{ | { |
|
PEG_METHOD_ENTER(TRC_DISPATCHER, "CIMResponseData::getSCMO"); |
|
// This function resolves to instances and so cannot handle responses to |
|
// the associators,etc.requests that return classes (input object path with |
|
// no keys). That issue is resolved however, since CIMResponseData uses the |
|
// _isClassOperation variable (set by the request) to determine whether |
|
// the responses are classpaths or instancepaths and the default is |
|
// false(instancePaths) so that this should always produce instance paths. |
|
|
_resolveToSCMO(); | _resolveToSCMO(); |
|
PEG_METHOD_EXIT(); |
return _scmoInstances; | return _scmoInstances; |
} | } |
| |
|
// set an array of SCMOInstances into the response data object |
void CIMResponseData::setSCMO(const Array<SCMOInstance>& x) | void CIMResponseData::setSCMO(const Array<SCMOInstance>& x) |
{ | { |
|
|
|
PEG_METHOD_ENTER(TRC_DISPATCHER, "CIMResponseData::setSCMO"); |
_scmoInstances=x; | _scmoInstances=x; |
_encoding |= RESP_ENC_SCMO; | _encoding |= RESP_ENC_SCMO; |
|
_size += x.size(); |
|
PEG_METHOD_EXIT(); |
} | } |
| |
|
|
// Binary data is just a data stream | // Binary data is just a data stream |
Array<Uint8>& CIMResponseData::getBinary() | Array<Uint8>& CIMResponseData::getBinary() |
{ | { |
|
|
| |
bool CIMResponseData::setXml(CIMBuffer& in) | bool CIMResponseData::setXml(CIMBuffer& in) |
{ | { |
|
PEG_METHOD_ENTER(TRC_DISPATCHER, "CIMResponseData::setXml"); |
|
|
switch (_dataType) | switch (_dataType) |
{ | { |
case RESP_INSTANCE: | case RESP_INSTANCE: |
|
|
return false; | return false; |
} | } |
_nameSpacesData.insert(0,ns); | _nameSpacesData.insert(0,ns); |
|
_size++; |
break; | break; |
} | } |
case RESP_INSTANCES: | case RESP_INSTANCES: |
|
|
_hostsData.append(host); | _hostsData.append(host); |
_nameSpacesData.append(ns); | _nameSpacesData.append(ns); |
} | } |
|
_size += count; |
break; | break; |
} | } |
case RESP_OBJECTS: | case RESP_OBJECTS: |
|
|
_hostsData.append(host); | _hostsData.append(host); |
_nameSpacesData.append(ns); | _nameSpacesData.append(ns); |
} | } |
|
_size += count; |
break; | break; |
} | } |
// internal xml encoding of instance names and object paths not | // internal xml encoding of instance names and object paths not |
|
|
case RESP_OBJECTPATHS: | case RESP_OBJECTPATHS: |
default: | default: |
{ | { |
PEGASUS_DEBUG_ASSERT(false); |
PEGASUS_ASSERT(false); |
} | } |
} | } |
_encoding |= RESP_ENC_XML; | _encoding |= RESP_ENC_XML; |
|
|
|
PEG_METHOD_EXIT(); |
return true; | return true; |
} | } |
| |
|
// Move the number of objects defined by the input parameter from |
|
// one CIMResponse Object to another CIMResponse Object. |
|
// Returns the new size of the CIMResponseData object. |
|
// NOTE: This is not protected by a mutex so the user must be certain |
|
// that the from object is not used during the move. |
|
Uint32 CIMResponseData::moveObjects(CIMResponseData & from, Uint32 count) |
|
{ |
|
PEG_METHOD_ENTER(TRC_DISPATCHER, "CIMResponseData::moveObjects"); |
|
|
|
PEG_TRACE((TRC_XML, Tracer::LEVEL3, |
|
"CIMResponseData::move(%u)", count)); |
|
|
|
PEGASUS_DEBUG_ASSERT(valid()); // KS_TEMP |
|
PEGASUS_DEBUG_ASSERT(_size == 0); // Validate size == 0 or fix below |
|
PEGASUS_DEBUG_ASSERT(_dataType == from._dataType); |
|
|
|
Uint32 rtnSize = 0; |
|
Uint32 toMove = count; |
|
|
|
if (RESP_ENC_XML == (from._encoding & RESP_ENC_XML)) |
|
{ |
|
switch (_dataType) |
|
{ |
|
case RESP_OBJECTPATHS: |
|
case RESP_INSTNAMES: |
|
break; |
|
case RESP_INSTANCE: |
|
{ |
|
if (from._instanceData.size() > 0) |
|
{ |
|
// temp test to assure all sizes are the same. |
|
PEGASUS_DEBUG_ASSERT(from._hostsData.size() == |
|
from._instanceData.size()); |
|
PEGASUS_DEBUG_ASSERT(from._referencesData.size() == |
|
from._instanceData.size()); |
|
PEGASUS_DEBUG_ASSERT(from._nameSpacesData.size() == |
|
from._instanceData.size()); |
|
_instanceData.append(from._instanceData.getData(),1); |
|
from._instanceData.remove(0, 1); |
|
_referencesData.append( |
|
from._referencesData.getData(),1); |
|
from._referencesData.remove(0, 1); |
|
if (_hostsData.size()) |
|
{ |
|
_hostsData.append(from._hostsData.getData(),1); |
|
from._hostsData.remove(0, 1); |
|
} |
|
if (_nameSpacesData.size()) |
|
{ |
|
_nameSpacesData.append( |
|
from._nameSpacesData.getData(),1); |
|
from._nameSpacesData.remove(0, 1); |
|
} |
|
rtnSize += 1; |
|
toMove--; |
|
_encoding |= RESP_ENC_XML; |
|
} |
|
} |
|
break; |
|
|
|
// KS-TODO The above could probably be folded into the following. |
|
// Need something like an assert if there is ever more than |
|
// one instance in _instanceData for type RESP_INSTANCE |
|
case RESP_INSTANCES: |
|
case RESP_OBJECTS: |
|
{ |
|
Uint32 moveCount = LOCAL_MIN(toMove, |
|
from._instanceData.size()); |
|
|
|
PEGASUS_DEBUG_ASSERT(from._referencesData.size() == |
|
from._instanceData.size()); |
|
_instanceData.append(from._instanceData.getData(), |
|
moveCount); |
|
from._instanceData.remove(0, moveCount); |
|
_referencesData.append(from._referencesData.getData(), |
|
moveCount); |
|
from._referencesData.remove(0, moveCount); |
|
_hostsData.append(from._hostsData.getData(), |
|
moveCount); |
|
from._hostsData.remove(0, moveCount); |
|
_nameSpacesData.append(from._nameSpacesData.getData(), |
|
moveCount); |
|
from._nameSpacesData.remove(0, moveCount); |
|
rtnSize += moveCount; |
|
toMove -= moveCount; |
|
_encoding |= RESP_ENC_XML; |
|
} |
|
break; |
|
} |
|
} |
|
if (RESP_ENC_BINARY == (from._encoding & RESP_ENC_BINARY)) |
|
{ |
|
// Cannot resolve this one without actually processing |
|
// the data since it is a stream. Concluded that we do not |
|
// want to do that since cost higher than gain. Therefore we do |
|
// not allow this option. Should only mean that provider agent |
|
// cannot generate binary for pull operations. |
|
rtnSize += 0; |
|
PEGASUS_ASSERT(false); |
|
} |
|
|
|
if (RESP_ENC_SCMO == (from._encoding & RESP_ENC_SCMO)) |
|
{ |
|
Uint32 moveCount = LOCAL_MIN(toMove, from._scmoInstances.size()); |
|
|
|
_scmoInstances.append(from._scmoInstances.getData(), moveCount); |
|
from._scmoInstances.remove(0, moveCount); |
|
rtnSize += moveCount; |
|
toMove -= moveCount; |
|
_encoding |= RESP_ENC_SCMO; |
|
} |
|
|
|
if (RESP_ENC_CIM == (from._encoding & RESP_ENC_CIM)) |
|
{ |
|
switch (_dataType) |
|
{ |
|
case RESP_OBJECTPATHS: |
|
case RESP_INSTNAMES: |
|
{ |
|
Uint32 moveCount = LOCAL_MIN(toMove, |
|
from._instanceNames.size()); |
|
|
|
_instanceNames.append( |
|
from._instanceNames.getData(), moveCount); |
|
from._instanceNames.remove(0, moveCount); |
|
rtnSize += moveCount; |
|
toMove -= moveCount; |
|
_encoding |= RESP_ENC_CIM; |
|
} |
|
break; |
|
case RESP_INSTANCE: |
|
case RESP_INSTANCES: |
|
{ |
|
|
|
Uint32 moveCount = LOCAL_MIN(toMove, |
|
from._instances.size()); |
|
|
|
_instances.append(from._instances.getData(), moveCount); |
|
from._instances.remove(0, moveCount); |
|
rtnSize += moveCount; |
|
toMove -= moveCount; |
|
_encoding |= RESP_ENC_CIM; |
|
} |
|
break; |
|
case RESP_OBJECTS: |
|
{ |
|
Uint32 moveCount = LOCAL_MIN(toMove, |
|
from._objects.size()); |
|
_objects.append(from._objects.getData(), moveCount); |
|
from._objects.remove(0, moveCount); |
|
rtnSize += moveCount; |
|
toMove -= moveCount; |
|
_encoding |= RESP_ENC_CIM; |
|
} |
|
break; |
|
} |
|
} |
|
PEGASUS_ASSERT(rtnSize == (count - toMove)); |
|
|
|
_size += rtnSize; |
|
|
|
// insure that _size never goes negative. This is probably a |
|
// diagnostics KS_TODO remove before release |
|
if (from._size >= rtnSize) |
|
{ |
|
|
|
from._size -= rtnSize; |
|
} |
|
else |
|
{ |
|
from._size = 0; |
|
} |
|
|
|
//// KS_TODO diagnostic that we should be able to remove |
|
if (rtnSize != _size) |
|
{ |
|
PEG_TRACE((TRC_XML, Tracer::LEVEL1, |
|
"Size calc error _size %u rtnSWize = %u", _size, rtnSize)); |
|
} |
|
PEG_METHOD_EXIT(); |
|
return rtnSize; |
|
} |
|
|
|
Boolean CIMResponseData::hasBinaryData() const |
|
{ |
|
return (RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)); |
|
} |
|
// Sets the _size variable based on the internal size counts. |
|
void CIMResponseData::setSize() |
|
{ |
|
PEGASUS_DEBUG_ASSERT(valid()); |
|
|
|
Uint32 rtnSize = 0; |
|
if (RESP_ENC_XML == (_encoding & RESP_ENC_XML)) |
|
{ |
|
switch (_dataType) |
|
{ |
|
case RESP_OBJECTPATHS: |
|
case RESP_INSTNAMES: |
|
break; |
|
case RESP_INSTANCE: |
|
rtnSize +=1; |
|
break; |
|
case RESP_INSTANCES: |
|
case RESP_OBJECTS: |
|
rtnSize += _instanceData.size(); |
|
break; |
|
} |
|
} |
|
if (RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)) |
|
{ |
|
// KS_PULL_TODO |
|
// Cannot resolve this one without actually processing |
|
// the data since it is a stream. |
|
rtnSize += 0; |
|
} |
|
|
|
if (RESP_ENC_SCMO == (_encoding & RESP_ENC_SCMO)) |
|
{ |
|
rtnSize += _scmoInstances.size(); |
|
} |
|
|
|
if (RESP_ENC_CIM == (_encoding & RESP_ENC_CIM)) |
|
{ |
|
switch (_dataType) |
|
{ |
|
case RESP_OBJECTPATHS: |
|
case RESP_INSTNAMES: |
|
rtnSize += _instanceNames.size(); |
|
break; |
|
case RESP_INSTANCE: |
|
case RESP_INSTANCES: |
|
rtnSize += _instances.size(); |
|
break; |
|
case RESP_OBJECTS: |
|
rtnSize += _objects.size(); |
|
break; |
|
} |
|
} |
|
_size = rtnSize; |
|
} |
|
// |
|
// Return the number of CIM objects in the CIM Response data object by |
|
// aggregating sizes of each of the encodings |
|
// |
|
Uint32 CIMResponseData::size() |
|
{ |
|
// If debug mode, add up all the individual size components to |
|
// determine overall size of this object. Then compare this with |
|
// the _size variable. This is a check on the completeness of the |
|
// size computations. We should be able to remove this at some point |
|
// but there are many sources of size info and we need to be sure we |
|
// have covered them all. |
|
#ifdef CIMRESPONSEDATA_DEBUG |
|
PEGASUS_DEBUG_ASSERT(valid()); |
|
|
|
Uint32 rtnSize = 0; |
|
|
|
if (RESP_ENC_XML == (_encoding & RESP_ENC_XML)) |
|
{ |
|
switch (_dataType) |
|
{ |
|
case RESP_OBJECTPATHS: |
|
case RESP_INSTNAMES: |
|
break; |
|
case RESP_INSTANCE: |
|
rtnSize +=1; |
|
break; |
|
case RESP_INSTANCES: |
|
case RESP_OBJECTS: |
|
rtnSize += _instanceData.size(); |
|
break; |
|
} |
|
} |
|
if (RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)) |
|
{ |
|
// KS_PULL_TODO |
|
// Cannot resolve this one without actually processing |
|
// the data since it is a stream. |
|
rtnSize += 0; |
|
} |
|
|
|
if (RESP_ENC_SCMO == (_encoding & RESP_ENC_SCMO)) |
|
{ |
|
rtnSize += _scmoInstances.size(); |
|
} |
|
|
|
if (RESP_ENC_CIM == (_encoding & RESP_ENC_CIM)) |
|
{ |
|
switch (_dataType) |
|
{ |
|
case RESP_OBJECTPATHS: |
|
case RESP_INSTNAMES: |
|
rtnSize += _instanceNames.size(); |
|
break; |
|
case RESP_INSTANCE: |
|
case RESP_INSTANCES: |
|
rtnSize += _instances.size(); |
|
break; |
|
case RESP_OBJECTS: |
|
rtnSize += _objects.size(); |
|
break; |
|
} |
|
} |
|
// Test of actual count against _size variable. KS_TODO diagnostic |
|
Uint32 lsize = _size; |
|
if (rtnSize != lsize) |
|
{ |
|
PEG_TRACE((TRC_XML, Tracer::LEVEL1, |
|
"CIMResponseData::size ERROR. debug size mismatch." |
|
"Computed = %u. variable = %u inc binary %s",rtnSize, _size, |
|
boolToString(RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)) |
|
)); |
|
} |
|
#endif |
|
return _size; |
|
} |
|
|
// function used by OperationAggregator to aggregate response data in a | // function used by OperationAggregator to aggregate response data in a |
// single ResponseData object |
// single ResponseData object. Adds all data in the from ResponseData object |
|
// input variable to the target ResponseData object |
|
// target array |
void CIMResponseData::appendResponseData(const CIMResponseData & x) | void CIMResponseData::appendResponseData(const CIMResponseData & x) |
{ | { |
// as the Messages set the data types, this should be impossible |
PEG_METHOD_ENTER(TRC_DISPATCHER, |
|
"CIMResponseData::appendResponseData"); |
|
|
|
PEGASUS_DEBUG_ASSERT(valid()); |
|
|
|
// Confirm that the CIMResponseData type matches the type |
|
// of the data being appended |
|
// A CIMResponseData must represent a single data content type. |
|
// ex. Cannot mix objects and instances. |
|
|
PEGASUS_DEBUG_ASSERT(_dataType == x._dataType); | PEGASUS_DEBUG_ASSERT(_dataType == x._dataType); |
_encoding |= x._encoding; | _encoding |= x._encoding; |
| |
|
|
| |
// add all the C++ stuff | // add all the C++ stuff |
_instanceNames.appendArray(x._instanceNames); | _instanceNames.appendArray(x._instanceNames); |
|
_size += x._instanceNames.size(); |
_instances.appendArray(x._instances); | _instances.appendArray(x._instances); |
|
_size += x._instances.size(); |
_objects.appendArray(x._objects); | _objects.appendArray(x._objects); |
|
_size += x._objects.size(); |
| |
// add the SCMO instances | // add the SCMO instances |
_scmoInstances.appendArray(x._scmoInstances); | _scmoInstances.appendArray(x._scmoInstances); |
|
_size += x._scmoInstances.size(); |
| |
// add Xml encodings too |
|
_referencesData.appendArray(x._referencesData); | _referencesData.appendArray(x._referencesData); |
_instanceData.appendArray(x._instanceData); | _instanceData.appendArray(x._instanceData); |
_hostsData.appendArray(x._hostsData); | _hostsData.appendArray(x._hostsData); |
_nameSpacesData.appendArray(x._nameSpacesData); | _nameSpacesData.appendArray(x._nameSpacesData); |
|
_size += x._instanceData.size(); |
|
|
|
// transfer property list |
|
_propertyList = x._propertyList; |
|
|
|
PEG_METHOD_EXIT(); |
} | } |
| |
// Encoding responses into output format | // Encoding responses into output format |
|
|
| |
// Need to do a complete job here by transferring all contained data | // Need to do a complete job here by transferring all contained data |
// into binary format and handing it out in the CIMBuffer | // into binary format and handing it out in the CIMBuffer |
|
// KS_TODO |
if (RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)) | if (RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)) |
{ | { |
// Binary does NOT need a marker as it consists of C++ and SCMO | // Binary does NOT need a marker as it consists of C++ and SCMO |
const Array<Uint8>& data = _binaryData; | const Array<Uint8>& data = _binaryData; |
out.putBytes(data.getData(), data.size()); | out.putBytes(data.getData(), data.size()); |
} | } |
|
|
if (RESP_ENC_CIM == (_encoding & RESP_ENC_CIM)) | if (RESP_ENC_CIM == (_encoding & RESP_ENC_CIM)) |
{ | { |
out.putTypeMarker(BIN_TYPE_MARKER_CPPD); | out.putTypeMarker(BIN_TYPE_MARKER_CPPD); |
|
|
p.setNameSpace(nsName); | p.setNameSpace(nsName); |
} | } |
} | } |
|
break; |
} | } |
case RESP_INSTANCES: | case RESP_INSTANCES: |
{ | { |
|
|
} | } |
} | } |
} | } |
|
|
if (RESP_ENC_SCMO == (_encoding & RESP_ENC_SCMO)) | if (RESP_ENC_SCMO == (_encoding & RESP_ENC_SCMO)) |
{ | { |
for (Uint32 j = 0, n = _scmoInstances.size(); j < n; j++) | for (Uint32 j = 0, n = _scmoInstances.size(); j < n; j++) |
|
|
} | } |
} | } |
| |
|
|
void CIMResponseData::completeHostNameAndNamespace( | void CIMResponseData::completeHostNameAndNamespace( |
const String & hn, | const String & hn, |
const CIMNamespaceName & ns) |
const CIMNamespaceName & ns, |
|
Boolean isPullOperation) |
{ | { |
|
PEG_METHOD_ENTER(TRC_DISPATCHER, |
|
"CIMResponseData::completeHostNameAndNamespace"); |
|
|
|
PEGASUS_DEBUG_ASSERT(valid()); |
|
|
|
//// PEG_TRACE(( TRC_DISPATCHER, Tracer::LEVEL4, // KS_TODO TEMP |
|
//// "completeHostNameAndNamespace Setting hostName, etc " |
|
//// "host %s ns %s set for dataType=%u encoding=%u isPull=%s", |
|
//// (const char *)hn.getCString(), |
|
//// (const char *)ns.getString().getCString(), |
|
//// _dataType, _encoding, boolToString(isPullOperation) )); |
|
|
if (RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)) | if (RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)) |
{ | { |
// On binary need remember hostname and namespace in case someone |
// On binary need to remember hostname and namespace in case someone |
// builds C++ default objects or Xml types from it later on |
// builds C++ default objects or Xml types later i.e. |
// -> usage: See resolveBinary() | // -> usage: See resolveBinary() |
_defaultNamespace=ns; | _defaultNamespace=ns; |
_defaultHostname=hn; | _defaultHostname=hn; |
|
|
} | } |
} | } |
} | } |
|
// Need to set for Pull Enumeration operations |
|
if ((RESP_ENC_XML == (_encoding & RESP_ENC_XML)) && |
|
((RESP_INSTANCES == _dataType) || isPullOperation)) |
|
{ |
|
for (Uint32 j = 0, n = _referencesData.size(); j < n; j++) |
|
{ |
|
if (0 == _hostsData[j].size()) |
|
{ |
|
_hostsData[j]=hn; |
|
} |
|
if (_nameSpacesData[j].isNull()) |
|
{ |
|
_nameSpacesData[j]=ns; |
|
} |
|
|
|
// KS_TODO Remove Diagnostic |
|
PEG_TRACE(( TRC_DISPATCHER, Tracer::LEVEL4, |
|
"completeHostNameAndNamespace Setting hostName, etc " |
|
"host %s ns %s set to _hostData %s _namespaceData %s", |
|
(const char *)hn.getCString(), |
|
(const char *)ns.getString().getCString(), |
|
(const char *)_hostsData[j].getCString(), |
|
(const char *)_nameSpacesData[j].getString().getCString() )); |
|
} |
|
} |
|
|
if (RESP_ENC_CIM == (_encoding & RESP_ENC_CIM)) | if (RESP_ENC_CIM == (_encoding & RESP_ENC_CIM)) |
{ | { |
switch (_dataType) | switch (_dataType) |
{ | { |
|
// Instances added to account for namedInstance in Pull operations. |
|
case RESP_INSTANCES: |
|
|
|
for (Uint32 j = 0, n = _instances.size(); j < n; j++) |
|
{ |
|
const CIMInstance& instance = _instances[j]; |
|
CIMObjectPath& p = |
|
const_cast<CIMObjectPath&>(instance.getPath()); |
|
if (p.getHost().size()==0) |
|
{ |
|
p.setHost(hn); |
|
} |
|
if (p.getNameSpace().isNull()) |
|
{ |
|
p.setNameSpace(ns); |
|
} |
|
} |
case RESP_OBJECTS: | case RESP_OBJECTS: |
{ | { |
for (Uint32 j = 0, n = _objects.size(); j < n; j++) | for (Uint32 j = 0, n = _objects.size(); j < n; j++) |
|
|
} | } |
break; | break; |
} | } |
|
// INSTNAMES added to account for instance paths in pull name |
|
// operations |
|
case RESP_INSTNAMES: |
case RESP_OBJECTPATHS: | case RESP_OBJECTPATHS: |
{ | { |
for (Uint32 j = 0, n = _instanceNames.size(); j < n; j++) | for (Uint32 j = 0, n = _instanceNames.size(); j < n; j++) |
{ | { |
CIMObjectPath& p = _instanceNames[j]; | CIMObjectPath& p = _instanceNames[j]; |
if (p.getHost().size() == 0) | if (p.getHost().size() == 0) |
|
{ |
p.setHost(hn); | p.setHost(hn); |
|
} |
if (p.getNameSpace().isNull()) | if (p.getNameSpace().isNull()) |
|
{ |
p.setNameSpace(ns); | p.setNameSpace(ns); |
} | } |
|
} |
break; | break; |
} | } |
default: | default: |
|
|
Uint32 nsLen = strlen(nsChars); | Uint32 nsLen = strlen(nsChars); |
switch (_dataType) | switch (_dataType) |
{ | { |
|
// KS_PULL add Instances and InstNames to cover pull operations |
|
// KS_PULL - Confirm that this OK. |
|
case RESP_INSTNAMES: |
|
case RESP_INSTANCES: |
case RESP_OBJECTS: | case RESP_OBJECTS: |
case RESP_OBJECTPATHS: | case RESP_OBJECTPATHS: |
{ | { |
for (Uint32 j = 0, n = _scmoInstances.size(); j < n; j++) | for (Uint32 j = 0, n = _scmoInstances.size(); j < n; j++) |
{ | { |
SCMOInstance & scmoInst=_scmoInstances[j]; | SCMOInstance & scmoInst=_scmoInstances[j]; |
if (0 == scmoInst.getHostName()) |
scmoInst.completeHostNameAndNamespace( |
{ |
hnChars, |
scmoInst.setHostName_l(hnChars,hnLen); |
hnLen, |
} |
nsChars, |
if (0 == scmoInst.getNameSpace()) |
nsLen); |
{ |
|
scmoInst.setNameSpace_l(nsChars,nsLen); |
|
} |
|
} | } |
break; | break; |
} | } |
|
|
} | } |
} | } |
} | } |
|
PEG_METHOD_EXIT(); |
} | } |
| |
void CIMResponseData::encodeXmlResponse(Buffer& out) |
// NOTE: The reason for the isPullResponse variable is that there are |
|
// some variations in ouput to Xml depending on whether the responses |
|
// are one of the pull responses or not |
|
void CIMResponseData::encodeXmlResponse(Buffer& out, |
|
Boolean isPullResponse, |
|
Boolean encodeInstanceOnly) |
{ | { |
|
PEG_METHOD_ENTER(TRC_DISPATCHER, |
|
"CIMResponseData::encodeXmlResponse"); |
|
|
PEG_TRACE((TRC_XML, Tracer::LEVEL3, | PEG_TRACE((TRC_XML, Tracer::LEVEL3, |
"CIMResponseData::encodeXmlResponse(encoding=%X,content=%X)", |
"CIMResponseData::encodeXmlResponse(encoding=%X,dataType=%X, isPull= %s" |
|
" encodeInstanceOnly= %s)", |
_encoding, | _encoding, |
_dataType)); |
_dataType, |
|
boolToString(isPullResponse), |
|
boolToString(encodeInstanceOnly) )); |
| |
// already existing Internal XML does not need to be encoded further | // already existing Internal XML does not need to be encoded further |
// binary input is not actually impossible here, but we have an established | // binary input is not actually impossible here, but we have an established |
// fallback | // fallback |
if (RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)) | if (RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)) |
{ | { |
_resolveBinary(); |
_resolveBinaryToSCMO(); |
} | } |
|
|
if (RESP_ENC_XML == (_encoding & RESP_ENC_XML)) | if (RESP_ENC_XML == (_encoding & RESP_ENC_XML)) |
{ | { |
switch (_dataType) | switch (_dataType) |
|
|
| |
for (Uint32 i = 0, n = a.size(); i < n; i++) | for (Uint32 i = 0, n = a.size(); i < n; i++) |
{ | { |
|
if (isPullResponse) |
|
{ |
|
out << STRLIT("<VALUE.INSTANCEWITHPATH>\n"); |
|
out << STRLIT("<INSTANCEPATH>\n"); |
|
XmlWriter::appendNameSpacePathElement(out, |
|
_hostsData[i], |
|
_nameSpacesData[i]); |
|
out.append((char*)b[i].getData(), b[i].size() - 1); |
|
out << STRLIT("</INSTANCEPATH>\n"); |
|
out.append((char *)a[i].getData(), a[i].size() - 1); |
|
out << STRLIT("</VALUE.INSTANCEWITHPATH>\n"); |
|
} |
|
else |
|
{ |
out << STRLIT("<VALUE.NAMEDINSTANCE>\n"); | out << STRLIT("<VALUE.NAMEDINSTANCE>\n"); |
out.append((char*)b[i].getData(), b[i].size() - 1); | out.append((char*)b[i].getData(), b[i].size() - 1); |
out.append((char*)a[i].getData(), a[i].size() - 1); | out.append((char*)a[i].getData(), a[i].size() - 1); |
out << STRLIT("</VALUE.NAMEDINSTANCE>\n"); | out << STRLIT("</VALUE.NAMEDINSTANCE>\n"); |
} | } |
|
} |
break; | break; |
} | } |
case RESP_OBJECTS: | case RESP_OBJECTS: |
{ | { |
const Array<ArraySint8>& a = _instanceData; | const Array<ArraySint8>& a = _instanceData; |
const Array<ArraySint8>& b = _referencesData; | const Array<ArraySint8>& b = _referencesData; |
|
|
for (Uint32 i = 0, n = a.size(); i < n; i++) | for (Uint32 i = 0, n = a.size(); i < n; i++) |
{ | { |
|
if (isPullResponse) |
|
{ |
|
out << STRLIT("<VALUE.INSTANCEWITHPATH>\n"); |
|
} |
|
else |
|
{ |
out << STRLIT("<VALUE.OBJECTWITHPATH>\n"); | out << STRLIT("<VALUE.OBJECTWITHPATH>\n"); |
|
} |
out << STRLIT("<INSTANCEPATH>\n"); | out << STRLIT("<INSTANCEPATH>\n"); |
XmlWriter::appendNameSpacePathElement( | XmlWriter::appendNameSpacePathElement( |
out, | out, |
_hostsData[i], | _hostsData[i], |
_nameSpacesData[i]); | _nameSpacesData[i]); |
|
|
|
if (isPullResponse) |
|
{ |
|
out.append((char*)b[i].getData(),b[i].size()-1); |
|
} |
|
else |
|
{ |
// Leave out the surrounding tags "<VALUE.REFERENCE>\n" | // Leave out the surrounding tags "<VALUE.REFERENCE>\n" |
// and "</VALUE.REFERENCE>\n" which are 18 and 19 characters |
// and "</VALUE.REFERENCE>\n" which are 18 and 19 |
// long |
// characters long |
|
//// KS_TODO Should be able to do this by properly |
|
//// building in the CIMXmlInternalEncoder |
out.append( | out.append( |
((char*)b[i].getData())+18, | ((char*)b[i].getData())+18, |
b[i].size() - 1 - 18 -19); | b[i].size() - 1 - 18 -19); |
|
} |
|
|
out << STRLIT("</INSTANCEPATH>\n"); | out << STRLIT("</INSTANCEPATH>\n"); |
// append instance body | // append instance body |
out.append((char*)a[i].getData(), a[i].size() - 1); | out.append((char*)a[i].getData(), a[i].size() - 1); |
|
if (isPullResponse) |
|
{ |
|
out << STRLIT("</VALUE.INSTANCEWITHPATH>\n"); |
|
} |
|
else |
|
{ |
out << STRLIT("</VALUE.OBJECTWITHPATH>\n"); | out << STRLIT("</VALUE.OBJECTWITHPATH>\n"); |
} | } |
|
} |
break; | break; |
} | } |
// internal xml encoding of instance names and object paths not | // internal xml encoding of instance names and object paths not |
|
|
case RESP_OBJECTPATHS: | case RESP_OBJECTPATHS: |
default: | default: |
{ | { |
PEGASUS_DEBUG_ASSERT(false); |
PEGASUS_ASSERT(false); |
} | } |
} | } |
} | } |
|
|
{ | { |
for (Uint32 i = 0, n = _instanceNames.size(); i < n; i++) | for (Uint32 i = 0, n = _instanceNames.size(); i < n; i++) |
{ | { |
XmlWriter::appendInstanceNameElement(out,_instanceNames[i]); |
// Element type is different for Pull responses |
|
if (isPullResponse) |
|
{ |
|
XmlWriter::appendInstancePathElement(out, |
|
_instanceNames[i]); |
|
} |
|
else |
|
{ |
|
XmlWriter::appendInstanceNameElement(out, |
|
_instanceNames[i]); |
|
} |
} | } |
break; | break; |
} | } |
|
|
{ | { |
if (_instances.size() > 0) | if (_instances.size() > 0) |
{ | { |
XmlWriter::appendInstanceElement(out, _instances[0]); |
XmlWriter::appendInstanceElement( |
|
out, |
|
_instances[0], |
|
_includeQualifiers, |
|
_includeClassOrigin, |
|
_propertyList); |
} | } |
break; | break; |
} | } |
|
|
{ | { |
for (Uint32 i = 0, n = _instances.size(); i < n; i++) | for (Uint32 i = 0, n = _instances.size(); i < n; i++) |
{ | { |
|
if (isPullResponse) |
|
{ |
|
if (encodeInstanceOnly) |
|
{ |
|
XmlWriter::appendInstanceElement( |
|
out, |
|
_instances[i], |
|
_includeQualifiers, |
|
_includeClassOrigin, |
|
_propertyList); |
|
} |
|
else |
|
{ |
|
XmlWriter::appendValueInstanceWithPathElement( |
|
out, |
|
_instances[i], |
|
_includeQualifiers, |
|
_includeClassOrigin, |
|
_propertyList); |
|
} |
|
} |
|
else |
|
{ |
XmlWriter::appendValueNamedInstanceElement( | XmlWriter::appendValueNamedInstanceElement( |
out, _instances[i]); |
out, |
|
_instances[i], |
|
_includeQualifiers, |
|
_includeClassOrigin, |
|
_propertyList); |
|
} |
} | } |
break; | break; |
} | } |
|
|
{ | { |
for (Uint32 i = 0; i < _objects.size(); i++) | for (Uint32 i = 0; i < _objects.size(); i++) |
{ | { |
|
// If pull, map to instances |
|
if (isPullResponse) |
|
{ |
|
|
|
CIMInstance x = (CIMInstance)_objects[i]; |
|
if (encodeInstanceOnly) |
|
{ |
|
XmlWriter::appendInstanceElement( |
|
out, |
|
x, |
|
_includeQualifiers, |
|
_includeClassOrigin, |
|
_propertyList); |
|
} |
|
else |
|
{ |
|
XmlWriter::appendValueInstanceWithPathElement( |
|
out, |
|
x, |
|
_includeQualifiers, |
|
_includeClassOrigin, |
|
_propertyList); |
|
} |
|
} |
|
else |
|
{ |
XmlWriter::appendValueObjectWithPathElement( | XmlWriter::appendValueObjectWithPathElement( |
out, | out, |
_objects[i]); |
_objects[i], |
|
_includeQualifiers, |
|
_includeClassOrigin, |
|
_isClassOperation, |
|
_propertyList); |
|
} |
} | } |
break; | break; |
} | } |
|
|
{ | { |
for (Uint32 i = 0, n = _instanceNames.size(); i < n; i++) | for (Uint32 i = 0, n = _instanceNames.size(); i < n; i++) |
{ | { |
|
// ObjectPaths come from providers for pull operations |
|
// but are encoded as instancePathElements. If pull |
|
// only instances allowed. |
|
if (isPullResponse) |
|
{ |
|
XmlWriter::appendInstancePathElement( |
|
out, |
|
_instanceNames[i]); |
|
} |
|
else |
|
{ |
|
//Append The path element (Class or instance) |
out << "<OBJECTPATH>\n"; | out << "<OBJECTPATH>\n"; |
XmlWriter::appendValueReferenceElement( |
XmlWriter::appendClassOrInstancePathElement( |
out, | out, |
_instanceNames[i], | _instanceNames[i], |
false); |
_isClassOperation); |
out << "</OBJECTPATH>\n"; | out << "</OBJECTPATH>\n"; |
} | } |
|
} |
break; | break; |
} | } |
default: | default: |
{ | { |
PEGASUS_DEBUG_ASSERT(false); |
PEGASUS_ASSERT(false); |
} | } |
} | } |
} | } |
|
|
{ | { |
for (Uint32 i = 0, n = _scmoInstances.size(); i < n; i++) | for (Uint32 i = 0, n = _scmoInstances.size(); i < n; i++) |
{ | { |
|
if (isPullResponse) |
|
{ |
|
SCMOXmlWriter::appendInstancePathElement( |
|
out, |
|
_scmoInstances[i]); |
|
} |
|
else |
|
{ |
SCMOXmlWriter::appendInstanceNameElement( | SCMOXmlWriter::appendInstanceNameElement( |
out, | out, |
_scmoInstances[i]); | _scmoInstances[i]); |
} | } |
|
} |
break; | break; |
} | } |
case RESP_INSTANCE: | case RESP_INSTANCE: |
{ | { |
if (_scmoInstances.size() > 0) | if (_scmoInstances.size() > 0) |
{ | { |
SCMOXmlWriter::appendInstanceElement(out,_scmoInstances[0]); |
_appendInstanceElement(out, _scmoInstances[0]); |
} | } |
break; | break; |
} | } |
case RESP_INSTANCES: | case RESP_INSTANCES: |
{ | { |
|
if (isPullResponse) |
|
{ |
|
// pull and encodeInstanceOnly (i.e. response to |
|
// OpenQueryInstances and pullInstances |
|
if (encodeInstanceOnly) |
|
{ |
|
// KS_TODO move this to SCMOXmlWriter |
for (Uint32 i = 0, n = _scmoInstances.size(); i < n; i++) | for (Uint32 i = 0, n = _scmoInstances.size(); i < n; i++) |
{ | { |
SCMOXmlWriter::appendValueSCMOInstanceElement( |
_appendInstanceElement(out, _scmoInstances[i]); |
out, |
} |
_scmoInstances[i]); |
} |
|
else |
|
{ |
|
SCMOXmlWriter::appendValueSCMOInstanceWithPathElements( |
|
out, _scmoInstances, _propertyList); |
|
} |
|
} |
|
else |
|
{ |
|
SCMOXmlWriter::appendValueSCMOInstanceElements( |
|
out, _scmoInstances, _propertyList); |
} | } |
break; | break; |
} | } |
case RESP_OBJECTS: | case RESP_OBJECTS: |
{ | { |
for (Uint32 i = 0; i < _scmoInstances.size(); i++) |
if (isPullResponse) |
|
{ |
|
// if encodeInstanceOnly flag, encode objects as instances |
|
// Used by OpenQueryInstances and pullInstances. |
|
if (encodeInstanceOnly) |
|
{ |
|
for (Uint32 i = 0, n = _scmoInstances.size();i < n; i++) |
|
{ |
|
_appendInstanceElement(out, _scmoInstances[i]); |
|
} |
|
} |
|
else |
|
{ |
|
SCMOXmlWriter::appendValueSCMOInstanceWithPathElements( |
|
out,_scmoInstances, _propertyList); |
|
} |
|
} |
|
else |
{ | { |
|
// KS_TODO why is this one named element rather than |
|
// elements |
SCMOXmlWriter::appendValueObjectWithPathElement( | SCMOXmlWriter::appendValueObjectWithPathElement( |
out, |
out, _scmoInstances, _propertyList); |
_scmoInstances[i]); |
|
} | } |
break; | break; |
} | } |
|
|
{ | { |
for (Uint32 i = 0, n = _scmoInstances.size(); i < n; i++) | for (Uint32 i = 0, n = _scmoInstances.size(); i < n; i++) |
{ | { |
|
if (isPullResponse) |
|
{ |
|
SCMOXmlWriter::appendInstancePathElement(out, |
|
_scmoInstances[i]); |
|
} |
|
else |
|
{ |
out << "<OBJECTPATH>\n"; | out << "<OBJECTPATH>\n"; |
SCMOXmlWriter::appendValueReferenceElement( |
SCMOXmlWriter::appendClassOrInstancePathElement( |
out, |
out, _scmoInstances[i]); |
_scmoInstances[i], |
|
false); |
|
out << "</OBJECTPATH>\n"; | out << "</OBJECTPATH>\n"; |
} | } |
|
} |
break; | break; |
} | } |
default: | default: |
{ | { |
PEGASUS_DEBUG_ASSERT(false); |
PEGASUS_ASSERT(false); |
} | } |
} | } |
} | } |
|
PEG_METHOD_EXIT(); |
} | } |
| |
// contrary to encodeXmlResponse this function encodes the Xml in a format | // contrary to encodeXmlResponse this function encodes the Xml in a format |
// not usable by clients | // not usable by clients |
void CIMResponseData::encodeInternalXmlResponse(CIMBuffer& out) |
void CIMResponseData::encodeInternalXmlResponse(CIMBuffer& out, |
|
Boolean isPullOperation) |
{ | { |
|
PEG_METHOD_ENTER(TRC_DISPATCHER, |
|
"CIMResponseData::encodeInternalXmlResponse"); |
|
|
PEG_TRACE((TRC_XML, Tracer::LEVEL3, | PEG_TRACE((TRC_XML, Tracer::LEVEL3, |
"CIMResponseData::encodeInternalXmlResponse(encoding=%X,content=%X)", |
"CIMResponseData::encodeInternalXmlResponse(encoding=%X,content=%X" |
|
" isPullOperation=%s)", |
_encoding, | _encoding, |
_dataType)); |
_dataType, |
|
boolToString(isPullOperation))); |
| |
// For mixed (CIM+SCMO) responses, we need to tell the receiver the | // For mixed (CIM+SCMO) responses, we need to tell the receiver the |
// total number of instances. The totalSize variable is used to keep track | // total number of instances. The totalSize variable is used to keep track |
|
|
// fallback | // fallback |
if (RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)) | if (RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)) |
{ | { |
_resolveBinary(); |
_resolveBinaryToSCMO(); |
} | } |
if ((0 == _encoding) || | if ((0 == _encoding) || |
(RESP_ENC_CIM == (_encoding & RESP_ENC_CIM))) | (RESP_ENC_CIM == (_encoding & RESP_ENC_CIM))) |
|
|
if (0 == _instances.size()) | if (0 == _instances.size()) |
{ | { |
_instances.append(CIMInstance()); | _instances.append(CIMInstance()); |
|
CIMInternalXmlEncoder::_putXMLInstance( |
|
out, |
|
_instances[0]); |
|
break; |
} | } |
CIMInternalXmlEncoder::_putXMLInstance(out, _instances[0]); |
CIMInternalXmlEncoder::_putXMLInstance( |
|
out, |
|
_instances[0], |
|
_includeQualifiers, |
|
_includeClassOrigin, |
|
_propertyList); |
break; | break; |
} | } |
case RESP_INSTANCES: | case RESP_INSTANCES: |
|
|
{ | { |
CIMInternalXmlEncoder::_putXMLNamedInstance( | CIMInternalXmlEncoder::_putXMLNamedInstance( |
out, | out, |
_instances[i]); |
_instances[i], |
|
_includeQualifiers, |
|
_includeClassOrigin, |
|
_propertyList); |
} | } |
break; | break; |
} | } |
|
|
out.putUint32(totalSize); | out.putUint32(totalSize); |
for (Uint32 i = 0; i < n; i++) | for (Uint32 i = 0; i < n; i++) |
{ | { |
CIMInternalXmlEncoder::_putXMLObject(out, _objects[i]); |
// if is pull map to instances. |
|
if (isPullOperation) |
|
{ |
|
CIMInternalXmlEncoder::_putXMLNamedInstance( |
|
out, |
|
(CIMInstance)_objects[i], |
|
_includeQualifiers, |
|
_includeClassOrigin, |
|
_propertyList); |
|
} |
|
else |
|
{ |
|
CIMInternalXmlEncoder::_putXMLObject( |
|
out, |
|
_objects[i], |
|
_includeQualifiers, |
|
_includeClassOrigin, |
|
_propertyList); |
|
} |
} | } |
break; | break; |
} | } |
|
|
{ | { |
_scmoInstances.append(SCMOInstance()); | _scmoInstances.append(SCMOInstance()); |
} | } |
SCMOInternalXmlEncoder::_putXMLInstance(out, _scmoInstances[0]); |
SCMOInternalXmlEncoder::_putXMLInstance( |
|
out, |
|
_scmoInstances[0], |
|
_propertyList); |
break; | break; |
} | } |
case RESP_INSTANCES: | case RESP_INSTANCES: |
|
|
{ | { |
out.putUint32(n); | out.putUint32(n); |
} | } |
for (Uint32 i = 0; i < n; i++) |
|
{ |
|
SCMOInternalXmlEncoder::_putXMLNamedInstance( | SCMOInternalXmlEncoder::_putXMLNamedInstance( |
out, | out, |
_scmoInstances[i]); |
_scmoInstances, |
} |
_propertyList); |
break; | break; |
} | } |
case RESP_OBJECTS: | case RESP_OBJECTS: |
|
|
{ | { |
out.putUint32(n); | out.putUint32(n); |
} | } |
for (Uint32 i = 0; i < n; i++) |
// if is pull map to instances. |
|
if (isPullOperation) |
|
{ |
|
SCMOInternalXmlEncoder::_putXMLNamedInstance( |
|
out, |
|
_scmoInstances, |
|
_propertyList); |
|
} |
|
else |
{ | { |
SCMOInternalXmlEncoder::_putXMLObject( | SCMOInternalXmlEncoder::_putXMLObject( |
out, | out, |
_scmoInstances[i]); |
_scmoInstances, |
|
_propertyList); |
} | } |
break; | break; |
} | } |
|
|
} | } |
} | } |
} | } |
|
PEG_METHOD_EXIT(); |
} | } |
| |
void CIMResponseData::_resolveToCIM() | void CIMResponseData::_resolveToCIM() |
|
|
} | } |
if (RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)) | if (RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)) |
{ | { |
_resolveBinary(); |
_resolveBinaryToSCMO(); |
} | } |
if (RESP_ENC_SCMO == (_encoding & RESP_ENC_SCMO)) | if (RESP_ENC_SCMO == (_encoding & RESP_ENC_SCMO)) |
{ | { |
|
|
PEGASUS_DEBUG_ASSERT(_encoding == RESP_ENC_CIM || _encoding == 0); | PEGASUS_DEBUG_ASSERT(_encoding == RESP_ENC_CIM || _encoding == 0); |
} | } |
| |
|
// Resolve any binary data to SCMO. This externalfunction added because we |
|
// cannot do a move on Binary data so convert it a to movable format |
|
void CIMResponseData::resolveBinaryToSCMO() |
|
{ |
|
PEG_METHOD_ENTER(TRC_DISPATCHER, |
|
"CIMResponseData::resolveBinaryToSCMO"); |
|
if (RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)) |
|
{ |
|
_resolveBinaryToSCMO(); |
|
} |
|
PEG_METHOD_EXIT(); |
|
} |
|
|
void CIMResponseData::_resolveToSCMO() | void CIMResponseData::_resolveToSCMO() |
{ | { |
PEG_TRACE((TRC_XML, Tracer::LEVEL3, | PEG_TRACE((TRC_XML, Tracer::LEVEL3, |
|
|
} | } |
if (RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)) | if (RESP_ENC_BINARY == (_encoding & RESP_ENC_BINARY)) |
{ | { |
_resolveBinary(); |
_resolveBinaryToSCMO(); |
} | } |
if (RESP_ENC_CIM == (_encoding & RESP_ENC_CIM)) | if (RESP_ENC_CIM == (_encoding & RESP_ENC_CIM)) |
{ | { |
|
|
// helper functions to transform different formats into one-another | // helper functions to transform different formats into one-another |
// functions work on the internal data and calling of them should be | // functions work on the internal data and calling of them should be |
// avoided whenever possible | // avoided whenever possible |
void CIMResponseData::_resolveBinary() |
void CIMResponseData::_resolveBinaryToSCMO() |
{ | { |
PEG_METHOD_ENTER(TRC_DISPATCHER, | PEG_METHOD_ENTER(TRC_DISPATCHER, |
"CIMResponseData::_resolveBinary"); |
"CIMResponseData::_resolveBinaryToSCMO"); |
| |
CIMBuffer in((char*)_binaryData.getData(), _binaryData.size()); | CIMBuffer in((char*)_binaryData.getData(), _binaryData.size()); |
| |
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
} | } |
| |
void CIMResponseData::_resolveXmlToCIM() |
|
|
void CIMResponseData::_deserializeObject(Uint32 idx,CIMObject& cimObject) |
{ | { |
switch (_dataType) |
|
|
PEG_METHOD_ENTER(TRC_DISPATCHER, |
|
"CIMResponseData::_deserializeObject"); |
|
// Only start the parser when instance data is present. |
|
if (0 != _instanceData[idx].size()) |
{ | { |
// Xml encoding for instance names and object paths not used |
CIMInstance cimInstance; |
case RESP_OBJECTPATHS: |
CIMClass cimClass; |
case RESP_INSTNAMES: |
|
|
XmlParser parser((char*)_instanceData[idx].getData()); |
|
|
|
if (XmlReader::getInstanceElement(parser, cimInstance)) |
{ | { |
break; |
cimObject = CIMObject(cimInstance); |
|
return; |
} | } |
case RESP_INSTANCE: |
|
{ |
if (XmlReader::getClassElement(parser, cimClass)) |
CIMInstance cimInstance; |
|
// Deserialize instance: |
|
{ | { |
XmlParser parser((char*)_instanceData[0].getData()); |
cimObject = CIMObject(cimClass); |
|
return; |
|
} |
|
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, |
|
"Failed to resolve XML object data, parser error!"); |
|
} |
|
PEG_METHOD_EXIT(); |
|
} |
| |
if (!XmlReader::getInstanceElement(parser, cimInstance)) |
void CIMResponseData::_deserializeInstance(Uint32 idx,CIMInstance& cimInstance) |
{ | { |
cimInstance = CIMInstance(); |
PEG_METHOD_ENTER(TRC_DISPATCHER, |
|
"CIMResponseData::_deserializeInstance"); |
|
// Only start the parser when instance data is present. |
|
if (0 != _instanceData[idx].size()) |
|
{ |
|
XmlParser parser((char*)_instanceData[idx].getData()); |
|
if (XmlReader::getInstanceElement(parser, cimInstance)) |
|
{ |
|
return; |
|
} |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, | PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, |
"Failed to resolve XML instance, parser error!"); | "Failed to resolve XML instance, parser error!"); |
} | } |
|
// reset instance when parsing may not be successfull or |
|
// no instance is present. |
|
cimInstance = CIMInstance(); |
|
|
|
PEG_METHOD_EXIT(); |
} | } |
// Deserialize path: |
|
{ |
|
XmlParser parser((char*)_referencesData[0].getData()); |
|
CIMObjectPath cimObjectPath; |
|
| |
|
Boolean CIMResponseData::_deserializeReference( |
|
Uint32 idx, |
|
CIMObjectPath& cimObjectPath) |
|
{ |
|
// Only start the parser when reference data is present. |
|
if (0 != _referencesData[idx].size()) |
|
{ |
|
XmlParser parser((char*)_referencesData[idx].getData()); |
if (XmlReader::getValueReferenceElement(parser, cimObjectPath)) | if (XmlReader::getValueReferenceElement(parser, cimObjectPath)) |
{ | { |
if (_hostsData.size()) |
if (_hostsData[idx].size()) |
{ | { |
cimObjectPath.setHost(_hostsData[0]); |
cimObjectPath.setHost(_hostsData[idx]); |
} | } |
if (!_nameSpacesData[0].isNull()) |
if (!_nameSpacesData[idx].isNull()) |
{ | { |
cimObjectPath.setNameSpace(_nameSpacesData[0]); |
cimObjectPath.setNameSpace(_nameSpacesData[idx]); |
} | } |
cimInstance.setPath(cimObjectPath); |
return true; |
// only if everything works we add the CIMInstance to the |
|
// array |
|
_instances.append(cimInstance); |
|
} | } |
|
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, |
|
"Failed to resolve XML reference, parser error!"); |
|
|
} | } |
break; |
return false; |
} | } |
case RESP_INSTANCES: |
|
|
Boolean CIMResponseData::_deserializeInstanceName( |
|
Uint32 idx, |
|
CIMObjectPath& cimObjectPath) |
{ | { |
for (Uint32 i = 0; i < _instanceData.size(); i++) |
// Only start the parser when instance name data is present. |
|
if (0 != _referencesData[idx].size()) |
{ | { |
CIMInstance cimInstance; |
XmlParser parser((char*)_referencesData[idx].getData()); |
// Deserialize instance: |
if (XmlReader::getInstanceNameElement(parser, cimObjectPath)) |
{ | { |
XmlParser parser((char*)_instanceData[i].getData()); |
if (_hostsData[idx].size()) |
|
{ |
if (!XmlReader::getInstanceElement(parser, cimInstance)) |
cimObjectPath.setHost(_hostsData[idx]); |
|
} |
|
if (!_nameSpacesData[idx].isNull()) |
{ | { |
|
cimObjectPath.setNameSpace(_nameSpacesData[idx]); |
|
} |
|
return true; |
|
} |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, | PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, |
"Failed to resolve XML instance." |
"Failed to resolve XML instance name, parser error!"); |
" Creating empty instance!"); |
|
cimInstance = CIMInstance(); |
|
} | } |
|
return false; |
} | } |
| |
// Deserialize path: |
void CIMResponseData::_resolveXmlToCIM() |
{ | { |
XmlParser parser((char*)_referencesData[i].getData()); |
PEG_METHOD_ENTER(TRC_DISPATCHER, |
CIMObjectPath cimObjectPath; |
"CIMResponseData::_resolveXmlToCIM"); |
| |
if (XmlReader::getInstanceNameElement(parser,cimObjectPath)) |
switch (_dataType) |
{ | { |
if (!_nameSpacesData[i].isNull()) |
// Xml encoding for instance names and object paths not used |
cimObjectPath.setNameSpace(_nameSpacesData[i]); |
case RESP_OBJECTPATHS: |
|
case RESP_INSTNAMES: |
if (_hostsData[i].size()) |
{ |
cimObjectPath.setHost(_hostsData[i]); |
break; |
|
|
cimInstance.setPath(cimObjectPath); |
|
} |
|
} | } |
|
case RESP_INSTANCE: |
|
{ |
|
CIMInstance cimInstance; |
|
CIMObjectPath cimObjectPath; |
| |
|
_deserializeInstance(0,cimInstance); |
|
if (_deserializeReference(0,cimObjectPath)) |
|
{ |
|
cimInstance.setPath(cimObjectPath); |
|
// A single CIMInstance has to have an objectpath. |
|
// So only add it when an objectpath exists. |
_instances.append(cimInstance); | _instances.append(cimInstance); |
} | } |
break; | break; |
} | } |
case RESP_OBJECTS: |
case RESP_INSTANCES: |
{ |
|
for (Uint32 i=0, n=_instanceData.size(); i<n; i++) |
|
{ | { |
CIMObject cimObject; |
for (Uint32 i = 0; i < _instanceData.size(); i++) |
|
|
// Deserialize Objects: |
|
{ | { |
XmlParser parser((char*)_instanceData[i].getData()); |
|
|
|
CIMInstance cimInstance; | CIMInstance cimInstance; |
CIMClass cimClass; |
CIMObjectPath cimObjectPath; |
| |
if (XmlReader::getInstanceElement(parser, cimInstance)) |
_deserializeInstance(i,cimInstance); |
{ |
if (_deserializeInstanceName(i,cimObjectPath)) |
cimObject = CIMObject(cimInstance); |
|
} |
|
else if (XmlReader::getClassElement(parser, cimClass)) |
|
{ | { |
cimObject = CIMObject(cimClass); |
cimInstance.setPath(cimObjectPath); |
} | } |
else |
// enumarate instances can be without name |
{ |
_instances.append(cimInstance); |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, |
|
"Failed to get XML object data!"); |
|
} | } |
|
break; |
} | } |
|
case RESP_OBJECTS: |
// Deserialize paths: |
{ |
|
for (Uint32 i=0, n=_instanceData.size(); i<n; i++) |
{ | { |
XmlParser parser((char*)_referencesData[i].getData()); |
CIMObject cimObject; |
CIMObjectPath cimObjectPath; | CIMObjectPath cimObjectPath; |
| |
if (XmlReader::getValueReferenceElement( |
_deserializeObject(i,cimObject); |
parser, |
if (_deserializeReference(i,cimObjectPath)) |
cimObjectPath)) |
|
{ | { |
if (!_nameSpacesData[i].isNull()) |
|
cimObjectPath.setNameSpace(_nameSpacesData[i]); |
|
|
|
if (_hostsData[i].size()) |
|
cimObjectPath.setHost(_hostsData[i]); |
|
|
|
cimObject.setPath(cimObjectPath); | cimObject.setPath(cimObjectPath); |
} | } |
} |
|
_objects.append(cimObject); | _objects.append(cimObject); |
} | } |
break; | break; |
} | } |
default: | default: |
{ | { |
PEGASUS_DEBUG_ASSERT(false); |
PEGASUS_ASSERT(false); |
} | } |
} | } |
// Xml was resolved, release Xml content now | // Xml was resolved, release Xml content now |
|
|
_encoding &=(~RESP_ENC_XML); | _encoding &=(~RESP_ENC_XML); |
// add CIM Encoding flag | // add CIM Encoding flag |
_encoding |=RESP_ENC_CIM; | _encoding |=RESP_ENC_CIM; |
|
|
|
PEG_METHOD_EXIT(); |
} | } |
| |
void CIMResponseData::_resolveXmlToSCMO() | void CIMResponseData::_resolveXmlToSCMO() |
{ | { |
|
PEG_METHOD_ENTER(TRC_DISPATCHER, |
|
"CIMResponseData::_resolveXmlToSCMO"); |
// Not optimal, can probably be improved | // Not optimal, can probably be improved |
// but on the other hand, since using the binary format this case should | // but on the other hand, since using the binary format this case should |
// actually not ever happen. | // actually not ever happen. |
_resolveXmlToCIM(); | _resolveXmlToCIM(); |
_resolveCIMToSCMO(); | _resolveCIMToSCMO(); |
|
|
|
PEG_METHOD_EXIT(); |
} | } |
| |
void CIMResponseData::_resolveSCMOToCIM() | void CIMResponseData::_resolveSCMOToCIM() |
{ | { |
|
PEG_METHOD_ENTER(TRC_DISPATCHER, |
|
"CIMResponseData::_resolveSCMOToCIM"); |
switch(_dataType) | switch(_dataType) |
{ | { |
case RESP_INSTNAMES: | case RESP_INSTNAMES: |
|
|
_encoding &=(~RESP_ENC_SCMO); | _encoding &=(~RESP_ENC_SCMO); |
// add SCMO Encoding flag | // add SCMO Encoding flag |
_encoding |=RESP_ENC_CIM; | _encoding |=RESP_ENC_CIM; |
|
|
|
PEG_METHOD_EXIT(); |
} | } |
| |
void CIMResponseData::_resolveCIMToSCMO() | void CIMResponseData::_resolveCIMToSCMO() |
{ | { |
|
PEG_METHOD_ENTER(TRC_DISPATCHER, |
|
"CIMResponseData::_resolveCIMToSCMO"); |
CString nsCString=_defaultNamespace.getString().getCString(); | CString nsCString=_defaultNamespace.getString().getCString(); |
const char* _defNamespace = nsCString; | const char* _defNamespace = nsCString; |
Uint32 _defNamespaceLen; | Uint32 _defNamespaceLen; |
|
|
_instanceNames[i], | _instanceNames[i], |
_defNamespace, | _defNamespace, |
_defNamespaceLen); | _defNamespaceLen); |
// TODO: More description about this. |
if (_isClassOperation) |
if (0 == _instanceNames[i].getKeyBindings().size()) |
|
{ | { |
// if there is no keybinding, this is a class |
|
addme.setIsClassOnly(true); | addme.setIsClassOnly(true); |
} | } |
_scmoInstances.append(addme); | _scmoInstances.append(addme); |
|
|
_encoding &=(~RESP_ENC_CIM); | _encoding &=(~RESP_ENC_CIM); |
// add SCMO Encoding flag | // add SCMO Encoding flag |
_encoding |=RESP_ENC_SCMO; | _encoding |=RESP_ENC_SCMO; |
|
|
|
PEG_METHOD_EXIT(); |
|
} |
|
|
|
/** |
|
* Validate the magic object for this CIMResponseData. This |
|
* compiles only in debug mode and can be use to validate the |
|
* CIMResponseData object |
|
* |
|
* @return Boolean True if valid object. |
|
*/ |
|
Boolean CIMResponseData::valid() const |
|
{ |
|
return _magic; |
|
} |
|
|
|
void CIMResponseData::setRequestProperties( |
|
const Boolean includeQualifiers, |
|
const Boolean includeClassOrigin, |
|
const CIMPropertyList& propertyList) |
|
{ |
|
_includeQualifiers = includeQualifiers; |
|
_includeClassOrigin = includeClassOrigin; |
|
_propertyList = propertyList; |
|
} |
|
|
|
void CIMResponseData::setIsClassOperation(Boolean b) |
|
{ |
|
_isClassOperation = b; |
|
} |
|
|
|
// Clear all of the input encodings by clearing their arrays and |
|
// unsetting the encoding flag. |
|
void CIMResponseData::clear() |
|
{ |
|
// Clear the xml data area |
|
_referencesData.clear(); |
|
_hostsData.clear(); |
|
_nameSpacesData.clear(); |
|
_instanceData.clear(); |
|
|
|
// Clear the binary data area |
|
_binaryData.clear(); |
|
|
|
// Clear the SCMO data |
|
_scmoInstances.clear(); |
|
|
|
//Clear the C++ Data areaa |
|
_instanceNames.clear(); |
|
_instances.clear(); |
|
_objects.clear(); |
|
|
|
_encoding = 0; |
|
_size = 0; |
|
} |
|
|
|
// The following are debugging support only |
|
//// #ifdef PEGASUS_DEBUG |
|
void CIMResponseData::traceResponseData() const |
|
{ |
|
PEG_TRACE((TRC_XML, Tracer::LEVEL3, |
|
"%s", (const char*)toStringTraceResponseData().getCString() )); |
|
} |
|
|
|
String CIMResponseData::toStringTraceResponseData() const |
|
{ |
|
int rtnSize; |
|
char *p; |
|
|
|
int allocSize = 256; |
|
|
|
if ((p = (char*)malloc(allocSize)) == NULL) |
|
{ |
|
return String(); |
|
} |
|
|
|
do |
|
{ |
|
rtnSize = snprintf(p, allocSize, |
|
"CIMResponseData::traceResponseData(encoding=%X,dataType=%X " |
|
" size=%u C++instNamecount=%u c++Instances=%u c++Objects=%u " |
|
"scomInstances=%u XMLInstData=%u binaryData=%u " |
|
"xmlref=%u xmlinst=%u, xmlhost=%u xmlns=%u", |
|
_encoding,_dataType, _size, |
|
_instanceNames.size(),_instances.size(), _objects.size(), |
|
_scmoInstances.size(),_instanceData.size(),_binaryData.size(), |
|
_referencesData.size(), _instanceData.size(), _hostsData.size(), |
|
_nameSpacesData.size()); |
|
|
|
// return if successful if not negative and |
|
// returns less than allocated size. |
|
if (rtnSize > -1 && rtnSize < allocSize) |
|
{ |
|
break; |
|
} |
|
|
|
// increment alloc size. Assumes that positive return is |
|
// expected size and negative is error. |
|
allocSize = (rtnSize > -1)? (rtnSize + 1) : allocSize * 2; |
|
|
|
} while((p = (char*)peg_inln_realloc(p, allocSize)) != NULL); |
|
|
|
// Free allocated memory and return formatted output in String |
|
String rtnStr(p); |
|
free(p); |
|
return(rtnStr); |
} | } |
|
//// #endif |
|
|
| |
PEGASUS_NAMESPACE_END | PEGASUS_NAMESPACE_END |