![]() ![]() |
![]() |
File: [Pegasus] / pegasus / src / Pegasus / ProviderManager2 / CMPI / CMPI_Instance.cpp
(download)
Revision: 1.65, Tue Jan 22 14:18:41 2013 UTC (11 years, 5 months ago) by marek Branch: MAIN CVS Tags: preBug9676, postBug9676, TASK-TASK_PEP362_RestfulService_branch-root, TASK-TASK_PEP362_RestfulService_branch-merged_out_from_trunk, TASK-TASK_PEP362_RestfulService_branch-merged_in_to_trunk, TASK-TASK_PEP362_RestfulService_branch-merged_in_from_branch, TASK-TASK_PEP362_RestfulService_branch-branch, TASK-PEP362_RestfulService-root, TASK-PEP362_RestfulService-merged_out_to_branch, TASK-PEP362_RestfulService-merged_out_from_trunk, TASK-PEP362_RestfulService-merged_in_to_trunk, TASK-PEP362_RestfulService-merged_in_from_branch, TASK-PEP362_RestfulService-branch, TASK-PEP317_pullop-merged_out_from_trunk, TASK-PEP317_pullop-merged_in_to_trunk, RELEASE_2_14_1, RELEASE_2_14_0-RC2, RELEASE_2_14_0-RC1, RELEASE_2_14_0, RELEASE_2_14-root, RELEASE_2_14-branch, RELEASE_2_13_0-RC2, RELEASE_2_13_0-RC1, RELEASE_2_13_0-FC, RELEASE_2_13_0, RELEASE_2_13-root, RELEASE_2_13-branch, HEAD, CIMRS_WORK_20130824 Changes since 1.64: +0 -1 lines BUG#:9555 TITLE: Footprint - Remove SCMODump from binaries ifndef PEGASUS_DEBUG DESCRIPTION: |
//%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/AutoPtr.h> #include "CMPI_Version.h" #include "CMPI_Instance.h" #include "CMPI_Broker.h" #include "CMPI_Value.h" #include "CMPI_String.h" #include "CMPISCMOUtilities.h" #include <Pegasus/Common/CIMNameCast.h> #include <Pegasus/Common/InternalException.h> #include <Pegasus/Common/System.h> #include <Pegasus/Common/Mutex.h> #include <string.h> #include <new> #include <Pegasus/Common/Tracer.h> PEGASUS_USING_STD; PEGASUS_NAMESPACE_BEGIN extern "C" { static CMPIStatus instRelease(CMPIInstance* eInst) { SCMOInstance* inst=(SCMOInstance*)eInst->hdl; if (inst) { delete inst; (reinterpret_cast<CMPI_Object*>(eInst))->unlinkAndDelete(); CMReturn(CMPI_RC_OK); } else { CMReturn(CMPI_RC_ERR_INVALID_HANDLE); } } static CMPIStatus instReleaseNop(CMPIInstance* eInst) { CMReturn(CMPI_RC_OK); } static CMPIInstance* instClone(const CMPIInstance* eInst, CMPIStatus* rc) { PEG_METHOD_ENTER( TRC_CMPIPROVIDERINTERFACE, "CMPI_Instance:instClone()"); SCMOInstance* inst=(SCMOInstance*)eInst->hdl; if (!inst) { CMSetStatus(rc, CMPI_RC_ERR_INVALID_HANDLE); PEG_METHOD_EXIT(); return NULL; } try { AutoPtr<SCMOInstance> cInst(new SCMOInstance(inst->clone())); AutoPtr<CMPI_Object> obj( new CMPI_Object(cInst.get(),CMPI_Object::ObjectTypeInstance)); cInst.release(); obj->unlink(); CMPIInstance* cmpiInstance = reinterpret_cast<CMPIInstance *>(obj.release()); CMSetStatus(rc,CMPI_RC_OK); PEG_METHOD_EXIT(); return cmpiInstance; } catch (const PEGASUS_STD(bad_alloc)&) { CMSetStatus(rc, CMPI_RC_ERROR_SYSTEM); PEG_METHOD_EXIT(); return NULL; } } static CMPIData instGetPropertyAt( const CMPIInstance* eInst, CMPICount pos, CMPIString** name, CMPIStatus* rc) { CMPIData data={0,CMPI_badValue,{0}}; SCMOInstance* inst=(SCMOInstance*)eInst->hdl; if (!inst) { CMSetStatus(rc, CMPI_RC_ERR_INVALID_HANDLE); return data; } const SCMBUnion* value = 0; Boolean isArray = 0; Uint32 size = 0; CIMType type = (CIMType)0; const char* pName=0; SCMO_RC src = inst->getPropertyAt((Uint32)pos, &pName, type, &value, isArray, size); switch(src) { case SCMO_OK: { CMPIType ct=type2CMPIType(type, isArray); CMPISCMOUtilities::scmoValue2CMPIData(value, ct, &data, size); if ((ct&~CMPI_ARRAY) == CMPI_string) { // We always receive strings as an array of pointers // with at least one element, which needs to be released // after it was converted to CMPIData free((void*)value); } break; } case SCMO_INDEX_OUT_OF_BOUND: { CMSetStatus(rc, CMPI_RC_ERR_NO_SUCH_PROPERTY); CMPIData rdata={0,CMPI_nullValue|CMPI_notFound,{0}}; return rdata; } case SCMO_NULL_VALUE: { // A NullValue does not indicate an error, but simply that // no value has been set for the property. data.type = type2CMPIType(type, isArray); data.state = CMPI_nullValue; data.value.uint64 = 0; break; } default: { // Other return codes should not appear here, but are possible // code wise (i.e. SCMO_NOT_FOUND etc.) PEG_TRACE(( TRC_CMPIPROVIDERINTERFACE, Tracer::LEVEL2, "Unexpected RC from SCMOInstance.instGetPropertyAt: %d", src)); CMSetStatus(rc, CMPI_RC_ERR_FAILED); return data; } break; } // Returning the property name as CMPI String if (name) { *name=string2CMPIString(pName); } CMSetStatus(rc,CMPI_RC_OK); return data; } static CMPIData instGetProperty(const CMPIInstance* eInst, const char *name, CMPIStatus* rc) { CMPIData data={0,CMPI_badValue,{0}}; SCMOInstance* inst=(SCMOInstance*)eInst->hdl; if (!inst) { CMSetStatus(rc, CMPI_RC_ERR_INVALID_HANDLE); return data; } if (!name) { CMSetStatus(rc, CMPI_RC_ERR_INVALID_PARAMETER); return data; } const SCMBUnion* value = 0; Boolean isArray = 0; Uint32 size = 0; CIMType type = (CIMType)0; SCMO_RC src = inst->getProperty(name, type, &value, isArray, size); if (src != SCMO_OK) { switch(src) { case SCMO_NOT_FOUND: { data.state = CMPI_nullValue | CMPI_notFound; CMSetStatus(rc, CMPI_RC_ERR_NO_SUCH_PROPERTY); return data; } break; case SCMO_NULL_VALUE: { // A NullValue does not indicate an error, but simply that // no value has been set for the property. data.type = type2CMPIType(type, isArray); data.value.uint64 = 0; data.state = CMPI_nullValue; CMSetStatus(rc, CMPI_RC_OK); return data; } break; default: { PEG_TRACE(( TRC_CMPIPROVIDERINTERFACE, Tracer::LEVEL1, "Unexpected RC from SCMOInstance.instGetPropertyAt: %d", src)); CMSetStatus(rc, CMPI_RC_ERR_FAILED); return data; } break; } } else { CMPIType ct=type2CMPIType(type, isArray); CMPISCMOUtilities::scmoValue2CMPIData(value, ct, &data, size); if ((ct&~CMPI_ARRAY) == CMPI_string) { // We always receive strings as an array of pointers // with at least one element, which needs to be released // after it was converted to CMPIData free((void*)value); } } CMSetStatus(rc,CMPI_RC_OK); return data; } static CMPICount instGetPropertyCount(const CMPIInstance* eInst, CMPIStatus* rc) { SCMOInstance* inst=(SCMOInstance*)eInst->hdl; if (!inst) { CMSetStatus(rc, CMPI_RC_ERR_INVALID_HANDLE); return 0; } CMSetStatus(rc,CMPI_RC_OK); return inst->getPropertyCount(); } static CMPIStatus instSetPropertyWithOrigin( const CMPIInstance* eInst, const char* name, const CMPIValue* data, const CMPIType type, const char* origin) { PEG_METHOD_ENTER( TRC_CMPIPROVIDERINTERFACE, "CMPI_Instance:instSetPropertyWithOrigin()"); SCMOInstance *inst=(SCMOInstance*)eInst->hdl; if (!inst) { PEG_METHOD_EXIT(); CMReturn(CMPI_RC_ERR_INVALID_HANDLE); } CMPIStatus cmpiRC = {CMPI_RC_OK,0}; SCMO_RC rc; if (!(type&CMPI_ARRAY)) { CIMType cimType=type2CIMType(type); Boolean nullValue = false; SCMBUnion scmoData = value2SCMOValue(data, type, nullValue); rc = inst->setPropertyWithOrigin(name, cimType, nullValue ? 0 : &scmoData, false, // isArray 0, // arraySize origin); } else { //Get the type of the elements in the array CMPIType aType=type&~CMPI_ARRAY; CIMType cimType=type2CIMType(aType); if( data == NULL || data->array == NULL ) { // In this case just set a NULL Value rc = inst->setPropertyWithOrigin(name,cimType,0,true,0,origin); } else { // When data is not NULL and data->array is also set CMPI_Array* ar = (CMPI_Array*)data->array->hdl; CMPIData* arrData = (CMPIData*)ar->hdl; Uint32 arraySize = arrData->value.uint32; // Convert the array of CMPIData to an array of SCMBUnion SCMBUnion * scmbArray = 0; SCMBUnion scmbArrayBuf[8]; if (arraySize > 8) { scmbArray=(SCMBUnion *)malloc(arraySize*sizeof(SCMBUnion)); } else { scmbArray=&(scmbArrayBuf[0]); } Boolean nullValue = false; for (unsigned int x=0; x<arraySize; x++) { // Note: First element is the array status information, // therefore cmpi array starts at index 1!!! scmbArray[x] = value2SCMOValue( &(arrData[x+1].value), arrData[x+1].type, nullValue); } rc = inst->setPropertyWithOrigin( name, cimType, scmbArray, true, // isArray arraySize, origin); if (arraySize > 8) { free(scmbArray); } } } if (rc != SCMO_OK) { PEG_TRACE((TRC_CMPIPROVIDERINTERFACE,Tracer::LEVEL3, "Property %s not set on created instance. SCMO_RC=%d", name, rc)); switch (rc) { case SCMO_NOT_SAME_ORIGIN: cmpiRC.rc = CMPI_RC_ERR_INVALID_PARAMETER; break; case SCMO_NOT_FOUND: { // Logical would be to return an error here, but previous // impl. returned OK since CMPI spec. is not specific about // this. Should become CMPI_RC_ERR_NO_SUCH_PROPERTY in // CMPI 2.1 or 3.0 cmpiRC.rc = CMPI_RC_OK; // Writing a message to log since provider tries to set a // non-existing property Logger::put_l( Logger::ERROR_LOG, System::CIMSERVER, Logger::WARNING, MessageLoaderParms( "ProviderManager.CMPI.CMPI_Instance." "NO_SUCH_PROPERTY", "Property $0 not set on the created instance of " "class $1", name, inst->getClassName())); break; } case SCMO_WRONG_TYPE: case SCMO_NOT_AN_ARRAY: case SCMO_IS_AN_ARRAY: cmpiRC.rc = CMPI_RC_ERR_INVALID_DATA_TYPE; break; default: cmpiRC.rc = CMPI_RC_ERR_FAILED; break; } } PEG_METHOD_EXIT(); return(cmpiRC); } static CMPIStatus instSetProperty(const CMPIInstance* eInst, const char *name, const CMPIValue* data, CMPIType type) { return instSetPropertyWithOrigin(eInst, name, data, type, NULL); } static CMPIObjectPath* instGetObjectPath(const CMPIInstance* eInst, CMPIStatus* rc) { PEG_METHOD_ENTER( TRC_CMPIPROVIDERINTERFACE, "CMPI_Instance:instGetObjectPath()"); SCMOInstance* inst=(SCMOInstance*)eInst->hdl; if (!inst) { CMSetStatus(rc, CMPI_RC_ERR_INVALID_HANDLE); PEG_METHOD_EXIT(); return NULL; } try { // Generate keys from instance inst->buildKeyBindingsFromProperties(); // Since we make no difference between ObjectPath and Instance, // we simply clone using the ObjectPathOnly option. SCMOInstance* cInst = new SCMOInstance(inst->clone(true)); CMPIObjectPath* cmpiObjPath = reinterpret_cast<CMPIObjectPath *> (new CMPI_Object(cInst,CMPI_Object::ObjectTypeObjectPath)); CMSetStatus(rc,CMPI_RC_OK); PEG_METHOD_EXIT(); return cmpiObjPath; } catch (const PEGASUS_STD(bad_alloc)&) { CMSetStatus(rc, CMPI_RC_ERROR_SYSTEM); PEG_METHOD_EXIT(); return NULL; } } static CMPIStatus instSetObjectPath( CMPIInstance* eInst, const CMPIObjectPath *obj) { PEG_METHOD_ENTER( TRC_CMPIPROVIDERINTERFACE, "CMPI_Instance:instSetObjectPath()"); SCMOInstance* prevInst=(SCMOInstance*)eInst->hdl; if (prevInst==NULL) { PEG_METHOD_EXIT(); CMReturn(CMPI_RC_ERR_INVALID_HANDLE); } if (obj==NULL) { PEG_METHOD_EXIT(); CMReturn(CMPI_RC_ERR_INVALID_PARAMETER); } SCMOInstance* ref = (SCMOInstance*)(obj->hdl); if (ref->isSame(*prevInst)) { // Since we represent CMPIObjectPath as well as CMPIInstance // through SCMOInstance, in this case both point to the same // physical SCMB and the objectPath is already set. // So this path is a nop. PEG_METHOD_EXIT(); CMReturn(CMPI_RC_OK); } else { // It is not possible to have an instance or objectPath in // this implementation without a classname or namespace. const char* nsRef = ref->getNameSpace(); Uint32 clsRefL; const char* clsRef = ref->getClassName_l(clsRefL); Uint32 clsPrevInstL; const char* clsPrevInst = prevInst->getClassName_l(clsPrevInstL); if (System::strncasecmp(clsRef,clsRefL,clsPrevInst,clsPrevInstL)) { // Set the new namespace prevInst->setNameSpace(nsRef); // Remove the previous key properties prevInst->clearKeyBindings(); // Copy the key properties from the given ObjectPath CMPIrc rc = CMPISCMOUtilities::copySCMOKeyProperties( ref, // source prevInst); // target if (rc != CMPI_RC_OK) { PEG_TRACE_CSTRING( TRC_CMPIPROVIDERINTERFACE, Tracer::LEVEL1, "Failed to copy key bindings"); PEG_METHOD_EXIT(); CMReturn(CMPI_RC_ERR_FAILED); } } else { // Uurrgh, changing class on an existing // CMPIInstance is a prohibited change. // Simply returning an error PEG_TRACE_CSTRING( TRC_CMPIPROVIDERINTERFACE, Tracer::LEVEL1, "Cannot set objectpath because it would change classname" "or namespace of instance"); PEG_METHOD_EXIT(); CMReturnWithString( CMPI_RC_ERR_FAILED, string2CMPIString("Incompatible ObjectPath")); } } PEG_METHOD_EXIT(); CMReturn(CMPI_RC_OK); } static CMPIStatus instSetPropertyFilter(CMPIInstance* eInst, const char** propertyList, const char **keys) { PEG_METHOD_ENTER( TRC_CMPIPROVIDERINTERFACE, "CMPI_Instance:instSetPropertyFilter()"); SCMOInstance* inst=(SCMOInstance*)eInst->hdl; PEG_METHOD_EXIT(); if (inst==NULL) { CMReturn(CMPI_RC_ERR_INVALID_HANDLE); } //Property filtering is done by the CIMOM infrastructure. CMReturn(CMPI_RC_OK); } static CMPIStatus instSetPropertyFilterIgnore(CMPIInstance* eInst, const char** propertyList, const char **keys) { /* We ignore it. */ CMReturn ( CMPI_RC_OK); } } static CMPIInstanceFT instance_FT={ CMPICurrentVersion, instRelease, instClone, instGetProperty, instGetPropertyAt, instGetPropertyCount, instSetProperty, instGetObjectPath, instSetPropertyFilter, #if defined(CMPI_VER_100) instSetObjectPath, #endif #if defined(CMPI_VER_200) instSetPropertyWithOrigin, #endif }; static CMPIInstanceFT instanceOnStack_FT={ CMPICurrentVersion, instReleaseNop, instClone, instGetProperty, instGetPropertyAt, instGetPropertyCount, instSetProperty, instGetObjectPath, instSetPropertyFilterIgnore, #if defined(CMPI_VER_100) instSetObjectPath, #endif #if defined(CMPI_VER_200) instSetPropertyWithOrigin, #endif }; CMPIInstanceFT *CMPI_Instance_Ftab=&instance_FT; CMPIInstanceFT *CMPI_InstanceOnStack_Ftab=&instanceOnStack_FT; CMPI_InstanceOnStack::CMPI_InstanceOnStack(const SCMOInstance* ci) { PEG_METHOD_ENTER( TRC_CMPIPROVIDERINTERFACE, "CMPI_InstanceOnStack::CMPI_InstanceOnStack()"); hdl=(void*)ci; ft=CMPI_InstanceOnStack_Ftab; PEG_METHOD_EXIT(); } CMPI_InstanceOnStack::CMPI_InstanceOnStack(const SCMOInstance& ci) { PEG_METHOD_ENTER( TRC_CMPIPROVIDERINTERFACE, "CMPI_InstanceOnStack::CMPI_InstanceOnStack()"); hdl=(void*) new SCMOInstance(ci); ft=CMPI_InstanceOnStack_Ftab; PEG_METHOD_EXIT(); } CMPI_InstanceOnStack::~CMPI_InstanceOnStack() { if (hdl) { delete((SCMOInstance*)hdl); } } PEGASUS_NAMESPACE_END
No CVS admin address has been configured |
Powered by ViewCVS 0.9.2 |