pdirt/data/
pdirt/data/HELP/
pdirt/data/HELP/0/
pdirt/data/HELP/F/
pdirt/data/HELP/G/
pdirt/data/HELP/H/
pdirt/data/HELP/J/
pdirt/data/HELP/K/
pdirt/data/HELP/O/
pdirt/data/HELP/Q/
pdirt/data/HELP/R/
pdirt/data/HELP/U/
pdirt/data/HELP/V/
pdirt/data/HELP/Y/
pdirt/data/HELP/Z/
pdirt/data/MESSAGES/
pdirt/data/POWERINFO/
pdirt/data/WIZ_ZONES/
pdirt/drv/
pdirt/drv/bin/
pdirt/drv/compiler/converter/
pdirt/drv/compiler/libs/
pdirt/drv/compiler/scripts/
pdirt/drv/include/AberChat/
pdirt/drv/include/InterMud/
pdirt/drv/include/machine/
pdirt/drv/src/InterMud/
pdirt/drv/src/Players/
pdirt/drv/utils/UAFPort/
pdirt/drv/utils/dnsresolv/
pdirt/drv/utils/gdbm/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define __DPRIVATE
#include "InterMud/darray.h"
#define MAX(a,b) ( (a) > (b) ? (a) : (b) )

/*
 * __resize
 *  This function will resize a dynamic array to the given
 *  size.  Note that data may be lost if the size is shrunk.
 */
static void __resize( pdarray array, int newSize)
{
  void **pBlock;

  int copySize = ( newSize < array->size ) ? newSize : array->size;
  int index;

  if( newSize > 0)
    {
      pBlock = (void**)malloc( sizeof( void* ) * newSize );
      memcpy( pBlock, array->dataBlock, sizeof( void* ) * copySize );
      if( newSize > array->size )
        {
          for( index = array->size;
               index < newSize;
               index++) 
            pBlock[ index ] = NULL;
        }
    }
  else pBlock = NULL;

  free( array->dataBlock );
  array->dataBlock = pBlock;
  array->size = newSize; 
}

/*
 *
 * __compact
 *
 *  This function removes all NULL valued entries from 
 *  an array.  Used as a precussor to sorting, and to act
 *  as garbage collection.
 */
static void __compact( pdarray array )
{
  int index, count;

  for( index = 0, count = 0; index < array->size; index++ )
    if( array->dataBlock[ index ] != NULL ) count++;

  if( count != array->size  && count > 0)
    {
      void **pBlock = (void**)malloc( sizeof( void* ) * count );
      int newIndex;

      for( newIndex = 0, index = 0; 
           index < array->size && newIndex < count;
           index++ )
        if( array->dataBlock[ index ] != NULL ) 
          pBlock[ newIndex++ ] = array->dataBlock[ index ];
      free( array->dataBlock );
      array->dataBlock = pBlock;
      array->size = count;
    }
  
}

/*
 *
 * newArray
 *
 *  Creates and returns a dynamic array object.  sort
 *  is a function with the prototype:
 * 	int comFunc(const void* a, const void* b)
 *  which is used to compare to objects during sorting,
 *  see the man page on qsort for info on the ordering of
 *  arguments.
 *
 *  search is also of type comFunc, but the first item will
 *  be an obejct of the type that the list is made up of,
 *  the second item will be the key you are searching on.
 *  (note: the implimentaions of these search functions may
 *   need to do typecasting.)
 *
 *  size is the initali size of the array
 * 
 *  step is the initial increment for automatically growing the array.
 *
 */
pdarray newArray(int size, int step, comFunc *sort, comFunc *search)
{
  int index;
  darray *narray = (pdarray)malloc( sizeof(darray) );

  narray->dataBlock = (void**)malloc( sizeof(void*) * size );
  narray->size = size;
  narray->step = step;
  narray->dirty = 0;
  narray->sortFunc = sort;
  narray->searchFunc = search;

  for( index = 0; index < size; index++ )
    {
      narray->dataBlock[ index ] = NULL;
    }

  return narray;
}

/*
 *
 * delArray
 *
 *   Frees all data associated with a dynamic array object.
 */
void delArray(pdarray array)
{
  if( array ) 
    {
      if( array->dataBlock ) 
	free( array->dataBlock );
      free( array );
    }
}

/*
 *
 * arrayGet
 *
 *  Gets an item out of a dynamic array at the given index.
 *  Useful for stepping through an array.
 */
void* arrayGet(pdarray array, int index)
{
  if( index < 0 || index >= array->size )
    {
      return NULL;
    }

  return array->dataBlock[ index ];
}

/*
 *
 * arraySet
 *
 *  Set's the value of a given index in the array.
 */
void* arraySet(pdarray array, int index, void *newVal)
{
  if( index < 0 || index >= array->size )
    {
      return NULL;
    }

  array->dirty = 1;
  return array->dataBlock[ index ] = newVal;
}

/*
 *
 * arrayAdd
 *
 *  Adds a value to the arary, resizing the array if necessary.
 */
void* arrayAdd(pdarray array, void* info)
{
  int index,origSize;

  array->dirty = 1;
  origSize = array->size;

  if( (array->size == 0 ) || array->dataBlock[ array->size - 1 ] != NULL ) 
    {
      __resize( array, array->size + array->step );
      return array->dataBlock[ origSize ] = info;
    }

  for( index = MAX( 0, array->size - array->step );
       index < array->size;
       index++ )
    {
      if( array->dataBlock[ index ] == NULL ) 
      {
        return array->dataBlock[ index ] = info; 
      }
    }
  __resize( array, array->size + array->step );
  fprintf(stderr,"DEBUG::::::RESIZE TWO\n");
  return array->dataBlock[ origSize ] = info;
}

/*
 *
 * arrayRemove
 *
 *  Remove's an item from the array.
 */

void* arrayRemove(pdarray array, void* info)
{
  int index;

  array->dirty = 1;
  
  for( index = 0;
       index < array->size;
       index++ )
    {
      if( array->dataBlock[ index ] == info )
        return array->dataBlock[ index ] = NULL;
    } 
  return info;
}

/*
 *
 * arrayLFindWith
 *
 *  Finds an item doing a linear, as opposed to a binary,
 *  search.  This allows searching in a list that hasn't
 *  been sorted yet, to avoid overhead of continuously sorting
 *  the list.  (I.e. adding an item, sorting it, looking for something,
 *  adding an item, sorting it, looking for something, etc... )
 *  Note: this variant on arrayLFind uses a user defined search function.
 */

void* arrayLFindWith(pdarray array, void* key, comFunc *search)
{
  int index;

  if( array->size > 0 )
    {
      for( index = 0; index < array->size; index++ )
        {
          if( array->dataBlock[ index ] )
            {
              if( search( &key, &( array->dataBlock[ index ] ) ) )
                continue;
              return array->dataBlock[ index ];
            }
        }
    }
  return NULL;
}

/*
 *
 * arrayLFind
 *
 *  Finds an item doing a linear, as opposed to a binary,
 *  search.  This allows searching in a list that hasn't
 *  been sorted yet, to avoid overhead of continuously sorting
 *  the list.  (I.e. adding an item, sorting it, looking for something,
 *  adding an item, sorting it, looking for something, etc... )
 */

void* arrayLFind(pdarray array, void* key)
{
  int index;

  if( array->size > 0 )
    {
      for( index = 0; index < array->size; index++ )
        {
          if( array->dataBlock[ index ] )
            {
              if( array->searchFunc( &key, &( array->dataBlock[ index ] ) ) )
                continue;
              return array->dataBlock[ index ];
            }
        }
    }
  return NULL;
}

/*
 *
 * arrayFindWith
 *
 *  Does a binary search on the array to find the given item
 *  based on the key using the given search function.
 */

void* arrayFindWith(pdarray array, void* key, comFunc *search)
{
  void** temp;

  if( array->size == 0 ) return NULL;
  if( array->dirty )
    arraySort(array);
  temp = (void**)bsearch( &key,
                          array->dataBlock,
                          array->size,
                          sizeof( void* ),
                          search );
  if( temp != NULL )
    return *temp;
  return NULL;
}

/*
 *
 * arrayFind
 *
 *  Does a binary search on the array to find the given item
 *  based on the key.
 */
void* arrayFind(pdarray array, void* key)
{
  void** temp;

  if( array->size == 0 ) return NULL;
  if( array->dirty )
    arraySort(array);
  temp = (void**)bsearch( &key,
                          array->dataBlock,
                          array->size,
                          sizeof( void* ),
                          array->searchFunc );
  if( temp != NULL )
    return *temp;
  return NULL;
}

/*
 *
 * arraySort
 *
 *  Sorts the given array.
 *
 */
void arraySort(pdarray array )
{
  __compact(array);
  if( array->size > 0 )
  {
    qsort( array->dataBlock, array->size, sizeof( void* ), 
           array->sortFunc );
  }
  array->dirty = 0;
}

/*
 *
 * arrayGetSize()
 *
 *  Get's the size of the given array.
 */
int arrayGetSize(pdarray array)
{
  return array->size;
}

/*
 *
 * arraySetSize
 *
 *  resets and resize's the given array.
 */
int arraySetSize(pdarray array, int newSize)
{
  __resize( array, newSize );
  return array->size;
}

/*
 *
 * arrayGetStep
 *
 *  gets the increment size of the array.
 */
int arrayGetStep(pdarray array)
{
  return array->step;
}

/*
 *
 * arraySetStep
 *
 *  Sets the incrementing size of the array.
 */

int arraySetStep(pdarray array, int newStep)
{
  return ( array->step = newStep ) ;
}