summaryrefslogtreecommitdiffstats
path: root/Router/alList.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Router/alList.cpp')
-rw-r--r--Router/alList.cpp1029
1 files changed, 1029 insertions, 0 deletions
diff --git a/Router/alList.cpp b/Router/alList.cpp
new file mode 100644
index 00000000..2c884c56
--- /dev/null
+++ b/Router/alList.cpp
@@ -0,0 +1,1029 @@
+/**
+ * OpenAL cross platform audio library
+ * Copyright (C) 1999-2003 by authors.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ * Or go to http://www.gnu.org/copyleft/lgpl.html
+ */
+
+
+
+
+#include "alList.h"
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+//****************************************************************************
+//****************************************************************************
+//
+// Defines
+//
+//****************************************************************************
+//****************************************************************************
+
+//
+// Some occasionally useful debugging stuff.
+//
+#if(DBG)
+ #ifndef ASSERT
+ static ALint alListDebugAssertsEnabled = 1;
+ #define ASSERT(exp) \
+ { \
+ if(!(exp) && alListDebugAssertsEnabled) \
+ { \
+ char tempStr[256]; \
+ OutputDebugString("\n"); \
+ sprintf(tempStr, "Assert failed in file %s, line %d!\n", \
+ __FILE__, __LINE__); \
+ OutputDebugString(tempStr); \
+ OutputDebugString("\n"); \
+ if(alListDebugAssertsEnabled) \
+ { \
+ DebugBreak(); \
+ } \
+ } \
+ }
+
+ #endif
+#else
+ #ifndef ASSERT
+ #define ASSERT(exp)
+ #endif
+#endif
+
+
+
+//****************************************************************************
+//****************************************************************************
+//
+// List Functions
+//
+//****************************************************************************
+//****************************************************************************
+
+//*****************************************************************************
+// alListAddEntry
+//*****************************************************************************
+// Adds an entry to the tail of the list. Each entry must be unique.
+//
+ALvoid alListAddEntry
+(
+ IN ALlist* pList,
+ IN ALlistEntry* pEntry
+)
+{
+#if(DBG)
+ ALlistEntry* pCurrent = 0;
+#endif
+
+ ASSERT(pList);
+ ASSERT(pEntry);
+ ASSERT(pList->Locked);
+ ASSERT(!pEntry->Next);
+ ASSERT(!pEntry->Previous);
+
+ //
+ // Verify the entry doesn't already exist.
+ //
+#if(DBG)
+ pCurrent = pList->Head;
+ while(pCurrent)
+ {
+ if(pCurrent == pEntry)
+ {
+ break;
+ }
+
+ pCurrent = pCurrent->Next;
+ }
+
+ if(pCurrent)
+ {
+ // Duplicate entries are not supported.
+ ASSERT(0);
+ return;
+ }
+#endif
+
+
+ //
+ // Add the item to the tail of the list.
+ //
+ if(pList->Tail)
+ {
+ pList->Tail->Next = pEntry;
+ }
+
+ pEntry->Previous = pList->Tail;
+ pList->Tail = pEntry;
+
+ //
+ // Check if this is the first entry.
+ //
+ if(!pList->Head)
+ {
+ pList->Head = pEntry;
+ pList->Current = pEntry;
+ }
+
+ pList->NumberOfEntries++;
+}
+
+
+//*****************************************************************************
+// alListAddEntryToHead
+//*****************************************************************************
+// Adds an entry to the head of the list. Each entry must be unique.
+//
+ALvoid alListAddEntryToHead
+(
+ IN ALlist* pList,
+ IN ALlistEntry* pEntry
+)
+{
+#if(DBG)
+ ALlistEntry* pCurrent = 0;
+#endif
+ ASSERT(pList);
+ ASSERT(pEntry);
+ ASSERT(pList->Locked);
+ ASSERT(!pEntry->Next);
+ ASSERT(!pEntry->Previous);
+
+ //
+ // Verify the entry doesn't already exist.
+ //
+#if(DBG)
+ pCurrent = pList->Head;
+ while(pCurrent)
+ {
+ if(pCurrent == pEntry)
+ {
+ break;
+ }
+
+ pCurrent = pCurrent->Next;
+ }
+
+ if(pCurrent)
+ {
+ // Duplicate entries are not supported.
+ ASSERT(0);
+ return;
+ }
+#endif
+
+
+ //
+ // Add the item to the head of the list.
+ //
+ if(pList->Head)
+ {
+ pList->Head->Previous = pEntry;
+ }
+
+ pEntry->Next = pList->Head;
+ pList->Head = pEntry;
+
+ //
+ // Check if this is the first entry.
+ //
+ if(!pList->Tail)
+ {
+ pList->Tail = pEntry;
+ pList->Current = pEntry;
+ }
+
+ pList->NumberOfEntries++;
+}
+
+
+//*****************************************************************************
+// alListAcquireLock
+//*****************************************************************************
+// This is called to aquire the list lock for operations that span multiple
+// list calls like iterating over the list.
+//
+ALvoid alListAcquireLock
+(
+ IN ALlist* pList
+)
+{
+ ASSERT(pList);
+
+ EnterCriticalSection(&pList->Lock);
+#if(DBG)
+ pList->Locked++;
+#endif
+
+ //
+ // Check that only one person has the lock.
+ //
+ ASSERT(pList->Locked == 1);
+}
+
+
+//*****************************************************************************
+// alListCreate
+//*****************************************************************************
+// Creates and initializes a list.
+//
+ALboolean alListCreate
+(
+ OUT ALlist** ppList
+)
+{
+ ALlist* pList = 0;
+
+ ASSERT(ppList);
+
+ //
+ // Allocate and initialize the list context.
+ //
+ *ppList = 0;
+ pList = (ALlist*)malloc(sizeof(ALlist));
+ if(!pList)
+ {
+ // Failed to allocate the list!
+ ASSERT(0);
+ return FALSE;
+ }
+
+ memset(pList, 0, sizeof(ALlist));
+ InitializeCriticalSection(&pList->Lock);
+ pList->NumberOfEntries = 0;
+ *ppList = pList;
+ return TRUE;
+}
+
+
+//*****************************************************************************
+// alListFree
+//*****************************************************************************
+// Destroys the list.
+//
+ALvoid alListFree
+(
+ IN ALlist* pList
+)
+{
+ ASSERT(pList);
+ ASSERT(!pList->Head);
+
+ //
+ // Free the resources allocated during the creation.
+ //
+ if(pList)
+ {
+ DeleteCriticalSection(&pList->Lock);
+ free(pList);
+ }
+
+ return;
+}
+
+
+//*****************************************************************************
+// alListGetData
+//*****************************************************************************
+// Returns the data from the list entry.
+//
+ALvoid* alListGetData
+(
+ IN ALlistEntry* pEntry
+)
+{
+ ASSERT(pEntry);
+
+ return pEntry->Data;
+}
+
+
+//*****************************************************************************
+// alListGetEntryAt
+//*****************************************************************************
+// Returns the entry in the list at the specified index of the list.
+//
+ALlistEntry* alListGetEntryAt
+(
+ IN ALlist* pList,
+ IN ALint Index
+)
+{
+ ALlistEntry* pEntry = 0;
+ ALint i;
+
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+ ASSERT(Index < pList->NumberOfEntries);
+
+ pEntry = pList->Head;
+ for(i = 0; i < Index && pEntry; i++)
+ {
+ pEntry = pEntry->Next;
+ }
+
+ return pEntry;
+}
+
+
+//*****************************************************************************
+// alListGetEntryCount
+//*****************************************************************************
+// Returns the number of items stored in the list.
+//
+ALint alListGetEntryCount
+(
+ IN ALlist* pList
+)
+{
+ ASSERT(pList->Locked);
+ return pList->NumberOfEntries;
+}
+
+
+//*****************************************************************************
+// alListGetHead
+//*****************************************************************************
+// Returns the first entry in the list.
+//
+ALlistEntry* alListGetHead
+(
+ IN ALlist* pList
+)
+{
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+ return pList->Head;
+}
+
+
+//*****************************************************************************
+// alListGetNext
+//*****************************************************************************
+// Returns the entry after to the entry pointed to by the iterator. If
+// the iterator is at the last entry (or has finished iterating over the
+// list), the returned entry will be 0.
+//
+ALlistEntry* alListGetNext
+(
+ IN ALlist* pList
+)
+{
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+ if(!pList->Current)
+ {
+ return 0;
+ }
+
+ return pList->Current->Next;
+}
+
+
+//*****************************************************************************
+// alListGetPrevious
+//*****************************************************************************
+// Returns the entry previous to the entry pointed to by the iterator. If
+// the iterator is at the first entry, the returned entry will be 0.
+//
+ALlistEntry* alListGetPrevious
+(
+ IN ALlist* pList
+)
+{
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+ if(!pList->Current)
+ {
+ return 0;
+ }
+
+ return pList->Current->Previous;
+}
+
+
+//*****************************************************************************
+// alListGetTail
+//*****************************************************************************
+// Returns the last entry in the list.
+//
+ALlistEntry* alListGetTail
+(
+ IN ALlist* pList
+)
+{
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+ return pList->Tail;
+}
+
+
+//*****************************************************************************
+// alListInitializeEntry
+//*****************************************************************************
+// Initializes a preallocated list entry.
+//
+ALvoid alListInitializeEntry
+(
+ ALlistEntry* pEntry,
+ ALvoid* pData
+)
+{
+ ASSERT(pEntry);
+
+ pEntry->Data = pData;
+ pEntry->Next = 0;
+ pEntry->Previous = 0;
+}
+
+
+//*****************************************************************************
+// alListIsEmpty
+//*****************************************************************************
+// Returns the TRUE if the list is empty.
+//
+ALboolean alListIsEmpty
+(
+ IN ALlist* pList
+)
+{
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+ return (pList->Head == 0);
+}
+
+
+//*****************************************************************************
+// alListIteratorGet
+//*****************************************************************************
+// Returns the entry pointed to by the iterator.
+//
+ALlistEntry* alListIteratorGet
+(
+ IN ALlist* pList
+)
+{
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+ return pList->Current;
+}
+
+
+//*****************************************************************************
+// alListIteratorFindData
+//*****************************************************************************
+// Searches the list for the matching item and return the pointer to the
+// entry. If the match is not found, the return will be 0.
+//
+ALlistEntry* alListIteratorFindData
+(
+ IN ALlist* pList,
+ IN ALvoid* pData
+)
+{
+ ALlistEntry* pCurrent = 0;
+
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+ //
+ // Find the item.
+ //
+ pCurrent = pList->Head;
+ while(pCurrent)
+ {
+ if(pCurrent->Data == pData)
+ {
+ break;
+ }
+
+ pCurrent = pCurrent->Next;
+ }
+
+ pList->Current = pCurrent;
+ return pCurrent;
+}
+
+
+//*****************************************************************************
+// alListIteratorNext
+//*****************************************************************************
+// This is called to advance the list iterator to the next entry in the list
+// and return that entry.
+//
+ALlistEntry* alListIteratorNext
+(
+ IN ALlist* pList
+)
+{
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+ if(!pList->Current)
+ {
+ return 0;
+ }
+
+ pList->Current = pList->Current->Next;
+ return pList->Current;
+}
+
+
+//*****************************************************************************
+// alListIteratorPrevious
+//*****************************************************************************
+// This is called to advance the list iterator to the previous entry in the
+// list and return that entry.
+//
+ALlistEntry* alListIteratorPrevious
+(
+ IN ALlist* pList
+)
+{
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+ if(!pList->Current)
+ {
+ return 0;
+ }
+
+ pList->Current = pList->Current->Previous;
+ return pList->Current;
+}
+
+
+//*****************************************************************************
+// alListIteratorRemove
+//*****************************************************************************
+// Removes the current item from the list and returns it. The iterator will
+// equal the next item in the list.
+//
+ALlistEntry* alListIteratorRemove
+(
+ IN ALlist* pList
+)
+{
+ ALlistEntry* pEntry = 0;
+
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+ //
+ // Make sure we aren't at the end of the list.
+ //
+ if(!pList->Current)
+ {
+ return 0;
+ }
+
+ //
+ // Remove the item from the list.
+ //
+ pEntry = pList->Current;
+
+ //
+ // Fix up the next item in the list.
+ //
+ if(pEntry->Next)
+ {
+ pEntry->Next->Previous = pEntry->Previous;
+ }
+
+ //
+ // Fix up the previous item in the list.
+ //
+ if(pEntry->Previous)
+ {
+ pEntry->Previous->Next = pEntry->Next;
+ }
+
+ //
+ // Fix up the current pointer.
+ //
+ pList->Current = pEntry->Next;
+
+ //
+ // Check the head pointer.
+ //
+ if(pList->Head == pEntry)
+ {
+ pList->Head = pEntry->Next;
+ }
+
+ //
+ // Check the tail pointer.
+ //
+ if(pList->Tail == pEntry)
+ {
+ pList->Tail = pEntry->Previous;
+ }
+
+ //
+ // Set the entry pointers.
+ //
+ pEntry->Next = 0;
+ pEntry->Previous = 0;
+ pList->NumberOfEntries--;
+ ASSERT(0 <= pList->NumberOfEntries);
+ return pEntry;
+}
+
+
+//*****************************************************************************
+// alListIteratorReset
+//*****************************************************************************
+// Returns the list iterator to the head of the list.
+//
+ALlistEntry* alListIteratorReset
+(
+ IN ALlist* pList
+)
+{
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+ pList->Current = pList->Head;
+ return pList->Current;
+}
+
+
+//*****************************************************************************
+// alListIteratorSet
+//*****************************************************************************
+// Sets the current entry pointer to the entry passed in. If the entry is not
+// found, the current entry will be 0.
+//
+ALlistEntry* alListIteratorSet
+(
+ IN ALlist* pList,
+ IN ALlistEntry* pEntry
+)
+{
+ ALlistEntry* pCurrent = 0;
+
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+ pCurrent = pList->Head;
+ while(pCurrent)
+ {
+ if(pCurrent == pEntry)
+ {
+ break;
+ }
+
+ pCurrent = pCurrent->Next;
+ }
+
+ pList->Current = pCurrent;
+ return pList->Current;
+}
+
+
+//*****************************************************************************
+// alListMatchEntry
+//*****************************************************************************
+// Matches the entry to an item in the list and returns the data in that
+// entry. If the match is not found, the return will be 0.
+//
+ALvoid* alListMatchEntry
+(
+ IN ALlist* pList,
+ IN ALlistEntry* pEntry
+)
+{
+ ALlistEntry* pCurrent = 0;
+
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+ //
+ // Find the item.
+ //
+ pCurrent = pList->Head;
+ while(pCurrent)
+ {
+ if(pCurrent == pEntry)
+ {
+ break;
+ }
+
+ pCurrent = pCurrent->Next;
+ }
+
+ if(!pCurrent)
+ {
+ return 0;
+ }
+
+ return pCurrent->Data;
+}
+
+
+//*****************************************************************************
+// alListMatchData
+//*****************************************************************************
+// Searches the list for the first matching item and returns the pointer to
+// the entry. If the match is not found, the return will be 0.
+//
+ALlistEntry* alListMatchData
+(
+ IN ALlist* pList,
+ IN ALvoid* pData
+)
+{
+ ALlistEntry* pCurrent = 0;
+
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+ //
+ // Find the item.
+ //
+ pCurrent = pList->Head;
+ while(pCurrent)
+ {
+ if(pCurrent->Data == pData)
+ {
+ break;
+ }
+
+ pCurrent = pCurrent->Next;
+ }
+
+ return pCurrent;
+}
+
+
+//*****************************************************************************
+// alListReleaseLock
+//*****************************************************************************
+// This is called to release the list lock.
+//
+ALvoid alListReleaseLock
+(
+ IN ALlist* pList
+)
+{
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+#if(DBG)
+ pList->Locked--;
+ ASSERT(pList->Locked == 0);
+#endif
+
+ LeaveCriticalSection(&pList->Lock);
+}
+
+
+//*****************************************************************************
+// alListRemoveEntry
+//*****************************************************************************
+// Removes the item from the list and returns the data from the item. If
+// this is the current item, the current item will equal the next item in the
+// list.
+//
+ALvoid* alListRemoveEntry
+(
+ IN ALlist* pList,
+ IN ALlistEntry* pEntry
+)
+{
+ ALlistEntry* pCurrent = 0;
+
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+ ASSERT(pEntry);
+
+ //
+ // Release the item from the list.
+ //
+ pCurrent = pList->Head;
+ while(pCurrent)
+ {
+ if(pCurrent == pEntry)
+ {
+ break;
+ }
+
+ pCurrent = pCurrent->Next;
+ }
+
+ if(!pCurrent)
+ {
+ return 0;
+ }
+
+ //
+ // Fix up the next item in the list.
+ //
+ if(pEntry->Next)
+ {
+ pEntry->Next->Previous = pEntry->Previous;
+ }
+
+ //
+ // Fix up the previous item in the list.
+ //
+ if(pEntry->Previous)
+ {
+ pEntry->Previous->Next = pEntry->Next;
+ }
+
+ //
+ // Fix up the current pointer.
+ //
+ if(pCurrent == pList->Current)
+ {
+ pList->Current = pEntry->Next;
+ }
+
+ //
+ // Check the head pointer.
+ //
+ if(pList->Head == pEntry)
+ {
+ pList->Head = pEntry->Next;
+ }
+
+ //
+ // Check the tail pointer.
+ //
+ if(pList->Tail == pEntry)
+ {
+ pList->Tail = pEntry->Previous;
+ }
+
+ //
+ // Set the entry pointers.
+ //
+ pEntry->Next = 0;
+ pEntry->Previous = 0;
+ pList->NumberOfEntries--;
+ ASSERT(0 <= pList->NumberOfEntries);
+ return pEntry->Data;
+}
+
+
+//*****************************************************************************
+// alListRemoveHead
+//*****************************************************************************
+// Removes the list entry at the head of the list. If this is the current
+// item, the current item will equal the next item in the list.
+//
+ALlistEntry* alListRemoveHead
+(
+ IN ALlist* pList
+)
+{
+ ALlistEntry* pCurrent = 0;
+
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+ //
+ // Release the item from the list.
+ //
+ pCurrent = pList->Head;
+ if(!pCurrent)
+ {
+ return 0;
+ }
+
+ //
+ // Fix up the next item in the list.
+ //
+ if(pCurrent->Next)
+ {
+ pCurrent->Next->Previous = 0;
+ }
+
+ //
+ // Fix up the previous item in the list.
+ //
+ ASSERT(!pCurrent->Previous)
+
+ //
+ // Fix up the current pointer.
+ //
+ if(pCurrent == pList->Current)
+ {
+ pList->Current = pCurrent->Next;
+ }
+
+ //
+ // Check the head pointer.
+ //
+ pList->Head = pCurrent->Next;
+
+ //
+ // Check the tail pointer.
+ //
+ if(pList->Tail == pCurrent)
+ {
+ pList->Tail = 0;
+ }
+
+ //
+ // Set the entry pointers.
+ //
+ pCurrent->Next = 0;
+ pCurrent->Previous = 0;
+ pList->NumberOfEntries--;
+ ASSERT(0 <= pList->NumberOfEntries);
+ return pCurrent;
+}
+
+
+//*****************************************************************************
+// alListRemoveTail
+//*****************************************************************************
+// Removes the list entry at the tail of the list. If this is the current
+// item, the current item will be null.
+//
+ALlistEntry* alListRemoveTail
+(
+ IN ALlist* pList
+)
+{
+ ALlistEntry* pCurrent = 0;
+
+ ASSERT(pList);
+ ASSERT(pList->Locked);
+
+ //
+ // Release the item from the list.
+ //
+ pCurrent = pList->Tail;
+ if(!pCurrent)
+ {
+ return 0;
+ }
+
+ //
+ // Fix up the next item in the list.
+ //
+ ASSERT(!pCurrent->Next)
+
+ //
+ // Fix up the previous item in the list.
+ //
+ if(pCurrent->Previous)
+ {
+ pCurrent->Previous->Next = 0;
+ }
+
+ //
+ // Fix up the current pointer.
+ //
+ if(pCurrent == pList->Current)
+ {
+ pList->Current = 0;
+ }
+
+ //
+ // Check the head pointer.
+ //
+ if(pList->Head == pCurrent)
+ {
+ pList->Head = 0;
+ }
+
+ //
+ // Check the tail pointer.
+ //
+ pList->Tail = pCurrent->Previous;
+
+ //
+ // Set the entry pointers.
+ //
+ pCurrent->Next = 0;
+ pCurrent->Previous = 0;
+ pList->NumberOfEntries--;
+ ASSERT(0 <= pList->NumberOfEntries);
+ return pCurrent;
+}
+