#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "sp_list.h"
typedef struct tag_STRU_SP_LIST_ELEMENT
{
void *pvUserElement;
struct tag_STRU_SP_LIST_ELEMENT *pstruNext;
}STRU_SP_LIST_ELEMENT;
typedef struct tag_STRU_SP_LIST
{
u32 u32ElementSize;
u32 u32ElementNum;
PFUNC_CONSTRUCTOR pFuncConstructor;
PFUNC_DESTRUCTOR pFuncDestructor;
STRU_SP_LIST_ELEMENT *pstruListHead;
STRU_SP_LIST_ELEMENT *pstruListTail;
}STRU_SP_LIST;
extern STRU_SP_LIST_ELEMENT * SP_LIST_CreateNewElement(PLIST pList, void *pvUserElement);
extern void SP_LIST_DestroyElement(PLIST pList, STRU_SP_LIST_ELEMENT * pstruListElement);
extern STRU_SP_LIST_ELEMENT * SP_LIST_GetListElementAt(PLIST pList, u32 u32Pos);
PLIST SP_LIST_Create(u32 u32ElementSize, PFUNC_CONSTRUCTOR pFuncConstructor, PFUNC_DESTRUCTOR pFuncDestructor)
{
PLIST pNewList = (PLIST)malloc(sizeof(STRU_SP_LIST));
if(C_SYS_NULL != pNewList)
{
pNewList->u32ElementSize = u32ElementSize;
pNewList->u32ElementNum = 0;
pNewList->pstruListHead = C_SYS_NULL;
pNewList->pstruListTail = C_SYS_NULL;
if (C_SYS_NULL == pFuncConstructor)
{
pNewList->pFuncConstructor = SP_LIB_DefaultConstructor;
}
else
{
pNewList->pFuncConstructor = pFuncConstructor;
}
if (C_SYS_NULL == pFuncDestructor)
{
pNewList->pFuncDestructor = SP_LIB_DefaultDestructor;
}
else
{
pNewList->pFuncDestructor = pFuncDestructor;
}
}
return pNewList;
}
void SP_LIST_Destroy(PLIST pList)
{
if(C_SYS_NULL != pList)
{
while (!SP_LIST_IsEmpty(pList))
{
SP_LIST_Remove(pList, 0);
}
free(pList);
}
}
u32 SP_LIST_Append(PLIST pList, void *pvNewElement)
{
STRU_SP_LIST_ELEMENT *pstruNewListElement = C_SYS_NULL;
u32 u32NewElementPos = 0;
if ((C_SYS_NULL == pList) || (C_SYS_NULL == pvNewElement))
{
return C_SP_LIB_INVALID_POSITION;
}
pstruNewListElement = SP_LIST_CreateNewElement(pList, pvNewElement);
if (C_SYS_NULL != pstruNewListElement)
{
if(SP_LIST_IsEmpty(pList))
{
pList->pstruListHead = pstruNewListElement;
pList->pstruListTail = pstruNewListElement;
}
else
{
pList->pstruListTail->pstruNext = pstruNewListElement;
pList->pstruListTail = pstruNewListElement;
}
u32NewElementPos = pList->u32ElementNum;
pList->u32ElementNum++;
return u32NewElementPos;
}
else
{
return C_SP_LIB_INVALID_POSITION;
}
}
STRU_SP_LIST_ELEMENT * SP_LIST_CreateNewElement(PLIST pList, void *pvUserElement)
{
STRU_SP_LIST_ELEMENT *pstruNewListElement = C_SYS_NULL;
if ((C_SYS_NULL == pList) || (C_SYS_NULL == pvUserElement))
{
return C_SYS_NULL;
}
pstruNewListElement = (STRU_SP_LIST_ELEMENT *)malloc(sizeof(STRU_SP_LIST_ELEMENT));
if(C_SYS_NULL != pstruNewListElement)
{
pstruNewListElement->pstruNext = C_SYS_NULL;
pstruNewListElement->pvUserElement = (*pList->pFuncConstructor)(pvUserElement, pList->u32ElementSize);
}
return pstruNewListElement;
}
u32 SP_LIST_Size(PLIST pList)
{
if (C_SYS_NULL != pList)
{
return pList->u32ElementNum;
}
else
{
return C_SP_LIB_INVALID_POSITION;
}
}
SYS_BOOL SP_LIST_IsEmpty(PLIST pList)
{
if (C_SYS_NULL != pList)
{
if (0 == pList->u32ElementNum)
{
return TRUE;
}
else
{
return FALSE;
}
}
else
{
return TRUE;
}
}
SYS_BOOL SP_LIST_Remove(PLIST pList, u32 u32Pos)
{
STRU_SP_LIST_ELEMENT *pstruListElement = C_SYS_NULL;
STRU_SP_LIST_ELEMENT *pstruFrontElement = C_SYS_NULL;
STRU_SP_LIST_ELEMENT *pstruNextElement = C_SYS_NULL;
if (C_SYS_NULL == pList)
{
return FALSE;
}
if (0 == pList->u32ElementNum)
{
return FALSE;
}
if (u32Pos >= pList->u32ElementNum)
{
return FALSE;
}
if (1 != pList->u32ElementNum)
{
pstruListElement = SP_LIST_GetListElementAt(pList, u32Pos);
if (0 == u32Pos)
{
pstruNextElement = SP_LIST_GetListElementAt(pList, u32Pos + 1);
SP_LIST_DestroyElement(pList, pList->pstruListHead);
pList->pstruListHead = pstruNextElement;
}
else if (u32Pos == (pList->u32ElementNum - 1))
{
pstruFrontElement = SP_LIST_GetListElementAt(pList, u32Pos - 1);
SP_LIST_DestroyElement(pList, pList->pstruListTail);
pstruFrontElement->pstruNext = C_SYS_NULL;
pList->pstruListTail = pstruFrontElement;
}
else
{
pstruFrontElement = SP_LIST_GetListElementAt(pList, u32Pos - 1);
pstruNextElement = SP_LIST_GetListElementAt(pList, u32Pos + 1);
SP_LIST_DestroyElement(pList, pstruListElement);
pstruFrontElement->pstruNext = pstruNextElement;
}
pList->u32ElementNum --;
}
else
{
SP_LIST_DestroyElement(pList, pList->pstruListHead);
pList->pstruListHead = C_SYS_NULL;
pList->pstruListTail = C_SYS_NULL;
pList->u32ElementNum = 0;
}
return TRUE;
}
void * SP_LIST_GetAt(PLIST pList, u32 u32Pos)
{
STRU_SP_LIST_ELEMENT *pstruListElement = C_SYS_NULL;
if (C_SYS_NULL == pList)
{
return C_SYS_NULL;
}
if (u32Pos >= pList->u32ElementNum)
{
return C_SYS_NULL;
}
pstruListElement = SP_LIST_GetListElementAt(pList, u32Pos);
if (C_SYS_NULL != pstruListElement)
{
return pstruListElement->pvUserElement;
}
else
{
return C_SYS_NULL;
}
}
STRU_SP_LIST_ELEMENT * SP_LIST_GetListElementAt(PLIST pList, u32 u32Pos)
{
STRU_SP_LIST_ELEMENT *pstruListElement = C_SYS_NULL;
u32 u32Count = 0;
if (C_SYS_NULL == pList)
{
return C_SYS_NULL;
}
if (u32Pos >= pList->u32ElementNum)
{
return C_SYS_NULL;
}
pstruListElement = pList->pstruListHead;
while (u32Count < u32Pos)
{
pstruListElement = pstruListElement->pstruNext;
u32Count++;
}
return pstruListElement;
}
void SP_LIST_DestroyElement(PLIST pList, STRU_SP_LIST_ELEMENT * pstruListElement)
{
if ((C_SYS_NULL == pList) || (C_SYS_NULL == pstruListElement))
{
return;
}
(*pList->pFuncDestructor)(pstruListElement->pvUserElement);
pstruListElement->pvUserElement = C_SYS_NULL;
free(pstruListElement);
}
u32 SP_LIST_Find(PLIST pList, PFUNC_COMPARE pFuncCompare, const void *pcvElementOutsight)
{
STRU_SP_LIST_ELEMENT *pstruListElement = C_SYS_NULL;
u32 u32Postion = 0;
if((C_SYS_NULL == pList)
|| (C_SYS_NULL == pFuncCompare)
|| (C_SYS_NULL == pcvElementOutsight))
{
return C_SP_LIB_INVALID_POSITION;
}
pstruListElement = pList->pstruListHead;
while(C_SYS_NULL != pstruListElement)
{
if(0 == (*pFuncCompare)(pcvElementOutsight, pstruListElement->pvUserElement, pList->u32ElementSize))
{
return u32Postion;
}
u32Postion++;
pstruListElement = pstruListElement->pstruNext;
}
return C_SP_LIB_INVALID_POSITION;
}
SYS_BOOL SP_LIST_Insert(PLIST pList, u32 u32Pos, void *pvElement)
{
STRU_SP_LIST_ELEMENT *pstruNewListElement = C_SYS_NULL;
STRU_SP_LIST_ELEMENT *pstruFrontElement = C_SYS_NULL;
STRU_SP_LIST_ELEMENT *pstruListElement = C_SYS_NULL;
if (C_SYS_NULL == pList)
{
return FALSE;
}
if (u32Pos >= pList->u32ElementNum)
{
return FALSE;
}
if (0 == u32Pos)
{
pstruNewListElement = SP_LIST_CreateNewElement(pList, pvElement);
if (C_SYS_NULL != pstruNewListElement)
{
pstruNewListElement->pstruNext = pList->pstruListHead;
pList->pstruListHead = pstruNewListElement;
pList->u32ElementNum++;
return TRUE;
}
else
{
return FALSE;
}
}
else
{
pstruFrontElement = SP_LIST_GetListElementAt(pList, u32Pos-1);
pstruListElement = SP_LIST_GetListElementAt(pList, u32Pos);
pstruNewListElement = SP_LIST_CreateNewElement(pList, pvElement);
if ((C_SYS_NULL != pstruNewListElement)
&& (C_SYS_NULL != pstruFrontElement)
&& (C_SYS_NULL != pstruListElement))
{
pstruFrontElement->pstruNext = pstruNewListElement;
pstruNewListElement->pstruNext = pstruListElement;
pList->u32ElementNum++;
return TRUE;
}
else
{
return FALSE;
}
}
}
void SP_LIST_Traversal(PLIST pList, PFUNC_TRAVERSAL pFuncTraversal, void *pvParam)
{
STRU_SP_LIST_ELEMENT *pstruListElement = C_SYS_NULL;
if (C_SYS_NULL != pList)
{
pstruListElement = pList->pstruListHead;
while(C_SYS_NULL != pstruListElement)
{
(*pFuncTraversal)(pstruListElement->pvUserElement, pvParam);
pstruListElement = pstruListElement->pstruNext;
}
}
}
void * SP_LIST_GetNext(PLIST pList, u32 u32Pos)
{
return SP_LIST_GetAt(pList, u32Pos + 1);
}