(file) Return to CMPI_Instance.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / ProviderManager2 / CMPI

Diff for /pegasus/src/Pegasus/ProviderManager2/CMPI/CMPI_Instance.cpp between version 1.55 and 1.56

version 1.55, 2009/11/16 09:48:03 version 1.56, 2009/12/15 11:39:39
Line 36 
Line 36 
 #include "CMPI_Broker.h" #include "CMPI_Broker.h"
 #include "CMPI_Value.h" #include "CMPI_Value.h"
 #include "CMPI_String.h" #include "CMPI_String.h"
   #include "CMPISCMOUtilities.h"
  
 #include <Pegasus/Common/CIMNameCast.h> #include <Pegasus/Common/CIMNameCast.h>
 #include <Pegasus/Common/InternalException.h> #include <Pegasus/Common/InternalException.h>
Line 44 
Line 45 
 #include <string.h> #include <string.h>
 #include <new> #include <new>
 #include <Pegasus/Common/Tracer.h> #include <Pegasus/Common/Tracer.h>
   #include <Pegasus/Common/SCMODump.h>
  
 PEGASUS_USING_STD; PEGASUS_USING_STD;
 PEGASUS_NAMESPACE_BEGIN PEGASUS_NAMESPACE_BEGIN
Line 53 
Line 55 
  
     static CMPIStatus instRelease(CMPIInstance* eInst)     static CMPIStatus instRelease(CMPIInstance* eInst)
     {     {
         CIMInstance* inst=(CIMInstance*)eInst->hdl;          SCMOInstance* inst=(SCMOInstance*)eInst->hdl;
         if (inst)         if (inst)
         {         {
             delete inst;             delete inst;
Line 76 
Line 78 
         PEG_METHOD_ENTER(         PEG_METHOD_ENTER(
             TRC_CMPIPROVIDERINTERFACE,             TRC_CMPIPROVIDERINTERFACE,
             "CMPI_Instance:instClone()");             "CMPI_Instance:instClone()");
         CIMInstance* inst=(CIMInstance*)eInst->hdl;          SCMOInstance* inst=(SCMOInstance*)eInst->hdl;
         if (!inst)         if (!inst)
         {         {
             CMSetStatus(rc, CMPI_RC_ERR_INVALID_HANDLE);             CMSetStatus(rc, CMPI_RC_ERR_INVALID_HANDLE);
Line 85 
Line 87 
         }         }
         try         try
         {         {
             AutoPtr<CIMInstance> cInst(new CIMInstance(inst->clone()));              AutoPtr<SCMOInstance> cInst(new SCMOInstance(inst->clone()));
             AutoPtr<CMPI_Object> obj(new CMPI_Object(cInst.get()));              AutoPtr<CMPI_Object> obj(
                   new CMPI_Object(cInst.get(),CMPI_Object::ObjectTypeInstance));
             cInst.release();             cInst.release();
             obj->unlink();             obj->unlink();
             CMSetStatus(rc,CMPI_RC_OK);  
             CMPIInstance* cmpiInstance =             CMPIInstance* cmpiInstance =
                 reinterpret_cast<CMPIInstance *>(obj.release());                 reinterpret_cast<CMPIInstance *>(obj.release());
               CMSetStatus(rc,CMPI_RC_OK);
             PEG_METHOD_EXIT();             PEG_METHOD_EXIT();
             return cmpiInstance;             return cmpiInstance;
         }         }
Line 107 
Line 110 
         const CMPIInstance* eInst, CMPICount pos, CMPIString** name,         const CMPIInstance* eInst, CMPICount pos, CMPIString** name,
         CMPIStatus* rc)         CMPIStatus* rc)
     {     {
         CIMInstance* inst=(CIMInstance*)eInst->hdl;          CMPIData data={0,CMPI_badValue,{0}};
         CMPIData data={0,CMPI_nullValue,{0}};  
  
           SCMOInstance* inst=(SCMOInstance*)eInst->hdl;
         if (!inst)         if (!inst)
         {         {
             CMSetStatus(rc, CMPI_RC_ERR_INVALID_HANDLE);             CMSetStatus(rc, CMPI_RC_ERR_INVALID_HANDLE);
             return data;             return data;
         }         }
  
         if (pos>inst->getPropertyCount())          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 );
                   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);             CMSetStatus(rc, CMPI_RC_ERR_NO_SUCH_PROPERTY);
             CMPIData retData={0,CMPI_nullValue|CMPI_notFound,{0}};                  CMPIData rdata={0,CMPI_nullValue|CMPI_notFound,{0}};
             return retData;                  return rdata;
                   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.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;
         }         }
         const CIMProperty& p=inst->getProperty(pos);  
         const CIMValue& v=p.getValue();  
         CIMType pType=p.getType();  
         CMPIType t=type2CMPIType(pType,p.isArray());  
  
         value2CMPIData(v,t,&data);  
  
           // Returning the property name as CMPI String
         if (name)         if (name)
         {         {
             String str=p.getName().getString();              *name=string2CMPIString(pName);
             *name=(CMPIString*)string2CMPIString(str);  
         }         }
  
         CMSetStatus(rc,CMPI_RC_OK);         CMSetStatus(rc,CMPI_RC_OK);
Line 142 
Line 193 
     static CMPIData instGetProperty(const CMPIInstance* eInst,     static CMPIData instGetProperty(const CMPIInstance* eInst,
         const char *name, CMPIStatus* rc)         const char *name, CMPIStatus* rc)
     {     {
         CMPIData data={0,CMPI_nullValue|CMPI_notFound,{0}};          CMPIData data={0,CMPI_badValue,{0}};
  
         if (!eInst->hdl)          SCMOInstance* inst=(SCMOInstance*)eInst->hdl;
           if (!inst)
         {         {
             CMSetStatus(rc, CMPI_RC_ERR_INVALID_HANDLE);             CMSetStatus(rc, CMPI_RC_ERR_INVALID_HANDLE);
             return data;             return data;
         }         }
   
         if (!name)         if (!name)
         {         {
             CMSetStatus(rc, CMPI_RC_ERR_INVALID_PARAMETER);             CMSetStatus(rc, CMPI_RC_ERR_INVALID_PARAMETER);
             return data;             return data;
         }         }
         CIMInstance* inst=(CIMInstance*)eInst->hdl;  
         Uint32 pos=inst->findProperty(String(name));  
  
         if (pos!=PEG_NOT_FOUND)          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)
         {         {
             CMSetStatus(rc,CMPI_RC_OK);              switch(src)
             return instGetPropertyAt(eInst,pos,NULL,rc);              {
               case SCMO_NOT_FOUND:
                   {
                       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.
   
                       // TBD: Though the CMPI specification mandates to return a
                       // nullvalue when a property exists on an instance but has
                       // not yet been assigned a value, for compatibility with
                       // previous versions we return CMPI_RC_ERR_NO_SUCH_PROPERTY
                       // in this case.
                       // If SCMO would distinguish between nullvalues and values
                       // that have not been set at all on an instance, we could
                       // be more precise here.
                       /*
                            // Correct code for nullvalues
                            data.type = type2CMPIType(type, isArray);
                            data.state = CMPI_nullValue;
                            data.value.uint64 = 0;
                       */
                       // Code for properties that have not been set
         CMSetStatus(rc, CMPI_RC_ERR_NO_SUCH_PROPERTY);         CMSetStatus(rc, CMPI_RC_ERR_NO_SUCH_PROPERTY);
         return data;         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,     static CMPICount instGetPropertyCount(const CMPIInstance* eInst,
         CMPIStatus* rc)         CMPIStatus* rc)
     {     {
         CIMInstance* inst=(CIMInstance*)eInst->hdl;          SCMOInstance* inst=(SCMOInstance*)eInst->hdl;
         if (!inst)         if (!inst)
         {         {
             CMSetStatus(rc, CMPI_RC_ERR_INVALID_HANDLE);             CMSetStatus(rc, CMPI_RC_ERR_INVALID_HANDLE);
Line 180 
Line 296 
         return inst->getPropertyCount();         return inst->getPropertyCount();
     }     }
  
     static CMPIStatus instSetPropertyWithOrigin(const CMPIInstance* eInst,      static CMPIStatus instSetPropertyWithOrigin(
         const char* name, const CMPIValue* data, const CMPIType type,          const CMPIInstance* eInst,
           const char* name,
           const CMPIValue* data,
           const CMPIType type,
         const char* origin)         const char* origin)
     {     {
         PEG_METHOD_ENTER(         PEG_METHOD_ENTER(
             TRC_CMPIPROVIDERINTERFACE,             TRC_CMPIPROVIDERINTERFACE,
             "CMPI_Instance:instSetPropertyWithOrigin()");             "CMPI_Instance:instSetPropertyWithOrigin()");
         CIMInstance *inst=(CIMInstance*)eInst->hdl;  
           SCMOInstance *inst=(SCMOInstance*)eInst->hdl;
         if (!inst)         if (!inst)
         {         {
             PEG_METHOD_EXIT();             PEG_METHOD_EXIT();
             CMReturn(CMPI_RC_ERR_INVALID_HANDLE);             CMReturn(CMPI_RC_ERR_INVALID_HANDLE);
         }         }
         CMPIrc rc;  
         CIMValue v=value2CIMValue(data,type,&rc);  
         Uint32 pos;  
         int count=0;  
   
         if ((pos=inst->findProperty(CIMNameCast(name)))!=PEG_NOT_FOUND)  
         {  
   
             CIMProperty cp=inst->getProperty(pos);  
  
           CMPIStatus cmpiRC = {CMPI_RC_OK,0};
           SCMO_RC rc;
  
             /* The CMPI interface uses the type "CMPI_instance" to represent          if (!(type&CMPI_ARRAY))
                both embedded objects and embedded instances. CMPI has no  
                "CMPI_object" type. So when converting a CMPIValue with type  
                "CMPI_instance" to a CIMValue (see value2CIMValue) the type  
                CIMTYPE_OBJECT is always used. If the property's type is  
                CIMTYPE_INSTANCE, and the value's type is CIMTYPE_OBJECT, then  
                we convert the value's type to match the property's type.  
             */  
             if (cp.getType() == CIMTYPE_INSTANCE &&  
                 v.getType() == CIMTYPE_OBJECT)  
             {  
                 if (cp.isArray())  
                 {  
                     if (!v.isArray())  
                     {                     {
                         PEG_TRACE((              CIMType cimType=type2CIMType(type);
                             TRC_CMPIPROVIDERINTERFACE,              SCMBUnion scmoData = value2SCMOValue(data, type);
                             Tracer::LEVEL1,  
                             "TypeMisMatch, Expected Type: %s, Actual Type: %s",              rc = inst->setPropertyWithOrigin(name,
                             cimTypeToString(cp.getType()),                                               cimType,
                             cimTypeToString(v.getType())));                                               &scmoData,
                         PEG_METHOD_EXIT();                                               false,  // isArray
                         CMReturn(CMPI_RC_ERR_TYPE_MISMATCH);                                               0,      // arraySize
                     }                                               origin);
                     Array<CIMObject> tmpObjs;  
                     Array<CIMInstance> tmpInsts;  
                     v.get(tmpObjs);  
                     for (Uint32 i = 0; i < tmpObjs.size() ; ++i)  
                     {  
                         tmpInsts.append(CIMInstance(tmpObjs[i]));  
                     }  
                     v.set(tmpInsts);  
                 }                 }
                 else                 else
                 {                 {
                     CIMObject co;              //Get the type of the elements in the array
                     v.get(co);              CMPIType aType=type&~CMPI_ARRAY;
                     if (co.isInstance())              CIMType cimType=type2CIMType(aType);
                         v.set(CIMInstance(co));  
                 }              if( data == NULL || data->array == NULL )
             }  
             try  
             {  
                 cp.setValue(v);  
                 if (origin)  
                 {                 {
                     CIMName oName(origin);                  // In this case just set a NULL Value
                     cp.setClassOrigin(oName);                  rc = inst->setPropertyWithOrigin(name,cimType,0,true,0,origin);
                 }  
             }             }
             catch (const TypeMismatchException &)              else
             {             {
                 PEG_TRACE((                  // When data is not NULL and data->array is also set
                     TRC_CMPIPROVIDERINTERFACE,                  CMPI_Array* ar = (CMPI_Array*)data->array->hdl;
                     Tracer::LEVEL1,                  CMPIData* arrData = (CMPIData*)ar->hdl;
                     " TypeMisMatch exception for: %s",  
                     name));                  Uint32 arraySize = arrData->value.uint32;
                 if (getenv("PEGASUS_CMPI_CHECKTYPES")!=NULL)  
                   // Convert the array of CMPIData to an array of SCMBUnion
                   SCMBUnion * scmbArray = 0;
                   SCMBUnion scmbArrayBuf[8];
                   if (arraySize > 8)
                 {                 {
                     PEG_TRACE_CSTRING(                      scmbArray=(SCMBUnion *)malloc(arraySize*sizeof(SCMBUnion));
                         TRC_CMPIPROVIDERINTERFACE,  
                         Tracer::LEVEL1,  
                         " Aborting because of CMPI_CHECKTYPES..");  
                         abort();  
                 }                 }
                 PEG_METHOD_EXIT();                  else
                 CMReturn(CMPI_RC_ERR_TYPE_MISMATCH);  
             }  
             catch (const InvalidNameException &)  
             {             {
                 PEG_TRACE((                      scmbArray=&(scmbArrayBuf[0]);
                     TRC_CMPIPROVIDERINTERFACE,  
                     Tracer::LEVEL1,  
                     " InvalidName exception for: %s",  
                     origin));  
   
                 PEG_METHOD_EXIT();  
                 CMReturn(CMPI_RC_ERR_INVALID_PARAMETER);  
             }             }
             catch (const Exception &e)                  for (unsigned int x=0; x<arraySize; x++)
             {             {
                 PEG_TRACE((TRC_CMPIPROVIDERINTERFACE,Tracer::LEVEL1,                      // Note:  First element is the array status information,
                     "Exception for %s: %s",name,                      //        therefore cmpi array starts at index 1!!!
                     (const char*)e.getMessage().getCString()));                      scmbArray[x] = value2SCMOValue(
                 if (getenv("PEGASUS_CMPI_CHECKTYPES")!=NULL)                          &(arrData[x+1].value),
                           arrData[x+1].type);
                   }
   
                   rc = inst->setPropertyWithOrigin(
                       name,
                       cimType,
                       scmbArray,
                       true,          // isArray
                       arraySize,
                       origin);
                   if (arraySize > 8)
                 {                 {
                     PEG_TRACE_CSTRING(                      free(scmbArray);
                         TRC_CMPIPROVIDERINTERFACE,  
                         Tracer::LEVEL1,  
                         " Aborting because of CMPI_CHECKTYPES..");  
                         abort();  
                 }                 }
                 PEG_METHOD_EXIT();  
                 CMReturnWithString(CMPI_RC_ERR_FAILED,  
                     reinterpret_cast<CMPIString*>(  
                     new CMPI_Object(e.getMessage())));  
             }             }
         }         }
         else  
           if (rc != SCMO_OK)
         {         {
             PEG_TRACE((TRC_CMPIPROVIDERINTERFACE,Tracer::LEVEL3,             PEG_TRACE((TRC_CMPIPROVIDERINTERFACE,Tracer::LEVEL3,
                        "Property %s not set on created instance."                        "Property %s not set on created instance."
                            "Either the property is not part of the class or"                            "Either the property is not part of the class or"
                                "not part of the property list.",                         "not part of the property list. SCMO_RC=%d",
                        name));                         name,
                          rc));
   
               switch (rc)
               {
                   case SCMO_NOT_SAME_ORIGIN:
                       cmpiRC.rc = CMPI_RC_ERR_INVALID_PARAMETER;
                       break;
                   case SCMO_NOT_FOUND:
                       //TBD: Should return an error here, but previous impl.
                       //     returned OK. Is this correct?
                       //cmpiRC.rc = CMPI_RC_ERR_NO_SUCH_PROPERTY;
                       cmpiRC.rc = CMPI_RC_OK;
                       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();         PEG_METHOD_EXIT();
         CMReturn(CMPI_RC_OK);          return(cmpiRC);
     }     }
  
     static CMPIStatus instSetProperty(const CMPIInstance* eInst,     static CMPIStatus instSetProperty(const CMPIInstance* eInst,
Line 326 
Line 429 
         PEG_METHOD_ENTER(         PEG_METHOD_ENTER(
             TRC_CMPIPROVIDERINTERFACE,             TRC_CMPIPROVIDERINTERFACE,
             "CMPI_Instance:instGetObjectPath()");             "CMPI_Instance:instGetObjectPath()");
         CIMInstance* inst=(CIMInstance*)eInst->hdl;  
           SCMOInstance* inst=(SCMOInstance*)eInst->hdl;
         if (!inst)         if (!inst)
         {         {
             CMSetStatus(rc, CMPI_RC_ERR_INVALID_HANDLE);             CMSetStatus(rc, CMPI_RC_ERR_INVALID_HANDLE);
             PEG_METHOD_EXIT();             PEG_METHOD_EXIT();
             return NULL;             return NULL;
         }         }
         const CIMObjectPath &clsRef=inst->getPath();  
         AutoPtr<CIMObjectPath> objPath(NULL);  
         AutoPtr<CMPI_Object> obj(NULL);  
         try  
         {  
             /* Check if NameSpace is NULL before calling GetClass. When  
                providers run out-of-process and getClass request is made  
                through CIMClient,  CIMOperationRequestEncoder tries to  
                encode the request and finds the namespace is invalid  
                (empty) and throws InvalidNamespaceNameException.  
             */  
             if (clsRef.getKeyBindings().size()==0 &&  
                 !clsRef.getNameSpace().isNull())  
             {  
                 CIMClass *cc=mbGetClass(CMPI_ThreadContext::getBroker(),clsRef);  
                 /* It seems that when converting the CIMInstnace to XML form,  
                    we miss CIMObjectPath from it. When we don't have namespace  
                    we may not get class, so make ObjectPath with class-name  
                    only.  
                    TODO: This will create problems when passing the  
                    EmbeddedInstances as arguements to MethodProviders, where it  
                    needs to get ObjectPath from instance. Shall we need to  
                    include CIMObjectPath in CIMInstance while converting to XML  
                    form ??? ...  
                 */  
                 if (!cc)  
                 {  
                     objPath.reset(new CIMObjectPath(clsRef));  
                 }  
                 else  
                 {  
                     try                     try
                     {                     {
                         const CIMObjectPath &ref=inst->buildPath(              // Generate keys from instance
                             *(reinterpret_cast<const CIMConstClass*>(cc)));              inst->buildKeyBindingsFromProperties();
                         objPath.reset(new CIMObjectPath(ref));  
                         objPath->setHost(clsRef.getHost());  
                         objPath->setNameSpace(clsRef.getNameSpace());  
                     }  
                     catch(const Exception &e)  
                     {  
                         CMSetStatusWithString(  
                             rc,  
                             CMPI_RC_ERR_FAILED,  
                             (CMPIString*)string2CMPIString(e.getMessage()));  
                         PEG_METHOD_EXIT();  
                         return NULL;  
                     }  
  
                 }              // Since we make no difference between ObjectPath and Instance,
             }              // we simply clone using the ObjectPathOnly option.
             else              SCMOInstance* cInst = new SCMOInstance(inst->clone(true));
                 objPath.reset(new CIMObjectPath(clsRef));  
             obj.reset(new CMPI_Object(objPath.get()));              CMPIObjectPath* cmpiObjPath =
             objPath.release();                  reinterpret_cast<CMPIObjectPath *>
                   (new CMPI_Object(cInst,CMPI_Object::ObjectTypeObjectPath));
             CMSetStatus(rc,CMPI_RC_OK);             CMSetStatus(rc,CMPI_RC_OK);
             CMPIObjectPath* cmpiObjectPath =  
                 reinterpret_cast<CMPIObjectPath*> (obj.release());  
             PEG_METHOD_EXIT();             PEG_METHOD_EXIT();
             return cmpiObjectPath;              return cmpiObjPath;
         }         }
         catch (const PEGASUS_STD(bad_alloc)&)         catch (const PEGASUS_STD(bad_alloc)&)
         {         {
Line 409 
Line 469 
         PEG_METHOD_ENTER(         PEG_METHOD_ENTER(
             TRC_CMPIPROVIDERINTERFACE,             TRC_CMPIPROVIDERINTERFACE,
             "CMPI_Instance:instSetObjectPath()");             "CMPI_Instance:instSetObjectPath()");
         CIMInstance* inst=(CIMInstance*)eInst->hdl;  
         if (inst==NULL)          SCMOInstance* prevInst=(SCMOInstance*)eInst->hdl;
           if (prevInst==NULL)
         {         {
             PEG_METHOD_EXIT();             PEG_METHOD_EXIT();
             CMReturn(CMPI_RC_ERR_INVALID_HANDLE);             CMReturn(CMPI_RC_ERR_INVALID_HANDLE);
Line 421 
Line 482 
             CMReturn ( CMPI_RC_ERR_INVALID_PARAMETER);             CMReturn ( CMPI_RC_ERR_INVALID_PARAMETER);
         }         }
  
         CIMObjectPath &ref = *(CIMObjectPath*)(obj->hdl);          SCMOInstance* ref = (SCMOInstance*)(obj->hdl);
         try          if (ref->isSame(*prevInst))
         {  
             inst->setPath(ref);  
         }  
         catch (const TypeMismatchException &e)  
         {         {
             PEG_METHOD_EXIT();              // Since we represent CMPIObjectPath as well as CMPIInstance
             CMReturnWithString(CMPI_RC_ERR_FAILED,              // through SCMOInstance, in this case both point to the same
                 reinterpret_cast<CMPIString*>(              // physical SCMB and the objectPath is already set.
                     new CMPI_Object(e.getMessage())));              // So this path is a nop.
         }  
         PEG_METHOD_EXIT();         PEG_METHOD_EXIT();
         CMReturn ( CMPI_RC_OK);         CMReturn ( CMPI_RC_OK);
     }     }
           else
     /* The function removes all properties not part of the given  
        array of property names(property lists).  
        Function can handle second list being set or not set.  
        This is an internal function used by instSetPropertyFilter()  
     */  
     static void filterCIMInstance(  
         const char** listroot1,  
         const char** listroot2,  
         CIMInstance & inst)  
     {  
         /* listroot1 never can be 0, this function is only called by  
            instSetPropertyFilter() and the check is done there already */  
   
         /* determine number of properties on the instance */  
         int propertyCount = inst.getPropertyCount();  
   
         /* number of properties in each property list */  
         int numProperties1 = 0;  
         int numProperties2 = 0;  
         /* Masks for property lists  
            0 = list element not yet found  
            1 = list element already found)  
         */  
         char * plMask1=0;  
         char * plMask2=0;  
         /* end of array of property list names */  
         const char **listend1 = listroot1;  
         /* place end pointer at end of array and count number of properties  
            named in the first list */  
         while (*listend1)  
         {  
             listend1++;  
         }  
         /* former while loop steps one field to far, step one back */  
         listend1--;  
         /* calculate last valid index of a property */  
         numProperties1 = listend1 - listroot1;  
         /* reserver memory for index + 1 property mask fields */  
         plMask1 = (char*) calloc(1, numProperties1+1);  
   
         /* special dish for two lists, need to check those at same time */  
         /* variable to hold end of array of property list names */  
         const char **listend2 = listroot2;  
         /* place end pointer at end of array and count number of properties  
            named in the first list */  
         if (listroot2)  
         {  
             while (*listend2)  
             {  
                 listend2++;  
             }  
             /* former while loop steps one field to far, step one back */  
             listend2--;  
             /* calculate last valid index of a property */  
             numProperties2 = listend2 - listroot2;  
             /* reserver memory for index + 1 property mask fields */  
             plMask2 = (char*) calloc(1, numProperties2+1);  
         }  
   
         /* for each property on the instance */  
         /* use reverse order, so we don't change index of properties not yet  
            checked when removing a property */  
         for (int idx=propertyCount-1; idx >= 0; idx--)  
         {  
             CIMConstProperty prop = inst.getProperty(idx);  
             CString cName = prop.getName().getString().getCString();  
             const char* pName = (const char*)cName;  
   
             /* work the property list backward too, as often times  
                properties on the instance and in the list are ordered in the  
                same way, this helps reduce number of required strcasecmp */  
             int found = false;  
             /* use temporary list1 to step through the list */  
             const char **list1 = listend1;  
   
             /* steps through the entire property list and does compare  
                the name in the property list with the currently investigated  
                name of the property, except one of the following conditions  
                is true:  
                  1.) the property list element has already been found as  
                      indicated by the property list mask  
                  2.) the property is found, mark it as found in the mask and  
                      leave the for-loop  
             */  
             for (int pos1=numProperties1; pos1 >= 0; pos1--,list1--)  
             {  
                 if (!plMask1[pos1])  
                 {  
                     if (System::strcasecmp(pName, *list1)==0)  
                     {  
                         found = true;  
                         plMask1[pos1] = 1;  
                         break;  
                     }  
                 }  
             }  
             /* Do the same algorithm for the second list too,  
                except if we found the property already */  
             if (listroot2 && !found)  
             {  
                 /* use temporary list2 to step through the list */  
                 const char **list2 = listend2;  
                 for (int pos2=numProperties2; pos2 >= 0; pos2--,list2--)  
                 {  
                     if (!plMask2[pos2])  
                     {                     {
                         if (System::strcasecmp(pName, *list2)==0)              // 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)
                         {                         {
                             found = true;                      PEG_TRACE_CSTRING(
                             plMask2[pos2] = 1;                          TRC_CMPIPROVIDERINTERFACE,
                             break;                          Tracer::LEVEL1,
                         }                          "Failed to copy key bindings");
                     }                      PEG_METHOD_EXIT();
                       CMReturn(CMPI_RC_ERR_FAILED);
                 }                 }
             }             }
             /* If the property could not be found in either property list,              else
                remove the property from the instance */  
             if (!found)  
             {             {
                 inst.removeProperty(idx);                  // 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"));
         }         }
         free(plMask1);  
         if (listroot2)  
         {  
             free(plMask2);  
         }         }
   
           PEG_METHOD_EXIT();
           CMReturn(CMPI_RC_OK);
     }     }
  
   
     static CMPIStatus instSetPropertyFilter(CMPIInstance* eInst,     static CMPIStatus instSetPropertyFilter(CMPIInstance* eInst,
         const char** propertyList, const char **keys)         const char** propertyList, const char **keys)
     {     {
         PEG_METHOD_ENTER(         PEG_METHOD_ENTER(
             TRC_CMPIPROVIDERINTERFACE,             TRC_CMPIPROVIDERINTERFACE,
             "CMPI_Instance:instSetPropertyFilter()");             "CMPI_Instance:instSetPropertyFilter()");
   
         if (!eInst->hdl)         if (!eInst->hdl)
         {         {
             PEG_METHOD_EXIT();             PEG_METHOD_EXIT();
Line 580 
Line 561 
         /* The property list is to be applied on the given instance.         /* The property list is to be applied on the given instance.
            Currently CMPI provider have to call instSetPropertyFilter to honor            Currently CMPI provider have to call instSetPropertyFilter to honor
            property filters or have to filter for themselves.            property filters or have to filter for themselves.
            Removing properties from the CIMInstance here helps to effectively             Removing properties from the SCMOInstance here helps to effectively
            avoid the need to carry a property list around in the CMPI layer.            avoid the need to carry a property list around in the CMPI layer.
  
            A (propertyList == 0) means the property list is null and there            A (propertyList == 0) means the property list is null and there
Line 591 
Line 572 
            (*propertyList == 0)            (*propertyList == 0)
         */         */
  
         CIMInstance& inst=*(CIMInstance*)(eInst->hdl);          SCMOInstance* inst=(SCMOInstance*)eInst->hdl;
         if (propertyList)          inst->setPropertyFilter(propertyList);
         {  
             if (!keys)  
             {  
                 filterCIMInstance(propertyList, 0, inst);  
             }  
             else  
             {  
                 filterCIMInstance(propertyList, keys, inst);  
             }  
         };  
         PEG_METHOD_EXIT();         PEG_METHOD_EXIT();
         CMReturn(CMPI_RC_OK);         CMReturn(CMPI_RC_OK);
     }     }
Line 657 
Line 629 
 CMPIInstanceFT *CMPI_InstanceOnStack_Ftab=&instanceOnStack_FT; CMPIInstanceFT *CMPI_InstanceOnStack_Ftab=&instanceOnStack_FT;
  
  
 CMPI_InstanceOnStack::CMPI_InstanceOnStack(const CIMInstance& ci)  CMPI_InstanceOnStack::CMPI_InstanceOnStack(const SCMOInstance* ci)
 { {
     PEG_METHOD_ENTER(     PEG_METHOD_ENTER(
         TRC_CMPIPROVIDERINTERFACE,         TRC_CMPIPROVIDERINTERFACE,
         "CMPI_InstanceOnStack::CMPI_InstanceOnStack()");         "CMPI_InstanceOnStack::CMPI_InstanceOnStack()");
  
     hdl=(void*)&ci;      hdl=(void*)ci;
     ft=CMPI_InstanceOnStack_Ftab;     ft=CMPI_InstanceOnStack_Ftab;
     PEG_METHOD_EXIT();     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 PEGASUS_NAMESPACE_END
  


Legend:
Removed from v.1.55  
changed lines
  Added in v.1.56

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2