/*****
 NAME
	chash.m - source code for CHash class
 VERSION
	$Id$
 CHANGELOG
	$Log$
 */

#include <coconut/chash.h>
#include <coconut/csystem.h>
#include <coconut/ptext.h>
#include <coconut/fobject.h>

static void foreach_norm_func(gpointer key, gpointer value, gpointer userdata) ;
static void foreach_hash_func(gpointer key, gpointer value, gpointer userdata) ;

static gboolean remove_hash_elm(gpointer key, gpointer value, gpointer user) ;

typedef struct {
	foreach_func_t		func ;
	void *			p1 ;
	void *			p2 ;
} foreach_norm_param_t ;

typedef struct {
	foreach_hash_func_t	func ;
	void *			p1 ;
	void *			p2 ;
} foreach_hash_param_t ;

@implementation CHash 

- init
{
	return [self initHash: &g_str_hash equal: &g_str_equal 
	  removeKey: &remove_nothing_func removeData: &remove_object_func] ;
}

- initHash: (hash_func_t) hashf equal: (equal_func_t) compf
    removeKey: (remove_func_t) removekey
    removeData: (remove_func_t) removedata
{
	hash_table = g_hash_table_new_full(hashf, compf, removekey, removedata);
	[CSystem checkPtr: hash_table] ;
	return [super init] ;
}

- (void) dealloc
{
	g_hash_table_destroy(hash_table) ;
	[super dealloc] ;
}

- (u_int) count
{
	return g_hash_table_size(hash_table) ;
}

- clear
{
	param_p2_t	par ;
	g_hash_table_foreach_remove(hash_table, &remove_hash_elm, &par);
	return nil ;
}

- (const void *) foreach: (foreach_func_t) func with: (void *) p1 
    with: (void *) p2
{
	foreach_norm_param_t param ;

	param.func = func ; param.p1 = p1 ; param.p2 = p2 ;
	g_hash_table_foreach(hash_table, &foreach_norm_func, &param) ;
	return nil ;
}

- (const void *) foreachHash: (foreach_hash_func_t) func with: (void *) p1 
    with: (void *) p2
{
	foreach_hash_param_t param ;

	param.func = func ; param.p1 = p1 ; param.p2 = p2 ;
	g_hash_table_foreach(hash_table, &foreach_hash_func, &param) ;
	return nil ;
}

- add: (const void *) key data: (const void *) value
{
	g_hash_table_insert(hash_table, (gpointer) key, (gpointer) value) ;
	return nil ;
}

- (const void *) search: (const void *) key
{
	/* the function g_hash_table_lookup causes segmentation fault 
	   when the parameter key is null pointer */
	return key ? g_hash_table_lookup(hash_table, (gpointer) key) : NULL ;
}

@end

static void foreach_norm_func(gpointer key, gpointer value, gpointer userdata)
{
	foreach_norm_param_t *	param = (foreach_norm_param_t *) userdata ;
	(param->func)(value, param->p1, param->p2) ;
}

static void foreach_hash_func(gpointer key, gpointer value, gpointer userdata)
{
	foreach_hash_param_t *	param = (foreach_hash_param_t *) userdata ;
	(param->func)(key, value, param->p1, param->p2) ;
}

static gboolean remove_hash_elm(gpointer key, gpointer value, gpointer user)
{
	return 1 ; /* always remove OK */
}


