This commit is contained in:
parent
b6d38c892a
commit
0590924941
@ -92,8 +92,8 @@ extern "C" {
|
||||
|
||||
ase_dll_t* ase_dll_open (
|
||||
ase_mmgr_t* mmgr /* memory manager */ ,
|
||||
ase_size_t extension /* size of extension area in bytes */,
|
||||
void (*initializer) (ase_dll_t*) /* extension initializer */
|
||||
ase_size_t ext /* size of extension area in bytes */,
|
||||
void (*init) (ase_dll_t*) /* extension initializer */
|
||||
);
|
||||
|
||||
/*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: map.h 344 2008-08-22 15:23:09Z baconevi $
|
||||
* $Id: map.h 345 2008-08-26 08:50:12Z baconevi $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
@ -43,11 +43,11 @@ typedef int (*ase_map_comper_t) (
|
||||
ase_size_t klen2 /* the length of a key in bytes */
|
||||
);
|
||||
|
||||
/* pair visitor */
|
||||
/* pair visitor - should return ASE_MAP_WALK_STOP or ASE_MAP_WALK_FORWARD */
|
||||
typedef int (*ase_map_walker_t) (
|
||||
ase_map_t* map,
|
||||
ase_map_pair_t* pair,
|
||||
void* arg
|
||||
ase_map_t* map /* a map */,
|
||||
ase_map_pair_t* pair /* the pointer to a key/value pair */,
|
||||
void* arg /* the pointer to user-defined data */
|
||||
);
|
||||
|
||||
struct ase_map_pair_t
|
||||
@ -62,7 +62,7 @@ struct ase_map_pair_t
|
||||
ase_map_pair_t* next;
|
||||
};
|
||||
|
||||
enum ase_map_id_t
|
||||
enum ase_map_id_t
|
||||
{
|
||||
ASE_MAP_KEY = 0,
|
||||
ASE_MAP_VAL = 1
|
||||
@ -85,12 +85,16 @@ struct ase_map_t
|
||||
|
||||
ase_map_pair_t** buck;
|
||||
|
||||
/*
|
||||
void (*freeval) (void* owner,void* val);
|
||||
*/
|
||||
void (*sameval) (void* owner, void* vptr, ase_size_t vlen);
|
||||
};
|
||||
|
||||
/* values that can be returned by ase_map_walker_t */
|
||||
enum ase_map_walk_t
|
||||
{
|
||||
ASE_MAP_WALK_STOP = 0,
|
||||
ASE_MAP_WALK_FORWARD = 1
|
||||
};
|
||||
|
||||
#define ASE_MAP_COPIER_INLINE ase_map_copyinline
|
||||
|
||||
#define ASE_MAP_KPTR(p) ((p)->kptr)
|
||||
@ -104,14 +108,12 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Creates a hashed map with a dynamic array bucket and a list of values linked
|
||||
* NAME: create a map
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* The ase_map_open() function creates a hashed map with a dynamic array
|
||||
* bucket and a list of values linked.
|
||||
*/
|
||||
/*
|
||||
ase_map_t* ase_map_open (
|
||||
void* owner, ase_size_t capa, unsigned int factor,
|
||||
void(*freeval)(void*,void*), void(*sameval)(void*,void*),
|
||||
ase_mmgr_t* mmgr);
|
||||
*/
|
||||
ase_map_t* ase_map_open (
|
||||
ase_mmgr_t* mmgr,
|
||||
ase_size_t ext,
|
||||
@ -119,30 +121,109 @@ ase_map_t* ase_map_open (
|
||||
);
|
||||
|
||||
/* destroy a map */
|
||||
void ase_map_close (ase_map_t* map);
|
||||
void ase_map_close (
|
||||
ase_map_t* map /* a map */
|
||||
);
|
||||
|
||||
/* clear a map */
|
||||
void ase_map_clear (ase_map_t* map);
|
||||
void ase_map_clear (
|
||||
ase_map_t* map /* a map */
|
||||
);
|
||||
|
||||
/* get the number of key/value pairs in a map
|
||||
ase_size_t ase_map_getsize (ase_map_t* map);
|
||||
/*
|
||||
* NAME: specifies how to clone an element
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* A special copier ASE_MAP_COPIER_INLINE is provided. This copier enables
|
||||
* you to copy the data inline to the internal node. No freeer is invoked
|
||||
* when the node is freeed.
|
||||
*
|
||||
* You may set the copier to ASE_NULL to perform no special operation
|
||||
* when the data pointer is rememebered.
|
||||
*/
|
||||
void ase_map_setcopier (
|
||||
ase_map_t* map /* a map */,
|
||||
int id /* ASE_MAP_KEY or ASE_MAP_VAL */,
|
||||
ase_map_copier_t copier /* a element copier */
|
||||
);
|
||||
|
||||
ase_map_pair_t* ase_map_get (
|
||||
ase_map_copier_t ase_map_getcopier (
|
||||
ase_map_t* map /* a map */,
|
||||
int id /* ASE_MAP_KEY or ASE_MAP_VAL */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME: specifies how to destroy an element
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The freeer is called when a node containing the element is destroyed.
|
||||
*/
|
||||
void ase_map_setfreeer (
|
||||
ase_map_t* map /* a map */,
|
||||
int id /* ASE_MAP_KEY or ASE_MAP_VAL */,
|
||||
ase_map_freeer_t freeer /* a element freeer */
|
||||
);
|
||||
|
||||
ase_map_freeer_t ase_map_getfreeer (
|
||||
ase_map_t* map /* a map */,
|
||||
int id /* ASE_MAP_KEY or ASE_MAP_VAL */
|
||||
);
|
||||
|
||||
ase_map_hasher_t ase_map_gethasher (
|
||||
ase_map_t* map
|
||||
);
|
||||
|
||||
void ase_map_sethasher (
|
||||
ase_map_t* map,
|
||||
ase_map_hasher_t hasher
|
||||
);
|
||||
|
||||
ase_map_comper_t ase_map_getcomper (
|
||||
ase_map_t* map
|
||||
);
|
||||
|
||||
void ase_map_setcomper (
|
||||
ase_map_t* map,
|
||||
ase_map_comper_t comper
|
||||
);
|
||||
|
||||
void* ase_map_getextension (
|
||||
ase_map_t* map
|
||||
);
|
||||
|
||||
ase_mmgr_t* ase_map_getmmgr (
|
||||
ase_map_t* map
|
||||
);
|
||||
|
||||
void ase_map_setmmgr (
|
||||
ase_map_t* map,
|
||||
ase_mmgr_t* mmgr
|
||||
);
|
||||
|
||||
/* get the number of key/value pairs in a map */
|
||||
ase_size_t ase_map_getsize (
|
||||
ase_map_t* map /* a map */
|
||||
);
|
||||
|
||||
/* get the pointer to the pair with a matching key */
|
||||
ase_map_pair_t* ase_map_get (
|
||||
ase_map_t* map /* a map */,
|
||||
const void* kptr,
|
||||
ase_size_t klen
|
||||
);
|
||||
|
||||
|
||||
/* insert or update a pair with a matching key */
|
||||
ase_map_pair_t* ase_map_put (
|
||||
ase_map_t* map,
|
||||
const void* kptr,
|
||||
ase_size_t klen,
|
||||
void* vptr,
|
||||
ase_size_t vlen
|
||||
ase_map_t* map /* a map */,
|
||||
void* kptr /* the pointer to the beginning of a key */,
|
||||
ase_size_t klen /* the length of the key in bytes */,
|
||||
void* vptr /* the pointer to the beginning of a value */,
|
||||
ase_size_t vlen /* the length of the value in bytes */
|
||||
);
|
||||
|
||||
int ase_map_putx (
|
||||
ase_map_t* map,
|
||||
ase_map_t* map /* a map */,
|
||||
void* kptr,
|
||||
ase_size_t klen,
|
||||
void* vptr,
|
||||
@ -151,25 +232,39 @@ int ase_map_putx (
|
||||
);
|
||||
|
||||
ase_map_pair_t* ase_map_set (
|
||||
ase_map_t* map,
|
||||
ase_map_t* map /* a map */,
|
||||
void* kptr,
|
||||
ase_size_t klen,
|
||||
void* vptr,
|
||||
ase_size_t vlen
|
||||
);
|
||||
|
||||
/* remove a pair with a matching key */
|
||||
int ase_map_remove (
|
||||
ase_map_t* map, const void* kptr, ase_size_t klen);
|
||||
ase_map_t* map /* a map */,
|
||||
const void* kptr,
|
||||
ase_size_t klen
|
||||
);
|
||||
|
||||
/* traverse a map */
|
||||
int ase_map_walk (ase_map_t* map, ase_map_walker_t walker, void* arg);
|
||||
void ase_map_walk (
|
||||
ase_map_t* map /* a map */,
|
||||
ase_map_walker_t walker /* the pointer to the function for each pair */,
|
||||
void* arg /* a pointer to user-specific data */
|
||||
);
|
||||
|
||||
/* get the pointer to the first pair in the map. */
|
||||
ase_map_pair_t* ase_map_getfirstpair (ase_map_t* map, ase_size_t* buckno);
|
||||
ase_map_pair_t* ase_map_getfirstpair (
|
||||
ase_map_t* map /* a map */,
|
||||
ase_size_t* buckno
|
||||
);
|
||||
|
||||
/* get the pointer to the next pair in the map. */
|
||||
ase_map_pair_t* ase_map_getnextpair (
|
||||
ase_map_t* map, ase_map_pair_t* pair, ase_size_t* buckno);
|
||||
ase_map_t* map /* a map */,
|
||||
ase_map_pair_t* pair,
|
||||
ase_size_t* buckno
|
||||
);
|
||||
|
||||
void* ase_map_copyinline (ase_map_t* map, void* dptr, ase_size_t dlen);
|
||||
|
||||
|
@ -91,8 +91,8 @@ extern "C" {
|
||||
|
||||
ase_sll_t* ase_sll_open (
|
||||
ase_mmgr_t* mmgr /* memory manager */ ,
|
||||
ase_size_t extension /* size of extension area in bytes */,
|
||||
void (*initializer) (ase_sll_t*) /* extension initializer */
|
||||
ase_size_t ext /* size of extension area in bytes */,
|
||||
void (*init) (ase_sll_t*) /* extension initializer */
|
||||
);
|
||||
|
||||
/*
|
||||
@ -112,7 +112,7 @@ void ase_sll_clear (
|
||||
/*
|
||||
* NAME: specifies how to clone an element
|
||||
*
|
||||
* DESCRIPTION
|
||||
* DESCRIPTION:
|
||||
* A special copier ASE_SLL_COPIER_INLINE is provided. This copier enables
|
||||
* you to copy the data inline to the internal node. No freeer is invoked
|
||||
* when the node is freeed.
|
||||
|
@ -10,10 +10,40 @@
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
static ase_bool_t is_upper (ase_cint_t c) { return isupper(c); }
|
||||
static ase_bool_t is_lower (ase_cint_t c) { return islower(c); }
|
||||
static ase_bool_t is_alpha (ase_cint_t c) { return isalpha(c); }
|
||||
static ase_bool_t is_digit (ase_cint_t c) { return isdigit(c); }
|
||||
static ase_bool_t is_xdigit (ase_cint_t c) { return isxdigit(c); }
|
||||
static ase_bool_t is_alnum (ase_cint_t c) { return isalnum(c); }
|
||||
static ase_bool_t is_space (ase_cint_t c) { return isspace(c); }
|
||||
static ase_bool_t is_print (ase_cint_t c) { return isprint(c); }
|
||||
static ase_bool_t is_graph (ase_cint_t c) { return isgraph(c); }
|
||||
static ase_bool_t is_cntrl (ase_cint_t c) { return iscntrl(c); }
|
||||
static ase_bool_t is_punct (ase_cint_t c) { return ispunct(c); }
|
||||
|
||||
ase_bool_t ase_ccls_is (ase_cint_t c, int type)
|
||||
{
|
||||
/* TODO: use GetStringTypeW/A for WIN32 to implement these */
|
||||
#error NOT IMPLEMENTED YET.
|
||||
|
||||
static ase_bool_t (*f[]) (ase_cint_t) =
|
||||
{
|
||||
is_upper,
|
||||
is_lower,
|
||||
is_alpha,
|
||||
is_digit,
|
||||
is_xdigit,
|
||||
is_alnum,
|
||||
is_space,
|
||||
is_print,
|
||||
is_graph,
|
||||
is_cntrl,
|
||||
is_punct
|
||||
};
|
||||
|
||||
ASE_ASSERTX (type >= ASE_CCLS_UPPER && type <= ASE_CCLS_PUNCT,
|
||||
"The character type should be one of ase_ccls_type_t values");
|
||||
return f[type] (c);
|
||||
}
|
||||
|
||||
ase_cint_t ase_ccls_to (ase_cint_t c, int type)
|
||||
|
@ -8,8 +8,7 @@
|
||||
#include "mem.h"
|
||||
|
||||
ase_dll_t* ase_dll_open (
|
||||
ase_mmgr_t* mmgr, ase_size_t extension,
|
||||
void (*initializer) (ase_dll_t*))
|
||||
ase_mmgr_t* mmgr, ase_size_t ext, void (*init) (ase_dll_t*))
|
||||
{
|
||||
ase_dll_t* dll;
|
||||
|
||||
@ -23,13 +22,13 @@ ase_dll_t* ase_dll_open (
|
||||
if (mmgr == ASE_NULL) return ASE_NULL;
|
||||
}
|
||||
|
||||
dll = ASE_MMGR_ALLOC (mmgr, ASE_SIZEOF(ase_dll_t) + extension);
|
||||
dll = ASE_MMGR_ALLOC (mmgr, ASE_SIZEOF(ase_dll_t) + ext);
|
||||
if (dll == ASE_NULL) return ASE_NULL;
|
||||
|
||||
ASE_MEMSET (dll, 0, ASE_SIZEOF(ase_dll_t) + extension);
|
||||
ASE_MEMSET (dll, 0, ASE_SIZEOF(ase_dll_t) + ext);
|
||||
dll->mmgr = mmgr;
|
||||
|
||||
if (initializer) initializer (dll);
|
||||
if (init) init (dll);
|
||||
|
||||
return dll;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: map.c 344 2008-08-22 15:23:09Z baconevi $
|
||||
* $Id: map.c 345 2008-08-26 08:50:12Z baconevi $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
@ -216,6 +216,34 @@ map_t* ase_map_open (mmgr_t* mmgr, size_t ext, void (*init) (map_t*))
|
||||
return map;
|
||||
}
|
||||
|
||||
void ase_map_close (map_t* map)
|
||||
{
|
||||
ase_map_clear (map);
|
||||
ASE_MMGR_FREE (map->mmgr, map->buck);
|
||||
ASE_MMGR_FREE (map->mmgr, map);
|
||||
}
|
||||
|
||||
void ase_map_clear (map_t* map)
|
||||
{
|
||||
size_t i;
|
||||
pair_t* pair, * next;
|
||||
|
||||
for (i = 0; i < map->capa; i++)
|
||||
{
|
||||
pair = map->buck[i];
|
||||
|
||||
while (pair != ASE_NULL)
|
||||
{
|
||||
next = ASE_MAP_NEXT(pair);
|
||||
free_pair (map, pair);
|
||||
map->size--;
|
||||
pair = next;
|
||||
}
|
||||
|
||||
map->buck[i] = ASE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
copier_t ase_map_getcopier (map_t* map, int id)
|
||||
{
|
||||
ASE_ASSERTX (id == ASE_MAP_KEY || id == ASE_MAP_VAL,
|
||||
@ -279,34 +307,6 @@ void ase_map_setmmgr (map_t* map, mmgr_t* mmgr)
|
||||
map->mmgr = mmgr;
|
||||
}
|
||||
|
||||
void ase_map_close (map_t* map)
|
||||
{
|
||||
ase_map_clear (map);
|
||||
ASE_MMGR_FREE (map->mmgr, map->buck);
|
||||
ASE_MMGR_FREE (map->mmgr, map);
|
||||
}
|
||||
|
||||
void ase_map_clear (map_t* map)
|
||||
{
|
||||
size_t i;
|
||||
pair_t* pair, * next;
|
||||
|
||||
for (i = 0; i < map->capa; i++)
|
||||
{
|
||||
pair = map->buck[i];
|
||||
|
||||
while (pair != ASE_NULL)
|
||||
{
|
||||
next = ASE_MAP_NEXT(pair);
|
||||
free_pair (map, pair);
|
||||
map->size--;
|
||||
pair = next;
|
||||
}
|
||||
|
||||
map->buck[i] = ASE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
size_t ase_map_getsize (map_t* map)
|
||||
{
|
||||
return map->size;
|
||||
@ -323,9 +323,10 @@ pair_t* ase_map_get (
|
||||
|
||||
while (pair != ASE_NULL)
|
||||
{
|
||||
if (map->comper (map,
|
||||
KPTR(pair), KLEN(pair),
|
||||
kptr, klen) == 0) return pair;
|
||||
if (map->comper (map, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
||||
{
|
||||
return pair;
|
||||
}
|
||||
|
||||
pair = ASE_MAP_NEXT(pair);
|
||||
}
|
||||
@ -358,9 +359,7 @@ int ase_map_putx (
|
||||
{
|
||||
next = ASE_MAP_NEXT(pair);
|
||||
|
||||
if (map->comper (map,
|
||||
KPTR(pair), KLEN(pair),
|
||||
kptr, klen) == 0)
|
||||
if (map->comper (map, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
||||
{
|
||||
p = change_pair_val (map, pair, vptr, vlen);
|
||||
if (p == ASE_NULL) return -1; /* change error */
|
||||
@ -427,9 +426,7 @@ pair_t* ase_map_set (map_t* map,
|
||||
|
||||
while (pair != ASE_NULL)
|
||||
{
|
||||
if (map->comper (map,
|
||||
KPTR(pair), KLEN(pair),
|
||||
kptr, klen) == 0)
|
||||
if (map->comper (map, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
||||
{
|
||||
/*TODO: this is wrong... change code .... same way as putx... */
|
||||
return change_pair_val (map, pair, vptr, vlen);
|
||||
@ -440,22 +437,6 @@ pair_t* ase_map_set (map_t* map,
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
pair_t* ase_map_getpair (
|
||||
map_t* map, const void* kptr, size_t klen,
|
||||
void** val, size_t* vptr)
|
||||
{
|
||||
pair_t* pair;
|
||||
|
||||
pair = ase_map_get (map, kptr, klen);
|
||||
if (pair == ASE_NULL) return ASE_NULL;
|
||||
if (val) *val = VPTR(pair);
|
||||
if (vptr) *vptr = VLEN(pair);
|
||||
|
||||
return pair;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ase_map_remove (
|
||||
map_t* map, const void* kptr, size_t klen)
|
||||
{
|
||||
@ -468,9 +449,7 @@ int ase_map_remove (
|
||||
|
||||
while (pair != ASE_NULL)
|
||||
{
|
||||
if (map->comper (map,
|
||||
KPTR(pair), KLEN(pair),
|
||||
kptr, klen) == 0)
|
||||
if (map->comper (map, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
||||
{
|
||||
if (prev == ASE_NULL)
|
||||
map->buck[hc] = ASE_MAP_NEXT(pair);
|
||||
@ -489,7 +468,7 @@ int ase_map_remove (
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ase_map_walk (map_t* map, walker_t walker, void* arg)
|
||||
void ase_map_walk (map_t* map, walker_t walker, void* arg)
|
||||
{
|
||||
size_t i;
|
||||
pair_t* pair, * next;
|
||||
@ -501,13 +480,10 @@ int ase_map_walk (map_t* map, walker_t walker, void* arg)
|
||||
while (pair != ASE_NULL)
|
||||
{
|
||||
next = ASE_MAP_NEXT(pair);
|
||||
/* TODO: ASE_MAP_WALK_STOP ASE_MAP_WALK_FORWARD */
|
||||
if (walker(map, pair, arg) == -1) return -1;
|
||||
if (walker(map, pair, arg) == ASE_MAP_WALK_STOP) return;
|
||||
pair = next;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
pair_t* ase_map_getfirstpair (map_t* map, size_t* buckno)
|
||||
|
@ -7,11 +7,26 @@
|
||||
#include <ase/cmn/sll.h>
|
||||
#include "mem.h"
|
||||
|
||||
ase_sll_t* ase_sll_open (
|
||||
ase_mmgr_t* mmgr, ase_size_t extension,
|
||||
void (*initializer) (ase_sll_t*))
|
||||
#define sll_t ase_sll_t
|
||||
#define node_t ase_sll_node_t
|
||||
#define copier_t ase_sll_copier_t
|
||||
#define freeer_t ase_sll_freeer_t
|
||||
#define walker_t ase_sll_walker_t
|
||||
|
||||
#define HEAD(s) ASE_SLL_HEAD(s)
|
||||
#define TAIL(s) ASE_SLL_TAIL(s)
|
||||
#define SIZE(s) ASE_SLL_SIZE(s)
|
||||
|
||||
#define DPTR(n) ASE_SLL_DPTR(n)
|
||||
#define DLEN(n) ASE_SLL_DLEN(n)
|
||||
#define NEXT(n) ASE_SLL_NEXT(n)
|
||||
|
||||
#define size_t ase_size_t
|
||||
#define mmgr_t ase_mmgr_t
|
||||
|
||||
sll_t* ase_sll_open (mmgr_t* mmgr, size_t ext, void (*init) (sll_t*))
|
||||
{
|
||||
ase_sll_t* sll;
|
||||
sll_t* sll;
|
||||
|
||||
if (mmgr == ASE_NULL)
|
||||
{
|
||||
@ -23,220 +38,220 @@ ase_sll_t* ase_sll_open (
|
||||
if (mmgr == ASE_NULL) return ASE_NULL;
|
||||
}
|
||||
|
||||
sll = ASE_MMGR_ALLOC (mmgr, ASE_SIZEOF(ase_sll_t) + extension);
|
||||
sll = ASE_MMGR_ALLOC (mmgr, ASE_SIZEOF(sll_t) + ext);
|
||||
if (sll == ASE_NULL) return ASE_NULL;
|
||||
|
||||
ASE_MEMSET (sll, 0, ASE_SIZEOF(ase_sll_t) + extension);
|
||||
ASE_MEMSET (sll, 0, ASE_SIZEOF(sll_t) + ext);
|
||||
sll->mmgr = mmgr;
|
||||
|
||||
if (initializer) initializer (sll);
|
||||
if (init) init (sll);
|
||||
|
||||
return sll;
|
||||
}
|
||||
|
||||
void ase_sll_close (ase_sll_t* sll)
|
||||
void ase_sll_close (sll_t* sll)
|
||||
{
|
||||
ase_sll_clear (sll);
|
||||
ASE_MMGR_FREE (sll->mmgr, sll);
|
||||
}
|
||||
|
||||
void ase_sll_clear (ase_sll_t* sll)
|
||||
void ase_sll_clear (sll_t* sll)
|
||||
{
|
||||
while (sll->head != ASE_NULL) ase_sll_delete (sll, sll->head);
|
||||
ASE_ASSERT (sll->tail == ASE_NULL);
|
||||
while (HEAD(sll) != ASE_NULL) ase_sll_delete (sll, HEAD(sll));
|
||||
ASE_ASSERT (TAIL(sll) == ASE_NULL);
|
||||
}
|
||||
|
||||
void* ase_sll_getextension (ase_sll_t* sll)
|
||||
void* ase_sll_getextension (sll_t* sll)
|
||||
{
|
||||
return sll + 1;
|
||||
}
|
||||
|
||||
ase_mmgr_t* ase_sll_getmmgr (ase_sll_t* sll)
|
||||
mmgr_t* ase_sll_getmmgr (sll_t* sll)
|
||||
{
|
||||
return sll->mmgr;
|
||||
}
|
||||
|
||||
void ase_sll_setmmgr (ase_sll_t* sll, ase_mmgr_t* mmgr)
|
||||
void ase_sll_setmmgr (sll_t* sll, mmgr_t* mmgr)
|
||||
{
|
||||
sll->mmgr = mmgr;
|
||||
}
|
||||
|
||||
ase_size_t ase_sll_getsize (ase_sll_t* sll)
|
||||
size_t ase_sll_getsize (sll_t* sll)
|
||||
{
|
||||
return sll->size;
|
||||
return SIZE(sll);
|
||||
}
|
||||
|
||||
ase_sll_node_t* ase_sll_gethead (ase_sll_t* sll)
|
||||
node_t* ase_sll_gethead (sll_t* sll)
|
||||
{
|
||||
return sll->head;
|
||||
return HEAD(sll);
|
||||
}
|
||||
|
||||
ase_sll_node_t* ase_sll_gettail (ase_sll_t* sll)
|
||||
node_t* ase_sll_gettail (sll_t* sll)
|
||||
{
|
||||
return sll->tail;
|
||||
return TAIL(sll);
|
||||
}
|
||||
|
||||
ase_sll_copier_t ase_sll_getcopier (ase_sll_t* sll)
|
||||
copier_t ase_sll_getcopier (sll_t* sll)
|
||||
{
|
||||
return sll->copier;
|
||||
}
|
||||
|
||||
void ase_sll_setcopier (ase_sll_t* sll, ase_sll_copier_t copier)
|
||||
void ase_sll_setcopier (sll_t* sll, copier_t copier)
|
||||
{
|
||||
sll->copier = copier;
|
||||
}
|
||||
|
||||
ase_sll_freeer_t ase_sll_getfreeer (ase_sll_t* sll)
|
||||
freeer_t ase_sll_getfreeer (sll_t* sll)
|
||||
{
|
||||
return sll->freeer;
|
||||
}
|
||||
|
||||
void ase_sll_setfreeer (ase_sll_t* sll, ase_sll_freeer_t freeer)
|
||||
void ase_sll_setfreeer (sll_t* sll, freeer_t freeer)
|
||||
{
|
||||
sll->freeer = freeer;
|
||||
}
|
||||
|
||||
static ase_sll_node_t* alloc_node (ase_sll_t* sll, void* dptr, ase_size_t dlen)
|
||||
static node_t* alloc_node (sll_t* sll, void* dptr, size_t dlen)
|
||||
{
|
||||
ase_sll_node_t* n;
|
||||
node_t* n;
|
||||
|
||||
if (sll->copier == ASE_NULL)
|
||||
{
|
||||
n = ASE_MMGR_ALLOC (sll->mmgr, ASE_SIZEOF(ase_sll_node_t));
|
||||
n = ASE_MMGR_ALLOC (sll->mmgr, ASE_SIZEOF(node_t));
|
||||
if (n == ASE_NULL) return ASE_NULL;
|
||||
n->dptr = dptr;
|
||||
DPTR(n) = dptr;
|
||||
}
|
||||
else if (sll->copier == ASE_SLL_COPIER_INLINE)
|
||||
{
|
||||
n = ASE_MMGR_ALLOC (sll->mmgr, ASE_SIZEOF(ase_sll_node_t) + dlen);
|
||||
n = ASE_MMGR_ALLOC (sll->mmgr, ASE_SIZEOF(node_t) + dlen);
|
||||
if (n == ASE_NULL) return ASE_NULL;
|
||||
|
||||
ASE_MEMCPY (n + 1, dptr, dlen);
|
||||
n->dptr = n + 1;
|
||||
DPTR(n) = n + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = ASE_MMGR_ALLOC (sll->mmgr, ASE_SIZEOF(ase_sll_node_t));
|
||||
n = ASE_MMGR_ALLOC (sll->mmgr, ASE_SIZEOF(node_t));
|
||||
if (n == ASE_NULL) return ASE_NULL;
|
||||
n->dptr = sll->copier (sll, dptr, dlen);
|
||||
if (n->dptr == ASE_NULL)
|
||||
DPTR(n) = sll->copier (sll, dptr, dlen);
|
||||
if (DPTR(n) == ASE_NULL)
|
||||
{
|
||||
ASE_MMGR_FREE (sll->mmgr, n);
|
||||
return ASE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
n->dlen = dlen;
|
||||
n->next = ASE_NULL;
|
||||
DLEN(n) = dlen;
|
||||
NEXT(n) = ASE_NULL;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
ase_sll_node_t* ase_sll_insert (
|
||||
ase_sll_t* sll, ase_sll_node_t* pos, void* dptr, ase_size_t dlen)
|
||||
node_t* ase_sll_insert (
|
||||
sll_t* sll, node_t* pos, void* dptr, size_t dlen)
|
||||
{
|
||||
ase_sll_node_t* n = alloc_node (sll, dptr, dlen);
|
||||
node_t* n = alloc_node (sll, dptr, dlen);
|
||||
if (n == ASE_NULL) return ASE_NULL;
|
||||
|
||||
if (pos == ASE_NULL)
|
||||
{
|
||||
/* insert at the end */
|
||||
if (sll->head == ASE_NULL)
|
||||
if (HEAD(sll) == ASE_NULL)
|
||||
{
|
||||
ASE_ASSERT (sll->tail == ASE_NULL);
|
||||
sll->head = n;
|
||||
ASE_ASSERT (TAIL(sll) == ASE_NULL);
|
||||
HEAD(sll) = n;
|
||||
}
|
||||
else sll->tail->next = n;
|
||||
else NEXT(TAIL(sll)) = n;
|
||||
|
||||
sll->tail = n;
|
||||
TAIL(sll) = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* insert in front of the positional node */
|
||||
n->next = pos;
|
||||
if (pos == sll->head) sll->head = n;
|
||||
NEXT(n) = pos;
|
||||
if (pos == HEAD(sll)) HEAD(sll) = n;
|
||||
else
|
||||
{
|
||||
/* take note of performance penalty */
|
||||
ase_sll_node_t* n2 = sll->head;
|
||||
while (n2->next != pos) n2 = n2->next;
|
||||
n2->next = n;
|
||||
node_t* n2 = HEAD(sll);
|
||||
while (NEXT(n2) != pos) n2 = NEXT(n2);
|
||||
NEXT(n2) = n;
|
||||
}
|
||||
}
|
||||
|
||||
sll->size++;
|
||||
SIZE(sll)++;
|
||||
return n;
|
||||
}
|
||||
|
||||
ase_sll_node_t* ase_sll_pushhead (ase_sll_t* sll, void* data, ase_size_t size)
|
||||
node_t* ase_sll_pushhead (sll_t* sll, void* data, size_t size)
|
||||
{
|
||||
return ase_sll_insert (sll, sll->head, data, size);
|
||||
return ase_sll_insert (sll, HEAD(sll), data, size);
|
||||
}
|
||||
|
||||
ase_sll_node_t* ase_sll_pushtail (ase_sll_t* sll, void* data, ase_size_t size)
|
||||
node_t* ase_sll_pushtail (sll_t* sll, void* data, size_t size)
|
||||
{
|
||||
return ase_sll_insert (sll, ASE_NULL, data, size);
|
||||
}
|
||||
|
||||
void ase_sll_delete (ase_sll_t* sll, ase_sll_node_t* pos)
|
||||
void ase_sll_delete (sll_t* sll, node_t* pos)
|
||||
{
|
||||
if (pos == ASE_NULL) return; /* not a valid node */
|
||||
|
||||
if (pos == sll->head)
|
||||
if (pos == HEAD(sll))
|
||||
{
|
||||
/* it is simple to delete the head node */
|
||||
sll->head = pos->next;
|
||||
if (sll->head == ASE_NULL) sll->tail = ASE_NULL;
|
||||
HEAD(sll) = NEXT(pos);
|
||||
if (HEAD(sll) == ASE_NULL) TAIL(sll) = ASE_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* but deletion of other nodes has significant performance
|
||||
* penalty as it has look for the predecessor of the
|
||||
* target node */
|
||||
ase_sll_node_t* n2 = sll->head;
|
||||
while (n2->next != pos) n2 = n2->next;
|
||||
node_t* n2 = HEAD(sll);
|
||||
while (NEXT(n2) != pos) n2 = NEXT(n2);
|
||||
|
||||
n2->next = pos->next;
|
||||
NEXT(n2) = NEXT(pos);
|
||||
|
||||
/* update the tail node if necessary */
|
||||
if (pos == sll->tail) sll->tail = n2;
|
||||
if (pos == TAIL(sll)) TAIL(sll) = n2;
|
||||
}
|
||||
|
||||
if (sll->freeer != ASE_NULL)
|
||||
{
|
||||
/* free the actual data */
|
||||
sll->freeer (sll, pos->dptr, pos->dlen);
|
||||
sll->freeer (sll, DPTR(pos), DLEN(pos));
|
||||
}
|
||||
|
||||
/* free the node */
|
||||
ASE_MMGR_FREE (sll->mmgr, pos);
|
||||
|
||||
/* decrement the number of elements */
|
||||
sll->size--;
|
||||
SIZE(sll)--;
|
||||
}
|
||||
|
||||
void ase_sll_pophead (ase_sll_t* sll)
|
||||
void ase_sll_pophead (sll_t* sll)
|
||||
{
|
||||
ase_sll_delete (sll, sll->head);
|
||||
ase_sll_delete (sll, HEAD(sll));
|
||||
}
|
||||
|
||||
void ase_sll_poptail (ase_sll_t* sll)
|
||||
void ase_sll_poptail (sll_t* sll)
|
||||
{
|
||||
ase_sll_delete (sll, sll->tail);
|
||||
ase_sll_delete (sll, TAIL(sll));
|
||||
}
|
||||
|
||||
void ase_sll_walk (ase_sll_t* sll, ase_sll_walker_t walker, void* arg)
|
||||
void ase_sll_walk (sll_t* sll, walker_t walker, void* arg)
|
||||
{
|
||||
ase_sll_node_t* n = sll->head;
|
||||
node_t* n = HEAD(sll);
|
||||
|
||||
while (n != ASE_NULL)
|
||||
{
|
||||
if (walker(sll,n,arg) == ASE_SLL_WALK_STOP) return;
|
||||
n = n->next;
|
||||
n = NEXT(n);
|
||||
}
|
||||
}
|
||||
|
||||
void* ase_sll_copyinline (ase_sll_t* sll, void* dptr, ase_size_t dlen)
|
||||
void* ase_sll_copyinline (sll_t* sll, void* dptr, size_t dlen)
|
||||
{
|
||||
/* this is a dummy copier */
|
||||
return ASE_NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user