blob: 92cc2985f6bf016c2054461ff4d0da16cb5eb353 [file] [log] [blame]
/*!
\file qualifier.c
\brief Native qualifier implementation.
This module implements a native qualifier, 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.3 $
*/
#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.
*/
// struct native_qualifier {} // defined in frontend/sfcc/native.h
/****************************************************************************/
static CMPIData __convert2CMPIData ( struct native_qualifier * qual,
CMPIString ** qualname )
{
CMPIData result = { 0, CMPI_nullValue, {0} };
if ( qual != NULL ) {
result.type = qual->type;
result.state = qual->state;
result.value = qual->value;
if ( qualname ) {
*qualname = native_new_CMPIString ( qual->name,
NULL );
}
}
return result;
}
/**
* returns non-zero if already existant
*/
static int __addQualifier ( struct native_qualifier ** qual,
const char * name,
CMPIType type,
CMPIValueState state,
CMPIValue * value )
{
CMPIStatus rc;
if ( *qual == NULL ) {
struct native_qualifier * tmp = *qual =
(struct native_qualifier *) calloc ( 1, sizeof ( struct native_qualifier ) );
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 ( (*qual)->name, name ) == 0 ||
__addQualifier ( &( (*qual)->next ), name, type, state, value ) );
}
/**
* returns -1 if non-existant
*/
static int __setQualifier ( struct native_qualifier * qual,
const char * name,
CMPIType type,
CMPIValue * value )
{
CMPIStatus rc;
if ( qual == NULL ) return -1;
if ( strcasecmp ( qual->name, name ) == 0 ) {
if ( ! ( qual->state & CMPI_nullValue ) )
native_release_CMPIValue ( qual->type, &qual->value );
qual->type = type;
if ( type == CMPI_chars ) {
qual->type = CMPI_string;
qual->value.string = native_new_CMPIString ( (char *) value, &rc );
}
else {
if ( type != CMPI_null )
qual->value = native_clone_CMPIValue ( type, value, &rc );
else qual->state = CMPI_nullValue;
}
return 0;
}
return __setQualifier ( qual->next, name, type, value);
}
static struct native_qualifier * __getQualifier ( struct native_qualifier * qual,
const char * name )
{
if ( ! qual || ! name ) {
return NULL;
}
return ( strcasecmp ( qual->name, name ) == 0 )?
qual: __getQualifier ( qual->next, name );
}
static CMPIData __getDataQualifier ( struct native_qualifier * qual,
const char * name,
CMPIStatus * rc )
{
struct native_qualifier * p = __getQualifier ( qual, name );
CMSetStatus( rc, ( p ) ? CMPI_RC_OK : CMPI_RC_ERR_FAILED );
return __convert2CMPIData ( p, NULL );
}
static struct native_qualifier * __getQualifierAt ( struct native_qualifier * qual,
unsigned int pos )
{
if ( ! qual ) {
return NULL;
}
return ( pos == 0 )?
qual: __getQualifierAt ( qual->next, --pos );
}
static CMPIData __getDataQualifierAt ( struct native_qualifier * qual,
unsigned int pos,
CMPIString ** qualname,
CMPIStatus * rc )
{
struct native_qualifier * p = __getQualifierAt ( qual, pos );
CMSetStatus( rc, ( p ) ? CMPI_RC_OK : CMPI_RC_ERR_NO_SUCH_PROPERTY );
return __convert2CMPIData ( p, qualname );
}
static CMPICount __getQualifierCount ( struct native_qualifier * qual,
CMPIStatus * rc )
{
CMPICount c = 0;
CMSetStatus ( rc, CMPI_RC_OK );
while ( qual != NULL ) {
c++;
qual = qual->next;
}
return c;
}
static void __release ( struct native_qualifier * qual )
{
struct native_qualifier *next;
for ( ; qual; qual = next ) {
free ( qual->name );
native_release_CMPIValue ( qual->type, &qual->value );
next = qual->next;
free ( qual );
}
}
static struct native_qualifier * __clone ( struct native_qualifier * qual,
CMPIStatus * rc )
{
struct native_qualifier * result;
CMPIStatus tmp;
if ( qual == NULL ) {
CMSetStatus ( rc, CMPI_RC_OK );
return NULL;
}
result = (struct native_qualifier * )
calloc ( 1, sizeof ( struct native_qualifier ) );
result->name = strdup ( qual->name );
result->type = qual->type;
result->state = qual->state;
result->value = native_clone_CMPIValue ( qual->type,
&qual->value,
&tmp );
if ( tmp.rc != CMPI_RC_OK ) {
result->state = CMPI_nullValue;
}
result->next = __clone ( qual->next, rc );
return result;
}
/**
* Global function table to access native_qualifier helper functions.
*/
struct native_qualifierFT const qualifierFT = {
NATIVE_FT_VERSION,
__release,
__clone,
__addQualifier,
__setQualifier,
__getDataQualifier,
__getDataQualifierAt,
__getQualifierCount
};
/****************************************************************************/
/*** Local Variables: ***/
/*** mode: C ***/
/*** c-basic-offset: 8 ***/
/*** End: ***/