From 5a131688e43abd7d80984cea1c2c7f80835f7890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 5 Dec 2012 17:24:01 -0500 Subject: [PATCH] libwinpr-utils: implement ArrayList --- winpr/include/winpr/collections.h | 14 +- winpr/libwinpr/utils/collections/ArrayList.c | 223 +++++++++++++++---- winpr/libwinpr/utils/collections/Queue.c | 10 +- winpr/libwinpr/utils/collections/Stack.c | 16 +- 4 files changed, 207 insertions(+), 56 deletions(-) diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index 95b4d6ee8..65bd9e3f0 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -64,7 +64,7 @@ WINPR_API void Queue_Free(wQueue* queue); struct _wStack { - BOOL bSynchronized; + BOOL synchronized; }; typedef struct _wStack wStack; @@ -86,7 +86,13 @@ WINPR_API void Stack_Free(wStack* stack); struct _wArrayList { - BOOL bSynchronized; + int capacity; + int growthFactor; + BOOL synchronized; + + int size; + void** array; + HANDLE mutex; }; typedef struct _wArrayList wArrayList; @@ -95,7 +101,9 @@ WINPR_API int ArrayList_Count(wArrayList* arrayList); WINPR_API BOOL ArrayList_IsFixedSized(wArrayList* arrayList); WINPR_API BOOL ArrayList_IsReadOnly(wArrayList* arrayList); WINPR_API BOOL ArrayList_IsSynchronized(wArrayList* arrayList); -WINPR_API void* ArrayList_Item(wArrayList* arrayList, int index, void* obj); + +WINPR_API void* ArrayList_GetItem(wArrayList* arrayList, int index); +WINPR_API void ArrayList_SetItem(wArrayList* arrayList, int index, void* obj); WINPR_API void ArrayList_Clear(wArrayList* arrayList); WINPR_API BOOL ArrayList_Contains(wArrayList* arrayList, void* obj); diff --git a/winpr/libwinpr/utils/collections/ArrayList.c b/winpr/libwinpr/utils/collections/ArrayList.c index a00ec1ec3..d91baf6e3 100644 --- a/winpr/libwinpr/utils/collections/ArrayList.c +++ b/winpr/libwinpr/utils/collections/ArrayList.c @@ -21,6 +21,8 @@ #include "config.h" #endif +#include + #include /** @@ -38,12 +40,7 @@ int ArrayList_Capacity(wArrayList* arrayList) { - if (arrayList->bSynchronized) - { - - } - - return 0; + return arrayList->capacity; } /** @@ -52,12 +49,7 @@ int ArrayList_Capacity(wArrayList* arrayList) int ArrayList_Count(wArrayList* arrayList) { - if (arrayList->bSynchronized) - { - - } - - return 0; + return arrayList->size; } /** @@ -84,32 +76,94 @@ BOOL ArrayList_IsReadOnly(wArrayList* arrayList) BOOL ArrayList_IsSynchronized(wArrayList* arrayList) { - return arrayList->bSynchronized; + return arrayList->synchronized; } /** - * Gets or sets the element at the specified index. + * Gets the element at the specified index. */ -void* ArrayList_Item(wArrayList* arrayList, int index, void* obj) +void* ArrayList_GetItem(wArrayList* arrayList, int index) { - return NULL; + void* obj = NULL; + + if (arrayList->synchronized) + WaitForSingleObject(arrayList->mutex, INFINITE); + + if ((index >= 0) && (index < arrayList->size)) + { + obj = arrayList->array[index]; + } + + if (arrayList->synchronized) + ReleaseMutex(arrayList->mutex); + + return obj; +} + +/** + * Sets the element at the specified index. + */ + +void ArrayList_SetItem(wArrayList* arrayList, int index, void* obj) +{ + if (arrayList->synchronized) + WaitForSingleObject(arrayList->mutex, INFINITE); + + if ((index >= 0) && (index < arrayList->size)) + { + arrayList->array[index] = obj; + } + + if (arrayList->synchronized) + ReleaseMutex(arrayList->mutex); } /** * Methods */ +/** + * Shift a section of the list. + */ + +void ArrayList_Shift(wArrayList* arrayList, int index, int count) +{ + if (arrayList->synchronized) + WaitForSingleObject(arrayList->mutex, INFINITE); + + if (count > 0) + { + if (arrayList->size + count > arrayList->capacity) + { + arrayList->capacity *= arrayList->growthFactor; + arrayList->array = (void**) realloc(arrayList->array, sizeof(void*) * arrayList->capacity); + } + + MoveMemory(&arrayList->array[index + count], &arrayList->array[index], count); + arrayList->size += count; + } + else if (count < 0) + { + MoveMemory(&arrayList->array[index + count], &arrayList->array[index], count); + arrayList->size += count; + } + + if (arrayList->synchronized) + ReleaseMutex(arrayList->mutex); +} + /** * Removes all elements from the ArrayList. */ void ArrayList_Clear(wArrayList* arrayList) { - if (arrayList->bSynchronized) - { + if (arrayList->synchronized) + WaitForSingleObject(arrayList->mutex, INFINITE); - } + if (arrayList->synchronized) + ReleaseMutex(arrayList->mutex); } /** @@ -118,10 +172,11 @@ void ArrayList_Clear(wArrayList* arrayList) BOOL ArrayList_Contains(wArrayList* arrayList, void* obj) { - if (arrayList->bSynchronized) - { + if (arrayList->synchronized) + WaitForSingleObject(arrayList->mutex, INFINITE); - } + if (arrayList->synchronized) + ReleaseMutex(arrayList->mutex); return FALSE; } @@ -132,12 +187,18 @@ BOOL ArrayList_Contains(wArrayList* arrayList, void* obj) int ArrayList_Add(wArrayList* arrayList, void* obj) { - if (arrayList->bSynchronized) - { + int index; - } + if (arrayList->synchronized) + WaitForSingleObject(arrayList->mutex, INFINITE); - return FALSE; + arrayList->array[arrayList->size++] = obj; + index = arrayList->size; + + if (arrayList->synchronized) + ReleaseMutex(arrayList->mutex); + + return index; } /* @@ -146,10 +207,17 @@ int ArrayList_Add(wArrayList* arrayList, void* obj) void ArrayList_Insert(wArrayList* arrayList, int index, void* obj) { - if (arrayList->bSynchronized) - { + if (arrayList->synchronized) + WaitForSingleObject(arrayList->mutex, INFINITE); + if ((index >= 0) && (index < arrayList->size)) + { + ArrayList_Shift(arrayList, index, 1); + arrayList->array[index] = obj; } + + if (arrayList->synchronized) + ReleaseMutex(arrayList->mutex); } /** @@ -158,10 +226,26 @@ void ArrayList_Insert(wArrayList* arrayList, int index, void* obj) void ArrayList_Remove(wArrayList* arrayList, void* obj) { - if (arrayList->bSynchronized) - { + int index; + BOOL found = FALSE; + if (arrayList->synchronized) + WaitForSingleObject(arrayList->mutex, INFINITE); + + for (index = 0; index < arrayList->size; index++) + { + if (arrayList->array[index] == obj) + { + found = TRUE; + break; + } } + + if (found) + ArrayList_Shift(arrayList, index, -1); + + if (arrayList->synchronized) + ReleaseMutex(arrayList->mutex); } /** @@ -170,10 +254,16 @@ void ArrayList_Remove(wArrayList* arrayList, void* obj) void ArrayList_RemoveAt(wArrayList* arrayList, int index, void* obj) { - if (arrayList->bSynchronized) - { + if (arrayList->synchronized) + WaitForSingleObject(arrayList->mutex, INFINITE); + if ((index >= 0) && (index < arrayList->size)) + { + ArrayList_Shift(arrayList, index, -1); } + + if (arrayList->synchronized) + ReleaseMutex(arrayList->mutex); } /** @@ -188,12 +278,34 @@ void ArrayList_RemoveAt(wArrayList* arrayList, int index, void* obj) int ArrayList_IndexOf(wArrayList* arrayList, void* obj, int startIndex, int count) { - if (arrayList->bSynchronized) - { + int index; + BOOL found = FALSE; + if (arrayList->synchronized) + WaitForSingleObject(arrayList->mutex, INFINITE); + + if (startIndex < 0) + startIndex = 0; + + if (count < 0) + count = arrayList->size; + + for (index = startIndex; index < startIndex + count; index++) + { + if (arrayList->array[index] == obj) + { + found = TRUE; + break; + } } - return 0; + if (!found) + index = -1; + + if (arrayList->synchronized) + ReleaseMutex(arrayList->mutex); + + return index; } /** @@ -208,19 +320,41 @@ int ArrayList_IndexOf(wArrayList* arrayList, void* obj, int startIndex, int coun int ArrayList_LastIndexOf(wArrayList* arrayList, void* obj, int startIndex, int count) { - if (arrayList->bSynchronized) - { + int index; + BOOL found = FALSE; + if (arrayList->synchronized) + WaitForSingleObject(arrayList->mutex, INFINITE); + + if (startIndex < 0) + startIndex = 0; + + if (count < 0) + count = arrayList->size; + + for (index = startIndex + count - 1; index >= startIndex; index--) + { + if (arrayList->array[index] == obj) + { + found = TRUE; + break; + } } - return 0; + if (!found) + index = -1; + + if (arrayList->synchronized) + ReleaseMutex(arrayList->mutex); + + return index; } /** * Construction, Destruction */ -wArrayList* ArrayList_New(BOOL bSynchronized) +wArrayList* ArrayList_New(BOOL synchronized) { wArrayList* arrayList = NULL; @@ -228,7 +362,15 @@ wArrayList* ArrayList_New(BOOL bSynchronized) if (arrayList) { - arrayList->bSynchronized = bSynchronized; + arrayList->synchronized = synchronized; + + arrayList->size = 0; + arrayList->capacity = 32; + arrayList->growthFactor = 2; + + arrayList->array = (void**) malloc(sizeof(void*) * arrayList->capacity); + + arrayList->mutex = CreateMutex(NULL, FALSE, NULL); } return arrayList; @@ -236,5 +378,6 @@ wArrayList* ArrayList_New(BOOL bSynchronized) void ArrayList_Free(wArrayList* arrayList) { + CloseHandle(arrayList->mutex); free(arrayList); } diff --git a/winpr/libwinpr/utils/collections/Queue.c b/winpr/libwinpr/utils/collections/Queue.c index 211f73802..1920b11eb 100644 --- a/winpr/libwinpr/utils/collections/Queue.c +++ b/winpr/libwinpr/utils/collections/Queue.c @@ -187,7 +187,7 @@ void* Queue_Peek(wQueue* queue) * Construction, Destruction */ -wQueue* Queue_New(BOOL synchronized, int iCapacity, int iGrowthFactor) +wQueue* Queue_New(BOOL synchronized, int capacity, int growthFactor) { wQueue* queue = NULL; @@ -204,11 +204,11 @@ wQueue* Queue_New(BOOL synchronized, int iCapacity, int iGrowthFactor) queue->synchronized = synchronized; - if (iCapacity > 0) - queue->capacity = iCapacity; + if (capacity > 0) + queue->capacity = capacity; - if (iGrowthFactor > 0) - queue->growthFactor = iGrowthFactor; + if (growthFactor > 0) + queue->growthFactor = growthFactor; queue->array = (void**) malloc(sizeof(void*) * queue->capacity); diff --git a/winpr/libwinpr/utils/collections/Stack.c b/winpr/libwinpr/utils/collections/Stack.c index 464a33570..ce6f0ad6a 100644 --- a/winpr/libwinpr/utils/collections/Stack.c +++ b/winpr/libwinpr/utils/collections/Stack.c @@ -38,7 +38,7 @@ int Stack_Count(wStack* stack) { - if (stack->bSynchronized) + if (stack->synchronized) { } @@ -52,7 +52,7 @@ int Stack_Count(wStack* stack) BOOL Stack_IsSynchronized(wStack* stack) { - return stack->bSynchronized; + return stack->synchronized; } /** @@ -65,7 +65,7 @@ BOOL Stack_IsSynchronized(wStack* stack) void Stack_Clear(wStack* stack) { - if (stack->bSynchronized) + if (stack->synchronized) { } @@ -77,7 +77,7 @@ void Stack_Clear(wStack* stack) BOOL Stack_Contains(wStack* stack, void* obj) { - if (stack->bSynchronized) + if (stack->synchronized) { } @@ -91,7 +91,7 @@ BOOL Stack_Contains(wStack* stack, void* obj) void Stack_Push(wStack* stack, void* obj) { - if (stack->bSynchronized) + if (stack->synchronized) { } @@ -103,7 +103,7 @@ void Stack_Push(wStack* stack, void* obj) void* Stack_Pop(wStack* stack) { - if (stack->bSynchronized) + if (stack->synchronized) { } @@ -117,7 +117,7 @@ void* Stack_Pop(wStack* stack) void* Stack_Peek(wStack* stack) { - if (stack->bSynchronized) + if (stack->synchronized) { } @@ -137,7 +137,7 @@ wStack* Stack_New(BOOL bSynchronized) if (stack) { - stack->bSynchronized = bSynchronized; + stack->synchronized = bSynchronized; } return stack;