* File name: m_list.h
* Author: Seree Rakwong
* Date: 13-SEP-2013
*
* A list is implemented by the range as [a, b) (including a, but b)
*/
#ifndef _MLIST_H_
#define _MLIST_H_
#include <stdlib.h>
#include <string.h>
#include "m_node.h"
#ifdef __cplusplus
extern "C" {
#endif
struct _LIST_STRUCT;
typedef struct _LIST_STRUCT list_t;
struct _LIST_ITER_STRUCT;
typedef struct _LIST_ITER_STRUCT* list_iter_t;
list_t* list_create();
void list_destroy(list_t*);
typedef long (*fn_list_insert_first)(list_t*, const void*, unsigned long);
typedef long (*fn_list_insert_last)(list_t*, const void*, unsigned long);
typedef long (*fn_list_insert_before)(list_t*, list_iter_t, const void*, unsigned long);
typedef long (*fn_list_insert_after)(list_t*, list_iter_t, const void*, unsigned long);
typedef long (*fn_list_remove_at)(list_t*, list_iter_t);
typedef long (*fn_list_remove_all)(list_t*);
typedef long (*fn_list_remove_first)(list_t*);
typedef long (*fn_list_remove_last)(list_t*);
typedef unsigned long (*fn_list_get_count)(list_t*);
typedef list_iter_t (*fn_list_begin)(list_t*);
typedef list_iter_t (*fn_list_end)(list_t*);
typedef node_t (*fn_list_at)(list_iter_t iter);
/*
long list_insert_first(list_t*, const void*, unsigned long);
long list_insert_last(list_t*, const void*, unsigned long);
long list_insert_before(list_t*, list_iter_t, const void*, unsigned long);
long list_insert_after(list_t*, list_iter_t, const void*, unsigned long);
long list_remove_at(list_t*, list_iter_t);
long list_remove_all(list_t*);
long list_remove_first(list_t*);
long list_remove_last(list_t*);
unsigned long list_get_count(list_t*);
list_iter_t list_begin(list_t*);
list_iter_t list_end(list_t*);
node_t list_at(list_iter_t iter);
*/
struct _LIST_ITER_STRUCT
{
node_t node;
list_iter_t prev;
list_iter_t next;
};
struct _LIST_STRUCT
{
list_iter_t head;
list_iter_t tail;
unsigned long nodes;
/* methods */
fn_list_insert_first insert_first;
fn_list_insert_last insert_last;
fn_list_insert_before insert_before;
fn_list_insert_after insert_after;
fn_list_remove_at remove_at;
fn_list_remove_all remove_all;
fn_list_remove_first remove_first;
fn_list_remove_last remove_last;
fn_list_get_count count;
fn_list_begin begin;
fn_list_end end;
fn_list_at at;
};
#ifdef __cplusplus
}
#endif
#endif /* _MLIST_H_ */
/*
* File name: m_list.c
* Author: Seree Rakwong
* Date: 13-SEP-2013
*/
#include "m_list.h"
#ifdef __cplusplus
extern "C" {
#endif
{
list_iter_t iter = (list_iter_t)malloc(sizeof(struct _LIST_ITER_STRUCT));
if (iter != 0)
{
memset(iter, 0, sizeof(struct _LIST_ITER_STRUCT));
if (vp && size > 0)
{
iter->node = node_init(vp, size);
}
}
return iter;
}
void _list_iterator_release(list_iter_t iter)
{
if (iter)
{
if (iter->node)
{
node_release(iter->node);
}
free(iter);
}
}
/*------------------------------------------------------------*/
long list_insert_first(list_t*, const void*, unsigned long);
long list_insert_last(list_t*, const void*, unsigned long);
long list_insert_before(list_t*, list_iter_t, const void*, unsigned long);
long list_insert_after(list_t*, list_iter_t, const void*, unsigned long);
void list_free(list_t*);
long list_remove_at(list_t*, list_iter_t);
long list_remove_all(list_t*);
long list_remove_first(list_t*);
long list_remove_last(list_t*);
unsigned long list_get_count(list_t*);
list_iter_t list_begin(list_t*);
list_iter_t list_end(list_t*);
node_t list_at(list_iter_t iter);
/*------------------------------------------------------------*/
list_t* list_create()
{
list_t* list = (list_t*)malloc(sizeof(list_t));
if (list != 0)
{
list->nodes = 0;
list->head = list->tail = _list_iterator_init(0, 0);
/* init methods */
list->insert_first = list_insert_first;
list->insert_last = list_insert_last;
list->insert_before = list_insert_before;
list->insert_after = list_insert_after;
list->remove_at = list_remove_at;
list->remove_all = list_remove_all;
list->remove_first = list_remove_first;
list->remove_last = list_remove_last;
list->count = list_get_count;
list->begin = list_begin;
list->end = list_end;
list->at = list_at;
}
return list;
}
void list_destroy(list_t* list)
{
if (list)
{
list->remove_all(list);
free(list);
}
}
long list_insert_first(list_t* list, const void* vp, unsigned long size)
{
long rc = 0;
list_iter_t iter = 0;
if (vp && size)
{
iter = _list_iterator_init(vp, size);
if (iter != 0)
{
iter->next = list->head;
list->head->prev = iter;
list->head = iter;
++list->nodes;
}
else
{
rc = -2;
}
}
else
{
rc = -1;
}
return rc;
}
long list_insert_last(list_t* list, const void* vp, unsigned long size)
{
long rc = 0;
list_iter_t iter = 0;
if (vp && size)
{
iter = _list_iterator_init(vp, size);
if (iter != 0)
{
iter->next = list->tail;
iter->prev = list->tail->prev;
if (list->tail->prev)
{
list->tail->prev->next = iter;
}
list->tail->prev = iter;
if (list->head == list->tail)
{
list->head = iter;
}
++list->nodes;
}
else
{
rc = -2;
}
}
else
{
rc = -1;
}
return rc;
}
long list_insert_before(list_t* list, list_iter_t iter_after, const void* vp, unsigned long size)
{
long rc = 0;
list_iter_t iter = 0;
if (vp && size > 0)
{
iter = _list_iterator_init(vp, size);
if (iter != 0)
{
iter->next = iter_after;
iter->prev = iter_after->prev;
if (iter_after->prev)
{
iter_after->prev->next = iter;
}
iter_after->prev = iter;
++list->nodes;
}
else
{
rc = -2;
}
}
else
{
rc = -1;
}
return rc;
}
long list_insert_after(list_t* list, list_iter_t iter_before, const void* vp, unsigned long size)
{
long rc = 0;
list_iter_t iter = 0;
if (vp && size > 0)
{
iter = _list_iterator_init(vp, size);
if (iter != 0)
{
iter->prev = iter_before;
iter->next = iter_before->next;
if (iter_before->next)
{
iter_before->next->prev = iter;
}
iter_before->next = iter;
++list->nodes;
}
else
{
rc = -2;
}
}
else
{
rc = -1;
}
return rc;
}
long list_remove_at(list_t* list, list_iter_t iter)
{
long rc = 0;
/* is it a head item? */
if (iter == list->head)
{
return list->remove_first(list);
}
/* is it a tail item? */
if (iter == list->tail)
{
return list->remove_last(list);
}
/* link them */
if (iter->next)
{
iter->next->prev = iter->prev;
}
if (iter->prev)
{
iter->prev->next = iter->next;
}
/* remove it */
_list_iterator_release(iter);
if (list->nodes > 0)
{
--list->nodes;
}
return rc;
}
long list_remove_all(list_t* list)
{
long rc = 0;
list_iter_t iter = list->head;
while (iter != list->tail)
{
list->remove_first(list);
iter = list->head;
}
/*
* set the tail and head of the list
*/
list->tail->prev = 0;
list->head = list->tail;
list->nodes = 0;
return rc;
}
long list_remove_first(list_t* list)
{
long rc = 0;
list_iter_t iter = list->head;
if (iter == list->tail)
{
/* no more item to remove */
return 0;
}
list->head = iter->next;
list->head->prev = 0;
/* ok to free the memory */
_list_iterator_release(iter);
if (list->nodes > 0)
{
--list->nodes;
}
return rc;
}
long list_remove_last(list_t* list)
{
long rc = 0;
list_iter_t iter = list->tail->prev;
if (!iter)
{
/* no more item to remove */
return 0;
}
list->tail->prev = iter->prev;
if (iter->prev)
{
iter->prev->next = list->tail;
}
/* ok to free the memory */
_list_iterator_release(iter);
if (list->nodes > 0)
{
--list->nodes;
}
return rc;
}
unsigned long list_get_count(list_t* list)
{
return list->nodes;
}
list_iter_t list_begin(list_t* list)
{
return list->head;
}
list_iter_t list_end(list_t* list)
{
return list->tail;
}
node_t list_at(list_iter_t iter)
{
if (iter)
{
return iter->node;
}
return 0;
}
#ifdef __cplusplus
}
#endif
No comments:
Post a Comment