/*******************************************************************
  uLan Communication - C interface library

  ul_gsa.h	- generic sorted arrays

  (C) Copyright 2001 by Pavel Pisa - Originator

  The uLan driver is distributed under the Gnu General Public License. 
  See file COPYING for details.

  Originator reserve the right to use and publish sources
  under different conditions too. If third party contributors
  do not accept this condition, they can delete this statement
  and only GNU license will apply.
 *******************************************************************/

#ifndef _UL_GSA_H
#define _UL_GSA_H

#ifdef __cplusplus
extern "C" {
#endif

/* function to compare fields of two array items */
typedef int gsa_cmp_fnc_t(const void *a, const void *b);

/* compare two integer fields */
int gsa_cmp_int(const void *a, const void *b);

/* compare two unsigned long fields */
int gsa_cmp_ulong(const void *a, const void *b);

/* define structure representing head of array */
#define GSA_ARRAY_FOR(_type) \
  struct { \
    _type **items; \
    unsigned count; \
    unsigned alloc_count; \
    int key_offs; \
    gsa_cmp_fnc_t *cmp_fnc; \
  }

/* offset of structure field */
#define GSA_OFFSET(_type,_member) \
		((int)&(((_type*)0)->_member))

/* array type for functions independent on stored type */
typedef GSA_ARRAY_FOR(void) gsa_array_t;

/* initialize array head structure */
void
gsa_struct_init(gsa_array_t *array, int key_offs,
		gsa_cmp_fnc_t *cmp_fnc);

/* delete all pointers from array */
void 
gsa_delete_all(gsa_array_t *array);

/* Core binary search routine for GSA arrays
   searches in "array" for index "indx" of item
   with value of item field at offset "key_offs" 
   equal to "*key". Values are compared by function
   "*cmp_fnc".
   Integer "mode" modifies search algorithm
     0 .. finds index of any item with field value "*key"
     1 .. finds index of first item with "*key"
     2 .. index points after last item with "*key" value 
          reworded - index points at first item with higher 
          value of field or after last item
   Return of nonzerro value indicates match found.
 */
int 
gsa_bsearch_indx(gsa_array_t *array, void *key, int key_offs,
	    gsa_cmp_fnc_t *cmp_fnc, int mode, unsigned *indx);

/* returns item with key field value equal to "*key" or NULL */
void * 
gsa_find(gsa_array_t *array, void *key);

/* same as above, but first matching item is found */
void * 
gsa_find_first(gsa_array_t *array, void *key);

/* find index "indx" of the first matching item */
void * 
gsa_find_indx(gsa_array_t *array, void *key, int *indx);

/* insert new item at index "where" */
int
gsa_insert_at(gsa_array_t *array, void *item, unsigned where);

/* insert new item at the right index, 
   "mode" has same meaning as in "gsa_bsearch_indx"
   if mode==0 then strict sorting is required
   and violation result in ignore of new item
   and return value <0
 */
int
gsa_insert(gsa_array_t *array, void *item, int mode);

/* delete item at index */
int
gsa_delete_at(gsa_array_t *array, unsigned indx);

/* delete item from array */
int
gsa_delete(gsa_array_t *array, void *item);

/* set new sorting field and function
   returns 0 if no change needed */
int
gsa_setsort(gsa_array_t *array, int key_offs,
	       gsa_cmp_fnc_t *cmp_fnc);

#ifdef __cplusplus
} /* extern "C"*/
#endif

#endif /* _UL_GSA_H */
