Logo Search packages:      
Sourcecode: tucnak2 version File versions  Download package

iarray.c

/*
    Tucnak - VHF contest log
    Copyright (C) 2002-2006  Ladislav Vaiz <ok1zia@nagano.cz>
    and authors of glib www.gtk.org

*/


/* 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.
 */

/*
 * Modified by the GLib Team and others 1997-1999.  See the AUTHORS
 * file for a list of people on the GLib Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GLib at ftp://ftp.gtk.org/pub/gtk/. 
 */

/* 
 * MT safe
 */


#include "header.h"
/*#include <string.h>
#include <stdlib.h>
#include <glib.h>*/
#include "iarray.h"

#define MIN_ARRAY_SIZE  16



static gint g_nearest_pow (gint num);

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

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

    return n;
}

/* Index Array
 */

typedef struct _GRealIndexArray GRealIndexArray;

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

static void g_index_array_maybe_expand (GRealIndexArray * array, gint len);

static GMemChunk *index_array_mem_chunk = NULL;

G_LOCK_DEFINE_STATIC (index_array_mem_chunk);


GIndexArray *g_index_array_new (void)
{
    GRealIndexArray *array;

    G_LOCK (index_array_mem_chunk);
    if (!index_array_mem_chunk)
        index_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
                                                 sizeof (GRealIndexArray),
                                                 1024, G_ALLOC_AND_FREE);

    array = g_chunk_new (GRealIndexArray, index_array_mem_chunk);
    G_UNLOCK (index_array_mem_chunk);

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

    return (GIndexArray *) array;
}

void g_index_array_free (GIndexArray * array, gboolean free_segment)
{
    g_return_if_fail (array);

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

    G_LOCK (index_array_mem_chunk);
    g_mem_chunk_free (index_array_mem_chunk, array);
    G_UNLOCK (index_array_mem_chunk);
    
}

static void g_index_array_maybe_expand (GRealIndexArray * 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,
                sizeof (gpointer) * (array->alloc - old_alloc));
    }
}

void g_index_array_set_size (GIndexArray * farray, gint length)
{
    GRealIndexArray *array = (GRealIndexArray *) farray;

    g_return_if_fail (array);

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

    array->len = length;
}

gpointer g_index_array_remove_index (GIndexArray * farray, guint index)
{
    GRealIndexArray *array = (GRealIndexArray *) farray;
    gpointer result;

    g_return_val_if_fail (array, NULL);

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

    result = array->pdata[index];

    if (index != array->len - 1){
        g_memmove (array->pdata + index, array->pdata + index + 1,
                   sizeof (gpointer) * (array->len - index - 1));
    }

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

    array->len -= 1;

    return result;
}

gpointer g_index_array_remove_index_fast (GIndexArray * farray, guint index)
{
    GRealIndexArray *array = (GRealIndexArray *) farray;
    gpointer result;

    g_return_val_if_fail (array, NULL);

    g_return_val_if_fail (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_index_array_remove (GIndexArray * farray, gpointer data)
{
    GRealIndexArray *array = (GRealIndexArray *) farray;
    int i;

    g_return_val_if_fail (array, FALSE);

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

    return FALSE;
}

gboolean g_index_array_remove_fast (GIndexArray * farray, gpointer data)
{
    GRealIndexArray *array = (GRealIndexArray *) farray;
    int i;

    g_return_val_if_fail (array, FALSE);

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

    return FALSE;
}

void g_index_array_add (GIndexArray * farray, gpointer data)
{
    GRealIndexArray *array = (GRealIndexArray *) farray;

    g_return_if_fail (array);

    g_index_array_maybe_expand (array, 1);

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


/* new stuff */

void g_index_array_qsort (GIndexArray *farray, 
        int (*compar)(const void *, const void *)){
    
    GRealIndexArray *array = (GRealIndexArray *) farray;

    qsort( (void *)array->pdata, array->len, sizeof(gpointer), compar);
}

gpointer *g_index_array_bsearch(GIndexArray *farray, const void *key,
        int (*compar)(const void *, const void *)){
    
    GRealIndexArray *array = (GRealIndexArray *) farray;
    
    return (gpointer) bsearch (key, 
                (void *)array->pdata, 
                array->len, 
                sizeof(gpointer), 
                compar);
}

gint g_index_array_bsearch_index(GIndexArray *farray, const void *key,
        int (*compar)(const void *, const void *)){
    gpointer found;
    gint index;

    found = g_index_array_bsearch(farray, key, compar);
    if (!found) return -1;
    
    index = (gpointer *)found - (gpointer*)farray->pdata;
    
    return index;
}

void g_index_array_free_all(GIndexArray  *array){
    int i;
    gpointer item;
            
    for (i=array->len-1; i>=0; i--){                   
        item=g_index_array_index(array, i);
        g_free(item);
    }
    array->len=0;   
    g_index_array_free(array, array->pdata?TRUE:FALSE);
}



Generated by  Doxygen 1.6.0   Back to index