You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
357 lines
7.2 KiB
357 lines
7.2 KiB
#include "precomp.h"
|
|
DEBUG_FILEZONE(ZONE_T120_T123PSTN);
|
|
|
|
/* slist.cpp
|
|
*
|
|
* Copyright (c) 1996 by Microsoft Corporation
|
|
*
|
|
* Written by: Christos Tsollis
|
|
*
|
|
* Revisions:
|
|
*
|
|
* Abstract:
|
|
*
|
|
* This is the implementation of a linked list data structure.
|
|
*
|
|
*/
|
|
|
|
|
|
#define MyMalloc(size) LocalAlloc (LMEM_FIXED, (size))
|
|
#define MyFree(ptr) LocalFree ((HLOCAL) (ptr))
|
|
#define Max(a,b) (((a) > (b)) ? (a) : (b))
|
|
|
|
/* Function: Constructor
|
|
*
|
|
* Parameters:
|
|
* ltype: List type
|
|
* num_of_items: Size of the list's cache
|
|
*
|
|
* Return value:
|
|
* None
|
|
*/
|
|
|
|
SListClass::SListClass (DWORD num_of_items)
|
|
{
|
|
|
|
MaxEntries = Max (num_of_items, DEFAULT_NUMBER_OF_ITEMS);
|
|
|
|
// Allocate the block of items (which, hopefully, will be the last one)
|
|
Entries = (DWORD_PTR *) MyMalloc (MaxEntries * sizeof (DWORD_PTR));
|
|
|
|
// Initialize the private member variables
|
|
NumOfEntries = 0;
|
|
HeadOffset = 0;
|
|
CurrOffset = 0xFFFFFFFF;
|
|
|
|
}
|
|
|
|
|
|
/* Function: Destructor
|
|
*
|
|
* Parameters:
|
|
* None.
|
|
*
|
|
* Return value:
|
|
* None
|
|
*
|
|
*/
|
|
|
|
SListClass::~SListClass (void)
|
|
{
|
|
if (Entries != NULL)
|
|
MyFree (Entries);
|
|
}
|
|
|
|
|
|
/* Function: Expand
|
|
* This private member function, expands the storage array of a list. It doubles its size.
|
|
*
|
|
* Parameters:
|
|
* None.
|
|
*
|
|
* Return value:
|
|
* TRUE, if the expansion was successful. FALSE, otherwise.
|
|
*
|
|
*/
|
|
|
|
BOOL SListClass::Expand (void)
|
|
{
|
|
DWORD_PTR *OldEntries; // Keeps a copy of the old array of values.
|
|
DWORD dwTemp; // Temporary DWORD value
|
|
|
|
if (Entries == NULL) {
|
|
// the list is empty; we try to allocate space anyway.
|
|
Entries = (DWORD_PTR *) MyMalloc (MaxEntries * sizeof (DWORD_PTR));
|
|
if (Entries == NULL)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
ASSERT (Entries != NULL);
|
|
|
|
// The current array of entries is full, so we need to allocate a bigger one
|
|
// The new array has twice the size of the old one
|
|
OldEntries = Entries;
|
|
Entries = (DWORD_PTR *) MyMalloc ((MaxEntries << 1) * sizeof (DWORD_PTR));
|
|
if (Entries == NULL) {
|
|
// we failed; we have to return
|
|
Entries = OldEntries;
|
|
return FALSE;
|
|
}
|
|
|
|
// copy the old entries into the new array, starting from the beginning
|
|
dwTemp = MaxEntries - HeadOffset;
|
|
memcpy ((void *) Entries, (void *) (OldEntries + HeadOffset), dwTemp * sizeof (DWORD));
|
|
memcpy ((void *) (Entries + dwTemp), (void *) OldEntries, HeadOffset * sizeof (DWORD));
|
|
|
|
// Free the old array of entries
|
|
MyFree (OldEntries);
|
|
|
|
// Set the instance variables
|
|
MaxEntries <<= 1;
|
|
HeadOffset = 0;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/* Function: append
|
|
* Inserts a value at the end of a list.
|
|
*
|
|
* Parameters:
|
|
* new_key: The new value that has to be inserted in the list
|
|
*
|
|
* Return value:
|
|
* None.
|
|
*
|
|
*/
|
|
|
|
|
|
void SListClass::append (DWORD_PTR new_key)
|
|
{
|
|
DWORD_PTR dwTemp;
|
|
|
|
if (Entries == NULL || NumOfEntries >= MaxEntries)
|
|
if (! Expand ())
|
|
return;
|
|
|
|
ASSERT (Entries != NULL);
|
|
ASSERT (NumOfEntries < MaxEntries);
|
|
|
|
dwTemp = HeadOffset + (NumOfEntries++);
|
|
if (dwTemp >= MaxEntries)
|
|
dwTemp -= MaxEntries;
|
|
Entries[dwTemp] = new_key;
|
|
}
|
|
|
|
|
|
/* Function: prepend
|
|
* Inserts a value at the beginning of a list.
|
|
*
|
|
* Parameters:
|
|
* new_key: The new value that has to be inserted in the list
|
|
*
|
|
* Return value:
|
|
* None.
|
|
*
|
|
*/
|
|
|
|
void SListClass::prepend (DWORD_PTR new_key)
|
|
{
|
|
if (Entries == NULL || NumOfEntries >= MaxEntries)
|
|
if (! Expand ())
|
|
return;
|
|
|
|
ASSERT (Entries != NULL);
|
|
ASSERT (NumOfEntries < MaxEntries);
|
|
|
|
NumOfEntries++;
|
|
if (HeadOffset == 0)
|
|
HeadOffset = MaxEntries - 1;
|
|
else
|
|
HeadOffset--;
|
|
Entries[HeadOffset] = new_key;
|
|
}
|
|
|
|
|
|
/* Function: find
|
|
* Looks up a value in a DWORD_LIST list.
|
|
*
|
|
* Parameters:
|
|
* Key: The value to look up
|
|
*
|
|
* Return value:
|
|
* TRUE, if "Key" is found in the list. FALSE, otherwise.
|
|
*
|
|
*/
|
|
|
|
BOOL SListClass::find (DWORD_PTR Key)
|
|
{
|
|
DWORD i;
|
|
DWORD_PTR *pItem; // Goes through the items in the list.
|
|
|
|
for (i = 0, pItem = Entries + HeadOffset; i < NumOfEntries; i++) {
|
|
if (Key == *pItem)
|
|
return TRUE;
|
|
|
|
// Advance the "pItem" pointer
|
|
if ((DWORD) (++pItem - Entries) >= MaxEntries)
|
|
pItem = Entries;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/* Function: read
|
|
* Reads an item from the list. The list item is not removed from the list.
|
|
*
|
|
* Parameters:
|
|
* index: Index of the item to be read. 0 is the index of the 1st list item.
|
|
* NumOfEntries - 1 is the last valid index.
|
|
*
|
|
* Return value:
|
|
* The value at the index-th entry in the list. If the index is invalid, 0.
|
|
*
|
|
*/
|
|
|
|
DWORD_PTR SListClass::read (DWORD index)
|
|
{
|
|
DWORD dwTemp;
|
|
|
|
if (index >= NumOfEntries)
|
|
return 0;
|
|
|
|
dwTemp = HeadOffset + index;
|
|
if (dwTemp >= MaxEntries)
|
|
dwTemp -= MaxEntries;
|
|
|
|
return (Entries[dwTemp]);
|
|
}
|
|
|
|
|
|
/* Function: remove
|
|
* Removes a value from the list
|
|
*
|
|
* Parameters:
|
|
* Key: The value that has to be removed from the DWORD_LIST list
|
|
*
|
|
* Return value:
|
|
* None.
|
|
*
|
|
*/
|
|
|
|
void SListClass::remove (DWORD_PTR Key)
|
|
{
|
|
DWORD i, dwTemp;
|
|
DWORD_PTR *pItem; // Goes through the list items
|
|
|
|
for (i = 0, pItem = Entries + HeadOffset; i < NumOfEntries; i++) {
|
|
if (Key == *pItem) {
|
|
// we found the "Key"; to remove it, we move the last value into its place.
|
|
dwTemp = HeadOffset + (--NumOfEntries);
|
|
if (dwTemp >= MaxEntries)
|
|
dwTemp -= MaxEntries;
|
|
*pItem = Entries[dwTemp];
|
|
return;
|
|
}
|
|
|
|
// Advance the "pItem" pointer
|
|
if ((DWORD) (++pItem - Entries) >= MaxEntries)
|
|
pItem = Entries;
|
|
}
|
|
}
|
|
|
|
|
|
/* Function: get
|
|
* Reads and removes the 1st item from the list.
|
|
*
|
|
* Parameters:
|
|
* None.
|
|
*
|
|
* Return value:
|
|
* The value at the 1st entry in the list. If the list is empty, 0.
|
|
*
|
|
*/
|
|
|
|
DWORD_PTR SListClass::get (void)
|
|
{
|
|
DWORD_PTR return_value = 0;
|
|
|
|
if (NumOfEntries > 0) {
|
|
return_value = Entries[HeadOffset];
|
|
NumOfEntries--;
|
|
if (++HeadOffset >= MaxEntries)
|
|
HeadOffset = 0;
|
|
}
|
|
return return_value;
|
|
}
|
|
|
|
|
|
/* Function: removeLast
|
|
* Reads and removes the last item from the list
|
|
*
|
|
* Parameters:
|
|
* None.
|
|
*
|
|
* Return value:
|
|
* The value at the last entry in the list. If the list is empty, 0.
|
|
*
|
|
*/
|
|
|
|
DWORD_PTR SListClass::removeLast (void)
|
|
{
|
|
DWORD_PTR return_value = 0;
|
|
DWORD dwTemp;
|
|
|
|
if (NumOfEntries > 0) {
|
|
dwTemp = HeadOffset + (--NumOfEntries);
|
|
if (dwTemp >= MaxEntries)
|
|
dwTemp -= MaxEntries;
|
|
return_value = Entries[dwTemp];
|
|
}
|
|
return return_value;
|
|
}
|
|
|
|
|
|
/* Function: iterate
|
|
* Iterates through the items of a list. It remembers where it has
|
|
* stopped during the last call and starts from there.
|
|
*
|
|
* Parameters
|
|
* pKey: Pointer to DWORD or unsigned short value to receive the next item's value.
|
|
* It can be NULL.
|
|
*
|
|
* Return value:
|
|
* FALSE, when we reach the end of the dictionary
|
|
* TRUE, otherwise. Then, *pKey is valid
|
|
*
|
|
*/
|
|
|
|
BOOL SListClass::iterate (DWORD_PTR *pKey)
|
|
{
|
|
DWORD dwTemp;
|
|
|
|
if (NumOfEntries <= 0)
|
|
return FALSE;
|
|
|
|
if (CurrOffset == 0xFFFFFFFF) {
|
|
// start from the beginning
|
|
CurrOffset = 0;
|
|
}
|
|
else {
|
|
if (++CurrOffset >= NumOfEntries) {
|
|
// reset the iterator
|
|
CurrOffset = 0xFFFFFFFF;
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
dwTemp = CurrOffset + HeadOffset;
|
|
if (dwTemp >= MaxEntries)
|
|
dwTemp -= MaxEntries;
|
|
|
|
*pKey = Entries[dwTemp];
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|