This source file includes following definitions.
- gf_list_new
- gf_list_del
- gf_list_reset
- gf_list_add
- gf_list_count
- gf_list_get
- gf_list_last
- gf_list_rem
- gf_list_rem_last
- gf_list_insert
- gf_list_new
- gf_list_del
- gf_list_reset
- gf_list_add
- gf_list_count
- gf_list_get
- gf_list_last
- gf_list_rem
- gf_list_rem_last
- gf_list_insert
- gf_list_new
- gf_list_del
- gf_list_add
- gf_list_count
- gf_list_get
- gf_list_last
- gf_list_rem
- gf_list_rem_last
- gf_list_insert
- gf_list_reset
- gf_list_new
- gf_list_del
- realloc_chain
- gf_list_add
- gf_list_count
- gf_list_get
- gf_list_last
- gf_list_rem
- gf_list_rem_last
- gf_list_insert
- gf_list_reset
- gf_list_find
- gf_list_del_item
- gf_list_enum
- gf_list_rev_enum
- gf_list_swap
- gf_list_transfer
- gf_list_clone
- gf_list_reverse
- gf_list_pop_front
- gf_list_pop_back
#include <gpac/list.h>
#ifdef _WIN32_WCE
#define GF_LIST_LINKED
#else
#define GF_LIST_ARRAY_GROW
#endif
#define GF_LIST_REALLOC(a) (a = a ? (3*a/2) : 10)
#if defined(GF_LIST_LINKED)
typedef struct tagIS
{
struct tagIS *next;
void *data;
} ItemSlot;
struct _tag_array
{
struct tagIS *head;
struct tagIS *tail;
u32 entryCount;
s32 foundEntryNumber;
struct tagIS *foundEntry;
};
GF_EXPORT
GF_List * gf_list_new()
{
GF_List *nlist = (GF_List *) gf_malloc(sizeof(GF_List));
if (! nlist) return NULL;
nlist->head = nlist->foundEntry = NULL;
nlist->tail = NULL;
nlist->foundEntryNumber = -1;
nlist->entryCount = 0;
return nlist;
}
GF_EXPORT
void gf_list_del(GF_List *ptr)
{
if (!ptr) return;
while (ptr->entryCount) gf_list_rem(ptr, 0);
gf_free(ptr);
}
GF_EXPORT
void gf_list_reset(GF_List *ptr)
{
while (ptr && ptr->entryCount) gf_list_rem(ptr, 0);
}
GF_EXPORT
GF_Err gf_list_add(GF_List *ptr, void* item)
{
ItemSlot *entry;
if (! ptr) return GF_BAD_PARAM;
entry = (ItemSlot *) gf_malloc(sizeof(ItemSlot));
if (!entry) return GF_OUT_OF_MEM;
entry->data = item;
entry->next = NULL;
if (! ptr->head) {
ptr->head = entry;
ptr->entryCount = 1;
} else {
ptr->entryCount += 1;
ptr->tail->next = entry;
}
ptr->tail = entry;
ptr->foundEntryNumber = ptr->entryCount - 1;
ptr->foundEntry = entry;
return GF_OK;
}
GF_EXPORT
u32 gf_list_count(const GF_List *ptr)
{
if (! ptr) return 0;
return ptr->entryCount;
}
GF_EXPORT
void *gf_list_get(GF_List *ptr, u32 itemNumber)
{
ItemSlot *entry;
u32 i;
if (!ptr || (itemNumber >= ptr->entryCount) ) return NULL;
if (!ptr->foundEntry || (itemNumber < (u32) ptr->foundEntryNumber) ) {
ptr->foundEntryNumber = 0;
ptr->foundEntry = ptr->head;
}
entry = ptr->foundEntry;
for (i = ptr->foundEntryNumber; i < itemNumber; i++ ) {
entry = entry->next;
}
ptr->foundEntryNumber = itemNumber;
ptr->foundEntry = entry;
return (void *) entry->data;
}
GF_EXPORT
void *gf_list_last(GF_List *ptr)
{
ItemSlot *entry;
if (!ptr || !ptr->entryCount) return NULL;
entry = ptr->head;
while (entry->next) entry = entry->next;
return entry->data;
}
GF_EXPORT
GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber)
{
ItemSlot *tmp, *tmp2;
u32 i;
if ( (! ptr) || (! ptr->head) || (ptr->head && !ptr->entryCount) || (itemNumber >= ptr->entryCount) )
return GF_BAD_PARAM;
if (! itemNumber) {
tmp = ptr->head;
ptr->head = ptr->head->next;
ptr->entryCount --;
ptr->foundEntry = ptr->head;
ptr->foundEntryNumber = 0;
gf_free(tmp);
if (!ptr->entryCount) {
ptr->tail = ptr->head = ptr->foundEntry = NULL;
ptr->foundEntryNumber = -1;
}
return GF_OK;
}
tmp = ptr->head;
i = 0;
while (i < itemNumber - 1) {
tmp = tmp->next;
i++;
}
tmp2 = tmp->next;
tmp->next = tmp2->next;
if (! tmp->next || (ptr->tail == tmp2) ) {
ptr->tail = tmp;
tmp->next = NULL;
}
gf_free(tmp2);
ptr->entryCount --;
ptr->foundEntry = ptr->head;
ptr->foundEntryNumber = 0;
return GF_OK;
}
GF_EXPORT
GF_Err gf_list_rem_last(GF_List *ptr)
{
return gf_list_rem(ptr, ptr->entryCount-1);
}
GF_EXPORT
GF_Err gf_list_insert(GF_List *ptr, void *item, u32 position)
{
u32 i;
ItemSlot *tmp, *tmp2;
if (!ptr || !item) return GF_BAD_PARAM;
if (position >= ptr->entryCount) return gf_list_add(ptr, item);
tmp2 = (ItemSlot *) gf_malloc(sizeof(ItemSlot));
tmp2->data = item;
tmp2->next = NULL;
if (position == 0) {
tmp2->next = ptr->head;
ptr->head = tmp2;
ptr->entryCount ++;
ptr->foundEntry = tmp2;
ptr->foundEntryNumber = 0;
return GF_OK;
}
tmp = ptr->head;
for (i = 1; i < position; i++) {
tmp = tmp->next;
if (!tmp)
break;
}
tmp2->next = tmp->next;
tmp->next = tmp2;
ptr->entryCount ++;
ptr->foundEntry = tmp2;
ptr->foundEntryNumber = i;
return GF_OK;
}
#elif defined(GF_LIST_DOUBLE_LINKED)
typedef struct tagIS
{
struct tagIS *next;
struct tagIS *prev;
void *data;
} ItemSlot;
struct _tag_array
{
struct tagIS *head;
struct tagIS *tail;
u32 entryCount;
s32 foundEntryNumber;
struct tagIS *foundEntry;
};
GF_EXPORT
GF_List * gf_list_new()
{
GF_List *nlist = (GF_List *) gf_malloc(sizeof(GF_List));
if (! nlist) return NULL;
nlist->head = nlist->foundEntry = NULL;
nlist->tail = NULL;
nlist->foundEntryNumber = -1;
nlist->entryCount = 0;
return nlist;
}
GF_EXPORT
void gf_list_del(GF_List *ptr)
{
if (!ptr) return;
while (ptr->entryCount) {
gf_list_rem(ptr, 0);
}
gf_free(ptr);
}
GF_EXPORT
void gf_list_reset(GF_List *ptr)
{
while (ptr && ptr->entryCount) gf_list_rem(ptr, 0);
}
GF_EXPORT
GF_Err gf_list_add(GF_List *ptr, void* item)
{
ItemSlot *entry;
if (! ptr) return GF_BAD_PARAM;
entry = (ItemSlot *) gf_malloc(sizeof(ItemSlot));
if (!entry) return GF_OUT_OF_MEM;
entry->data = item;
entry->next = entry->prev = NULL;
if (! ptr->head) {
ptr->head = entry;
ptr->entryCount = 1;
} else {
ptr->entryCount += 1;
entry->prev = ptr->tail;
ptr->tail->next = entry;
}
ptr->tail = entry;
ptr->foundEntryNumber = ptr->entryCount - 1;
ptr->foundEntry = entry;
return GF_OK;
}
GF_EXPORT
u32 gf_list_count(GF_List *ptr)
{
if (! ptr) return 0;
return ptr->entryCount;
}
GF_EXPORT
void *gf_list_get(GF_List *ptr, u32 itemNumber)
{
ItemSlot *entry;
u32 i;
if (!ptr || !ptr->head || (itemNumber >= ptr->entryCount) ) return NULL;
if (!itemNumber) {
ptr->foundEntry = ptr->head;
ptr->foundEntryNumber = 0;
return ptr->head->data;
}
entry = ptr->foundEntry;
if ( itemNumber < (u32) ptr->foundEntryNumber ) {
for (i = ptr->foundEntryNumber; i > itemNumber; i-- ) {
entry = entry->prev;
}
} else {
for (i = ptr->foundEntryNumber; i < itemNumber; i++ ) {
entry = entry->next;
}
}
ptr->foundEntryNumber = itemNumber;
ptr->foundEntry = entry;
return (void *) entry->data;
}
GF_EXPORT
void *gf_list_last(GF_List *ptr)
{
if(!ptr || !ptr->tail) return NULL;
return ptr->tail->data;
}
GF_EXPORT
GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber)
{
ItemSlot *tmp;
u32 i;
if ( (! ptr) || (! ptr->head) || (ptr->head && !ptr->entryCount) || (itemNumber >= ptr->entryCount) )
return GF_BAD_PARAM;
if (! itemNumber) {
tmp = ptr->head;
ptr->head = ptr->head->next;
ptr->entryCount --;
ptr->foundEntry = ptr->head;
ptr->foundEntryNumber = 0;
gf_free(tmp);
if (!ptr->entryCount) {
ptr->tail = ptr->head = ptr->foundEntry = NULL;
ptr->foundEntryNumber = -1;
} else {
ptr->head->prev = NULL;
}
return GF_OK;
}
else if (itemNumber==ptr->entryCount-1) {
tmp = ptr->tail;
ptr->tail = tmp->prev;
ptr->tail->next = NULL;
ptr->entryCount--;
if (ptr->foundEntry==tmp) {
ptr->foundEntry = ptr->tail;
ptr->foundEntryNumber = ptr->entryCount-1;
}
gf_free(tmp);
return GF_OK;
}
tmp = ptr->foundEntry;
if ( itemNumber < (u32) ptr->foundEntryNumber ) {
for (i = ptr->foundEntryNumber; i > itemNumber; i-- ) {
tmp = tmp->prev;
}
} else {
for (i = ptr->foundEntryNumber; i < itemNumber; i++ ) {
tmp = tmp->next;
}
}
tmp->prev->next = tmp->next;
tmp->next->prev = tmp->prev;
if (tmp==ptr->foundEntry) ptr->foundEntry = tmp->next;
gf_free(tmp);
ptr->entryCount--;
return GF_OK;
}
GF_EXPORT
GF_Err gf_list_rem_last(GF_List *ptr)
{
return gf_list_rem(ptr, ptr->entryCount-1);
}
GF_EXPORT
GF_Err gf_list_insert(GF_List *ptr, void *item, u32 position)
{
u32 i;
ItemSlot *tmp, *tmp2;
if (!ptr || !item) return GF_BAD_PARAM;
if (position >= ptr->entryCount) return gf_list_add(ptr, item);
tmp2 = (ItemSlot *) gf_malloc(sizeof(ItemSlot));
tmp2->data = item;
tmp2->next = tmp2->prev = NULL;
if (position == 0) {
ptr->head->prev = tmp2;
tmp2->next = ptr->head;
ptr->head = tmp2;
ptr->entryCount ++;
ptr->foundEntry = tmp2;
ptr->foundEntryNumber = 0;
return GF_OK;
}
tmp = ptr->foundEntry;
if ( position < (u32) ptr->foundEntryNumber ) {
for (i = ptr->foundEntryNumber; i >= position; i-- ) {
tmp = tmp->prev;
}
tmp = tmp->prev;
} else {
for (i = ptr->foundEntryNumber; i < position; i++ ) {
tmp = tmp->next;
}
}
tmp2->next = tmp->next;
tmp2->next->prev = tmp2;
tmp2->prev = tmp;
tmp2->prev->next = tmp2;
ptr->entryCount ++;
ptr->foundEntry = tmp2;
ptr->foundEntryNumber = position;
return GF_OK;
}
#elif defined(GF_LIST_ARRAY)
struct _tag_array
{
void **slots;
u32 entryCount;
};
GF_EXPORT
GF_List * gf_list_new()
{
GF_List *nlist = (GF_List *) gf_malloc(sizeof(GF_List));
if (! nlist) return NULL;
nlist->slots = NULL;
nlist->entryCount = 0;
return nlist;
}
GF_EXPORT
void gf_list_del(GF_List *ptr)
{
if (!ptr) return;
gf_free(ptr->slots);
gf_free(ptr);
}
GF_EXPORT
GF_Err gf_list_add(GF_List *ptr, void* item)
{
if (! ptr) return GF_BAD_PARAM;
ptr->entryCount ++;
ptr->slots = (void **) gf_realloc(ptr->slots, ptr->entryCount*sizeof(void*));
if (!ptr->slots) {
ptr->entryCount = 0;
return GF_OUT_OF_MEM;
}
ptr->slots[ptr->entryCount-1] = item;
return GF_OK;
}
GF_EXPORT
u32 gf_list_count(GF_List *ptr)
{
return ptr ? ptr->entryCount : 0;
}
GF_EXPORT
void *gf_list_get(GF_List *ptr, u32 itemNumber)
{
if(!ptr || (itemNumber >= ptr->entryCount)) return NULL;
return ptr->slots[itemNumber];
}
GF_EXPORT
void *gf_list_last(GF_List *ptr)
{
if(!ptr || !ptr->entryCount) return NULL;
return ptr->slots[ptr->entryCount-1];
}
GF_EXPORT
GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber)
{
u32 i;
if ( !ptr || !ptr->slots || !ptr->entryCount) return GF_BAD_PARAM;
i = ptr->entryCount - itemNumber - 1;
if (i) memmove(&ptr->slots[itemNumber], & ptr->slots[itemNumber +1], sizeof(void *)*i);
ptr->slots[ptr->entryCount-1] = NULL;
ptr->entryCount -= 1;
ptr->slots = (void **) gf_realloc(ptr->slots, sizeof(void*)*ptr->entryCount);
return GF_OK;
}
GF_EXPORT
GF_Err gf_list_rem_last(GF_List *ptr)
{
if ( !ptr || !ptr->slots || !ptr->entryCount) return GF_BAD_PARAM;
ptr->entryCount -= 1;
ptr->slots = (void **) gf_realloc(ptr->slots, sizeof(void*)*ptr->entryCount);
return GF_OK;
}
GF_EXPORT
GF_Err gf_list_insert(GF_List *ptr, void *item, u32 position)
{
u32 i;
if (!ptr || !item) return GF_BAD_PARAM;
if (position >= ptr->entryCount) return gf_list_add(ptr, item);
ptr->slots = (void **) gf_realloc(ptr->slots, (ptr->entryCount+1)*sizeof(void*));
i = ptr->entryCount - position;
memmove(&ptr->slots[position + 1], &ptr->slots[position], sizeof(void *)*i);
ptr->entryCount++;
ptr->slots[position] = item;
return GF_OK;
}
GF_EXPORT
void gf_list_reset(GF_List *ptr)
{
if (ptr) {
ptr->entryCount = 0;
gf_free(ptr->slots);
ptr->slots = NULL;
}
}
#else
struct _tag_array
{
void **slots;
u32 entryCount;
u32 allocSize;
};
GF_EXPORT
GF_List * gf_list_new()
{
GF_List *nlist;
nlist = (GF_List *) gf_malloc(sizeof(GF_List));
if (! nlist) return NULL;
nlist->slots = NULL;
nlist->entryCount = 0;
nlist->allocSize = 0;
return nlist;
}
GF_EXPORT
void gf_list_del(GF_List *ptr)
{
if (!ptr) return;
gf_free(ptr->slots);
gf_free(ptr);
}
static void realloc_chain(GF_List *ptr)
{
GF_LIST_REALLOC(ptr->allocSize);
ptr->slots = (void**)gf_realloc(ptr->slots, ptr->allocSize*sizeof(void*));
}
GF_EXPORT
GF_Err gf_list_add(GF_List *ptr, void* item)
{
if (! ptr) return GF_BAD_PARAM;
if (ptr->allocSize==ptr->entryCount) realloc_chain(ptr);
if (!ptr->slots) return GF_OUT_OF_MEM;
ptr->slots[ptr->entryCount] = item;
ptr->entryCount ++;
return GF_OK;
}
GF_EXPORT
u32 gf_list_count(const GF_List *ptr)
{
if (!ptr) return 0;
return ptr->entryCount;
}
GF_EXPORT
void *gf_list_get(GF_List *ptr, u32 itemNumber)
{
if(!ptr || (itemNumber >= ptr->entryCount)) return NULL;
return ptr->slots[itemNumber];
}
GF_EXPORT
void *gf_list_last(GF_List *ptr)
{
if(!ptr || !ptr->entryCount) return NULL;
return ptr->slots[ptr->entryCount-1];
}
GF_EXPORT
GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber)
{
u32 i;
if ( !ptr || !ptr->slots || !ptr->entryCount) return GF_BAD_PARAM;
i = ptr->entryCount - itemNumber - 1;
if (i) memmove(&ptr->slots[itemNumber], & ptr->slots[itemNumber +1], sizeof(void *)*i);
ptr->slots[ptr->entryCount-1] = NULL;
ptr->entryCount -= 1;
return GF_OK;
}
GF_EXPORT
GF_Err gf_list_rem_last(GF_List *ptr)
{
if ( !ptr || !ptr->slots || !ptr->entryCount) return GF_BAD_PARAM;
ptr->slots[ptr->entryCount-1] = NULL;
ptr->entryCount -= 1;
return GF_OK;
}
GF_EXPORT
GF_Err gf_list_insert(GF_List *ptr, void *item, u32 position)
{
u32 i;
if (!ptr || !item) return GF_BAD_PARAM;
if (position >= ptr->entryCount) return gf_list_add(ptr, item);
if (ptr->allocSize==ptr->entryCount) realloc_chain(ptr);
i = ptr->entryCount - position;
memmove(&ptr->slots[position + 1], &ptr->slots[position], sizeof(void *)*i);
ptr->entryCount++;
ptr->slots[position] = item;
return GF_OK;
}
GF_EXPORT
void gf_list_reset(GF_List *ptr)
{
if (ptr) ptr->entryCount = 0;
}
#endif
GF_EXPORT
s32 gf_list_find(GF_List *ptr, void *item)
{
u32 i, count;
count = gf_list_count(ptr);
for (i=0; i<count; i++) {
if (gf_list_get(ptr, i) == item) return (s32) i;
}
return -1;
}
GF_EXPORT
s32 gf_list_del_item(GF_List *ptr, void *item)
{
s32 i = gf_list_find(ptr, item);
if (i>=0) gf_list_rem(ptr, (u32) i);
return i;
}
GF_EXPORT
void *gf_list_enum(GF_List *ptr, u32 *pos)
{
void *res;
if (!ptr || !pos) return NULL;
res = gf_list_get(ptr, *pos);
(*pos)++;
return res;
}
GF_EXPORT
void *gf_list_rev_enum(GF_List *ptr, u32 *pos) {
void *res;
if (!ptr || !pos) return NULL;
res = gf_list_get(ptr, gf_list_count (ptr) - *pos - 1 );
(*pos)++;
return res;
}
GF_EXPORT
GF_Err gf_list_swap(GF_List *l1, GF_List *l2)
{
GF_Err e;
u32 count = gf_list_count(l1);
if (!l1 || !l2) return GF_BAD_PARAM;
if (l1 == l2) return GF_OK;
while (gf_list_count(l2)) {
void *ptr = gf_list_get(l2, 0);
e = gf_list_rem(l2, 0);
if (e) return e;
e = gf_list_add(l1, ptr);
if (e) return e;
}
while (count) {
void *ptr = gf_list_get(l1, 0);
e = gf_list_rem(l1, 0);
if (e) return e;
count--;
e = gf_list_add(l2, ptr);
if (e) return e;
}
return GF_OK;
}
GF_EXPORT
GF_Err gf_list_transfer(GF_List *l1, GF_List *l2)
{
GF_Err e;
if (!l1 || !l2) return GF_BAD_PARAM;
if (l1 == l2) return GF_OK;
while (gf_list_count(l2)) {
void *ptr = gf_list_get(l2, 0);
e = gf_list_rem(l2, 0);
if (e) return e;
e = gf_list_add(l1, ptr);
if (e) return e;
}
return GF_OK;
}
GF_EXPORT
GF_List* gf_list_clone(GF_List *ptr) {
GF_List* new_list;
u32 i = 0;
void* item;
if (!ptr) return NULL;
new_list = gf_list_new();
while ((item = gf_list_enum(ptr, &i)))
gf_list_add(new_list, item);
return new_list;
}
GF_EXPORT
void gf_list_reverse(GF_List *ptr) {
GF_List* saved_order;
void* item;
u32 i = 0;
if (!ptr) return;
saved_order = gf_list_clone(ptr);
gf_list_reset(ptr);
while ((item = gf_list_enum(saved_order, &i))) {
gf_list_insert(ptr, item, 0);
}
gf_list_del(saved_order);
}
GF_EXPORT
void* gf_list_pop_front(GF_List *ptr) {
void * item;
if (!ptr) return NULL;
item = gf_list_get(ptr, 0);
gf_list_rem(ptr, 0);
return item;
}
GF_EXPORT
void* gf_list_pop_back(GF_List *ptr) {
void * item;
if (!ptr) return NULL;
item = gf_list_last(ptr);
gf_list_rem_last(ptr);
return item;
}