2008-08-06 07:30:10 +00:00
|
|
|
/*
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* {License}
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <ase/cmn/sll.h>
|
2008-08-08 05:02:08 +00:00
|
|
|
#include "mem.h"
|
|
|
|
|
|
|
|
struct ase_sll_t
|
|
|
|
{
|
|
|
|
ase_mmgr_t* mmgr;
|
|
|
|
|
|
|
|
ase_sll_copier_t copier;
|
|
|
|
ase_sll_freeer_t freeer;
|
|
|
|
|
|
|
|
ase_size_t size;
|
|
|
|
ase_sll_node_t* head;
|
|
|
|
ase_sll_node_t* tail;
|
|
|
|
};
|
|
|
|
|
2008-08-09 04:35:04 +00:00
|
|
|
void* ase_sll_copyinline (ase_sll_t* sll, void* dptr, ase_size_t dlen)
|
2008-08-08 05:02:08 +00:00
|
|
|
{
|
|
|
|
/* this is a dummy copier */
|
|
|
|
return ASE_NULL;
|
|
|
|
}
|
2008-08-06 07:30:10 +00:00
|
|
|
|
|
|
|
ase_sll_t* ase_sll_open (ase_mmgr_t* mmgr)
|
|
|
|
{
|
|
|
|
return ase_sll_openx (mmgr, 0, ASE_NULL);
|
|
|
|
}
|
|
|
|
|
2008-08-08 05:02:08 +00:00
|
|
|
ase_sll_t* ase_sll_openx (ase_mmgr_t* mmgr, ase_size_t extension, ase_fuser_t fuser)
|
2008-08-06 07:30:10 +00:00
|
|
|
{
|
|
|
|
ase_sll_t* sll;
|
|
|
|
|
2008-08-08 05:02:08 +00:00
|
|
|
sll = ASE_MALLOC (mmgr, ASE_SIZEOF(ase_sll_t) + extension);
|
2008-08-06 07:30:10 +00:00
|
|
|
if (sll == ASE_NULL) return ASE_NULL;
|
|
|
|
|
2008-08-08 05:02:08 +00:00
|
|
|
ASE_MEMSET (sll, 0, ASE_SIZEOF(ase_sll_t) + extension);
|
|
|
|
if (fuser != ASE_NULL) mmgr = fuser (mmgr, sll + 1);
|
2008-08-06 07:30:10 +00:00
|
|
|
sll->mmgr = mmgr;
|
|
|
|
|
2008-08-08 05:02:08 +00:00
|
|
|
return sll;
|
2008-08-06 07:30:10 +00:00
|
|
|
}
|
2008-08-07 07:52:14 +00:00
|
|
|
|
|
|
|
void ase_sll_close (ase_sll_t* sll)
|
|
|
|
{
|
|
|
|
ase_sll_clear (sll);
|
|
|
|
ASE_FREE (sll->mmgr, sll);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ase_sll_clear (ase_sll_t* sll)
|
|
|
|
{
|
|
|
|
while (sll->head != ASE_NULL)
|
|
|
|
{
|
2008-08-09 04:35:04 +00:00
|
|
|
ase_sll_node_t* h = sll->head;
|
|
|
|
sll->head = h->next;
|
2008-08-07 07:52:14 +00:00
|
|
|
|
2008-08-08 05:02:08 +00:00
|
|
|
if (sll->freeer != ASE_NULL)
|
|
|
|
{
|
2008-08-09 04:35:04 +00:00
|
|
|
sll->freeer (sll, h->data.ptr, h->data.len);
|
2008-08-08 05:02:08 +00:00
|
|
|
}
|
2008-08-07 07:52:14 +00:00
|
|
|
|
2008-08-09 04:35:04 +00:00
|
|
|
ASE_FREE (sll->mmgr, h);
|
2008-08-07 07:52:14 +00:00
|
|
|
}
|
2008-08-08 05:02:08 +00:00
|
|
|
|
|
|
|
sll->tail = ASE_NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void* ase_sll_getextension (ase_sll_t* sll)
|
|
|
|
{
|
|
|
|
return sll + 1;
|
2008-08-07 07:52:14 +00:00
|
|
|
}
|
|
|
|
|
2008-08-08 05:02:08 +00:00
|
|
|
ase_size_t ase_sll_getsize (ase_sll_t* sll)
|
2008-08-07 07:52:14 +00:00
|
|
|
{
|
2008-08-08 05:02:08 +00:00
|
|
|
return sll->size;
|
2008-08-07 07:52:14 +00:00
|
|
|
}
|
|
|
|
|
2008-08-09 04:35:04 +00:00
|
|
|
ase_sll_node_t* ase_sll_gethead (ase_sll_t* sll)
|
|
|
|
{
|
|
|
|
return sll->head;
|
|
|
|
}
|
|
|
|
|
|
|
|
ase_sll_node_t* ase_sll_gettail (ase_sll_t* sll)
|
|
|
|
{
|
|
|
|
return sll->tail;
|
|
|
|
}
|
|
|
|
|
2008-08-08 05:02:08 +00:00
|
|
|
void ass_sll_setcopier (ase_sll_t* sll, ase_sll_copier_t copier)
|
2008-08-07 07:52:14 +00:00
|
|
|
{
|
2008-08-08 05:02:08 +00:00
|
|
|
sll->copier = copier;
|
2008-08-07 07:52:14 +00:00
|
|
|
}
|
|
|
|
|
2008-08-08 05:02:08 +00:00
|
|
|
void ase_sll_setfreeer (ase_sll_t* sll, ase_sll_freeer_t freeer)
|
2008-08-07 07:52:14 +00:00
|
|
|
{
|
2008-08-08 05:02:08 +00:00
|
|
|
sll->freeer = freeer;
|
2008-08-07 07:52:14 +00:00
|
|
|
}
|
|
|
|
|
2008-08-08 05:02:08 +00:00
|
|
|
static ase_sll_node_t* alloc_node (ase_sll_t* sll, void* data, ase_size_t size)
|
2008-08-07 07:52:14 +00:00
|
|
|
{
|
|
|
|
ase_sll_node_t* n;
|
|
|
|
|
2008-08-08 05:02:08 +00:00
|
|
|
if (sll->copier == ASE_NULL)
|
|
|
|
{
|
|
|
|
n = ASE_MALLOC (sll->mmgr, ASE_SIZEOF(ase_sll_node_t));
|
|
|
|
if (n == ASE_NULL) return ASE_NULL;
|
2008-08-09 04:35:04 +00:00
|
|
|
n->data.ptr = data;
|
2008-08-08 05:02:08 +00:00
|
|
|
}
|
|
|
|
else if (sll->copier == ASE_SLL_COPIER_INLINE)
|
|
|
|
{
|
|
|
|
n = ASE_MALLOC (sll->mmgr, ASE_SIZEOF(ase_sll_node_t) + size);
|
|
|
|
if (n == ASE_NULL) return ASE_NULL;
|
2008-08-07 07:52:14 +00:00
|
|
|
|
2008-08-08 05:02:08 +00:00
|
|
|
ASE_MEMCPY (n + 1, data, size);
|
2008-08-09 04:35:04 +00:00
|
|
|
n->data.ptr = n + 1;
|
2008-08-08 05:02:08 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
n = ASE_MALLOC (sll->mmgr, ASE_SIZEOF(ase_sll_node_t));
|
|
|
|
if (n == ASE_NULL) return ASE_NULL;
|
2008-08-09 04:35:04 +00:00
|
|
|
n->data.ptr = sll->copier (sll, data, size);
|
2008-08-08 05:02:08 +00:00
|
|
|
}
|
|
|
|
|
2008-08-09 04:35:04 +00:00
|
|
|
n->data.len = size;
|
2008-08-08 05:02:08 +00:00
|
|
|
n->next = ASE_NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ase_sll_node_t* ase_sll_prepend (ase_sll_t* sll, void* data, ase_size_t size)
|
|
|
|
{
|
|
|
|
ase_sll_node_t* n = alloc_node (sll, data, size);
|
2008-08-07 07:52:14 +00:00
|
|
|
if (n == ASE_NULL) return ASE_NULL;
|
|
|
|
|
|
|
|
n->next = sll->head;
|
2008-08-08 05:02:08 +00:00
|
|
|
|
2008-08-07 07:52:14 +00:00
|
|
|
sll->head = n;
|
2008-08-08 05:02:08 +00:00
|
|
|
if (sll->tail == ASE_NULL) sll->tail = n;
|
|
|
|
sll->size++;
|
2008-08-07 07:52:14 +00:00
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2008-08-08 05:02:08 +00:00
|
|
|
ase_sll_node_t* ase_sll_append (ase_sll_t* sll, void* data, ase_size_t size)
|
|
|
|
{
|
|
|
|
ase_sll_node_t* n = alloc_node (sll, data, size);
|
|
|
|
if (n == ASE_NULL) return ASE_NULL;
|
|
|
|
|
|
|
|
if (sll->tail != ASE_NULL) sll->tail->next = n;
|
|
|
|
sll->tail = n;
|
|
|
|
if (sll->head == ASE_NULL) sll->head = n;
|
|
|
|
sll->size++;
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2008-08-09 04:35:04 +00:00
|
|
|
ase_sll_node_t* ase_sll_prepend (ase_sll_t* sll, void* data, ase_size_t size)
|
|
|
|
{
|
|
|
|
return ase_sll_insert (sll, sll->head, data, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ase_sll_node_t* ase_sll_insert (
|
|
|
|
ase_sll_t* sll, ase_sll_node_t* pos, void* data, ase_size_t size)
|
|
|
|
{
|
|
|
|
ase_sll_node_t* n = alloc_node (sll, data, size);
|
|
|
|
if (n == ASE_NULL) return ASE_NULL;
|
|
|
|
|
|
|
|
if (pos == ASE_NULL)
|
|
|
|
{
|
|
|
|
/* insert at the end */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* insert in front of the positional node */
|
|
|
|
n->next = pos->next;
|
|
|
|
pos->next = n;
|
|
|
|
|
|
|
|
if (pos == sll->head) sll->head = n;
|
|
|
|
/* TODO: update head & tail properly */
|
|
|
|
}
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ase_sll_walk (ase_sll_t* sll, ase_sll_walker_t walker, void* arg)
|
2008-08-08 05:02:08 +00:00
|
|
|
{
|
|
|
|
ase_sll_node_t* n = sll->head;
|
|
|
|
|
|
|
|
while (n != ASE_NULL)
|
|
|
|
{
|
2008-08-09 04:35:04 +00:00
|
|
|
walker (sll, n, arg);
|
2008-08-08 05:02:08 +00:00
|
|
|
n = n->next;
|
|
|
|
}
|
|
|
|
}
|