372 lines
13 KiB
C
372 lines
13 KiB
C
/********************************************************************************/
|
|
/* */
|
|
/* NetList2.c */
|
|
/* */
|
|
/* This file defines the list management function */
|
|
/* */
|
|
/********************************************************************************/
|
|
|
|
/*
|
|
* list module
|
|
*/
|
|
|
|
/*
|
|
* Author: David Fournier
|
|
*
|
|
* Creation Date: 13/05/97
|
|
*
|
|
*/
|
|
|
|
|
|
#include "warnings.h"
|
|
#include "NetMemCo.h"
|
|
#include "NetList2.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
/*****************************************************************************
|
|
* Description: vNetListInit()
|
|
* Initialize a list variable.
|
|
*****************************************************************************
|
|
* Input: pList, pointer on a list variable.
|
|
* Output: no null value if no enough memory.
|
|
*****************************************************************************/
|
|
int iNetList2Init(tdstNetList2 *pList)
|
|
{
|
|
tdstNetList2Cell *p1,*p2;
|
|
p1=(tdstNetList2Cell *)pMalloc(sizeof(tdstNetList2Cell));
|
|
if (!p1) return -1;
|
|
p2=(tdstNetList2Cell *)pMalloc(sizeof(tdstNetList2Cell));
|
|
if (!p2) return -2;
|
|
pList->pFirstCell=p1;
|
|
pList->pLastCell=p2;
|
|
p1->pNext=p2;
|
|
p2->pPrev=p1;
|
|
p1->pPrev=NULL;
|
|
p2->pNext=NULL;
|
|
p1->ulSize=0L;
|
|
p2->ulSize=0L;
|
|
pList->ulNbrElem=0;
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: pNetList2IterInit()
|
|
* Initialize an iterator on a list.
|
|
* Iterator point the first position.
|
|
* Return adress of the first element if it exist or NULL otherwise.
|
|
*****************************************************************************
|
|
* Input: pIter, pointer on a iter variable to initialyze.
|
|
* pList, pointer on the list variable.
|
|
* Output: none.
|
|
*****************************************************************************/
|
|
void *pNetList2IterInit(tdstNetIter *pIter,tdstNetList2 *pList)
|
|
{
|
|
pIter->pList=pList;
|
|
return pNetList2ToFirst(pIter);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: pNetList2ReservElem()
|
|
* Reserv a new space element in the list at the current position.
|
|
*****************************************************************************
|
|
* Input: pIter for reserv.
|
|
* ulSize, size of new element.
|
|
* Output: return the adress of new element.
|
|
* return NULL if not enough memory.
|
|
*****************************************************************************/
|
|
void *pNetList2ReservElem(tdstNetIter *pIter,unsigned long ulSize)
|
|
{
|
|
tdstNetList2Cell *pNew;
|
|
pNew=(tdstNetList2Cell *)pMalloc(ulSize+sizeof(tdstNetList2Cell));
|
|
if (!pNew) return NULL;
|
|
pNew->pNext=pIter->pCurCell;
|
|
pNew->pPrev=pIter->pCurCell->pPrev;
|
|
pNew->pPrev->pNext=pNew;
|
|
pNew->pNext->pPrev=pNew;
|
|
pNew->ulSize=ulSize;
|
|
pIter->pCurCell=pNew;
|
|
pIter->pList->ulNbrElem++;
|
|
return pIter->pCurCell+1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: pNetList2InsertElem()
|
|
* Insert a new element in the list at the current position.
|
|
*****************************************************************************
|
|
* Input: pIter for insert.
|
|
* pElem, adress of the element. This element is duplicate in the list.
|
|
* ulSize, size of the element.
|
|
* Output: return the adress of new element.
|
|
* return NULL if not enough memory.
|
|
*****************************************************************************/
|
|
void *pNetList2InsertElem(tdstNetIter *pIter,void *pElem,unsigned long ulSize)
|
|
{
|
|
void *pNewElem;
|
|
pNewElem=pNetList2ReservElem(pIter,ulSize);
|
|
if (!pNewElem) return NULL;
|
|
memcpy(pNewElem,pElem,ulSize);
|
|
return pNewElem;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: pNetList2PeekElem()
|
|
* Return adresse of the element in the list at the current position.
|
|
* Return NULL if the current position is the end position.
|
|
*****************************************************************************
|
|
* Input: pIter.
|
|
* Output: return the adress of current element.
|
|
*****************************************************************************/
|
|
void *pNetList2PeekElem(tdstNetIter *pIter)
|
|
{
|
|
if (pIter->pCurCell->pNext==NULL) return NULL;
|
|
else return pIter->pCurCell+1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: pNetList2DeleteElem()
|
|
* Delete the element in the list at the current position.
|
|
* The current position must not be the end position.
|
|
*****************************************************************************
|
|
* Input: pIter.
|
|
* Output: return the adress of the new current element.
|
|
*****************************************************************************/
|
|
void *pNetList2DeleteElem(tdstNetIter *pIter)
|
|
{
|
|
tdstNetList2Cell *pOld;
|
|
pOld=pIter->pCurCell;
|
|
pOld->pNext->pPrev=pOld->pPrev;
|
|
pOld->pPrev->pNext=pOld->pNext;
|
|
pIter->pCurCell=pOld->pNext;
|
|
vFree(pOld);
|
|
pIter->pList->ulNbrElem--;
|
|
if (pIter->pCurCell->pNext==NULL) return NULL;
|
|
else return pIter->pCurCell+1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: pNetList2Next()
|
|
* Return adresse of the element in the list at the next position.
|
|
* Return NULL if the next position is the end position.
|
|
* The current position must not be the end position.
|
|
*****************************************************************************
|
|
* Input: pIter.
|
|
* Output: return the adress of next element.
|
|
*****************************************************************************/
|
|
void *pNetList2Next(tdstNetIter *pIter)
|
|
{
|
|
tdstNetList2Cell *pNext;
|
|
pNext=pIter->pCurCell->pNext;
|
|
pIter->pCurCell=pNext;
|
|
pIter->ulCurPos++;
|
|
if (pNext->pNext==NULL) return NULL;
|
|
else return pNext+1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: pNetList2Prev()
|
|
* Return adresse of the element in the list at the previous position.
|
|
* The current position must not be the first position.
|
|
*****************************************************************************
|
|
* Input: pIter.
|
|
* Output: return the adress of previous element.
|
|
*****************************************************************************/
|
|
void *pNetList2Prev(tdstNetIter *pIter)
|
|
{
|
|
tdstNetList2Cell *pPrev;
|
|
pPrev=pIter->pCurCell->pPrev;
|
|
pIter->pCurCell=pPrev;
|
|
pIter->ulCurPos--;
|
|
return pPrev+1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: iNetList2IsFirst()
|
|
* Return true if the iterator point the first position.
|
|
*****************************************************************************
|
|
* Input: pIter.
|
|
* Output: return boolean.
|
|
*****************************************************************************/
|
|
int iNetList2IsFirst(tdstNetIter *pIter)
|
|
{
|
|
return (!pIter->ulCurPos);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: iNetList2IsEnd()
|
|
* Return true if the iterator point the end position.
|
|
*****************************************************************************
|
|
* Input: pIter.
|
|
* Output: return boolean.
|
|
*****************************************************************************/
|
|
int iNetList2IsEnd(tdstNetIter *pIter)
|
|
{
|
|
return (pIter->ulCurPos==pIter->pList->ulNbrElem);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: iNetList2IsEnd()
|
|
* Return true if the iterator point the last element.
|
|
*****************************************************************************
|
|
* Input: pIter.
|
|
* Output: return boolean.
|
|
*****************************************************************************/
|
|
int iNetList2IsLast(tdstNetIter *pIter)
|
|
{
|
|
return (pIter->ulCurPos==pIter->pList->ulNbrElem-1);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: pNetList2ToFirst()
|
|
* Change the current position to the first.
|
|
*****************************************************************************
|
|
* Input: pIter.
|
|
* Output: return the adress of the first element if exist, NULL otherwise.
|
|
*****************************************************************************/
|
|
void *pNetList2ToFirst(tdstNetIter *pIter)
|
|
{
|
|
pIter->ulCurPos=0;
|
|
pIter->pCurCell=pIter->pList->pFirstCell->pNext;
|
|
if (pIter->pCurCell->pNext==NULL) return NULL;
|
|
else return pIter->pCurCell+1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: vNetList2ToEnd()
|
|
* Change the current position to the end.
|
|
*****************************************************************************
|
|
* Input: pIter.
|
|
* Output: none.
|
|
*****************************************************************************/
|
|
void vNetList2ToEnd(tdstNetIter *pIter)
|
|
{
|
|
pIter->ulCurPos=pIter->pList->ulNbrElem;
|
|
pIter->pCurCell=pIter->pList->pLastCell;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: vNetList2ToLast()
|
|
* Change the current position to the last element.
|
|
* The list must have one or more element.
|
|
*****************************************************************************
|
|
* Input: pIter.
|
|
* Output: return the adress of the last element.
|
|
*****************************************************************************/
|
|
void *pNetList2ToLast(tdstNetIter *pIter)
|
|
{
|
|
pIter->ulCurPos=pIter->pList->ulNbrElem-1;
|
|
pIter->pCurCell=pIter->pList->pLastCell->pPrev;
|
|
return pIter->pCurCell+1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: ulNetList2NbrElem()
|
|
* Return the number of element of the list.
|
|
*****************************************************************************
|
|
* Input: pList.
|
|
* Output: Number of element.
|
|
*****************************************************************************/
|
|
unsigned long ulNetList2NbrElem(tdstNetList2 *pList)
|
|
{
|
|
return pList->ulNbrElem;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: ulNetList2NbrElemIter()
|
|
* Return the number of element of the list.
|
|
*****************************************************************************
|
|
* Input: pIter.
|
|
* Output: Number of element.
|
|
*****************************************************************************/
|
|
unsigned long ulNetList2NbrElemIter(tdstNetIter *pIter)
|
|
{
|
|
return pIter->pList->ulNbrElem;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: ulNetList2PosIter()
|
|
* Return current position number of the iterator.
|
|
*****************************************************************************
|
|
* Input: pIter.
|
|
* Output: Position.
|
|
*****************************************************************************/
|
|
unsigned long ulNetList2PosIter(tdstNetIter *pIter)
|
|
{
|
|
return pIter->ulCurPos;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: pNetList2SetPos()
|
|
* Change the current position.
|
|
*****************************************************************************
|
|
* Input: pIter.
|
|
* ulPos, the new position.
|
|
* Output: return the adress of the first element if exist, NULL otherwise.
|
|
*****************************************************************************/
|
|
void *pNetList2SetPos(tdstNetIter *pIter,unsigned long ulPos)
|
|
{
|
|
if (ulPos<pIter->ulCurPos)
|
|
{
|
|
if (ulPos*2>pIter->ulCurPos)
|
|
{
|
|
ulPos=pIter->ulCurPos-ulPos;
|
|
pIter->ulCurPos-=ulPos;
|
|
while (ulPos--) pIter->pCurCell=pIter->pCurCell->pPrev;
|
|
}
|
|
else
|
|
{
|
|
pIter->ulCurPos=ulPos;
|
|
pIter->pCurCell=pIter->pList->pFirstCell->pNext;
|
|
while (ulPos--) pIter->pCurCell=pIter->pCurCell->pNext;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (ulPos*2-pIter->ulCurPos<pIter->pList->ulNbrElem)
|
|
{
|
|
ulPos-=pIter->ulCurPos;
|
|
pIter->ulCurPos+=ulPos;
|
|
while (ulPos--) pIter->pCurCell=pIter->pCurCell->pNext;
|
|
}
|
|
else
|
|
{
|
|
pIter->ulCurPos=ulPos;
|
|
ulPos=pIter->pList->ulNbrElem-ulPos;
|
|
pIter->pCurCell=pIter->pList->pLastCell;
|
|
while (ulPos--) pIter->pCurCell=pIter->pCurCell->pPrev;
|
|
}
|
|
}
|
|
if (pIter->pCurCell->pNext==NULL) return NULL;
|
|
else return pIter->pCurCell+1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: vNetList2Clear()
|
|
* Delete all element of a list.
|
|
*****************************************************************************
|
|
* Input: pIter.
|
|
* Output: none.
|
|
*****************************************************************************/
|
|
void vNetList2Clear(tdstNetIter *pIter)
|
|
{
|
|
if (pNetList2ToFirst(pIter)) while (pNetList2DeleteElem(pIter));
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Description: vNetList2Kill()
|
|
* Deallocate a list.
|
|
*****************************************************************************
|
|
* Input: pList.
|
|
* Output: none.
|
|
*****************************************************************************/
|
|
void vNetList2Kill(tdstNetList2 *pList)
|
|
{
|
|
tdstNetIter stIter;
|
|
pNetList2IterInit(&stIter,pList);
|
|
vNetList2Clear(&stIter);
|
|
vFree(pList->pFirstCell);
|
|
vFree(pList->pLastCell);
|
|
}
|