blob: 2d061bf493c1b30b70da0cec39f923f6849484b0 [file] [log] [blame]
/*!
\file property.c
\brief Native property implementation.
This module implements a native property, which is not public to any
provider programmer. It is used to implement various other data types
natively, such as instances, object-paths and args.
It provides means to maintain linked lists of named properties including
functionality to add, remove, clone and release them.
(C) Copyright IBM Corp. 2003
THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
You can obtain a current copy of the Eclipse Public License from
http://www.opensource.org/licenses/eclipse-1.0.php
\author Frank Scheffler
$Revision: 1.5 $
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cmcidt.h"
#include "cmcift.h"
#include "cmcimacs.h"
#include "native.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
//! Storage container for commonly needed data within native CMPI data types.
/*!
This structure is used to build linked lists of data containers as needed
for various native data types.
*/
/****************************************************************************/
static CMPIData __convert2CMPIData ( struct native_property * prop,
CMPIString ** propname )
{
CMPIData result = { 0, CMPI_nullValue, {0} };
if ( prop != NULL ) {
result.type = prop->type;
result.state = prop->state;
result.value = prop->value;
if ( propname ) {
*propname = native_new_CMPIString ( prop->name,
NULL );
}
}
return result;
}
/**
* returns non-zero if already existant
*/
static int __addProperty ( struct native_property ** prop,
const char * name,
CMPIType type,
CMPIValueState state,
CMPIValue * value )
{
CMPIStatus rc;
if ( *prop == NULL ) {
struct native_property * tmp = *prop =
(struct native_property *) calloc ( 1, sizeof ( struct native_property ) );
tmp->qualifiers = NULL;
tmp->name = strdup ( name );
tmp->type = type;
tmp->state = state;
if ( type != CMPI_null && state != CMPI_nullValue) {
if ( type == CMPI_chars ) {
tmp->type = CMPI_string;
tmp->value.string = native_new_CMPIString ( (char *) value, &rc );
}
else tmp->value = native_clone_CMPIValue ( type, value, &rc );
}
else {
tmp->state = CMPI_nullValue;
tmp->value.uint64=0;
}
return 0;
}
return ( strcasecmp ( (*prop)->name, name ) == 0 ||
__addProperty ( &( (*prop)->next ), name, type, state, value ) );
}
/**
* returns -1 if non-existant
*/
static int __setProperty ( struct native_property * prop,
const char * name,
CMPIType type,
CMPIValue * value )
{
CMPIStatus rc;
if ( prop == NULL ) return -1;
if ( strcasecmp ( prop->name, name ) == 0 ) {
if ( ! ( prop->state & CMPI_nullValue ) )
native_release_CMPIValue ( prop->type, &prop->value );
prop->type = type;
if ( type == CMPI_chars ) {
prop->type = CMPI_string;
prop->value.string = native_new_CMPIString ( (char *) value, &rc );
}
else {
if ( type != CMPI_null && value != NULL)
prop->value = native_clone_CMPIValue ( type, value, &rc );
else prop->state = CMPI_nullValue;
}
return 0;
}
return __setProperty ( prop->next, name, type, value);
}
static struct native_property * __getProperty ( struct native_property * prop,
const char * name )
{
if ( ! prop || ! name ) {
return NULL;
}
return ( strcasecmp ( prop->name, name ) == 0 )?
prop: __getProperty ( prop->next, name );
}
static CMPIData __getDataProperty ( struct native_property * prop,
const char * name,
CMPIStatus * rc )
{
struct native_property * p = __getProperty ( prop, name );
CMSetStatus( rc, ( p ) ? CMPI_RC_OK : CMPI_RC_ERR_NO_SUCH_PROPERTY );
return __convert2CMPIData ( p, NULL );
}
static struct native_qualifier *__getDataPropertyQualifiers ( struct native_property * prop,
const char * name,
CMPIStatus * rc )
{
struct native_property * p = __getProperty ( prop, name );
CMSetStatus( rc, ( p ) ? CMPI_RC_OK : CMPI_RC_ERR_NO_SUCH_PROPERTY );
return p ? p->qualifiers : NULL;
}
static struct native_property * __getPropertyAt( struct native_property * prop,
unsigned int pos )
{
if ( ! prop ) {
return NULL;
}
return ( pos == 0 )?
prop: __getPropertyAt ( prop->next, --pos );
}
static CMPIData __getDataPropertyAt ( struct native_property * prop,
unsigned int pos,
CMPIString ** propname,
CMPIStatus * rc )
{
struct native_property * p = __getPropertyAt ( prop, pos );
CMSetStatus ( rc, ( p ) ? CMPI_RC_OK : CMPI_RC_ERR_NO_SUCH_PROPERTY );
return __convert2CMPIData ( p, propname );
}
static CMPICount __getPropertyCount ( struct native_property * prop,
CMPIStatus * rc )
{
CMPICount c = 0;
CMSetStatus ( rc, CMPI_RC_OK );
while ( prop != NULL ) {
c++;
prop = prop->next;
}
return c;
}
static void __release ( struct native_property * prop )
{
struct native_property * next;
for ( ; prop; prop = next ) {
free ( prop->name );
if(prop->state != CMPI_nullValue)
native_release_CMPIValue ( prop->type, &prop->value );
qualifierFT.release(prop->qualifiers);
next=prop->next;
free ( prop );
}
}
static struct native_property * __clone ( struct native_property * prop,
CMPIStatus * rc )
{
struct native_property * result;
CMPIStatus tmp;
if ( prop == NULL ) {
CMSetStatus ( rc, CMPI_RC_OK );
return NULL;
}
result = (struct native_property * )
calloc ( 1, sizeof ( struct native_property ) );
result->name = strdup ( prop->name );
result->type = prop->type;
result->state = prop->state;
if (prop->state != CMPI_nullValue
&& prop->state != CMPI_badValue) {
result->value = native_clone_CMPIValue ( prop->type,
&prop->value,
&tmp );
if ( tmp.rc != CMPI_RC_OK ) {
result->state = CMPI_nullValue;
}
}
result->qualifiers = qualifierFT.clone ( prop->qualifiers, rc );
result->next = __clone ( prop->next, rc );
return result;
}
/**
* Global function table to access native_property helper functions.
*/
struct native_propertyFT const propertyFT = {
NATIVE_FT_VERSION,
__release,
__clone,
__getProperty,
__addProperty,
__setProperty,
__getDataProperty,
__getDataPropertyAt,
__getPropertyCount,
__getDataPropertyQualifiers
};
/****************************************************************************/
/*** Local Variables: ***/
/*** mode: C ***/
/*** c-basic-offset: 8 ***/
/*** End: ***/