version 1.3, 2015/04/20 18:10:09
|
version 1.4, 2015/04/20 18:19:49
|
|
|
#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> |
|
|
| |
/* | /* |
**============================================================================== | **============================================================================== |
|
|
**============================================================================== | **============================================================================== |
*/ | */ |
| |
#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; |
|
|
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; |
|
|
| |
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++; |
} | } |
|
|
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); |
| |
|
|
| |
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, |
|
|
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; |
} | } |
| |
|
|
return data; | return data; |
} | } |
| |
static MI_ClassDecl* _CloneClassDecl( |
MI_ClassDecl* _CloneClassDecl( |
const MI_ClassDecl* cd, | const MI_ClassDecl* cd, |
Batch* batch) | Batch* batch) |
{ | { |
|
|
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; |
| |
|
|
| |
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; |
} | } |
| |
|
|
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; |
|
|
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, |
|
|
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 */ |
|
|
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, |
|
|
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_); |
|
|
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 */ |
|
|
{ | { |
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; |
| |
|
|
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; |
} | } |
} | } |
|
|
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; |
} | } |
} | } |
|
|
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; |
|
} |
|
} |
} | } |
} | } |
| |
|
|
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; |
} | } |
} | } |
|
|
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; |
} | } |
} | } |
|
|
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, |
|
|
| |
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; |
} | } |
| |
|
|
{ | { |
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, |
|
|
| |
if (!v.instancea.data) | if (!v.instancea.data) |
{ | { |
r = MI_RESULT_FAILED; |
r = MI_RESULT_SERVER_LIMITS_EXCEEDED; |
goto failed; | goto failed; |
} | } |
| |
|
|
| |
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) |
{ | { |
|
|
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; |
} | } |
| |
|
|
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; |
} | } |
} | } |
|
|
| |
if (r != MI_RESULT_OK) | if (r != MI_RESULT_OK) |
{ | { |
r = MI_RESULT_TYPE_MISMATCH; |
|
goto failed; | goto failed; |
} | } |
} | } |
|
|
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) |
{ | { |
|
|
} | } |
| |
/* 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++) |
|
|
| |
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) |
|
|
| |
/* 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 */ |
|
|
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_) |
{ | { |
|
|
goto failed; | goto failed; |
} | } |
| |
|
cd->owningClass = (MI_Class*) -1; /* Mark as a dynamic instance */ |
self->classDecl = cd; | self->classDecl = cd; |
} | } |
| |
|
|
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: */ |
{ | { |
|
|
return MI_TRUE; | return MI_TRUE; |
} | } |
| |
|
/* Get underline instance */ |
|
Instance* Instance_GetSelf( |
|
const MI_Instance* self) |
|
{ |
|
return _SelfOf( self ); |
|
} |
|
|
/* | /* |
**============================================================================== | **============================================================================== |
** | ** |
|
|
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); |
} | } |
| |
|
|
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) |
|
|
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); |
} | } |
|
|
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; |
} | } |
| |
|
|
| |
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_); |
| |
|
|
| |
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) |
|
|
/* 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); |
|
|
| |
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_); |
| |
|
|
| |
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) |
|
|
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) |
|
|
/* 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; |
| |
|
|
| |
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) |
|
|
/* 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, |
|
|
| |
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, |
|
|
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) |
|
|
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 */ |
|
|
| |
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; |
|
|
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 = |
{ | { |
|
|
__MI_Instance_GetServerName, | __MI_Instance_GetServerName, |
__MI_Instance_SetServerName, | __MI_Instance_SetServerName, |
__MI_Instance_GetClass, | __MI_Instance_GetClass, |
__MI_Instance_Print, |
|
}; | }; |