/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
#include <string.h>
#include "glib.h"


#define MIN_ARRAY_SIZE  16


typedef struct _GRealArray  GRealArray;

struct _GRealArray
{
  guint8 *data;
  guint   len;
  guint   alloc;
  guint   elt_size;
  guint   zero_terminated : 1;
  guint   clear : 1;
};


static gint g_nearest_pow        (gint        num);
static void g_array_maybe_expand (GRealArray *array,
				  gint        len);


static GMemChunk *array_mem_chunk = NULL;


GArray*
g_array_new (gboolean zero_terminated,
	     gboolean clear,
	     guint    elt_size)
{
  GRealArray *array;

  if (!array_mem_chunk)
    array_mem_chunk = g_mem_chunk_new ("array mem chunk",
				       sizeof (GRealArray),
				       1024, G_ALLOC_AND_FREE);

  array = g_chunk_new (GRealArray, array_mem_chunk);

  array->data            = NULL;
  array->len             = 0;
  array->alloc           = 0;
  array->zero_terminated = (zero_terminated ? 1 : 0);
  array->clear           = (clear ? 1 : 0);
  array->elt_size        = elt_size;

  return (GArray*) array;
}

void
g_array_free (GArray  *array,
	      gboolean free_segment)
{
  if (free_segment)
    g_free (array->data);

  g_mem_chunk_free (array_mem_chunk, array);
}

GArray*
g_array_append_vals (GArray       *farray,
		     gconstpointer data,
		     guint         len)
{
  GRealArray *array = (GRealArray*) farray;

  g_array_maybe_expand (array, len);

  memcpy (array->data + array->elt_size * array->len, data, array->elt_size * len);

  array->len += len;

  return farray;
}

GArray*
g_array_prepend_vals (GArray        *farray,
		      gconstpointer  data,
		      guint          len)
{
  GRealArray *array = (GRealArray*) farray;

  g_array_maybe_expand (array, len);

  g_memmove (array->data + array->elt_size * len, array->data, array->elt_size * array->len);

  memcpy (array->data, data, len * array->elt_size);

  array->len += len;

  return farray;
}

GArray*
g_array_insert_vals (GArray        *farray,
		     guint          index,
		     gconstpointer  data,
		     guint          len)
{
  GRealArray *array = (GRealArray*) farray;

  g_array_maybe_expand (array, len);

  g_memmove (array->data + array->elt_size * (len + index), 
	     array->data + array->elt_size * index, 
	     array->elt_size * (array->len - index));

  memcpy (array->data + array->elt_size * index, data, len * array->elt_size);

  array->len += len;

  return farray;
}

GArray*
g_array_set_size (GArray *farray,
		  guint   length)
{
  GRealArray *array = (GRealArray*) farray;

  if (array->len < length)
    g_array_maybe_expand (array, length - array->len);

  array->len = length;

  return farray;
}

GArray*
g_array_remove_index (GArray* farray,
		      guint index)
{
  GRealArray* array = (GRealArray*) farray;

  g_return_val_if_fail (array, NULL);

  g_return_val_if_fail (index >= 0 && index < array->len, NULL);

  if (index != array->len - 1)
      g_memmove (array->data + array->elt_size * index, 
		 array->data + array->elt_size * (index + 1), 
		 array->elt_size * (array->len - index - 1));
  
  if (array->zero_terminated)
    memset (array->data + array->elt_size * (array->len - 1), 0, 
	    array->elt_size);

  array->len -= 1;

  return farray;
}

GArray*
g_array_remove_index_fast (GArray* farray,
			   guint index)
{
  GRealArray* array = (GRealArray*) farray;

  g_return_val_if_fail (array, NULL);

  g_return_val_if_fail (index >= 0 && index < array->len, NULL);

  if (index != array->len - 1)
    g_memmove (array->data + array->elt_size * index, 
	       array->data + array->elt_size * (array->len - 1), 
	       array->elt_size);
  
  if (array->zero_terminated)
    memset (array->data + array->elt_size * (array->len - 1), 0, 
	    array->elt_size);

  array->len -= 1;

  return farray;
}

static gint
g_nearest_pow (gint num)
{
  gint n = 1;

  while (n < num)
    n <<= 1;

  return n;
}

static void
g_array_maybe_expand (GRealArray *array,
		      gint        len)
{
  guint want_alloc = (array->len + len + array->zero_terminated) * array->elt_size;

  if (want_alloc > array->alloc)
    {
      guint old_alloc = array->alloc;

      array->alloc = g_nearest_pow (want_alloc);
      array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);

      array->data = g_realloc (array->data, array->alloc);

      if (array->clear || array->zero_terminated)
	memset (array->data + old_alloc, 0, array->alloc - old_alloc);
    }
}

/* Pointer Array
 */

typedef struct _GRealPtrArray  GRealPtrArray;

struct _GRealPtrArray
{
  gpointer *pdata;
  guint     len;
  guint     alloc;
};

static void g_ptr_array_maybe_expand (GRealPtrArray *array,
				      gint           len);


static GMemChunk *ptr_array_mem_chunk = NULL;



GPtrArray*
g_ptr_array_new (void)
{
  GRealPtrArray *array;

  if (!ptr_array_mem_chunk)
    ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
					   sizeof (GRealPtrArray),
					   1024, G_ALLOC_AND_FREE);

  array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk);

  array->pdata = NULL;
  array->len = 0;
  array->alloc = 0;

  return (GPtrArray*) array;
}

void
g_ptr_array_free (GPtrArray   *array,
		  gboolean  free_segment)
{
  g_return_if_fail (array);

  if (free_segment)
    g_free (array->pdata);

  g_mem_chunk_free (ptr_array_mem_chunk, array);
}

static void
g_ptr_array_maybe_expand (GRealPtrArray *array,
			  gint        len)
{
  guint old_alloc;

  if ((array->len + len) > array->alloc)
    {
      old_alloc = array->alloc;

      array->alloc = g_nearest_pow (array->len + len);
      array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
      if (array->pdata)
	array->pdata = g_realloc (array->pdata, sizeof(gpointer) * array->alloc);
      else
	array->pdata = g_new0 (gpointer, array->alloc);

      memset (array->pdata + old_alloc, 0, array->alloc - old_alloc);
    }
}

void
g_ptr_array_set_size  (GPtrArray   *farray,
		       gint	     length)
{
  GRealPtrArray* array = (GRealPtrArray*) farray;

  g_return_if_fail (array);

  if (length > array->len)
    g_ptr_array_maybe_expand (array, (length - array->len));

  array->len = length;
}

gpointer
g_ptr_array_remove_index (GPtrArray* farray,
			  guint index)
{
  GRealPtrArray* array = (GRealPtrArray*) farray;
  gpointer result;

  g_return_val_if_fail (array, NULL);

  g_return_val_if_fail (index >= 0 && index < array->len, NULL);

  result = array->pdata[index];
  
  if (index != array->len - 1)
    g_memmove (array->pdata + index, array->pdata + index + 1, 
	       array->len - index - 1);
  
  array->pdata[array->len - 1] = NULL;

  array->len -= 1;

  return result;
}

gpointer
g_ptr_array_remove_index_fast (GPtrArray* farray,
			       guint index)
{
  GRealPtrArray* array = (GRealPtrArray*) farray;
  gpointer result;

  g_return_val_if_fail (array, NULL);

  g_return_val_if_fail (index >= 0 && index < array->len, NULL);

  result = array->pdata[index];
  
  if (index != array->len - 1)
    array->pdata[index] = array->pdata[array->len - 1];

  array->pdata[array->len - 1] = NULL;

  array->len -= 1;

  return result;
}

gboolean
g_ptr_array_remove (GPtrArray* farray,
		    gpointer data)
{
  GRealPtrArray* array = (GRealPtrArray*) farray;
  int i;

  g_return_val_if_fail (array, FALSE);

  for (i = 0; i < array->len; i += 1)
    {
      if (array->pdata[i] == data)
	{
	  g_ptr_array_remove_index (farray, i);
	  return TRUE;
	}
    }

  return FALSE;
}

gboolean
g_ptr_array_remove_fast (GPtrArray* farray,
			 gpointer data)
{
  GRealPtrArray* array = (GRealPtrArray*) farray;
  int i;

  g_return_val_if_fail (array, FALSE);

  for (i = 0; i < array->len; i += 1)
    {
      if (array->pdata[i] == data)
	{
	  g_ptr_array_remove_index_fast (farray, i);
	  return TRUE;
	}
    }

  return FALSE;
}

void
g_ptr_array_add (GPtrArray* farray,
		 gpointer data)
{
  GRealPtrArray* array = (GRealPtrArray*) farray;

  g_return_if_fail (array);

  g_ptr_array_maybe_expand (array, 1);

  array->pdata[array->len++] = data;
}

/* Byte arrays
 */

GByteArray* g_byte_array_new      (void)
{
  return (GByteArray*) g_array_new (FALSE, FALSE, 1);
}

void	    g_byte_array_free     (GByteArray *array,
			           gboolean    free_segment)
{
  g_array_free ((GArray*) array, free_segment);
}

GByteArray* g_byte_array_append   (GByteArray *array,
				   const guint8 *data,
				   guint       len)
{
  g_array_append_vals ((GArray*) array, (guint8*)data, len);

  return array;
}

GByteArray* g_byte_array_prepend  (GByteArray *array,
				   const guint8 *data,
				   guint       len)
{
  g_array_prepend_vals ((GArray*) array, (guint8*)data, len);

  return array;
}

GByteArray* g_byte_array_set_size (GByteArray *array,
				   guint       length)
{
  g_array_set_size ((GArray*) array, length);

  return array;
}

GByteArray* g_byte_array_remove_index (GByteArray *array,
				       guint index)
{
  g_array_remove_index((GArray*) array, index);

  return array;
}

GByteArray* g_byte_array_remove_index_fast (GByteArray *array,
						   guint index)
{
  g_array_remove_index_fast((GArray*) array, index);

  return array;
}
