/*!
  \file array.c
  \brief Native CMPIArray implementation.

  This is the native CMPIArray implementation as used for remote
  providers. It reflects the well-defined interface of a regular
  CMPIArray object, however, it works independently from the management broker.
  
  It is part of a native broker implementation that simulates CMPI data
  types rather than interacting with the entities in a full-grown CIMOM.

  In contrast to a regular array, there exists an additional increase()
  method, which is only used by the native CMPIResult implementation to
  grow an array stepwise.

  (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.2 $
*/

#include <stdlib.h>
#include <string.h>
#include "cmcidt.h"
#include "cmcift.h"
#include "cmcimacs.h"
#include "native.h"

#ifdef DMALLOC
#include "dmalloc.h"
#endif

struct native_array_item {
  CMPIValueState state;
  CMPIValue      value;
};


struct native_array {
   CMPIArray array;
   CMPICount size, max, dynamic;
   CMPIType type;
   struct native_array_item * data;
};


static struct native_array * __new_empty_array ( CMPICount,
    CMPIType, CMPIStatus * );


/*****************************************************************************/

static void __make_NULL ( struct native_array * a,
     int from, int to, int release )
{
   for ( ; from <= to; from++ ) {
      a->data[from].state = CMPI_nullValue;

      if ( release ) {
         native_release_CMPIValue ( a->type, &a->data[from].value );
      }
   }
}

void native_array_increase_size(CMPIArray * array, CMPICount increment)
{
   struct native_array *a = (struct native_array *) array;

   if ((a->size+increment)>a->max) {
      if (a->size==0) a->max=8;
      else while ((a->size+increment)>a->max) a->max*=2;
      a->data = (struct native_array_item *)
         realloc(a->data, a->max * sizeof(struct native_array_item));
      memset(&a->data[a->size], 0, sizeof(struct native_array_item) * increment);
   }
   a->size += increment;
}


static CMPIStatus __aft_release ( CMPIArray * array )
{
   struct native_array * a = (struct native_array *) array;

   if ( a ) {

      int i = a->size;

      while ( i-- ) {
         if ( ! ( a->data[i].state & CMPI_nullValue ) ) {
            native_release_CMPIValue ( a->type, &a->data[i].value );
         }
      }

      free ( a->data );
      free ( a );

      CMReturn ( CMPI_RC_OK );
   }

   CMReturn ( CMPI_RC_ERR_FAILED );
}


static CMPIArray * __aft_clone ( CMPIArray * array, CMPIStatus * rc )
{
   CMPIStatus tmp;
   struct native_array * a   = (struct native_array *) array;
   struct native_array * new = __new_empty_array ( a->size, a->type, &tmp );

   int i = a->size;

   while ( i-- && tmp.rc == CMPI_RC_OK ) {
      new->data[i].state = a->data[i].state;
      if ( ! ( new->data[i].state & CMPI_nullValue ) ) {
         new->data[i].value = native_clone_CMPIValue ( a->type,
             &a->data[i].value, &tmp );
      }
   }

   CMSetStatus ( rc, tmp.rc );

   return (CMPIArray *) new;
}


static CMPICount __aft_getSize ( CMPIArray * array, CMPIStatus * rc )
{
   struct native_array * a = (struct native_array *) array;

   CMSetStatus ( rc, CMPI_RC_OK );
   return a->size;
}


static CMPIType __aft_getSimpleType ( CMPIArray * array, CMPIStatus * rc )
{
   struct native_array * a = (struct native_array *) array;

   CMSetStatus ( rc, CMPI_RC_OK );
   return a->type;
}


static CMPIData __aft_getElementAt ( CMPIArray * array, CMPICount index, CMPIStatus * rc )
{
   struct native_array * a = (struct native_array *) array;
   CMPIData result = { a->type, CMPI_badValue };

   if ( index < a->size ) {
      result.state = a->data[index].state;
      result.value = a->data[index].value;
   }

   CMSetStatus ( rc, CMPI_RC_OK );
   return result;
}


static CMPIStatus setElementAt ( CMPIArray * array, CMPICount index, CMPIValue * val,
       CMPIType type, int opt )
{
   struct native_array * a = (struct native_array *) array;

   if ( a->dynamic && index == a->size ) {
      native_array_increase_size(array, 1); 
   }
      
   if ( index < a->size ) {
      CMPIValue v;
      v.string=NULL;

      if ( type == CMPI_chars && a->type == CMPI_string ) {
	 if (val) {
	     v.string = native_new_CMPIString ( (char *) val->chars, NULL );
	     type = CMPI_string;
	     val  = &v;
	 } else {
	     type = CMPI_null;
	 }         
      }

      if ( type == CMPI_null ) {

         if ( ! ( a->data[index].state & CMPI_nullValue ) ) {
            __make_NULL ( a, index, index, 1 );
         }
         CMReturn ( CMPI_RC_OK );
      }

      if ( opt || type == a->type ) {

         CMPIStatus rc = {CMPI_RC_OK, NULL};

         a->data[index].state = 0;
	 a->data[index].value = (opt) ? 
			 *val : native_clone_CMPIValue ( type, val, &rc );
         if(v.string)
         	CMRelease(v.string);
         return rc;
      }
   }
   CMReturn ( CMPI_RC_ERR_FAILED );
}

static CMPIStatus __aft_setElementAt ( CMPIArray * array, CMPICount index, CMPIValue * val,
          CMPIType type )
{ 
   return setElementAt(array,index,val,type,0);
}


static struct native_array * __new_empty_array ( CMPICount size, CMPIType type,
      CMPIStatus * rc )
{
   static const CMPIArrayFT aft = {
      NATIVE_FT_VERSION,
      __aft_release,
      __aft_clone,
      __aft_getSize,
      __aft_getSimpleType,
      __aft_getElementAt,
      __aft_setElementAt
   };
   static const CMPIArray a = {
      "CMPIArray",
      (CMPIArrayFT*)&aft
   };

   struct native_array * array = (struct native_array *)
      calloc ( 1, sizeof ( struct native_array ) );

   array->array     = a;

   type        &= ~CMPI_ARRAY;
   array->type  = ( type == CMPI_chars )? CMPI_string: type;
   array->size  = size;
 
   if (array->size == 0) {
      array->max = 8;
      array->dynamic = 1;
   }
   else {
      array->max = array->size;
      array->dynamic = 0;
   }    
     
   array->data  = (struct native_array_item *) 
      calloc ( 1, array->max * sizeof ( struct native_array_item ) );

   __make_NULL ( array, 0, array->max - 1, 0 );

   CMSetStatus ( rc, CMPI_RC_OK );
   return array;
}


CMPIArray * native_new_CMPIArray ( CMPICount size, CMPIType type, CMPIStatus * rc )
{
   return (CMPIArray *) __new_empty_array ( size, type, rc );
}

CMPIStatus simpleArrayAdd(CMPIArray * array, CMPIValue * val, CMPIType type)
{
   struct native_array * a = (struct native_array *) array;
   if (a->dynamic) {
      if (a->size == 0) a->type = type;
      setElementAt(array, a->size, val, type,1);
   }   
   CMReturn ( CMPI_RC_ERR_FAILED );
} 

/****************************************************************************/

/*** Local Variables:  ***/
/*** mode: C           ***/
/*** c-basic-offset: 8 ***/
/*** End:              ***/
