#include "hpdf_conf.h"
#include "hpdf_utils.h"
#include "hpdf_consts.h"
#include "hpdf_list.h"
static HPDF_STATUS
Resize (HPDF_List list,
HPDF_UINT count);
HPDF_List
HPDF_List_New (HPDF_MMgr mmgr,
HPDF_UINT items_per_block)
{
HPDF_List list;
HPDF_PTRACE((" HPDF_List_New\n"));
if (mmgr == NULL)
return NULL;
list = (HPDF_List)HPDF_GetMem (mmgr, sizeof(HPDF_List_Rec));
if (list) {
list->mmgr = mmgr;
list->error = mmgr->error;
list->block_siz = 0;
list->items_per_block =
(items_per_block <= 0 ? HPDF_DEF_ITEMS_PER_BLOCK : items_per_block);
list->count = 0;
list->obj = NULL;
}
return list;
}
HPDF_STATUS
HPDF_List_Add (HPDF_List list,
void *item)
{
HPDF_PTRACE((" HPDF_List_Add\n"));
if (list->count >= list->block_siz) {
HPDF_STATUS ret = Resize (list,
list->block_siz + list->items_per_block);
if (ret != HPDF_OK) {
return ret;
}
}
list->obj[list->count++] = item;
return HPDF_OK;
}
HPDF_STATUS
HPDF_List_Insert (HPDF_List list,
void *target,
void *item)
{
HPDF_INT target_idx = HPDF_List_Find (list, target);
void *last_item = list->obj[list->count - 1];
HPDF_INT i;
HPDF_PTRACE((" HPDF_List_Insert\n"));
if (target_idx < 0)
return HPDF_ITEM_NOT_FOUND;
for (i = list->count - 2; i >= target_idx; i--)
list->obj[i + 1] = list->obj[i];
list->obj[target_idx] = item;
return HPDF_List_Add (list, last_item);
}
HPDF_STATUS
HPDF_List_Remove (HPDF_List list,
void *item)
{
HPDF_UINT i;
void **obj = list->obj;
HPDF_PTRACE((" HPDF_List_Remove\n"));
for (i = 0; i < list->count; i++) {
if (*obj == item) {
HPDF_List_RemoveByIndex(list, i);
return HPDF_OK;
} else
obj++;
}
return HPDF_ITEM_NOT_FOUND;
}
void*
HPDF_List_RemoveByIndex (HPDF_List list,
HPDF_UINT index)
{
void *tmp;
HPDF_PTRACE((" HPDF_List_RemoveByIndex\n"));
if (list->count <= index)
return NULL;
tmp = list->obj[index];
while (index < list->count - 1) {
list->obj[index] = list->obj[index + 1];
index++;
}
list->count--;
return tmp;
}
void*
HPDF_List_ItemAt (HPDF_List list,
HPDF_UINT index)
{
HPDF_PTRACE((" HPDF_List_ItemAt\n"));
return (list->count <= index) ? NULL : list->obj[index];
}
void
HPDF_List_Free (HPDF_List list)
{
HPDF_PTRACE((" HPDF_List_Free\n"));
if (!list)
return ;
HPDF_List_Clear (list);
HPDF_FreeMem (list->mmgr, list);
}
void
HPDF_List_Clear (HPDF_List list)
{
HPDF_PTRACE((" HPDF_List_Clear\n"));
if (list->obj)
HPDF_FreeMem (list->mmgr, list->obj);
list->block_siz = 0;
list->count = 0;
list->obj = NULL;
}
static HPDF_STATUS
Resize (HPDF_List list,
HPDF_UINT count)
{
void **new_obj;
HPDF_PTRACE((" HPDF_List_Resize\n"));
if (list->count >= count) {
if (list->count == count)
return HPDF_OK;
else
return HPDF_INVALID_PARAMETER;
}
new_obj = (void **)HPDF_GetMem (list->mmgr, count * sizeof(void *));
if (!new_obj)
return HPDF_Error_GetCode (list->error);
if (list->obj)
HPDF_MemCpy ((HPDF_BYTE *)new_obj, (HPDF_BYTE *)list->obj,
list->block_siz * sizeof(void *));
list->block_siz = count;
if (list->obj)
HPDF_FreeMem (list->mmgr, list->obj);
list->obj = new_obj;
return HPDF_OK;
}
HPDF_INT32
HPDF_List_Find (HPDF_List list,
void *item)
{
HPDF_UINT i;
HPDF_PTRACE((" HPDF_List_Find\n"));
for (i = 0; i < list->count; i++) {
if (list->obj[i] == item)
return i;
}
return -1;
}