Files
source/Standard Gaming Platform/Container.cpp
T

2111 lines
60 KiB
C++

//*****************************************************************************
//
// Filename : Container.c
//
// Purpose : Function definition for the Container
//
// Modification History :
// 25 nov 96 TS creation
//
// 19 Dec 97 AM Replace all memcpy() with memmove(), since overlap possibilities
// abound (and there were already bugs in do_copy() for ordered lists)
// While the memcpy() was working in _DEBUG mode, it was failing
// reproducibly in RELEASE mode whenever regions overlapped!
// Having read the code, I strongly suggest that you DO NOT use this
// stuff at all and write your own instead. Tarun was no Carmack...
// - Alex Meduna
// 1998 KM Detached all references to this file from JA2 as it caused a lot of hard to debug
// crashes. The VOBJECT/VSURFACE lists are now self-maintained and no longer use the
// this crap. DON'T USE THIS -- NO MATTER WHAT!!!
//*****************************************************************************
#ifdef JA2_PRECOMPILED_HEADERS
#include "JA2 SGP ALL.H"
#elif defined( WIZ8_PRECOMPILED_HEADERS )
#include "WIZ8 SGP ALL.H"
#else
#include "types.h"
#include <stdlib.h>
#include <malloc.h>
#include <stdio.h>
#include "windows.h"
#include "MemMan.h"
#include "Debug.h"
#include "Container.h"
#if _MSC_VER < 1300 //(iostream.h was removed from VC.NET2003)
#include <iostream.h>
#endif
#endif
//*****************************************************************************
//
// Defines and typedefs
//
//
//*****************************************************************************
typedef struct StackHeaderTag
{
UINT32 uiTotal_items;
UINT32 uiSiz_of_elem;
UINT32 uiMax_size;
} StackHeader;
typedef struct HeaderTag
{
UINT32 uiTotal_items;
UINT32 uiSiz_of_elem;
UINT32 uiMax_size;
UINT32 uiHead;
UINT32 uiTail;
} QueueHeader , ListHeader;
typedef struct OrdHeaderTag
{
UINT32 uiTotal_items;
UINT32 uiSiz_of_elem;
UINT32 uiMax_size;
UINT32 uiHead;
UINT32 uiTail;
INT8 (*pCompare)(void *,void *, UINT32);
} OrdListHeader;
typedef struct test
{
UINT32 me;
long you;
STR8 k;
STR8 p;
} TEST;
//*****************************************************************************
//
// CreateStack
//
// Parameter List : num_items - estimated number
// of items in stack
// siz_each - size of each item
// Return Value NULL if unsuccesful
// pointer to allocated memory
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
HSTACK CreateStack(UINT32 uiNum_items, UINT32 uiSiz_each)
{
UINT32 uiAmount;
HSTACK hStack;
StackHeader *pStack;
// assign an initial amount of memory to allocate
if ((uiNum_items > 0) && (uiSiz_each > 0))
uiAmount = uiNum_items * uiSiz_each;
else
{
DbgMessage(TOPIC_STACK_CONTAINERS, DBG_LEVEL_0, "Requested stack items and size have to be >0");
return NULL;
}
// allocate the container memory
if ((hStack = MemAlloc(uiAmount + sizeof(StackHeader))) == 0)
{
DbgMessage(TOPIC_STACK_CONTAINERS, DBG_LEVEL_0, "Could not allocate stack container memory");
return NULL;
}
pStack = (StackHeader *)hStack;
//initialize the header variables
pStack->uiMax_size = uiAmount + sizeof(StackHeader);
pStack->uiTotal_items = 0;
pStack->uiSiz_of_elem = uiSiz_each;
// return the pointer to the memory
return hStack;
}
//*****************************************************************************
//
// CreateQueue
//
// Parameter List : num_items - estimated number
// of items in queue
// siz_each - size of each item
// Return Value NULL if unsuccesful
// pointer to allocated memory
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
HQUEUE CreateQueue(UINT32 uiNum_items, UINT32 uiSiz_each)
{
UINT32 uiAmount;
HQUEUE hQueue;
QueueHeader *pQueue;
// check to see if the queue has more than 1
// element to be created and that the size > 1
if ((uiNum_items > 0) && (uiSiz_each > 0))
uiAmount = uiNum_items * uiSiz_each;
else
{
DbgMessage(TOPIC_QUEUE_CONTAINERS, DBG_LEVEL_0, "Requested queue items and size have to be >0");
return NULL;
}
// allocate the queue memory
if ((hQueue = MemAlloc(uiAmount + sizeof(QueueHeader))) == 0)
{
DbgMessage(TOPIC_QUEUE_CONTAINERS, DBG_LEVEL_0, "Could not allocate queue container memory");
return NULL;
}
pQueue = (QueueHeader *)hQueue;
//initialize the queue structure
pQueue->uiMax_size = uiAmount + sizeof(QueueHeader);
pQueue->uiTotal_items = 0;
pQueue->uiSiz_of_elem = uiSiz_each;
pQueue->uiTail = pQueue->uiHead = sizeof(QueueHeader);
// return the pointer to memory
return hQueue;
}
//*****************************************************************************
//
// CreateList
//
// Parameter List : num_items - estimated number
// of items in ordered list
// siz_each - size of each item
// Return Value NULL if unsuccesful
// pointer to allocated memory
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
HLIST CreateList(UINT32 uiNum_items, UINT32 uiSiz_each)
{
UINT32 uiAmount;
HLIST hList;
ListHeader *pList;
// check to see if the queue has more than 1
// element to be created and that the size > 1
if ((uiNum_items > 0) && (uiSiz_each > 0))
uiAmount = uiNum_items * uiSiz_each;
else
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Requested queue items and size have to be >0");
return 0;
}
// allocate the list memory
if ((hList = MemAlloc(uiAmount + sizeof(ListHeader))) == 0)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not allocate queue container memory");
return 0;
}
pList = (ListHeader *)hList;
//initialize the list structure
pList->uiMax_size = uiAmount + sizeof(ListHeader);
pList->uiTotal_items = 0;
pList->uiSiz_of_elem = uiSiz_each;
pList->uiTail = pList->uiHead = sizeof(ListHeader);
// return the pointer to memory
return hList;
}
//*****************************************************************************
//
// CreateOrdList
//
// Parameter List : num_items - estimated number
// of items in ordered list
// siz_each - size of each item
// Return Value NULL if unsuccesful
// pointer to allocated memory
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
HORDLIST CreateOrdList(UINT32 uiNum_items, UINT32 uiSiz_each, INT8 (*compare)(void *, void *, UINT32))
{
UINT32 uiAmount;
HLIST hOrdList;
OrdListHeader *pOrdList;
// check to see if the ordered list has more than 1
// element to be created and that the size > 1
if ((uiNum_items > 0) && (uiSiz_each > 0))
uiAmount = uiNum_items * uiSiz_each;
else
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Requested ordered list items and size have to be >0");
return 0;
}
// allocate the list memory
if ((hOrdList = MemAlloc(uiAmount + sizeof(OrdListHeader))) == 0)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not allocate queue container memory");
return 0;
}
pOrdList = (OrdListHeader *)hOrdList;
//initialize the list structure
pOrdList->uiMax_size = uiAmount + sizeof(OrdListHeader);
pOrdList->uiTotal_items = 0;
pOrdList->uiSiz_of_elem = uiSiz_each;
pOrdList->uiTail = pOrdList->uiHead = sizeof(OrdListHeader);
pOrdList->pCompare = compare;
// return the pointer to memory
return hOrdList;
}
//*****************************************************************************
//
// push
//
// Parameter List : void * - pointer to stack
// container
// data - data to add to stack
//
// Return Value BOOLEAN true if push ok
// else false
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
HSTACK Push(HSTACK hStack, void *pdata)
{
StackHeader *pTemp_cont;
UINT32 uiOffset;
UINT32 uiNew_size;
void *pvoid;
BYTE *pbyte;
// check for a NULL pointer
if (hStack == NULL)
{
DbgMessage(TOPIC_STACK_CONTAINERS, DBG_LEVEL_0, "This is not a valid pointer to the stack");
return NULL;
}
// some valid data should be passed in
if (pdata == NULL)
{
DbgMessage(TOPIC_STACK_CONTAINERS, DBG_LEVEL_0, "Data to be pushed onto stack is NULL");
return NULL;
}
//perform operations to calculate offset and decide if the container has to resized
pTemp_cont = (StackHeader *)hStack;
uiOffset = (pTemp_cont->uiSiz_of_elem * pTemp_cont->uiTotal_items) + sizeof(StackHeader);
if ((uiOffset + pTemp_cont->uiSiz_of_elem) > pTemp_cont->uiMax_size)
{
uiNew_size = pTemp_cont->uiMax_size + (pTemp_cont->uiMax_size - sizeof(StackHeader));
pTemp_cont->uiMax_size = uiNew_size;
if ((hStack = MemRealloc(hStack, uiNew_size)) == NULL)
{
DbgMessage(TOPIC_STACK_CONTAINERS, DBG_LEVEL_0, "Could not resize stack container memory");
return NULL;
}
pTemp_cont = (StackHeader *)hStack;
}
pbyte = (BYTE *)hStack;
pbyte += uiOffset;
pvoid = (void *)pbyte;
//copy data from pdata to pvoid - the stack
memmove(pvoid, pdata, pTemp_cont->uiSiz_of_elem);
pTemp_cont->uiTotal_items++;
//return push succeeded
return hStack;
}
//*****************************************************************************
//
// pop
//
// Parameter List : void * - pointer to stack
// container
//
//
// Return Value : void * - pointer to stack
// after pushing element
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
BOOLEAN Pop(HSTACK hStack, void *pdata)
{
StackHeader *pTemp_cont;
UINT32 uiOffset;
UINT32 uiSize_of_each;
UINT32 uiTotal;
void *pvoid;
BYTE *pbyte;
// check for a NULL queue
if (hStack == NULL)
{
DbgMessage(TOPIC_STACK_CONTAINERS, DBG_LEVEL_0, "This is not a valid pointer to the stack");
return FALSE;
}
if (pdata == NULL)
{
DbgMessage(TOPIC_STACK_CONTAINERS, DBG_LEVEL_0, "Variable where data is to be stored is NULL");
return FALSE;
}
pTemp_cont = (StackHeader *)hStack;
uiTotal = pTemp_cont->uiTotal_items;
uiSize_of_each = pTemp_cont->uiSiz_of_elem;
if (uiTotal == 0)
{
DbgMessage(TOPIC_STACK_CONTAINERS, DBG_LEVEL_0, "There is no data in stack to pop");
return FALSE;
}
// calculate offsets to decide if the page should be rezied
uiOffset = (uiSize_of_each * uiTotal) + sizeof(StackHeader);
uiOffset -= uiSize_of_each;
pbyte = (BYTE *)hStack;
pbyte += uiOffset;
pvoid = (void *)pbyte;
// get the data from pvoid and store in pdata
memmove(pdata, pvoid, uiSize_of_each);
pTemp_cont->uiTotal_items--;
return TRUE;
}
//*****************************************************************************
//
// PeekStack
//
// Parameter List : void * - buffer to hold data
//
//
// Return Value : TRUE if stack not empty
//
// Modification History :
// Apr 14 2000 SCT->Created
//
//*****************************************************************************
BOOLEAN PeekStack(HSTACK hStack, void *pdata)
{
StackHeader *pTemp_cont;
UINT32 uiOffset;
UINT32 uiSize_of_each;
UINT32 uiTotal;
void *pvoid;
BYTE *pbyte;
// check for a NULL queue
if (hStack == NULL)
{
DbgMessage(TOPIC_STACK_CONTAINERS, DBG_LEVEL_0, "This is not a valid pointer to the stack");
return FALSE;
}
if (pdata == NULL)
{
DbgMessage(TOPIC_STACK_CONTAINERS, DBG_LEVEL_0, "Variable where data is to be stored is NULL");
return FALSE;
}
pTemp_cont = (StackHeader *)hStack;
uiTotal = pTemp_cont->uiTotal_items;
uiSize_of_each = pTemp_cont->uiSiz_of_elem;
if (uiTotal == 0)
{
DbgMessage(TOPIC_STACK_CONTAINERS, DBG_LEVEL_0, "There is no data in stack to pop");
return FALSE;
}
// calculate offsets to decide if the page should be rezied
uiOffset = (uiSize_of_each * uiTotal) + sizeof(StackHeader);
uiOffset -= uiSize_of_each;
pbyte = (BYTE *)hStack;
pbyte += uiOffset;
pvoid = (void *)pbyte;
// get the data from pvoid and store in pdata
memmove(pdata, pvoid, uiSize_of_each);
return TRUE;
}
//*****************************************************************************
//
// DeleteStack
//
// Parameter List : pointer to memory
//
// Return Value : BOOLEAN
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
BOOLEAN DeleteStack(HSTACK hStack)
{
if (hStack == NULL)
{
DbgMessage(TOPIC_STACK_CONTAINERS, DBG_LEVEL_0, "This is not a valid pointer to the stack");
return FALSE;
}
// free the memory assigned to the handle
MemFree(hStack);
return TRUE;
}
//*****************************************************************************
//
// DeleteQueue
//
// Parameter List : pointer to memory
//
// Return Value : BOOLEAN
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
BOOLEAN DeleteQueue(HQUEUE hQueue)
{
if (hQueue == NULL)
{
DbgMessage(TOPIC_QUEUE_CONTAINERS, DBG_LEVEL_0, "This is not a valid pointer to the queue");
return FALSE;
}
// free the memory assigned to the handle
MemFree(hQueue);
return TRUE;
}
//*****************************************************************************
//
// DeleteList
//
// Parameter List : pointer to memory
//
// Return Value : BOOLEAN
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
BOOLEAN DeleteList(HLIST hList)
{
if (hList == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "This is not a valid pointer to the list");
return FALSE;
}
// free the memory assigned to the list
MemFree(hList);
return TRUE;
}
//*****************************************************************************
//
// DeleteOrdList
//
// Parameter List : pointer to memory
//
// Return Value : BOOLEAN
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
BOOLEAN DeleteOrdList(HORDLIST hOrdList)
{
if (hOrdList == NULL)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "This is not a valid pointer to the ordered list");
return FALSE;
}
// free the memory assigned to the list
MemFree(hOrdList);
return TRUE;
}
//*****************************************************************************
//
// InitializeContainers
//
// Parameter List : none
//
// Return Value : void
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
void InitializeContainers(void)
{
// register the appropriate debug topics
RegisterDebugTopic(TOPIC_STACK_CONTAINERS, "Stack Container");
RegisterDebugTopic(TOPIC_LIST_CONTAINERS, "List Container");
RegisterDebugTopic(TOPIC_QUEUE_CONTAINERS, "Queue Container");
RegisterDebugTopic(TOPIC_ORDLIST_CONTAINERS, "Ordered List Container");
}
//*****************************************************************************
//
// ShutdownContainers
//
// Parameter List : none
//
// Return Value : void
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
void ShutdownContainers( void )
{
UnRegisterDebugTopic(TOPIC_STACK_CONTAINERS, "Stack Container");
UnRegisterDebugTopic(TOPIC_LIST_CONTAINERS, "List Container");
UnRegisterDebugTopic(TOPIC_QUEUE_CONTAINERS, "Queue Container");
UnRegisterDebugTopic(TOPIC_ORDLIST_CONTAINERS, "Ordered List Container");
}
//*****************************************************************************
//
// PeekQueue - gets the first item in queue without
// actually deleting it.
//
// Parameter List : pvoid_queue - pointer to queue
// container
// data - data removed from queue
//
// Return Value pointer to queue with data removed
// or NULL if failed
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
BOOLEAN PeekQueue(HQUEUE hQueue, void *pdata)
{
QueueHeader *pTemp_cont;
void *pvoid;
BYTE *pbyte;
// cannot check for invalid handle , only 0
if (hQueue == NULL)
{
DbgMessage(TOPIC_QUEUE_CONTAINERS, DBG_LEVEL_0, "This is not a valid pointer to the queue");
return FALSE;
}
if (pdata == NULL)
{
DbgMessage(TOPIC_QUEUE_CONTAINERS, DBG_LEVEL_0, "Memory fo Data to be removed from queue is NULL");
return FALSE;
}
//assign to temporary variables
pTemp_cont = (QueueHeader *)hQueue;
// if theres no elements to remove return error
if (pTemp_cont->uiTotal_items == 0)
{
DbgMessage(TOPIC_QUEUE_CONTAINERS, DBG_LEVEL_0, "There is nothing in the queue");
return FALSE;
}
//copy the element pointed to by uiHead
pbyte = (BYTE *)hQueue;
pbyte += pTemp_cont->uiHead;
pvoid = (void *)pbyte;
memmove(pdata, pvoid, pTemp_cont->uiSiz_of_elem);
return TRUE;
}
//*****************************************************************************
//
// PeekList - gets the specified item in the list without
// actually deleting it.
//
// Parameter List : hList - pointer to list
// container
// data - data where list element is stored
//
// Return Value BOOLEAN
//
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
BOOLEAN PeekList(HLIST hList, void *pdata, UINT32 uiPos)
{
ListHeader *pTemp_cont;
void *pvoid;
UINT32 uiOffsetSrc;
BYTE *pbyte;
// cannot check for invalid handle , only 0
if (hList == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "This is not a valid pointer to the list");
return FALSE;
}
if (pdata == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Memory fo Data to be removed from list is NULL");
return FALSE;
}
//assign to temporary variables
pTemp_cont = (ListHeader *)hList;
// if theres no elements to peek return error
if (pTemp_cont->uiTotal_items == 0)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "There is nothing in the list");
return FALSE;
}
if (uiPos >= pTemp_cont->uiTotal_items)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "There is no item at this position");
return FALSE;
}
//copy the element pointed to by uiHead
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
if (uiOffsetSrc >= pTemp_cont->uiMax_size)
uiOffsetSrc = sizeof(ListHeader) + (uiOffsetSrc - pTemp_cont->uiMax_size);
pbyte = (BYTE *)hList;
pbyte += uiOffsetSrc;
pvoid = (void *)pbyte;
memmove(pdata, pvoid, pTemp_cont->uiSiz_of_elem);
return TRUE;
}
//*****************************************************************************
//
// SwapListNode - Swaps the contents of a list node with the given parameter.
// Note: The data being swapped in MUST have the same size as
// the current node size or strange things could happen.
// Contents of node and pdata parameter are swapped.
//
// Parameter List : hList - pointer to list container
// pdata - pointer to data to be swapped
// uiPos - List position with which to swap.
//
// Return Value BOOLEAN - TRUE if successful, FALSE if function fails.
//
//
// Modification History :
// Added to SGP by Bret Rowdon for use with JA2. May 1 '97.
// - This function was based on the PeekList function.
//
//*****************************************************************************
BOOLEAN SwapListNode(HLIST hList, void *pdata, UINT32 uiPos)
{
ListHeader *pTemp_cont;
BYTE *pvoid;
UINT32 uiOffsetSrc;
BYTE *pbyte;
BYTE *pSrc;
// cannot check for invalid handle, only 0
if (hList == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Invalid pointer to list");
return FALSE;
}
if (pdata == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Data pointer to be swapped from list is NULL");
return FALSE;
}
//assign to temporary variables
pTemp_cont = (ListHeader *)hList;
// if theres no elements to peek return error
if (pTemp_cont->uiTotal_items == 0)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Empty list");
return FALSE;
}
if (uiPos >= pTemp_cont->uiTotal_items)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Invalid list position");
return FALSE;
}
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
if (uiOffsetSrc >= pTemp_cont->uiMax_size)
uiOffsetSrc = sizeof(ListHeader) + (uiOffsetSrc - pTemp_cont->uiMax_size);
pbyte = (BYTE *)hList;
pbyte += uiOffsetSrc;
pvoid = pbyte;
pSrc = (BYTE *) pdata;
// possible overlap, use memmove()
memmove(pvoid, pdata, pTemp_cont->uiSiz_of_elem);
//memmove(pvoid, pdata, pTemp_cont->uiSiz_of_elem);
return TRUE;
}
//*****************************************************************************
//
// StoreListNode - Stores the contents of a list node with the given parameter.
// Unlike SwapListNode(), this does NOT swap previous contents
// back into the pdata buffer!
//
// Parameter List : hList - pointer to list container
// pdata - pointer to data to be stored
// uiPos - List position into which to store.
//
// Return Value BOOLEAN - TRUE if successful, FALSE if function fails.
//
//
// Modification History :
// Added to SGP by Alex Meduna for use with Wiz8. Oct 31 '97.
// - This function is nearly identical to the SwapListNode() function.
//
//*****************************************************************************
BOOLEAN StoreListNode(HLIST hList, void *pdata, UINT32 uiPos)
{
ListHeader *pTemp_cont;
UINT32 uiOffsetSrc;
BYTE *pbyte;
// cannot check for invalid handle , only 0
if (hList == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Invalid pointer to list");
return FALSE;
}
if (pdata == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Data pointer to be swapped from list is NULL");
return FALSE;
}
//assign to temporary variables
pTemp_cont = (ListHeader *)hList;
// if theres no elements to peek return error
if (pTemp_cont->uiTotal_items == 0)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Empty list");
return FALSE;
}
if (uiPos >= pTemp_cont->uiTotal_items)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Invalid list position");
return FALSE;
}
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
if (uiOffsetSrc >= pTemp_cont->uiMax_size)
uiOffsetSrc = sizeof(ListHeader) + (uiOffsetSrc - pTemp_cont->uiMax_size);
pbyte = (BYTE *)hList;
pbyte += uiOffsetSrc;
memmove(pbyte, pdata, pTemp_cont->uiSiz_of_elem);
return TRUE;
}
//*****************************************************************************
//
// PeekOrdList - gets the specified item in the list without
// actually deleting it.
//
// Parameter List : hList - pointer to ordered list
// container
// data - data where list element is stored
//
// Return Value BOOLEAN
//
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
BOOLEAN PeekOrdList(HORDLIST hOrdList, void *pdata, UINT32 uiPos)
{
OrdListHeader *pTemp_cont;
void *pvoid;
UINT32 uiOffsetSrc;
BYTE *pbyte;
// cannot check for invalid handle , only 0
if (hOrdList == NULL)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "This is not a valid pointer to the ordered list");
return FALSE;
}
if (pdata == NULL)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Memory fo Data to be removed from ordered list is NULL");
return FALSE;
}
//assign to temporary variables
pTemp_cont = (OrdListHeader *)hOrdList;
// if theres no elements to peek return error
if (pTemp_cont->uiTotal_items == 0)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "There is nothing in the list");
return FALSE;
}
if (uiPos >= pTemp_cont->uiTotal_items)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "There is no item at this position");
return FALSE;
}
//copy the element pointed to by uiHead
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
if (uiOffsetSrc >= pTemp_cont->uiMax_size)
uiOffsetSrc = sizeof(OrdListHeader) + (uiOffsetSrc - pTemp_cont->uiMax_size);
pbyte = (BYTE *)hOrdList;
pbyte += uiOffsetSrc;
pvoid = (void *)pbyte;
memmove(pdata, pvoid, pTemp_cont->uiSiz_of_elem);
return TRUE;
}
//*****************************************************************************
//
// RemfromQueue
//
// Parameter List : pvoid_queue - pointer to queue
// container
// data - data removed from queue
//
// Return Value pointer to queue with data removed
// or NULL if failed
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
BOOLEAN RemfromQueue(HQUEUE hQueue, void *pdata)
{
QueueHeader *pTemp_cont;
void *pvoid;
BYTE *pbyte;
// cannot check for invalid handle , only 0
if (hQueue == NULL)
{
DbgMessage(TOPIC_QUEUE_CONTAINERS, DBG_LEVEL_0, "This is not a valid pointer to the queue");
return FALSE;
}
if (pdata == NULL)
{
DbgMessage(TOPIC_QUEUE_CONTAINERS, DBG_LEVEL_0, "Memory fo Data to be removed from queue is NULL");
return FALSE;
}
//assign to temporary variables
pTemp_cont = (QueueHeader *)hQueue;
// if theres no elements to remove return error
if (pTemp_cont->uiTotal_items == 0)
{
DbgMessage(TOPIC_QUEUE_CONTAINERS, DBG_LEVEL_0, "There is nothing in the queue to remove");
return FALSE;
}
//remove the element pointed to by uiHead
pbyte = (BYTE *)hQueue;
pbyte += pTemp_cont->uiHead;
pvoid = (void *)pbyte;
memmove(pdata, pvoid, pTemp_cont->uiSiz_of_elem);
pTemp_cont->uiTotal_items--;
pTemp_cont->uiHead += pTemp_cont->uiSiz_of_elem;
// if after removing an element head = tail then set them both
// to the beginning of the container as it is empty
if (pTemp_cont->uiHead == pTemp_cont->uiTail)
pTemp_cont->uiHead = pTemp_cont->uiTail = sizeof(QueueHeader);
// if only the head is at the end of the container then make it point
// to the beginning of the container
if (pTemp_cont->uiHead == pTemp_cont->uiMax_size)
pTemp_cont->uiHead = sizeof(QueueHeader);
return TRUE;
}
//*****************************************************************************
//
// AddtoQueue
//
// Parameter List : pvoid_queue - pointer to queue
// container
// pdata - pointer to data to add to queue
//
// Return Value pointer to queue with data added
// else false
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
HQUEUE AddtoQueue(HQUEUE hQueue, void *pdata)
{
QueueHeader *pTemp_cont;
UINT32 uiMax_size;
UINT32 uiSize_of_each;
UINT32 uiTotal;
UINT32 uiNew_size;
UINT32 uiHead;
UINT32 uiTail;
void *pvoid;
BYTE *pbyte;
BYTE *pmaxsize;
BYTE *presize;
BOOLEAN fresize;
// check for invalid handle = 0
if (hQueue == NULL)
{
DbgMessage(TOPIC_QUEUE_CONTAINERS, DBG_LEVEL_0, "This is not a valid pointer to the queue");
return NULL;
}
// check for data = NULL
if (pdata == NULL)
{
DbgMessage(TOPIC_QUEUE_CONTAINERS, DBG_LEVEL_0, "Data to be added onto queue is NULL");
return NULL;
}
// assign some temporary variables
fresize = FALSE;
pTemp_cont = (QueueHeader *)hQueue;
uiTotal = pTemp_cont->uiTotal_items;
uiSize_of_each = pTemp_cont->uiSiz_of_elem;
uiMax_size = pTemp_cont->uiMax_size;
uiHead = pTemp_cont->uiHead;
uiTail = pTemp_cont->uiTail;
if ((uiTail + uiSize_of_each) > uiMax_size)
{
uiTail = pTemp_cont->uiTail = sizeof(QueueHeader);
fresize = TRUE;
}
if ((uiHead == uiTail) && ((uiHead >= (sizeof(QueueHeader) + uiSize_of_each)) || (fresize == TRUE)))
{
uiNew_size = uiMax_size + (uiMax_size - sizeof(QueueHeader));
pTemp_cont->uiMax_size = uiNew_size;
if ((hQueue = MemRealloc(hQueue, uiNew_size)) == NULL)
{
DbgMessage(TOPIC_QUEUE_CONTAINERS, DBG_LEVEL_0, "Could not resize queue container memory");
return NULL;
}
// copy memory from beginning of container to end of container
// so that all the data is in one continuous block
pTemp_cont = (QueueHeader *)hQueue;
presize = (BYTE *)hQueue;
pmaxsize = (BYTE *)hQueue;
presize += sizeof(QueueHeader);
pmaxsize += uiMax_size;
if (uiHead > sizeof(QueueHeader))
memmove(pmaxsize, presize, uiHead-sizeof(QueueHeader));
pTemp_cont->uiTail = uiMax_size + (uiHead-sizeof(QueueHeader));
}
pbyte = (BYTE *)hQueue;
pbyte += pTemp_cont->uiTail;
pvoid = (void *)pbyte;
memmove(pvoid, pdata, uiSize_of_each);
pTemp_cont->uiTotal_items++;
pTemp_cont->uiTail += uiSize_of_each;
return hQueue;
}
//*****************************************************************************
//
// do_copy
//
// Parameter List : pointer to mem, source offset, dest offset, size
//
// Return Value BOOLEAN
//
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
BOOLEAN do_copy(void *pmem_void, UINT32 uiSourceOfst, UINT32 uiDestOfst, UINT32 uiSize)
{
BYTE *pOffsetSrc;
BYTE *pOffsetDst;
void *pvoid_src;
void *pvoid_dest;
if ((uiSourceOfst < 0) || (uiDestOfst < 0) || (uiSize < 0))
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Invalid parameters passed to do_copy");
return FALSE;
}
if (pmem_void == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Invalid pointer passed to do_copy");
return FALSE;
}
pOffsetSrc = (BYTE *)pmem_void;
pOffsetSrc += uiSourceOfst;
pOffsetDst = (BYTE *)pmem_void;
pOffsetDst += uiDestOfst;
pvoid_src = (void *)pOffsetSrc;
pvoid_dest = (void *)pOffsetDst;
memmove(pvoid_dest, pvoid_src, uiSize);
return TRUE;
}
//*****************************************************************************
//
// do_copy_data
//
// Parameter List : pointer to mem, pointer to data, source offset, size
//
// Return Value BOOLEAN
//
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
BOOLEAN do_copy_data(void *pmem_void, void *data, UINT32 uiSrcOfst, UINT32 uiSize)
{
BYTE *pOffsetSrc;
void *pvoid_src;
if ((uiSrcOfst < 0) || (uiSize < 0))
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Invalid parameters passed to do_copy_data");
return FALSE;
}
if (pmem_void == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Invalid pointer passed to do_copy_data");
return FALSE;
}
pOffsetSrc = (BYTE *)pmem_void;
pOffsetSrc += uiSrcOfst;
pvoid_src = (void *)pOffsetSrc;
memmove(data, pvoid_src, uiSize);
return TRUE;
}
//*****************************************************************************
//
// StackSize
//
// Parameter List : pointer to stack
//
// Return Value UINT32 stack size
//
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
UINT32 StackSize(HSTACK hStack)
{
StackHeader *pTemp_cont;
if (hStack == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Stack pointer is NULL");
return 0;
}
pTemp_cont = (StackHeader *)hStack;
return pTemp_cont->uiTotal_items;
}
//*****************************************************************************
//
// QueueSize
//
// Parameter List : pointer to queue
//
// Return Value UINT32 queue size
//
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
UINT32 QueueSize(HQUEUE hQueue)
{
QueueHeader *pTemp_cont;
if (hQueue == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Queue pointer is NULL");
return 0;
}
pTemp_cont = (QueueHeader *)hQueue;
return pTemp_cont->uiTotal_items;
}
//*****************************************************************************
//
// ListSize
//
// Parameter List : pointer to queue
//
// Return Value UINT32 list size
//
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
UINT32 ListSize(HLIST hList)
{
ListHeader *pTemp_cont;
if (hList == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "List pointer is NULL");
return 0;
}
pTemp_cont = (ListHeader *)hList;
return pTemp_cont->uiTotal_items;
}
//*****************************************************************************
//
// OrdListSize
//
// Parameter List : pointer to list
//
// Return Value UINT32 Ordlist size
//
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
UINT32 OrdListSize(HORDLIST hOrdList)
{
OrdListHeader *pTemp_cont;
if (hOrdList == NULL)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Ordered List pointer is NULL");
return 0;
}
pTemp_cont = (OrdListHeader *)hOrdList;
return pTemp_cont->uiTotal_items;
}
//*****************************************************************************
//
// AddtoList
//
// Parameter List : HCONTAINER - handle to list
// container
// data - data to add to queue
// position - position after which data is to added
//
// Return Value BOOLEAN true if push ok
// else false
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
HLIST AddtoList(HLIST hList, void *pdata, UINT32 uiPos)
{
ListHeader *pTemp_cont;
UINT32 uiMax_size;
UINT32 uiSize_of_each;
UINT32 uiTotal;
UINT32 uiNew_size;
UINT32 uiHead;
UINT32 uiTail;
void *pvoid;
BYTE *pbyte;
UINT32 uiOffsetSrc;
UINT32 uiOffsetDst;
UINT32 uiFinalLoc = 0;
BOOLEAN fTail_check=FALSE;
// check for invalid handle = 0
if (hList == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "This is not a valid handle to the list");
return NULL;
}
// check for data = NULL
if (pdata == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Data to be pushed onto list is NULL");
return NULL;
}
// check for a 0 or negative position passed in
if (uiPos < 0)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Data to be pushed onto list is NULL");
return NULL;
}
// assign some temporary variables
pTemp_cont = (ListHeader *)hList;
if (uiPos > pTemp_cont->uiTotal_items)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "There are not enough elements in the list");
return NULL;
}
uiTotal = pTemp_cont->uiTotal_items;
uiSize_of_each = pTemp_cont->uiSiz_of_elem;
uiMax_size = pTemp_cont->uiMax_size;
uiHead = pTemp_cont->uiHead;
uiTail = pTemp_cont->uiTail;
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
if (uiOffsetSrc >= uiMax_size)
uiOffsetSrc = sizeof(ListHeader) + (uiOffsetSrc - uiMax_size);
if (uiTail == uiOffsetSrc)
fTail_check = TRUE;
// copy appropriate blocks
if (((uiTail + uiSize_of_each) <= uiMax_size) &&
((uiTail > uiHead) || ((uiTail == uiHead) && (uiHead == sizeof(ListHeader)))))
{
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
uiOffsetDst = uiOffsetSrc + pTemp_cont->uiSiz_of_elem;
if (fTail_check == FALSE)
{
if (do_copy(hList, uiOffsetSrc, uiOffsetDst, uiTail-uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return NULL;
}
}
if (fTail_check == FALSE)
pTemp_cont->uiTail += uiSize_of_each;
uiFinalLoc = uiOffsetSrc;
}
if ((((uiTail + uiSize_of_each) <= uiMax_size) && (uiTail < uiHead))
|| (((uiTail + uiSize_of_each) > uiMax_size) && (uiHead >= (sizeof(ListHeader) + uiSize_of_each))))
{
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
if (uiOffsetSrc >= uiMax_size)
{
uiOffsetSrc = sizeof(ListHeader) + (uiOffsetSrc - uiMax_size);
uiOffsetDst = uiOffsetSrc + uiSize_of_each;
if (do_copy(hList, uiOffsetDst, uiOffsetSrc, uiTail-uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return NULL;
}
uiFinalLoc = uiOffsetSrc;
} else
{
uiOffsetSrc = sizeof(ListHeader);
uiOffsetDst = uiOffsetSrc + uiSize_of_each;
if (do_copy(hList, uiOffsetSrc, uiOffsetDst, uiTail-uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return NULL;
}
uiOffsetSrc = uiMax_size - uiSize_of_each;
uiOffsetDst = sizeof(ListHeader);
if (do_copy(hList, uiOffsetSrc, uiOffsetDst, uiSize_of_each) == FALSE)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return NULL;
}
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
uiOffsetDst = uiOffsetSrc + uiSize_of_each;
if (do_copy(hList, uiOffsetSrc, uiOffsetDst, (uiMax_size-uiSize_of_each) - uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return NULL;
}
}
pTemp_cont->uiTail += uiSize_of_each;
uiFinalLoc = uiOffsetSrc;
}// end if
if ((((uiTail + uiSize_of_each) <= uiMax_size) && (uiTail == uiHead) && (uiHead >= (sizeof(ListHeader) + uiSize_of_each)))
|| (((uiTail + uiSize_of_each) > uiMax_size) && (uiHead == sizeof(ListHeader))))
{
// need to resize the container
uiNew_size = uiMax_size + (uiMax_size - sizeof(ListHeader));
pTemp_cont->uiMax_size = uiNew_size;
if ((hList = MemRealloc(hList, uiNew_size)) == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not resize list container memory");
return NULL;
}
pTemp_cont = (ListHeader *)hList;
if (do_copy(hList, sizeof(ListHeader), uiMax_size, uiHead - sizeof(ListHeader)) == FALSE)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not copy list container memory");
return NULL;
}
pTemp_cont->uiTail = uiMax_size + (uiHead-sizeof(ListHeader));
// now make place for the actual element
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
uiOffsetDst = uiOffsetSrc + pTemp_cont->uiSiz_of_elem;
if (do_copy(hList, uiOffsetSrc, uiOffsetDst, uiTail-uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return NULL;
}
pTemp_cont->uiTail += uiSize_of_each;
uiFinalLoc = uiOffsetSrc;
}
// finally insert data at position uiFinalLoc
pbyte = (BYTE *)hList;
if (uiFinalLoc == 0)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "This should never happen! report this problem!");
return NULL;
}
pbyte += uiFinalLoc;
pvoid = (void *)pbyte;
memmove(pvoid, pdata, pTemp_cont->uiSiz_of_elem);
pTemp_cont->uiTotal_items++;
if (fTail_check == TRUE)
pTemp_cont->uiTail += pTemp_cont->uiSiz_of_elem;
return hList;
}
//*****************************************************************************
//
// RemfromList
//
// Parameter List : HLIST - handle to list
// container
// data - data to remove from list
// position - position after which data is to added
//
// Return Value BOOLEAN true if push ok
// else false
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
BOOLEAN RemfromList(HLIST hList, void *pdata, UINT32 uiPos)
{
ListHeader *pTemp_cont;
UINT32 uiMax_size;
UINT32 uiSize_of_each;
UINT32 uiTotal;
UINT32 uiHead;
UINT32 uiTail;
UINT32 uiOffsetSrc;
UINT32 uiOffsetDst;
UINT32 uiFinalLoc = 0;
// check for invalid handle = 0
if (hList == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "This is not a valid handle to the list");
return FALSE;
}
// check for data = NULL
if (pdata == NULL)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Data to be pushed onto list is NULL");
return FALSE;
}
// check for a 0 or negative position passed in
if (uiPos < 0)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Data to be pushed onto list is NULL");
return FALSE;
}
// assign some temporary variables
pTemp_cont = (ListHeader *)hList;
if (uiPos >= pTemp_cont->uiTotal_items)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Cannot delete at the specified position");
return FALSE;
}
if (pTemp_cont->uiTotal_items == 0)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "There are no elements in the list to remove");
return FALSE;
}
uiTotal = pTemp_cont->uiTotal_items;
uiSize_of_each = pTemp_cont->uiSiz_of_elem;
uiMax_size = pTemp_cont->uiMax_size;
uiHead = pTemp_cont->uiHead;
uiTail = pTemp_cont->uiTail;
// copy appropriate blocks
if ((uiTail > uiHead) || ((uiTail == uiHead) && (uiHead == sizeof(ListHeader))))
{
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
uiOffsetDst = uiOffsetSrc + pTemp_cont->uiSiz_of_elem;
if (do_copy_data(hList, pdata, uiOffsetSrc, uiSize_of_each) == FALSE)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not copy the data from list");
return FALSE;
}
if (do_copy(hList, uiOffsetDst, uiOffsetSrc, uiTail-uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not remove the data the list");
return FALSE;
}
pTemp_cont->uiTail -= uiSize_of_each;
pTemp_cont->uiTotal_items--;
}
if ((uiTail < uiHead) || ((uiTail == uiHead) && (uiHead <= (sizeof(ListHeader)+uiSize_of_each))))
{
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
if (uiOffsetSrc >= uiMax_size)
{
uiOffsetSrc = sizeof(ListHeader) + (uiOffsetSrc - uiMax_size);
uiOffsetDst = uiOffsetSrc + uiSize_of_each;
if (do_copy_data(hList, pdata, uiOffsetSrc, uiSize_of_each) == FALSE)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not copy the data from list");
return FALSE;
}
if (do_copy(hList, uiOffsetSrc, uiOffsetDst, uiTail-uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return FALSE;
}
uiFinalLoc = uiOffsetSrc;
}
else
{
uiOffsetSrc = sizeof(ListHeader);
uiOffsetDst = uiOffsetSrc + uiSize_of_each;
if (do_copy(hList, uiOffsetSrc, uiOffsetDst, uiTail-uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return FALSE;
}
uiOffsetSrc = uiMax_size - uiSize_of_each;
uiOffsetDst = sizeof(ListHeader);
if (do_copy(hList, uiOffsetSrc, uiOffsetDst, uiSize_of_each) == FALSE)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return FALSE;
}
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
uiOffsetDst = uiOffsetSrc + uiSize_of_each;
if (do_copy_data(hList, pdata, uiOffsetSrc, uiSize_of_each) == FALSE)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not copy the data from list");
return FALSE;
}
if (do_copy(hList, uiOffsetSrc, uiOffsetDst, (uiMax_size-uiSize_of_each) - uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_LIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return FALSE;
}
}
pTemp_cont->uiTail -= uiSize_of_each;
pTemp_cont->uiTotal_items--;
} // end if
return TRUE;
}
//*****************************************************************************
//
// RemfromOrdList
//
// Parameter List : HORDLIST - handle to ordered list
// container
// data - data to remove from ordered list
// position - position after which data is to added
//
// Return Value BOOLEAN true if push ok
// else false
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
BOOLEAN RemfromOrdList(HORDLIST hOrdList, void *pdata, UINT32 uiPos)
{
OrdListHeader *pTemp_cont;
UINT32 uiMax_size;
UINT32 uiSize_of_each;
UINT32 uiTotal;
UINT32 uiHead;
UINT32 uiTail;
UINT32 uiOffsetSrc;
UINT32 uiOffsetDst;
UINT32 uiFinalLoc = 0;
// check for invalid handle = 0
if (hOrdList == NULL)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "This is not a valid handle to the ordered list");
return FALSE;
}
// check for data = NULL
if (pdata == NULL)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Data to be pushed onto ordered list is NULL");
return FALSE;
}
// check for a 0 or negative position passed in
if (uiPos < 0)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Data to be pushed onto ordered list is NULL");
return FALSE;
}
// assign some temporary variables
pTemp_cont = (OrdListHeader *)hOrdList;
if (uiPos >= pTemp_cont->uiTotal_items)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Cannot delete at the specified position");
return FALSE;
}
if (pTemp_cont->uiTotal_items == 0)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "There are no elements in the ordered list to remove");
return FALSE;
}
uiTotal = pTemp_cont->uiTotal_items;
uiSize_of_each = pTemp_cont->uiSiz_of_elem;
uiMax_size = pTemp_cont->uiMax_size;
uiHead = pTemp_cont->uiHead;
uiTail = pTemp_cont->uiTail;
// copy appropriate blocks
if ((uiTail > uiHead) || ((uiTail == uiHead) && (uiHead == sizeof(OrdListHeader))))
{
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
uiOffsetDst = uiOffsetSrc + pTemp_cont->uiSiz_of_elem;
if (do_copy_data(hOrdList, pdata, uiOffsetSrc, uiSize_of_each) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not copy the data from ordered list");
return FALSE;
}
if (do_copy(hOrdList, uiOffsetDst, uiOffsetSrc, uiTail-uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not remove the data from the ordered list");
return FALSE;
}
pTemp_cont->uiTail -= uiSize_of_each;
pTemp_cont->uiTotal_items--;
}
if ((uiTail < uiHead) || ((uiTail == uiHead) && (uiHead <= (sizeof(OrdListHeader)+uiSize_of_each))))
{
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
if (uiOffsetSrc >= uiMax_size)
{
uiOffsetSrc = sizeof(OrdListHeader) + (uiOffsetSrc - uiMax_size);
uiOffsetDst = uiOffsetSrc + uiSize_of_each;
if (do_copy_data(hOrdList, pdata, uiOffsetSrc, uiSize_of_each) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not copy the data from list");
return FALSE;
}
if (do_copy(hOrdList, uiOffsetSrc, uiOffsetDst, uiTail-uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return FALSE;
}
uiFinalLoc = uiOffsetSrc;
}
else
{
uiOffsetSrc = sizeof(OrdListHeader);
uiOffsetDst = uiOffsetSrc + uiSize_of_each;
if (do_copy(hOrdList, uiOffsetSrc, uiOffsetDst, uiTail-uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return FALSE;
}
uiOffsetSrc = uiMax_size - uiSize_of_each;
uiOffsetDst = sizeof(OrdListHeader);
if (do_copy(hOrdList, uiOffsetSrc, uiOffsetDst, uiSize_of_each) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return FALSE;
}
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
uiOffsetDst = uiOffsetSrc + uiSize_of_each;
if (do_copy_data(hOrdList, pdata, uiOffsetSrc, uiSize_of_each) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not copy the data from list");
return FALSE;
}
if (do_copy(hOrdList, uiOffsetSrc, uiOffsetDst, (uiMax_size-uiSize_of_each) - uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return FALSE;
}
}
pTemp_cont->uiTail -= uiSize_of_each;
pTemp_cont->uiTotal_items--;
} // end if
return TRUE;
}
//*****************************************************************************
//
// StoreinOrdList
//
// Parameter List : HORDLIST - handle to ordered list
// container
// data - data to add to the ordered list
// position - position after which data is to added
//
// Return Value BOOLEAN true if push ok
// else false
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
//
//*****************************************************************************
HORDLIST StoreinOrdList(HORDLIST hOrdList, void *pdata, UINT32 uiPos)
{
OrdListHeader *pTemp_cont;
UINT32 uiMax_size;
UINT32 uiSize_of_each;
UINT32 uiTotal;
UINT32 uiNew_size;
UINT32 uiHead;
UINT32 uiTail;
void *pvoid;
BYTE *pbyte;
UINT32 uiOffsetSrc;
UINT32 uiOffsetDst;
UINT32 uiFinalLoc = 0;
BOOLEAN fTail_check=FALSE;
// check for invalid handle = 0
if (hOrdList == NULL)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "This is not a valid handle to the ordered list");
return NULL;
}
// check for data = NULL
if (pdata == NULL)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Data to be pushed onto ordered list is NULL");
return NULL;
}
// assign some temporary variables
pTemp_cont = (OrdListHeader *)hOrdList;
// check for invalid position
if (uiPos > pTemp_cont->uiTotal_items)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "There are not enough elements in the ordered list to add after");
return NULL;
}
uiTotal = pTemp_cont->uiTotal_items;
uiSize_of_each = pTemp_cont->uiSiz_of_elem;
uiMax_size = pTemp_cont->uiMax_size;
uiHead = pTemp_cont->uiHead;
uiTail = pTemp_cont->uiTail;
uiOffsetSrc = pTemp_cont->uiHead + (uiPos * pTemp_cont->uiSiz_of_elem);
// this shouldn't be necessary? position should never be outside the range?
if (uiOffsetSrc >= uiMax_size)
uiOffsetSrc = sizeof(OrdListHeader) + (uiOffsetSrc - uiMax_size);
if (uiTail == uiOffsetSrc)
fTail_check = TRUE;
// now copy the appropriate blocks to make room...
if (((uiTail + uiSize_of_each) <= uiMax_size) &&
((uiTail > uiHead) || ((uiTail == uiHead) && (uiHead == sizeof(OrdListHeader)))))
{
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
uiOffsetDst = uiOffsetSrc + pTemp_cont->uiSiz_of_elem;
if (fTail_check == FALSE)
{
if (do_copy(hOrdList, uiOffsetSrc, uiOffsetDst, uiTail-uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in ordered list");
return NULL;
}
}
if (fTail_check == FALSE)
pTemp_cont->uiTail += uiSize_of_each;
uiFinalLoc = uiOffsetSrc;
}
if ((((uiTail + uiSize_of_each) <= uiMax_size) && (uiTail < uiHead)) ||
(((uiTail + uiSize_of_each) > uiMax_size) && (uiHead >= (sizeof(OrdListHeader) + uiSize_of_each))))
{
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
if (uiOffsetSrc >= uiMax_size)
{
uiOffsetSrc = sizeof(OrdListHeader) + (uiOffsetSrc - uiMax_size);
uiOffsetDst = uiOffsetSrc + uiSize_of_each;
if (do_copy(hOrdList, uiOffsetDst, uiOffsetSrc, uiTail-uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return NULL;
}
uiFinalLoc = uiOffsetSrc;
}
else
{
uiOffsetSrc = sizeof(OrdListHeader);
uiOffsetDst = uiOffsetSrc + uiSize_of_each;
if (do_copy(hOrdList, uiOffsetSrc, uiOffsetDst, uiTail-uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return NULL;
}
uiOffsetSrc = uiMax_size - uiSize_of_each;
uiOffsetDst = sizeof(OrdListHeader);
if (do_copy(hOrdList, uiOffsetSrc, uiOffsetDst, uiSize_of_each) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return NULL;
}
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
uiOffsetDst = uiOffsetSrc + uiSize_of_each;
if (do_copy(hOrdList, uiOffsetSrc, uiOffsetDst, (uiMax_size-uiSize_of_each) - uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return NULL;
}
}
pTemp_cont->uiTail += uiSize_of_each;
uiFinalLoc = uiOffsetSrc;
} // end if
if ((((uiTail + uiSize_of_each) <= uiMax_size) && (uiTail == uiHead) && (uiHead >= (sizeof(OrdListHeader) + uiSize_of_each)))
|| (((uiTail + uiSize_of_each) > uiMax_size) && (uiHead == sizeof(OrdListHeader))))
{
// need to resize the container
uiNew_size = uiMax_size + (uiMax_size - sizeof(OrdListHeader));
pTemp_cont->uiMax_size = uiNew_size;
if ((hOrdList = MemRealloc(hOrdList, uiNew_size)) == NULL)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not resize ordered list container memory");
return NULL;
}
pTemp_cont = (OrdListHeader *)hOrdList;
if (do_copy(hOrdList, sizeof(OrdListHeader), uiMax_size, uiHead - sizeof(OrdListHeader)) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not copy ordered list container memory");
return NULL;
}
pTemp_cont->uiTail = uiMax_size + (uiHead-sizeof(OrdListHeader));
// now make place for the actual element
uiOffsetSrc = pTemp_cont->uiHead + (uiPos*pTemp_cont->uiSiz_of_elem);
uiOffsetDst = uiOffsetSrc + pTemp_cont->uiSiz_of_elem;
if (do_copy(hOrdList, uiOffsetSrc, uiOffsetDst, uiTail-uiOffsetSrc) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not store the data in list");
return NULL;
}
pTemp_cont->uiTail += uiSize_of_each;
uiFinalLoc = uiOffsetSrc;
}
if (uiFinalLoc == 0)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "This should never happen! report this problem!");
return NULL;
}
// finally insert data at position uiFinalLoc
pbyte = (BYTE *)hOrdList;
pbyte += uiFinalLoc;
pvoid = (void *)pbyte;
memmove(pvoid, pdata, pTemp_cont->uiSiz_of_elem);
pTemp_cont->uiTotal_items++;
if (fTail_check == TRUE)
pTemp_cont->uiTail += pTemp_cont->uiSiz_of_elem;
return hOrdList;
}
//*****************************************************************************
//
// AddtoOrdList
//
// Parameter List : HORDLIST - handle to ordered list
// container
// data - data to add to the ordered list
//
// Return Value BOOLEAN true if Add ok else false
//
// Modification History :
// Nov 26th 1996->modified for use by Wizardry
// Dec 19th 1997->verified, cleaned up, and heavily commented by AM
//
//*****************************************************************************
HORDLIST AddtoOrdList(HORDLIST hOrdList, void *pdata)
{
OrdListHeader *pOrdList;
void *pTemp_data;
UINT32 uiOffset;
BOOLEAN fContinue = FALSE;
INT8 sbResult;
UINT32 uiPosition;
// get a pointer into the list header
pOrdList = (OrdListHeader *)hOrdList;
// if the list is empty or full)
if (pOrdList->uiHead == pOrdList->uiTail)
{
// if the head offset points to position 0, presumably that means it's empty (?)
if (pOrdList->uiHead == sizeof(OrdListHeader))
{
// so store it in position 0
if ((hOrdList = StoreinOrdList(hOrdList, pdata, 0)) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not copy the data into ordered list");
return NULL;
}
return hOrdList;
}
// set flag to go through the while loop even though head == tail
fContinue = TRUE;
}
// grab enough space to store one list entry
pTemp_data = MemAlloc(pOrdList->uiSiz_of_elem);
// start offset by pointing at the last entry in the the list
uiOffset = pOrdList->uiTail;
// figure out the index of the entry that the tail points to
uiPosition = (pOrdList->uiTail - sizeof(OrdListHeader)) / pOrdList->uiSiz_of_elem;
// continue looping while offset hasn't reached the start of the list yet (or at least once if list is full)
while ((uiOffset != pOrdList->uiHead) || (fContinue))
{
// when offset reaches the top of the list
if (uiOffset == sizeof(OrdListHeader))
{
// wrap around to the very bottom of the list (guaranteed to hold data?)
uiOffset = pOrdList->uiMax_size;
uiPosition = (pOrdList->uiMax_size - sizeof(OrdListHeader)) / pOrdList->uiSiz_of_elem;
}
// get entry data at the current offset position and store it in pTemp_data
if (do_copy_data(hOrdList, pTemp_data, (uiOffset - pOrdList->uiSiz_of_elem), pOrdList->uiSiz_of_elem ) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not copy the data from list");
MemFree(pTemp_data);
return NULL;
}
// run the compare function
sbResult = pOrdList->pCompare(pTemp_data, pdata, pOrdList->uiSiz_of_elem);
// and do the right thing based on the result...
switch (sbResult)
{
case ORDLIST_ERROR :
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not perform comparison for ordered lists");
MemFree(pTemp_data);
return NULL;
}
case ORDLIST_EQUAL :
case ORDLIST_LEFT_LESS :
{
// found the right spot! Insert it at the current position
if ((hOrdList = StoreinOrdList(hOrdList, pdata, uiPosition)) == NULL)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not copy the data into ordered list");
MemFree(pTemp_data);
return NULL;
}
return hOrdList;
}
case ORDLIST_RIGHT_LESS :
{
// keep looking
uiOffset -= pOrdList->uiSiz_of_elem;
uiPosition--;
break;
}
default :
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Invalid result received from Compare function");
MemFree(pTemp_data);
return NULL;
}
} // end switch
fContinue = FALSE;
} // end while
// don't need this anymore
MemFree(pTemp_data);
pTemp_data = NULL;
// never found the right spot, which means we must have reached the head (damn well better)
if (uiOffset != pOrdList->uiHead)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "ERROR - left the while loop but not at the head");
return NULL;
}
// the new item will be first in list, so calculate the position based on the head
uiPosition = (pOrdList->uiHead - sizeof(OrdListHeader)) / pOrdList->uiSiz_of_elem;
// and stick it in there...
if ((hOrdList = StoreinOrdList(hOrdList, pdata, uiPosition)) == FALSE)
{
DbgMessage(TOPIC_ORDLIST_CONTAINERS, DBG_LEVEL_0, "Could not copy the data into ordered list");
return NULL;
}
return hOrdList;
}
INT8 Compare(void *p, void *q, UINT32 size)
{
TEST *temp1;
TEST *temp2;
temp1 = (TEST *)p;
temp2 = (TEST *)q;
if (temp1->me < temp2->me)
return ORDLIST_LEFT_LESS;
if (temp1->me > temp2->me)
return ORDLIST_RIGHT_LESS;
if (temp1->me == temp2->me)
return ORDLIST_EQUAL;
return ORDLIST_ERROR;
}