/*!
  \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:              ***/
