(file) Return to instance.c CVS log (file) (dir) Up to [OMI] / omi / base

Diff for /omi/base/instance.c between version 1.3 and 1.4

version 1.3, 2015/04/20 18:10:09 version 1.4, 2015/04/20 18:19:49
Line 26 
Line 26 
 #include "instance.h" #include "instance.h"
 #include "helpers.h" #include "helpers.h"
 #include "naming.h" #include "naming.h"
 #include "indent.h"  
 #include "types.h" #include "types.h"
 #include "schemadecl.h" #include "schemadecl.h"
 #include "alloc.h" #include "alloc.h"
 #include "field.h" #include "field.h"
 #include "io.h"  #include "class.h"
   #include <stdio.h>
 #if 0  #ifdef _MSC_VER
 # include "return.h"  #pragma prefast (disable: 28252)
   #pragma prefast (disable: 28253)
 #endif #endif
   #include <wchar.h>
   
  
 /* /*
 **============================================================================== **==============================================================================
Line 45 
Line 47 
 **============================================================================== **==============================================================================
 */ */
  
 #define T MI_T  
   
 /* Magic number of InstanceHeader */ /* Magic number of InstanceHeader */
 static MI_Uint32 _MAGIC = 0xB26AEA60; static MI_Uint32 _MAGIC = 0xB26AEA60;
  
 /* Number of default pages for a self-owned batch object */ /* Number of default pages for a self-owned batch object */
 static MI_Uint32 _NUM_PAGES = 8;  static MI_Uint32 _NUM_PAGES = INFINITE;
  
 /* The minimum number of reserved properties for a dynamic instance */ /* The minimum number of reserved properties for a dynamic instance */
 static MI_Uint32 _CAPACITY = 32; static MI_Uint32 _CAPACITY = 32;
Line 96 
Line 96 
     return NULL;     return NULL;
 } }
  
   /* Return the index of the given property */
   MI_Uint32 _FindFeatureDecl(
       MI_FeatureDecl** features,
       MI_Uint32 numFeatures,
       const MI_Char* name)
   {
       MI_Uint32 code;
       MI_FeatureDecl** start = features;
       MI_FeatureDecl** p = start;
       MI_FeatureDecl** end = start + numFeatures;
   
       /* Zero-length CIM names are illegal */
       if (*name == '\0')
           return (MI_Uint32)-1;
   
       code = Hash(name);
   
       /* Find the property */
       while (p != end)
       {
           if (p[0]->code == code && Tcscasecmp(p[0]->name, name) == 0)
               return (MI_Uint32)(p - start);
           p++;
       }
   
       /* Not found */
       return (MI_Uint32)-1;
   }
   
   /* Return the index of the given property */
   MI_INLINE MI_Uint32 _FindPropertyDeclIndex(
       const MI_ClassDecl* cd,
       const MI_Char* name)
   {
       return _FindFeatureDecl(
           (MI_FeatureDecl**)cd->properties,
           cd->numProperties,
           name);
   }
   
 /* Return the index of the given property or (MI_Uin32)-1 if not found */ /* Return the index of the given property or (MI_Uin32)-1 if not found */
 static MI_Uint32 _FindPropertyDecl( static MI_Uint32 _FindPropertyDecl(
     const MI_ClassDecl* cd,     const MI_ClassDecl* cd,
     const MI_Char* name)      const ZChar* name)
 { {
     MI_PropertyDecl** start = cd->properties;     MI_PropertyDecl** start = cd->properties;
     MI_PropertyDecl** end = start + cd->numProperties;     MI_PropertyDecl** end = start + cd->numProperties;
Line 110 
Line 150 
  
     while (p != end)     while (p != end)
     {     {
         if ((*p)->code == code && Zcasecmp((*p)->name, name) == 0)          if ((*p)->code == code && Tcscasecmp((*p)->name, name) == 0)
             return (MI_Uint32)(p - start);             return (MI_Uint32)(p - start);
         p++;         p++;
     }     }
Line 118 
Line 158 
     return (MI_Uint32)-1;     return (MI_Uint32)-1;
 } }
  
   
 static MI_PropertyDecl* _LookupPropertyDecl( static MI_PropertyDecl* _LookupPropertyDecl(
     const MI_ClassDecl* cd,     const MI_ClassDecl* cd,
     const MI_Char* name)      const ZChar* name)
 { {
     MI_Uint32 index = _FindPropertyDecl(cd, name);     MI_Uint32 index = _FindPropertyDecl(cd, name);
  
Line 129 
Line 170 
  
     return cd->properties[index];     return cd->properties[index];
 } }
   static MI_Qualifier * _CloneQualifierDecl(
       MI_Qualifier * qualifier,
       _Inout_ Batch *batch)
   {
       MI_Qualifier *newQualifier = Batch_Get(batch, sizeof(MI_Qualifier));
       if (newQualifier == NULL)
       {
           return NULL;
       }
       memset(newQualifier, 0, sizeof(*newQualifier));
       newQualifier->name = Batch_Tcsdup(batch, qualifier->name);
       if (newQualifier->name == NULL)
       {
           return NULL;
       }
       newQualifier->type = qualifier->type;
       newQualifier->flavor = qualifier->flavor;
       /* Clone only boolean values. */
       if (qualifier->value && qualifier->type == MI_BOOLEAN)
       {
           newQualifier->value = Batch_Get(batch, sizeof(MI_Boolean));
           if (newQualifier->value == NULL)
           {
               return NULL;
           }
           *(MI_Boolean*)newQualifier->value = *(MI_Boolean*)qualifier->value;
       }
       else
       {
           newQualifier->value = NULL;
       }
   
       return newQualifier;
   }
   
   static MI_Qualifier  **_CloneQualifierDecls(
       MI_Qualifier **qualifiers,
       MI_Uint32 numQualifiers,
       _Inout_ Batch *batch)
   {
       MI_Qualifier **newQualifiers = Batch_Get(batch, sizeof(MI_Qualifier*)*numQualifiers);
       MI_Uint32 qualifierIndex = 0;
       if (newQualifiers == NULL)
       {
           return NULL;
       }
       for (;qualifierIndex != numQualifiers; qualifierIndex++)
       {
           newQualifiers[qualifierIndex] = _CloneQualifierDecl(qualifiers[qualifierIndex], batch);
           if (newQualifiers[qualifierIndex] == NULL)
           {
               return NULL;
           }
       }
   
       return newQualifiers;
   }
  
 static MI_PropertyDecl* _ClonePropertyDecl( static MI_PropertyDecl* _ClonePropertyDecl(
     const MI_PropertyDecl* pd,     const MI_PropertyDecl* pd,
Line 144 
Line 242 
     if (pd->name)     if (pd->name)
     {     {
         p->name = BStrdup(batch, pd->name, CALLSITE);         p->name = BStrdup(batch, pd->name, CALLSITE);
   
         if (!p->name)         if (!p->name)
             return NULL;             return NULL;
     }     }
  
     p->flags = pd->flags;  
     p->code = pd->code;     p->code = pd->code;
       p->flags = pd->flags;
     p->type = pd->type;     p->type = pd->type;
     p->offset = pd->offset;     p->offset = pd->offset;
  
       if (pd->qualifiers && pd->numQualifiers)
       {
           p->qualifiers = _CloneQualifierDecls(pd->qualifiers, pd->numQualifiers, batch);
           if (p->qualifiers == NULL)
           {
               return NULL;  /* Returning NULL causes whole batch to destruct */
           }
           p->numQualifiers = pd->numQualifiers;
       }
   
     return p;     return p;
 } }
  
Line 186 
Line 295 
     return data;     return data;
 } }
  
 static MI_ClassDecl* _CloneClassDecl(  MI_ClassDecl* _CloneClassDecl(
     const MI_ClassDecl* cd,     const MI_ClassDecl* cd,
     Batch* batch)     Batch* batch)
 { {
Line 201 
Line 310 
     if (cd->name)     if (cd->name)
     {     {
         p->name = BStrdup(batch, cd->name, CALLSITE);         p->name = BStrdup(batch, cd->name, CALLSITE);
   
         if (!p->name)         if (!p->name)
             return NULL;             return NULL;
     }     }
  
       /* Instance.code */
       p->code = cd->code;
   
     /* Instance.size */     /* Instance.size */
     p->size = cd->size;     p->size = cd->size;
  
Line 218 
Line 331 
  
         p->numProperties = cd->numProperties;         p->numProperties = cd->numProperties;
     }     }
       p->owningClass = (MI_Class*)-1; //We are using this clone because it is a dynamic classDecl, so mark this classDecl as dynamic
     return p;     return p;
 } }
  
Line 389 
Line 502 
     self->self = self;     self->self = self;
  
     /* MI_Instance.classDecl */     /* MI_Instance.classDecl */
       if ((cd->flags & (MI_FLAG_CLASS|MI_FLAG_ASSOCIATION|MI_FLAG_INDICATION)) && (cd->owningClass == NULL))
       {
           //Should be static
     self->classDecl = cd;     self->classDecl = cd;
       }
       else if ((cd->flags & (MI_FLAG_CLASS|MI_FLAG_ASSOCIATION|MI_FLAG_INDICATION)) && (cd->owningClass != (MI_Class*)-1))
       {
           //Bump up the ref-count on the owning classDecl if it is a class AND it is not a static classDecl
           MI_Class *newClass;
           MI_Result result = MI_Class_Clone(cd->owningClass, &newClass);
           if (result != MI_RESULT_OK)
               return result;
   
           self->classDecl = newClass->classDecl;
       }
       else if (cd->flags & (MI_FLAG_CLASS|MI_FLAG_ASSOCIATION|MI_FLAG_INDICATION))
       {
           if (!batch)
           {
               assert(0);
               MI_RETURN(MI_RESULT_INVALID_PARAMETER);
           }
   
           //This is a class, so do a full clone
           self->classDecl = Class_Clone_ClassDecl(batch, cd);
           if (self->classDecl == NULL)
               return MI_RESULT_FAILED;
       }
       else
       {
           if (!batch)
           {
               assert(0);
               MI_RETURN(MI_RESULT_INVALID_PARAMETER);
           }
   
           //This may be a parameter, so need to do a reduced clone
           self->classDecl = _CloneClassDecl(cd, batch);
           if (self->classDecl == NULL)
               return MI_RESULT_FAILED;
       }
  
     /* MI_Instance.batch */     /* MI_Instance.batch */
     self->batch = batch;     self->batch = batch;
Line 400 
Line 553 
     MI_RETURN(MI_RESULT_OK);     MI_RETURN(MI_RESULT_OK);
 } }
  
   _Use_decl_annotations_
 MI_Result Instance_New( MI_Result Instance_New(
     MI_Instance** selfOut,     MI_Instance** selfOut,
     const MI_ClassDecl* classDecl,     const MI_ClassDecl* classDecl,
Line 410 
Line 564 
     MI_Result r;     MI_Result r;
  
     /* Check for null arguments */     /* Check for null arguments */
     if (!selfOut || !classDecl || !batch)      if (!selfOut || !classDecl)
         MI_RETURN(MI_RESULT_INVALID_PARAMETER);         MI_RETURN(MI_RESULT_INVALID_PARAMETER);
  
     /* Null out selfOut */     /* Null out selfOut */
Line 449 
Line 603 
     return r;     return r;
 } }
  
   _Use_decl_annotations_
 MI_Result MI_CALL Instance_InitConvert( MI_Result MI_CALL Instance_InitConvert(
     MI_Instance* self_,     MI_Instance* self_,
     const MI_ClassDecl* cd1,     const MI_ClassDecl* cd1,
Line 456 
Line 611 
     MI_Boolean keysOnly,     MI_Boolean keysOnly,
     MI_Boolean allowKeylessInst,     MI_Boolean allowKeylessInst,
     MI_Boolean copy,     MI_Boolean copy,
     Batch* batch_)      Batch* batch_,
       MI_Uint32 flags)
 { {
     Instance* self;     Instance* self;
     const Instance* inst = _SelfOf(inst_);     const Instance* inst = _SelfOf(inst_);
Line 466 
Line 622 
     const MI_SchemaDecl* sd1;     const MI_SchemaDecl* sd1;
     Batch* batch = batch_;     Batch* batch = batch_;
  
     /* Resolve the schema declaration (based on type) */  
     if (cd1->flags & MI_FLAG_METHOD)  
         sd1 = ((MI_MethodDecl*)cd1)->schema;  
     else if (cd1->flags & MI_FLAG_CLASS)  
         sd1 = cd1->schema;  
     else  
     {  
         return MI_RESULT_FAILED;  
     }  
   
     /* Check parameters */     /* Check parameters */
     if (!self_ || !cd1 || !inst || !batch)      if (!self_ || !cd1 || !inst)
         MI_RETURN(MI_RESULT_INVALID_PARAMETER);         MI_RETURN(MI_RESULT_INVALID_PARAMETER);
  
     /* Create a new batch */     /* Create a new batch */
Line 485 
Line 631 
     {     {
         batch = Batch_New(_NUM_PAGES);         batch = Batch_New(_NUM_PAGES);
         if (!batch)         if (!batch)
               return MI_RESULT_SERVER_LIMITS_EXCEEDED;
       }
   
       /* Resolve the schema declaration (based on type) */
       if (cd1->flags & MI_FLAG_METHOD)
           sd1 = ((MI_MethodDecl*)cd1)->schema;
       else if (cd1->flags & MI_FLAG_CLASS)
           sd1 = cd1->schema;
       else
         {         {
             return MI_RESULT_FAILED;             return MI_RESULT_FAILED;
         }         }
     }  
  
     cd2 = inst->classDecl;     cd2 = inst->classDecl;
  
Line 511 
Line 665 
         self->nameSpace = BStrdup(batch, inst->nameSpace, CALLSITE);         self->nameSpace = BStrdup(batch, inst->nameSpace, CALLSITE);
         if (!self->nameSpace)         if (!self->nameSpace)
         {         {
             r = MI_RESULT_FAILED;              r = MI_RESULT_SERVER_LIMITS_EXCEEDED;
             goto failed;             goto failed;
         }         }
     }     }
Line 522 
Line 676 
         self->serverName = BStrdup(batch, inst->serverName, CALLSITE);         self->serverName = BStrdup(batch, inst->serverName, CALLSITE);
         if (!self->serverName)         if (!self->serverName)
         {         {
             r = MI_RESULT_FAILED;              r = MI_RESULT_SERVER_LIMITS_EXCEEDED;
             goto failed;             goto failed;
         }         }
     }     }
Line 541 
Line 695 
                 index = _FindPropertyDecl(cd2, pd1->name);                 index = _FindPropertyDecl(cd2, pd1->name);
                 if (index == (MI_Uint32)-1)                 if (index == (MI_Uint32)-1)
                 {                 {
                     r = MI_RESULT_TYPE_MISMATCH;                      if (pd1->value)
                       {
                           //add default key value
                           MI_Value* value = (MI_Value*)pd1->value;
                           r = MI_Instance_SetElementAt(self_, i, value, pd1->type, MI_FLAG_BORROW);
                           if (r != MI_RESULT_OK)
                           {
                     goto failed;                     goto failed;
                 }                 }
   
                       }
                       else
                       {
                           r = MI_RESULT_NO_SUCH_PROPERTY;
                           goto failed;
                       }
                   }
             }             }
         }         }
  
Line 558 
Line 726 
                 index = _FindPropertyDecl(cd1, pd2->name);                 index = _FindPropertyDecl(cd1, pd2->name);
                 if (index == (MI_Uint32)-1)                 if (index == (MI_Uint32)-1)
                 {                 {
                     r = MI_RESULT_TYPE_MISMATCH;                      r = MI_RESULT_NO_SUCH_PROPERTY;
                     goto failed;                     goto failed;
                 }                 }
             }             }
Line 583 
Line 751 
             if (pd2->type == MI_STRING)             if (pd2->type == MI_STRING)
             {             {
                 r = Instance_SetElementFromString(self_, pd2->name,                 r = Instance_SetElementFromString(self_, pd2->name,
                     ((MI_Value*)field)->string);                      ((MI_Value*)field)->string, flags);
  
                 if (r != MI_RESULT_OK)                 if (r != MI_RESULT_OK)
                 {                 {
                     r = MI_RESULT_TYPE_MISMATCH;  
                     goto failed;                     goto failed;
                 }                 }
             }             }
             else if (pd2->type == MI_STRINGA)             else if (pd2->type == MI_STRINGA)
             {             {
                 r = Instance_SetElementFromStringA(self_, pd2->name,                 r = Instance_SetElementFromStringA(self_, pd2->name,
                     (const MI_Char**)((MI_Value*)field)->stringa.data,                      (const ZChar**)((MI_Value*)field)->stringa.data,
                     ((MI_Value*)field)->stringa.size);                      ((MI_Value*)field)->stringa.size,
                       flags);
  
                 if (r != MI_RESULT_OK)                 if (r != MI_RESULT_OK)
                 {                 {
                     r = MI_RESULT_TYPE_MISMATCH;  
                     goto failed;                     goto failed;
                 }                 }
             }             }
Line 608 
Line 775 
                 MI_Instance* tmpInst;                 MI_Instance* tmpInst;
                 MI_ClassDecl* tmpCd;                 MI_ClassDecl* tmpCd;
                 MI_Type type;                 MI_Type type;
                   MI_Boolean allowKeylessEmbedInst = (pd2->type == MI_INSTANCE) ? MI_TRUE : MI_FALSE;
  
                 /* Find the class declaration in the schema */                 /* Find the class declaration in the schema */
                 tmpCd = SchemaDecl_FindClassDecl(sd1,                 tmpCd = SchemaDecl_FindClassDecl(sd1,
Line 615 
Line 783 
  
                 if (!tmpCd)                 if (!tmpCd)
                 {                 {
                     r = MI_RESULT_FAILED;                      r = MI_RESULT_NO_SUCH_PROPERTY;
                     goto failed;                     goto failed;
                 }                 }
  
                 /* Allocate static instance of this class */                 /* Allocate static instance of this class */
                 if (Instance_New(&tmpInst, tmpCd, batch) != MI_RESULT_OK)                  r = Instance_New(&tmpInst, tmpCd, batch);
                   if (r != MI_RESULT_OK)
                 {                 {
                     r = MI_RESULT_FAILED;  
                     goto failed;                     goto failed;
                 }                 }
  
                 /* Convert instance */                 /* Convert instance */
                 r = Instance_InitConvert(tmpInst, tmpCd,                 r = Instance_InitConvert(tmpInst, tmpCd,
                     ((MI_Value*)field)->instance, keysOnly, MI_FALSE, copy,                      ((MI_Value*)field)->instance, keysOnly, allowKeylessEmbedInst, copy,
                     ((Instance*)tmpInst)->batch);                      ((Instance*)tmpInst)->batch, flags);
  
                 if (r != MI_RESULT_OK)                 if (r != MI_RESULT_OK)
                 {                 {
                     __MI_Instance_Delete(tmpInst);                     __MI_Instance_Delete(tmpInst);
                     r = MI_RESULT_TYPE_MISMATCH;  
                     goto failed;                     goto failed;
                 }                 }
  
Line 714 
Line 881 
             {             {
                 MI_Value v;                 MI_Value v;
                 MI_Uint32 j;                 MI_Uint32 j;
                   MI_Boolean allowKeylessEmbedInst = (pd2->type == MI_INSTANCEA) ? MI_TRUE : MI_FALSE;
  
                 v.instancea.size = ((MI_Value*)field)->instancea.size;                 v.instancea.size = ((MI_Value*)field)->instancea.size;
                 v.instancea.data = BAlloc(batch,                 v.instancea.data = BAlloc(batch,
Line 721 
Line 889 
  
                 if (!v.instancea.data)                 if (!v.instancea.data)
                 {                 {
                     r = MI_RESULT_FAILED;                      r = MI_RESULT_SERVER_LIMITS_EXCEEDED;
                     goto failed;                     goto failed;
                 }                 }
  
Line 736 
Line 904 
  
                     if (!tmpCd)                     if (!tmpCd)
                     {                     {
                         r = MI_RESULT_FAILED;                          r = MI_RESULT_NO_SUCH_PROPERTY;
                         goto failed;                         goto failed;
                     }                     }
  
                     /* Allocate the instance for the provider */                     /* Allocate the instance for the provider */
                     if (Instance_New(&tmpInst,tmpCd,batch) != MI_RESULT_OK)                      r = Instance_New(&tmpInst,tmpCd,batch);
                       if (r != MI_RESULT_OK)
                     {                     {
                         r = MI_RESULT_FAILED;  
                         goto failed;                         goto failed;
                     }                     }
  
                     r = Instance_InitConvert(tmpInst, tmpCd,                     r = Instance_InitConvert(tmpInst, tmpCd,
                         ((MI_Value*)field)->instancea.data[j], keysOnly, MI_FALSE, copy,                          ((MI_Value*)field)->instancea.data[j], keysOnly, allowKeylessEmbedInst, copy,
                         ((Instance*)tmpInst)->batch);                          ((Instance*)tmpInst)->batch, flags);
  
                     if (r != MI_RESULT_OK)                     if (r != MI_RESULT_OK)
                     {                     {
Line 758 
Line 926 
                         for (k = 0; k < j; k++)                         for (k = 0; k < j; k++)
                             __MI_Instance_Delete(v.instancea.data[k]);                             __MI_Instance_Delete(v.instancea.data[k]);
  
                         r = MI_RESULT_TYPE_MISMATCH;  
                         goto failed;                         goto failed;
                     }                     }
  
Line 769 
Line 936 
                 r = __MI_Instance_SetElement(self_, pd2->name, &v, pd2->type,                 r = __MI_Instance_SetElement(self_, pd2->name, &v, pd2->type,
                     MI_FLAG_ADOPT);                     MI_FLAG_ADOPT);
  
                   /* Allow conversion from reference array to instance array */
                   if (r == MI_RESULT_TYPE_MISMATCH && pd2->type == MI_INSTANCEA)
                   {
                       r = __MI_Instance_SetElement(self_, pd2->name, &v,
                           MI_REFERENCEA, MI_FLAG_ADOPT);
                   }
   
                 if (r != MI_RESULT_OK)                 if (r != MI_RESULT_OK)
                 {                 {
                     for (j = 0; j < v.instancea.size; j++)                     for (j = 0; j < v.instancea.size; j++)
                         __MI_Instance_Delete(v.instancea.data[j]);                         __MI_Instance_Delete(v.instancea.data[j]);
  
                     r = MI_RESULT_TYPE_MISMATCH;  
                     goto failed;                     goto failed;
                 }                 }
             }             }
Line 788 
Line 961 
  
                 if (r != MI_RESULT_OK)                 if (r != MI_RESULT_OK)
                 {                 {
                     r = MI_RESULT_TYPE_MISMATCH;  
                     goto failed;                     goto failed;
                 }                 }
             }             }
Line 806 
Line 978 
     MI_Instance** instOut,     MI_Instance** instOut,
     Batch* batch_)     Batch* batch_)
 { {
     const Instance* self = _SelfOf(self_);      const Instance* self;
     Batch* batch = batch_;     Batch* batch = batch_;
     Instance* inst;     Instance* inst;
     MI_Uint32 i;     MI_Uint32 i;
     MI_Result r;     MI_Result r;
  
       /* Check for externally defined instance */
       if (self_ && self_->ft != &__mi_instanceFT && self_->ft != NULL)
           return MI_Instance_Clone(self_, instOut);
   
       self = _SelfOf(self_);
   
     /* Check for a null parameter */     /* Check for a null parameter */
     if (!self || !instOut)     if (!self || !instOut)
     {     {
Line 882 
Line 1060 
     }     }
  
     /* Set Instance.classDecl */     /* Set Instance.classDecl */
     if ((void*)self != (void*)self_)      if ((self->classDecl->flags & (MI_FLAG_CLASS|MI_FLAG_INDICATION|MI_FLAG_ASSOCIATION)) &&  (self->classDecl->owningClass == NULL)) //static
     {     {
           inst->classDecl = self->classDecl;
       }
       else if ((self->classDecl->owningClass == (MI_Class*)-1) || !(self->classDecl->flags & (MI_FLAG_CLASS|MI_FLAG_INDICATION|MI_FLAG_ASSOCIATION)))
       {
           //classDecl is from a dynamic instance without a proper classDecl
         inst->classDecl = _CloneClassDecl(self->classDecl, batch);         inst->classDecl = _CloneClassDecl(self->classDecl, batch);
  
         if (!inst->classDecl)         if (!inst->classDecl)
               MI_RETURN(MI_RESULT_FAILED);
       }
       else if (self->classDecl->owningClass)  //has a proper MI_Class owner so can clone it to bump refcount
         {         {
             r = MI_RESULT_FAILED;          MI_Class *clonedClass;
             goto failed;          MI_Result result = MI_Class_Clone(self->classDecl->owningClass, &clonedClass);
           if (result != MI_RESULT_OK)
               MI_RETURN(result);
           inst->classDecl = clonedClass->classDecl;
         }         }
       else//We had better do a hard clone
       {
           inst->classDecl = Class_Clone_ClassDecl(batch, self->classDecl);
           if (inst->classDecl == NULL)
               MI_RETURN(MI_RESULT_FAILED);
     }     }
     else  
         inst->classDecl = self->classDecl;  
  
     /* Clone each of the fields */     /* Clone each of the fields */
     for (i = 0; i < self->classDecl->numProperties; i++)     for (i = 0; i < self->classDecl->numProperties; i++)
Line 935 
Line 1127 
  
 MI_Result MI_CALL Instance_SetClassName( MI_Result MI_CALL Instance_SetClassName(
     MI_Instance* self_,     MI_Instance* self_,
     const MI_Char* className)      const ZChar* className)
 { {
     Instance* self = _SelfOf(self_);     Instance* self = _SelfOf(self_);
     MI_Char* oldClassName;      ZChar* oldClassName;
  
     /* Check parameters */     /* Check parameters */
     if (!self || !className)     if (!self || !className)
Line 949 
Line 1141 
  
     /* Set new className */     /* Set new className */
     {     {
         MI_Char* tmp = BStrdup(self->batch, className, CALLSITE);          ZChar* tmp = BStrdup(self->batch, className, CALLSITE);
  
         if (!tmp)         if (!tmp)
             MI_RETURN(MI_RESULT_FAILED);             MI_RETURN(MI_RESULT_FAILED);
  
         self->classDecl->name = tmp;         self->classDecl->name = tmp;
           self->classDecl->code = Hash(tmp);
     }     }
  
     /* Free old className */     /* Free old className */
Line 964 
Line 1157 
     MI_RETURN(MI_RESULT_OK);     MI_RETURN(MI_RESULT_OK);
 } }
  
   _Use_decl_annotations_
 MI_Result MI_CALL Instance_NewDynamic( MI_Result MI_CALL Instance_NewDynamic(
     MI_Instance** selfOut,     MI_Instance** selfOut,
     const MI_Char* className,      const ZChar* className,
     MI_Uint32 metaType,     MI_Uint32 metaType,
     Batch* batch_)     Batch* batch_)
 { {
Line 1024 
Line 1218 
                 goto failed;                 goto failed;
             }             }
  
               cd->owningClass = (MI_Class*) -1; /* Mark as a dynamic instance */
             self->classDecl = cd;             self->classDecl = cd;
         }         }
  
Line 1048 
Line 1243 
                 r = MI_RESULT_FAILED;                 r = MI_RESULT_FAILED;
                 goto failed;                 goto failed;
             }             }
   
         }         }
  
         /* MI_ClassDecl.code: */         /* MI_ClassDecl.code: */
         cd->code = Hash(className);          cd->code = Hash(cd->name);
  
         /* MI_ClassDecl.properties: */         /* MI_ClassDecl.properties: */
         {         {
Line 1185 
Line 1381 
     return MI_TRUE;     return MI_TRUE;
 } }
  
   /* Get underline instance */
   Instance* Instance_GetSelf(
       const MI_Instance* self)
   {
       return _SelfOf( self );
   }
   
 /* /*
 **============================================================================== **==============================================================================
 ** **
Line 1198 
Line 1401 
     InstanceHeader* h = _HeaderOf((Instance*)self);     InstanceHeader* h = _HeaderOf((Instance*)self);
  
     if (h)     if (h)
         AtomicInc(&h->u.refs);          Atomic_Inc(&h->u.refs);
 } }
  
 void __MI_Instance_Unref(MI_Instance* self) void __MI_Instance_Unref(MI_Instance* self)
 { {
     InstanceHeader* h = _HeaderOf((Instance*)self);     InstanceHeader* h = _HeaderOf((Instance*)self);
  
     if (h && AtomicDec(&h->u.refs))      if (h && Atomic_Dec(&h->u.refs) == 0)
         __MI_Instance_Delete((MI_Instance*)self);         __MI_Instance_Delete((MI_Instance*)self);
 } }
  
Line 1222 
Line 1425 
     Instance* self = _SelfOf(self_);     Instance* self = _SelfOf(self_);
     Batch* batch;     Batch* batch;
     MI_Uint32 i;     MI_Uint32 i;
       MI_Boolean releaseBatch;
  
     /* Check for null parameter */     /* Check for null parameter */
     if (!self)     if (!self)
         MI_RETURN(MI_RESULT_INVALID_PARAMETER);         MI_RETURN(MI_RESULT_INVALID_PARAMETER);
  
       /* Save release flag */
       releaseBatch = self->releaseBatch;
   
     /* Save pointer to batch */     /* Save pointer to batch */
     batch = self->batch;     batch = self->batch;
     if (!batch)     if (!batch)
Line 1265 
Line 1472 
         if ((void*)self != (void*)self_)         if ((void*)self != (void*)self_)
             _FreeInstance(batch, self);             _FreeInstance(batch, self);
     }     }
       else
       {
           if ((self->classDecl->flags & (MI_FLAG_CLASS|MI_FLAG_INDICATION|MI_FLAG_ASSOCIATION)) && self->classDecl->owningClass)
           {
               //Bump down the ref-count on the owning MI_Class if there is one, deleting it if necessary
               MI_Class_Delete(self->classDecl->owningClass);
           }
       }
   
       /* release batch */
       if (releaseBatch)
           Batch_Delete(batch);
  
     MI_RETURN(MI_RESULT_OK);     MI_RETURN(MI_RESULT_OK);
 } }
Line 1295 
Line 1514 
         MI_RETURN(r);         MI_RETURN(r);
  
     /* Release self pointer */     /* Release self pointer */
       if (MI_FALSE == releaseBatch)
     _FreeInstance(batch, (Instance*)self_);     _FreeInstance(batch, (Instance*)self_);
  
     /* Release the batch */  
     if (releaseBatch)  
         Batch_Delete(batch);  
   
     return r;     return r;
 } }
  
Line 1333 
Line 1549 
  
 MI_Result MI_CALL __MI_Instance_GetClassName( MI_Result MI_CALL __MI_Instance_GetClassName(
     const MI_Instance* self_,     const MI_Instance* self_,
     const MI_Char** classNameOut)      const ZChar** classNameOut)
 { {
     Instance* self = _SelfOf(self_);     Instance* self = _SelfOf(self_);
  
Line 1348 
Line 1564 
  
 MI_Result MI_CALL __MI_Instance_SetNameSpace( MI_Result MI_CALL __MI_Instance_SetNameSpace(
     MI_Instance* self_,     MI_Instance* self_,
     const MI_Char* nameSpace)      const ZChar* nameSpace)
 { {
     Instance* self = _SelfOf(self_);     Instance* self = _SelfOf(self_);
     MI_Char* oldNameSpace;      ZChar* oldNameSpace;
  
     /* Check parameters */     /* Check parameters */
     if (!self)     if (!self)
Line 1363 
Line 1579 
     /* Set new namespace */     /* Set new namespace */
     if (nameSpace)     if (nameSpace)
     {     {
         MI_Char* tmp = BStrdup(self->batch, nameSpace, CALLSITE);          ZChar* tmp = BStrdup(self->batch, nameSpace, CALLSITE);
  
         if (!tmp)         if (!tmp)
             MI_RETURN(MI_RESULT_FAILED);             MI_RETURN(MI_RESULT_FAILED);
Line 1382 
Line 1598 
  
 MI_Result MI_CALL __MI_Instance_GetNameSpace( MI_Result MI_CALL __MI_Instance_GetNameSpace(
     const MI_Instance* self_,     const MI_Instance* self_,
     const MI_Char** nameSpaceOut)      const ZChar** nameSpaceOut)
 { {
     Instance* self = _SelfOf(self_);     Instance* self = _SelfOf(self_);
  
Line 1412 
Line 1628 
  
 MI_Result MI_CALL __MI_Instance_AddElement( MI_Result MI_CALL __MI_Instance_AddElement(
     MI_Instance* self_,     MI_Instance* self_,
     const MI_Char* name,      const ZChar* name,
     const MI_Value* value,     const MI_Value* value,
     MI_Type type,     MI_Type type,
     MI_Uint32 flags)     MI_Uint32 flags)
Line 1462 
Line 1678 
         data = (MI_PropertyDecl**)BRealloc(         data = (MI_PropertyDecl**)BRealloc(
             self->batch,             self->batch,
             cd->properties,             cd->properties,
             cd->numProperties * sizeof(MI_PropertyDecl),              cd->numProperties * sizeof(MI_PropertyDecl*),
             cap * sizeof(MI_PropertyDecl),              cap * sizeof(MI_PropertyDecl*),
             CALLSITE);             CALLSITE);
  
         if (!data)         if (!data)
Line 1498 
Line 1714 
         /* MI_PropertyDecl.flags */         /* MI_PropertyDecl.flags */
         pd->flags = flags;         pd->flags = flags;
  
         /* MI_PropertyDecl.code */  
         pd->code = Hash(name);  
   
         /* MI_PropertyDecl.name */         /* MI_PropertyDecl.name */
         pd->name = BStrdup(self->batch, name, CALLSITE);         pd->name = BStrdup(self->batch, name, CALLSITE);
  
         if (!pd->name)         if (!pd->name)
             MI_RETURN(MI_RESULT_FAILED);             MI_RETURN(MI_RESULT_FAILED);
  
           /* MI_PropertyDecl.code */
           pd->code = Hash(pd->name);
   
         /* MI_PropertyDecl.type */         /* MI_PropertyDecl.type */
         pd->type = type;         pd->type = type;
  
Line 1536 
Line 1752 
  
 MI_Result MI_CALL __MI_Instance_SetElement( MI_Result MI_CALL __MI_Instance_SetElement(
     MI_Instance* self_,     MI_Instance* self_,
     const MI_Char* name,      const ZChar* name,
     const MI_Value* value,     const MI_Value* value,
     MI_Type type,     MI_Type type,
     MI_Uint32 flags)     MI_Uint32 flags)
Line 1589 
Line 1805 
     /* Set the value */     /* Set the value */
     {     {
         MI_Result r = Field_Set(         MI_Result r = Field_Set(
             (Field*)((char*)self + pd->offset),              (Field*)field,
             pd->type,             pd->type,
             value,             value,
             flags,             flags,
Line 1604 
Line 1820 
  
 MI_Result MI_CALL __MI_Instance_GetElement( MI_Result MI_CALL __MI_Instance_GetElement(
     const MI_Instance* self_,     const MI_Instance* self_,
     const MI_Char* name,      const ZChar* name,
     MI_Value* valueOut,     MI_Value* valueOut,
     MI_Type* typeOut,     MI_Type* typeOut,
     MI_Uint32* flagsOut,     MI_Uint32* flagsOut,
Line 1639 
Line 1855 
 MI_Result MI_CALL __MI_Instance_GetElementAt( MI_Result MI_CALL __MI_Instance_GetElementAt(
     const MI_Instance* self_,     const MI_Instance* self_,
     MI_Uint32 index,     MI_Uint32 index,
     const MI_Char** nameOut,      const ZChar** nameOut,
     MI_Value* valueOut,     MI_Value* valueOut,
     MI_Type* typeOut,     MI_Type* typeOut,
     MI_Uint32* flagsOut)     MI_Uint32* flagsOut)
Line 1669 
Line 1885 
     if (valueOut)     if (valueOut)
         memcpy(valueOut, field, Type_SizeOf((MI_Type)pd->type));         memcpy(valueOut, field, Type_SizeOf((MI_Type)pd->type));
  
     /* Set existsOut */      /* Set flagsOut */
     if (flagsOut)     if (flagsOut)
     {     {
         *flagsOut = pd->flags;          MI_Uint8 fieldFlags = 0;
           *flagsOut = pd->flags & ~(MI_FLAG_NULL | MI_FLAG_NOT_MODIFIED);
  
         if (!Field_GetExists(field, (MI_Type)pd->type))         if (!Field_GetExists(field, (MI_Type)pd->type))
             *flagsOut |= MI_FLAG_NULL;             *flagsOut |= MI_FLAG_NULL;
   
           /* get the field flags */
           switch ((MI_Type)pd->type)
           {
               case MI_UINT8:
               case MI_SINT8:
               case MI_BOOLEAN:
               {
                   MI_Uint8Field* f = (MI_Uint8Field*)field;
                   fieldFlags = f->flags;
                   break;
               }
               case MI_UINT16:
               case MI_SINT16:
               case MI_CHAR16:
               {
                   MI_Uint16Field* f = (MI_Uint16Field*)field;
                   fieldFlags = f->flags;
                   break;
               }
               case MI_UINT32:
               case MI_SINT32:
               case MI_REAL32:
               {
                   MI_Uint32Field* f = (MI_Uint32Field*)field;
                   fieldFlags = f->flags;
                   break;
               }
               case MI_UINT64:
               case MI_SINT64:
               case MI_REAL64:
               {
                   MI_Uint64Field* f = (MI_Uint64Field*)field;
                   fieldFlags = f->flags;
                   break;
               }
               case MI_DATETIME:
               {
                   MI_DatetimeField* f = (MI_DatetimeField*)field;
                   fieldFlags = f->flags;
                   break;
               }
               case MI_STRING:
               {
                   MI_StringField* f = (MI_StringField*)field;
                   fieldFlags = f->flags;
                   break;
               }
               case MI_INSTANCE:
               case MI_REFERENCE:
               {
                   MI_InstanceField* f = (MI_InstanceField*)field;
                   fieldFlags = f->flags;
                   break;
               }
               case MI_BOOLEANA:
               case MI_UINT8A:
               case MI_SINT8A:
               case MI_UINT16A:
               case MI_SINT16A:
               case MI_UINT32A:
               case MI_SINT32A:
               case MI_UINT64A:
               case MI_SINT64A:
               case MI_REAL32A:
               case MI_REAL64A:
               case MI_CHAR16A:
               case MI_DATETIMEA:
               case MI_INSTANCEA:
               case MI_REFERENCEA:
               case MI_STRINGA:
               {
                   MI_StringAField* f = (MI_StringAField*)field;
                   fieldFlags = f->flags;
                   break;
               }
           }
           if ((fieldFlags & _MODIFIED) == 0)
           {
               *flagsOut |= MI_FLAG_NOT_MODIFIED;
           }
     }     }
  
     /* Set typeOut */     /* Set typeOut */
Line 1687 
Line 1985 
  
 MI_Result MI_CALL __MI_Instance_ClearElement( MI_Result MI_CALL __MI_Instance_ClearElement(
     MI_Instance* self_,     MI_Instance* self_,
     const MI_Char* name)      const ZChar* name)
 { {
     Instance* self = _SelfOf(self_);     Instance* self = _SelfOf(self_);
     MI_Uint32 index;     MI_Uint32 index;
Line 1728 
Line 2026 
     field = (char*)self + pd->offset;     field = (char*)self + pd->offset;
  
     /* Clear the value */     /* Clear the value */
     Field_Clear((Field*)((char*)self + pd->offset), pd->type,      Field_Clear((Field*)field, pd->type,
         self->batch);         self->batch);
  
     MI_RETURN(MI_RESULT_OK);     MI_RETURN(MI_RESULT_OK);
 } }
  
 MI_Result MI_CALL Instance_Print(  MI_Result MI_CALL __MI_Instance_GetServerName(
     const MI_Instance* self_,     const MI_Instance* self_,
     FILE* os,      const ZChar** servername)
     MI_Uint32 level,  
     MI_Boolean showNulls)  
 { {
     Instance* self = _SelfOf(self_);     Instance* self = _SelfOf(self_);
     const MI_ClassDecl* cd = self->classDecl;  
     MI_Uint32 i;  
  
     /* Check for null arguments */  
     if (!self)     if (!self)
         MI_RETURN(MI_RESULT_INVALID_PARAMETER);         MI_RETURN(MI_RESULT_INVALID_PARAMETER);
  
     /* Print nameSpace and className */      if (servername)
     if (self->nameSpace)          *servername = self->serverName;
   
       MI_RETURN(MI_RESULT_OK);
   }
   
   MI_Result MI_CALL __MI_Instance_SetServerName(
       _Inout_ MI_Instance* self_,
       _In_z_ const ZChar* serverName)
   {
       Instance* self = _SelfOf(self_);
       Instance* selfOrg = (Instance*)self_;
       MI_Char* oldServerName;
   
       /* Check parameters */
       if (!self)
           MI_RETURN(MI_RESULT_INVALID_PARAMETER);
   
       /* Save old namespace */
       oldServerName = self->serverName;
   
       /* Set new namespace */
       if (serverName)
     {     {
         Indent(os, level);          MI_Char* tmp;
         Fzprintf(os, T("instance of %s:%s\n"), self->nameSpace, cd->name);  
           tmp = BStrdup(self->batch, serverName, CALLSITE);
   
           if (!tmp)
               MI_RETURN(MI_RESULT_SERVER_LIMITS_EXCEEDED);
   
           self->serverName = tmp;
     }     }
     else     else
     {          self->serverName = NULL;
         Indent(os, level);  
         Fzprintf(os, T("instance of %s\n"), cd->name);      if (selfOrg != self)
           selfOrg->serverName = self->serverName;
   
       /* Free old namespace */
       if (oldServerName)
           BFree(self->batch, oldServerName, CALLSITE);
   
       MI_RETURN(MI_RESULT_OK);
     }     }
  
     Indent(os, level);  MI_Result MI_CALL __MI_Instance_GetClass(
     Fzprintf(os, T("{\n"));      _In_ const MI_Instance* self_,
     level++;      _Outptr_ MI_Class** instanceClass)
   {
       Instance* self = _SelfOf(self_);
   
       return Class_New(self->classDecl, self->nameSpace, self->serverName, instanceClass);
   }
  
     /* Print the properties */  MI_Result MI_CALL MI_Instance_GetClassExt(
     for (i = 0; i < cd->numProperties; i++)      _In_ const MI_Instance *self,
       _Inout_ MI_Class* classToGet)
     {     {
         const MI_PropertyDecl* pd = cd->properties[i];      if ((self == NULL) || (classToGet == NULL))
         const Field* field = (Field*)((char*)self + pd->offset);          MI_RETURN(MI_RESULT_INVALID_PARAMETER);
  
         if (showNulls || Field_GetExists(field, pd->type))      return Class_Construct(classToGet, self->classDecl);
   }
   
   MI_Result Instance_SetElementArray(
       _Out_ MI_Instance* self_,
       _In_z_ const MI_Char* name,
       MI_Type type,
       MI_Uint32 flags,
       MI_Uint32 numberArrayItems,
       _Out_ MI_Uint32 *elementId
       )
         {         {
             Indent(os, level);      MI_Result result;
       Instance* self = _SelfOf(self_);
       MI_Uint32 index;
       MI_ArrayField *fieldValue;
       MI_Value nullValue;
   
       //Find the ID of the entry
       /* Check for null arguments */
       if (!self || !name)
           MI_RETURN(MI_RESULT_INVALID_PARAMETER);
   
       /* Find the property with this name */
       index = _FindPropertyDeclIndex(self->classDecl, name);
  
             if (pd->flags & MI_FLAG_KEY)      if (index == (MI_Uint32)-1)
                 Fzprintf(os, T("[Key] "));          MI_RETURN(MI_RESULT_NO_SUCH_PROPERTY);
  
             Fzprintf(os, T("%s="), pd->name);      //SetElementAt with NULL value
       nullValue.array.data = NULL;
       nullValue.array.size = 0;
       result = __MI_Instance_SetElementAt(self_, index, &nullValue, type|MI_ARRAY, flags);
       if (result != MI_RESULT_OK)
       {
           return result;
       }
  
             Field_Print(field, os, pd->type, level);      //Get the array field
       fieldValue = (MI_ArrayField*)((char*)self + self->classDecl->properties[index]->offset);
  
             if (pd->type == MI_INSTANCE || pd->type == MI_REFERENCE)      //Allocate the element array
       fieldValue->value.size = 0;  //We set the size as 0, but as items are added the number is increased
       if (numberArrayItems)
       {
           fieldValue->value.data = Batch_Get(self->batch, numberArrayItems*Type_SizeOf(type));
           if (fieldValue->value.data == NULL)
             {             {
                 if (!field->instance.value)              return MI_RESULT_SERVER_LIMITS_EXCEEDED;
                     fputc('\n', os);          }
             }             }
             else             else
                 fputc('\n', os);      {
           fieldValue->value.data = NULL;
         }         }
       *elementId = index;
       return MI_RESULT_OK;
     }     }
  
     level--;  MI_Result Instance_SetElementArrayItem(
     Indent(os, level);      _Out_ MI_Instance* self_,
       MI_Uint32 elementId,
       MI_Value value)
   {
       Instance* self = _SelfOf(self_);
       MI_ArrayField *fieldValue;
       MI_Type type;
       MI_Result result;
  
     Fzprintf(os, T("}\n"));      type = (MI_Type)(self->classDecl->properties[elementId]->type & ~16); //Remove array part of type;
  
     MI_RETURN(MI_RESULT_OK);      fieldValue = (MI_ArrayField*)((char*)self + self->classDecl->properties[elementId]->offset);
   
       result = Class_Clone_ArrayValue(self->batch, type, fieldValue->value.data, fieldValue->value.size, &value);
       if (result != MI_RESULT_OK)
           return result;
   
       //Bump how many array items we have in value
       fieldValue->value.size++;
       fieldValue->exists = MI_TRUE;
   
       return MI_RESULT_OK;
 } }
  
 MI_Result MI_CALL __MI_Instance_GetServerName(  MI_Boolean Instance_IsDynamic(
     const MI_Instance* self,      _In_ MI_Instance *self_)
     const MI_Char** name)  
 { {
     MI_RETURN(MI_RESULT_NOT_SUPPORTED);      Instance* self = _SelfOf(self_);
       if (self != (void*)self_)
           return MI_TRUE;
       else
           return MI_FALSE;
 } }
  
 MI_Result MI_CALL __MI_Instance_SetServerName(  /*
     _Inout_ MI_Instance* self,   * Verifies that all key properties of the instance have non-NULL values.  A
     _In_z_ const MI_Char* name)   * NULL key property means that it is a malformed instance.
    *
    * Note: __MI_Instance_* functions are used in case the provided instance
    *       does not have a function table.
    */
   MI_Boolean Instance_ValidateNonNullKeys(
       const MI_Instance* self )
 { {
     MI_RETURN(MI_RESULT_NOT_SUPPORTED);      MI_Uint32 i = 0;
 }  
  
 MI_Result MI_CALL __MI_Instance_GetClass(      if (Instance_IsDynamic((MI_Instance*)self))
     _In_ const MI_Instance* self,      {
     _Outptr_ MI_Class** instanceClass)          /* Dynamic instance
            * Since it doesn't have a MI_ClassDecl, the best we can do is to
            * validate whether all of its key properties are non-NULL. */
           MI_Uint32 count = 0;
           MI_Result result = __MI_Instance_GetElementCount( self, &count );
           if (MI_RESULT_OK != result)
               return MI_FALSE;
           for (i = 0; i < count; i++)
 { {
     MI_RETURN(MI_RESULT_NOT_SUPPORTED);              MI_Uint32 flags = 0;
               MI_Result result = __MI_Instance_GetElementAt( self, i, NULL, NULL, NULL, &flags );
               if (MI_RESULT_OK != result)
                   return MI_FALSE;
               if ((MI_FLAG_KEY & flags) &&
                   (MI_FLAG_NULL & flags))
                   return MI_FALSE;
 } }
           return MI_TRUE;
 MI_Result MI_CALL __MI_Instance_Print(      }
     const MI_Instance* self,      else
     FILE* os,      {
     MI_Uint32 level)          /* Static instance
            * Validate that each key property is non-NULL */
           const MI_ClassDecl* cd = self->classDecl;
           for (i = 0; i < cd->numProperties; i++)
 { {
     return Instance_Print(self, os, level, MI_TRUE);              if (cd->properties[i]->flags & MI_FLAG_KEY)
               {
                   MI_Uint32 flags = 0;
                   MI_Result result = __MI_Instance_GetElementAt( self, i, NULL, NULL, NULL, &flags );
                   if (MI_RESULT_OK != result)
                       return MI_FALSE;
                   if (MI_FLAG_NULL & flags)
                       return MI_FALSE;
               }
 } }
           return MI_TRUE;
       }
   }
   
  
 MI_InstanceFT __mi_instanceFT = MI_InstanceFT __mi_instanceFT =
 { {
Line 1848 
Line 2272 
     __MI_Instance_GetServerName,     __MI_Instance_GetServerName,
     __MI_Instance_SetServerName,     __MI_Instance_SetServerName,
     __MI_Instance_GetClass,     __MI_Instance_GetClass,
     __MI_Instance_Print,  
 }; };


Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

ViewCVS 0.9.2