qse/ase/lib/cmn/sll.c

164 lines
2.9 KiB
C
Raw Normal View History

2008-08-06 07:30:10 +00:00
/*
* $Id$
*
* {License}
*/
#include <ase/cmn/sll.h>
#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;
};
struct ase_sll_node_t
{
ase_sll_node_t* data;
ase_size_t size;
ase_sll_node_t* next;
};
void* ase_sll_copyinline (ase_sll_t* sll, void* data, ase_size_t size)
{
/* 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);
}
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;
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;
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;
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)
{
ase_sll_node_t* n = sll->head->next;
if (sll->freeer != ASE_NULL)
{
sll->freeer (sll, sll->head->data, sll->head->size);
}
2008-08-07 07:52:14 +00:00
ASE_FREE (sll->mmgr, sll->head);
sll->head = n;
}
sll->tail = ASE_NULL;
}
void* ase_sll_getextension (ase_sll_t* sll)
{
return sll + 1;
2008-08-07 07:52:14 +00:00
}
ase_size_t ase_sll_getsize (ase_sll_t* sll)
2008-08-07 07:52:14 +00:00
{
return sll->size;
2008-08-07 07:52:14 +00:00
}
void ass_sll_setcopier (ase_sll_t* sll, ase_sll_copier_t copier)
2008-08-07 07:52:14 +00:00
{
sll->copier = copier;
2008-08-07 07:52:14 +00:00
}
void ase_sll_setfreeer (ase_sll_t* sll, ase_sll_freeer_t freeer)
2008-08-07 07:52:14 +00:00
{
sll->freeer = freeer;
2008-08-07 07:52:14 +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;
if (sll->copier == ASE_NULL)
{
n = ASE_MALLOC (sll->mmgr, ASE_SIZEOF(ase_sll_node_t));
if (n == ASE_NULL) return ASE_NULL;
n->data = data;
}
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
ASE_MEMCPY (n + 1, data, size);
n->data = n + 1;
}
else
{
n = ASE_MALLOC (sll->mmgr, ASE_SIZEOF(ase_sll_node_t));
if (n == ASE_NULL) return ASE_NULL;
n->data = sll->copier (sll, data, size);
}
n->size = size;
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-07 07:52:14 +00:00
sll->head = n;
if (sll->tail == ASE_NULL) sll->tail = n;
sll->size++;
2008-08-07 07:52:14 +00:00
return n;
}
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;
}
void ase_sll_walk (ase_sll_t* sll, ase_sll_walker_t walker)
{
ase_sll_node_t* n = sll->head;
while (n != ASE_NULL)
{
walker (sll, n->data, n->size);
n = n->next;
}
}