381 lines
8.9 KiB
C
381 lines
8.9 KiB
C
/***************************************************************************/
|
|
|
|
#include <limits.h>
|
|
#include <memory.h>
|
|
|
|
#include "lib/framework/frame.h"
|
|
|
|
#include "ptrlist.h"
|
|
|
|
/***************************************************************************/
|
|
|
|
extern void *g_ElementToBeRemoved;
|
|
|
|
/***************************************************************************/
|
|
|
|
#ifdef WIN321 // ffs //Not really needed I guess? [Don't delete yet, possible future use?] -Qamly
|
|
static CRITICAL_SECTION critSecAudio;
|
|
#endif
|
|
/***************************************************************************/
|
|
|
|
static void ptrList_Init( PTRLIST *ptrList );
|
|
|
|
/***************************************************************************/
|
|
|
|
BOOL
|
|
ptrList_Create( PTRLIST **ppsList, UDWORD udwInitElements,
|
|
UDWORD udwExtElements, UDWORD udwElementSize )
|
|
{
|
|
/* create ptr list struct */
|
|
(*ppsList) = MALLOC( sizeof(PTRLIST) );
|
|
|
|
/* allocate heaps */
|
|
if ( !HEAP_CREATE( &(*ppsList)->psNodeHeap, sizeof(LISTNODE),
|
|
udwInitElements, udwExtElements) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if ( !HEAP_CREATE( &(*ppsList)->psElementHeap, udwElementSize,
|
|
udwInitElements, udwExtElements) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/* init members */
|
|
(*ppsList)->udwElements = udwInitElements;
|
|
(*ppsList)->udwExtElements = udwExtElements;
|
|
(*ppsList)->udwElementSize = udwElementSize;
|
|
|
|
ptrList_Init( *ppsList );
|
|
#ifdef WIN321 //ffs //Not really needed I guess? -Qamly
|
|
InitializeCriticalSection( &critSecAudio );
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
void
|
|
ptrList_Destroy( PTRLIST *ptrList )
|
|
{
|
|
ASSERT( (PTRVALID(ptrList, sizeof(PTRLIST)),
|
|
"ptrList_Destroy: list pointer invalid\n") );
|
|
|
|
ptrList_Clear( ptrList );
|
|
|
|
/* destroy heaps */
|
|
HEAP_DESTROY( ptrList->psNodeHeap );
|
|
HEAP_DESTROY( ptrList->psElementHeap );
|
|
|
|
/* free struct */
|
|
FREE( ptrList );
|
|
#ifdef WIN321 // Not really needed I guess? -Qamly
|
|
DeleteCriticalSection( &critSecAudio );
|
|
#endif
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
static void
|
|
ptrList_Init( PTRLIST *ptrList )
|
|
{
|
|
ptrList->sdwCurIndex = 0;
|
|
ptrList->psCurNode = NULL;
|
|
ptrList->psNode = NULL;
|
|
ptrList->bDontGetNext = FALSE;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
/*
|
|
* ptrList_Clear
|
|
*
|
|
* Returns all nodes from hash table to free node list
|
|
*/
|
|
/***************************************************************************/
|
|
|
|
void
|
|
ptrList_Clear( PTRLIST *ptrList )
|
|
{
|
|
LISTNODE *psNode, *psNodeTmp;
|
|
|
|
ASSERT( (PTRVALID(ptrList, sizeof(PTRLIST)),
|
|
"ptrList_Destroy: table pointer invalid\n") );
|
|
|
|
/* free nodes */
|
|
psNode = ptrList->psNode;
|
|
|
|
while ( psNode != NULL )
|
|
{
|
|
/* return node element to heap */
|
|
ASSERT( (PTRVALID(psNode->psElement, ptrList->udwElementSize),
|
|
"ptrList_Destroy: element pointer invalid\n") );
|
|
HEAP_FREE( ptrList->psElementHeap, psNode->psElement );
|
|
|
|
/* return node to heap */
|
|
ASSERT( (PTRVALID(psNode, sizeof(LISTNODE)),
|
|
"ptrList_Destroy: node pointer invalid\n") );
|
|
psNodeTmp = psNode->psNext;
|
|
HEAP_FREE( ptrList->psNodeHeap, psNode );
|
|
psNode = psNodeTmp;
|
|
}
|
|
|
|
ptrList_Init( ptrList );
|
|
}
|
|
|
|
/***************************************************************************/
|
|
/*
|
|
* ptrList_GetElement
|
|
*
|
|
* Gets free node from heap and returns element pointer
|
|
*/
|
|
/***************************************************************************/
|
|
|
|
void *
|
|
ptrList_GetElement( PTRLIST *ptrList )
|
|
{
|
|
void *psElement;
|
|
|
|
ASSERT( (PTRVALID(ptrList, sizeof(PTRLIST)),
|
|
"ptrList_GetElement: table pointer invalid\n") );
|
|
|
|
HEAP_ALLOC( ptrList->psElementHeap, &psElement );
|
|
|
|
return psElement;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
/*
|
|
* ptrList_FreeElement
|
|
*
|
|
* Free element that was allocated using ptrList_GetElement without
|
|
* inserting in list: will fail if element not allocated from ptrList
|
|
*/
|
|
/***************************************************************************/
|
|
|
|
void
|
|
ptrList_FreeElement( PTRLIST *ptrList, void *psElement )
|
|
{
|
|
ASSERT( (PTRVALID(ptrList, sizeof(PTRLIST)),
|
|
"ptrList_FreeElement: table pointer invalid\n") );
|
|
|
|
if ( HEAP_FREE( ptrList->psElementHeap, psElement ) == FALSE )
|
|
{
|
|
DBPRINTF( ("ptrList_FreeElement: couldn't free element\n") );
|
|
}
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
void
|
|
ptrList_InsertElement( PTRLIST *ptrList, void *psElement, SDWORD sdwKey )
|
|
{
|
|
LISTNODE *psNode, *psCurNode, *psPrevNode;
|
|
|
|
ASSERT( (PTRVALID(ptrList, sizeof(PTRLIST)),
|
|
"ptrList_InsertElement: table pointer invalid\n") );
|
|
ASSERT( (PTRVALID(psElement, ptrList->udwElementSize),
|
|
"ptrList_InsertElement: element pointer invalid\n") );
|
|
|
|
/* get node from heap */
|
|
HEAP_ALLOC( ptrList->psNodeHeap, (void*) &psNode );
|
|
|
|
/* set node elements */
|
|
psNode->sdwKey = sdwKey;
|
|
psNode->psElement = psElement;
|
|
psNode->psNext = NULL;
|
|
|
|
psPrevNode = NULL;
|
|
psCurNode = ptrList->psNode;
|
|
#ifdef WIN321 //ffs //Not really needed I guess? -Qamly
|
|
EnterCriticalSection( &critSecAudio );
|
|
#endif
|
|
|
|
/* find correct position to insert node */
|
|
while ( psCurNode != NULL )
|
|
{
|
|
if ( psCurNode->sdwKey < sdwKey )
|
|
{
|
|
break;
|
|
}
|
|
|
|
psPrevNode = psCurNode;
|
|
psCurNode = psCurNode->psNext;
|
|
}
|
|
|
|
/* insert node */
|
|
if ( psPrevNode == NULL )
|
|
{
|
|
ptrList->psNode = psNode;
|
|
|
|
if ( psCurNode != NULL )
|
|
{
|
|
psNode->psNext = psCurNode;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
psPrevNode->psNext = psNode;
|
|
psNode->psNext = psCurNode;
|
|
}
|
|
#ifdef WIN321 // ffs //Not really needed I guess? -Qamly
|
|
LeaveCriticalSection( &critSecAudio );
|
|
#endif
|
|
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
BOOL
|
|
ptrList_RemoveElement( PTRLIST *ptrList, void *psElement, SDWORD sdwKey )
|
|
{
|
|
LISTNODE *psCurNode, *psPrevNode;
|
|
BOOL bOK;
|
|
|
|
ASSERT( (PTRVALID(ptrList, sizeof(PTRLIST)),
|
|
"ptrList_RemoveElement: table pointer invalid\n") );
|
|
|
|
psPrevNode = NULL;
|
|
psCurNode = ptrList->psNode;
|
|
#ifdef WIN321 // ffs //Not really needed I guess? -Qamly
|
|
EnterCriticalSection( &critSecAudio );
|
|
#endif
|
|
|
|
/* find correct position to insert node */
|
|
while ( psCurNode != NULL &&
|
|
!(psCurNode->sdwKey == sdwKey &&
|
|
psCurNode->psElement == psElement) )
|
|
{
|
|
psPrevNode = psCurNode;
|
|
psCurNode = psCurNode->psNext;
|
|
}
|
|
|
|
/* remove node from hash table and return to heap */
|
|
if ( psCurNode == NULL )
|
|
{
|
|
bOK = FALSE;
|
|
}
|
|
else
|
|
{
|
|
|
|
ASSERT( (psCurNode->psElement == psElement,
|
|
"ptrList_RemoveElement: removing wrong element!\n") );
|
|
|
|
/* remove from list */
|
|
if ( psPrevNode == NULL )
|
|
{
|
|
ptrList->psNode = psCurNode->psNext;
|
|
}
|
|
else
|
|
{
|
|
psPrevNode->psNext = psCurNode->psNext;
|
|
}
|
|
|
|
/* check whether table current node pointer is this node */
|
|
if ( ptrList->psCurNode == psCurNode )
|
|
{
|
|
/* point it to the previous node if valid */
|
|
if ( psPrevNode == NULL )
|
|
{
|
|
/* set next node and set flag */
|
|
ptrList->psCurNode = psCurNode->psNext;
|
|
ptrList->bDontGetNext = TRUE;
|
|
}
|
|
else
|
|
{
|
|
ptrList->psCurNode = psPrevNode;
|
|
}
|
|
}
|
|
|
|
/* return element to heap */
|
|
ASSERT( (PTRVALID(psCurNode->psElement, ptrList->udwElementSize),
|
|
"ptrList_RemoveElement: element pointer invalid\n") );
|
|
ASSERT( (psCurNode->psElement == psElement,
|
|
"ptrList_RemoveElement: removing wrong element!\n") );
|
|
HEAP_FREE( ptrList->psElementHeap, psCurNode->psElement );
|
|
|
|
/* return node to heap */
|
|
ASSERT( (PTRVALID(psCurNode, sizeof(LISTNODE)),
|
|
"ptrList_RemoveElement: node pointer invalid\n") );
|
|
HEAP_FREE( ptrList->psNodeHeap, psCurNode );
|
|
|
|
bOK = TRUE;
|
|
}
|
|
#ifdef WIN321 // ffs //Not really needed I guess? -Qamly
|
|
LeaveCriticalSection( &critSecAudio );
|
|
#endif
|
|
return bOK;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
void *
|
|
ptrList_GetNext( PTRLIST *ptrList )
|
|
{
|
|
void *pElement = NULL;
|
|
#ifdef WIN321 // ffs //Not really needed I guess? -Qamly
|
|
EnterCriticalSection( &critSecAudio );
|
|
#endif
|
|
if ( ptrList == NULL )
|
|
{
|
|
pElement = NULL;
|
|
}
|
|
|
|
if ( ptrList->psCurNode == NULL )
|
|
{
|
|
pElement = NULL;
|
|
}
|
|
else
|
|
{
|
|
if ( ptrList->bDontGetNext == TRUE )
|
|
{
|
|
ptrList->bDontGetNext = FALSE;
|
|
}
|
|
else
|
|
{
|
|
ptrList->psCurNode = ptrList->psCurNode->psNext;
|
|
}
|
|
|
|
if ( ptrList->psCurNode == NULL )
|
|
{
|
|
pElement = NULL;
|
|
}
|
|
else
|
|
{
|
|
pElement = ptrList->psCurNode->psElement;
|
|
}
|
|
}
|
|
#ifdef WIN321 // ffs //Not really needed I guess? -Qamly
|
|
LeaveCriticalSection( &critSecAudio );
|
|
#endif
|
|
return pElement;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
void *
|
|
ptrList_GetFirst( PTRLIST *ptrList )
|
|
{
|
|
void *pElement = NULL;
|
|
#ifdef WIN321 // ffs //Not really needed I guess? -Qamly
|
|
EnterCriticalSection( &critSecAudio );
|
|
#endif
|
|
ptrList->bDontGetNext = FALSE;
|
|
ptrList->psCurNode = ptrList->psNode;
|
|
|
|
if ( ptrList->psCurNode == NULL )
|
|
{
|
|
pElement = NULL;
|
|
}
|
|
else
|
|
{
|
|
pElement = ptrList->psCurNode->psElement;
|
|
}
|
|
#ifdef WIN321 // ffs //Not really needed I guess? -Qamly
|
|
LeaveCriticalSection( &critSecAudio );
|
|
#endif
|
|
return pElement;
|
|
}
|
|
|
|
/***************************************************************************/
|