Implemented linked list compare and value copy functions.

This commit is contained in:
Armin Novak 2018-08-22 12:33:34 +02:00
parent 560552ce19
commit b77dc13b5f
2 changed files with 164 additions and 153 deletions

View File

@ -35,7 +35,9 @@
extern "C" {
#endif
typedef void* (*OBJECT_NEW_FN)(void);
/* We don't know if the new function will require an argument.
* Leave the braces empty, C defines that as variable arguments. */
typedef void* (*OBJECT_NEW_FN)();
typedef void (*OBJECT_INIT_FN)(void* obj);
typedef void (*OBJECT_UNINIT_FN)(void* obj);
typedef void (*OBJECT_FREE_FN)(void* obj);
@ -222,23 +224,6 @@ WINPR_API void ListDictionary_Free(wListDictionary* listDictionary);
/* System.Collections.Generic.LinkedList<T> */
typedef struct _wLinkedListItem wLinkedListNode;
struct _wLinkedListItem
{
void* value;
wLinkedListNode* prev;
wLinkedListNode* next;
};
struct _wLinkedList
{
int count;
int initial;
wLinkedListNode* head;
wLinkedListNode* tail;
wLinkedListNode* current;
};
typedef struct _wLinkedList wLinkedList;
WINPR_API int LinkedList_Count(wLinkedList* list);
@ -262,6 +247,8 @@ WINPR_API BOOL LinkedList_Enumerator_MoveNext(wLinkedList* list);
WINPR_API wLinkedList* LinkedList_New(void);
WINPR_API void LinkedList_Free(wLinkedList* list);
WINPR_API wObject* LinkedList_Object(wLinkedList* list);
/* System.Collections.Generic.KeyValuePair<TKey,TValue> */
typedef struct _wKeyValuePair wKeyValuePair;
@ -299,7 +286,8 @@ typedef struct _wReferenceTable wReferenceTable;
WINPR_API UINT32 ReferenceTable_Add(wReferenceTable* referenceTable, void* ptr);
WINPR_API UINT32 ReferenceTable_Release(wReferenceTable* referenceTable, void* ptr);
WINPR_API wReferenceTable* ReferenceTable_New(BOOL synchronized, void* context, REFERENCE_FREE ReferenceFree);
WINPR_API wReferenceTable* ReferenceTable_New(BOOL synchronized, void* context,
REFERENCE_FREE ReferenceFree);
WINPR_API void ReferenceTable_Free(wReferenceTable* referenceTable);
/* Countdown Event */
@ -327,7 +315,7 @@ WINPR_API void CountdownEvent_Free(wCountdownEvent* countdown);
/* Hash Table */
typedef UINT32 (*HASH_TABLE_HASH_FN)(void* key);
typedef UINT32(*HASH_TABLE_HASH_FN)(void* key);
typedef BOOL (*HASH_TABLE_KEY_COMPARE_FN)(void* key1, void* key2);
typedef BOOL (*HASH_TABLE_VALUE_COMPARE_FN)(void* value1, void* value2);
typedef void* (*HASH_TABLE_KEY_CLONE_FN)(void* key);
@ -478,7 +466,8 @@ WINPR_API BOOL MessageQueue_Wait(wMessageQueue* queue);
WINPR_API int MessageQueue_Size(wMessageQueue* queue);
WINPR_API BOOL MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message);
WINPR_API BOOL MessageQueue_Post(wMessageQueue* queue, void* context, UINT32 type, void* wParam, void* lParam);
WINPR_API BOOL MessageQueue_Post(wMessageQueue* queue, void* context, UINT32 type, void* wParam,
void* lParam);
WINPR_API BOOL MessageQueue_PostQuit(wMessageQueue* queue, int nExitCode);
WINPR_API int MessageQueue_Get(wMessageQueue* queue, wMessage* message);
@ -494,7 +483,7 @@ WINPR_API int MessageQueue_Peek(wMessageQueue* queue, wMessage* message, BOOL re
*
* \return 0 in case of success or a error code otherwise.
*/
WINPR_API int MessageQueue_Clear(wMessageQueue *queue);
WINPR_API int MessageQueue_Clear(wMessageQueue* queue);
/*! \brief Creates a new message queue.
* If 'callback' is null, no custom cleanup will be done
@ -508,7 +497,7 @@ WINPR_API int MessageQueue_Clear(wMessageQueue *queue);
*
* \return A pointer to a newly allocated MessageQueue or NULL.
*/
WINPR_API wMessageQueue* MessageQueue_New(const wObject *callback);
WINPR_API wMessageQueue* MessageQueue_New(const wObject* callback);
/*! \brief Frees resources allocated by a message queue.
* This function will only free resources allocated
@ -581,7 +570,7 @@ typedef struct _wEventType wEventType;
#define DEFINE_EVENT_BEGIN(_name) \
typedef struct _ ## _name ## EventArgs { \
wEventArgs e;
wEventArgs e;
#define DEFINE_EVENT_END(_name) \
} _name ## EventArgs; \
@ -592,77 +581,78 @@ typedef struct _wEventType wEventType;
#define DEFINE_EVENT_ENTRY(_name) \
{ #_name, { sizeof( _name ## EventArgs) }, 0, { \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } },
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } },
struct _wPubSub
{
CRITICAL_SECTION lock;
BOOL synchronized;
struct _wPubSub
{
CRITICAL_SECTION lock;
BOOL synchronized;
int size;
int count;
wEventType* events;
};
typedef struct _wPubSub wPubSub;
int size;
int count;
wEventType* events;
};
typedef struct _wPubSub wPubSub;
WINPR_API void PubSub_Lock(wPubSub* pubSub);
WINPR_API void PubSub_Unlock(wPubSub* pubSub);
WINPR_API void PubSub_Lock(wPubSub* pubSub);
WINPR_API void PubSub_Unlock(wPubSub* pubSub);
WINPR_API wEventType* PubSub_GetEventTypes(wPubSub* pubSub, int* count);
WINPR_API void PubSub_AddEventTypes(wPubSub* pubSub, wEventType* events, int count);
WINPR_API wEventType* PubSub_FindEventType(wPubSub* pubSub, const char* EventName);
WINPR_API wEventType* PubSub_GetEventTypes(wPubSub* pubSub, int* count);
WINPR_API void PubSub_AddEventTypes(wPubSub* pubSub, wEventType* events, int count);
WINPR_API wEventType* PubSub_FindEventType(wPubSub* pubSub, const char* EventName);
WINPR_API int PubSub_Subscribe(wPubSub* pubSub, const char* EventName, pEventHandler EventHandler);
WINPR_API int PubSub_Unsubscribe(wPubSub* pubSub, const char* EventName, pEventHandler EventHandler);
WINPR_API int PubSub_Subscribe(wPubSub* pubSub, const char* EventName, pEventHandler EventHandler);
WINPR_API int PubSub_Unsubscribe(wPubSub* pubSub, const char* EventName,
pEventHandler EventHandler);
WINPR_API int PubSub_OnEvent(wPubSub* pubSub, const char* EventName, void* context, wEventArgs* e);
WINPR_API int PubSub_OnEvent(wPubSub* pubSub, const char* EventName, void* context, wEventArgs* e);
WINPR_API wPubSub* PubSub_New(BOOL synchronized);
WINPR_API void PubSub_Free(wPubSub* pubSub);
WINPR_API wPubSub* PubSub_New(BOOL synchronized);
WINPR_API void PubSub_Free(wPubSub* pubSub);
/* BipBuffer */
/* BipBuffer */
struct _wBipBlock
{
size_t index;
size_t size;
};
typedef struct _wBipBlock wBipBlock;
struct _wBipBlock
{
size_t index;
size_t size;
};
typedef struct _wBipBlock wBipBlock;
struct _wBipBuffer
{
size_t size;
BYTE* buffer;
size_t pageSize;
wBipBlock blockA;
wBipBlock blockB;
wBipBlock readR;
wBipBlock writeR;
};
typedef struct _wBipBuffer wBipBuffer;
struct _wBipBuffer
{
size_t size;
BYTE* buffer;
size_t pageSize;
wBipBlock blockA;
wBipBlock blockB;
wBipBlock readR;
wBipBlock writeR;
};
typedef struct _wBipBuffer wBipBuffer;
WINPR_API BOOL BipBuffer_Grow(wBipBuffer* bb, size_t size);
WINPR_API void BipBuffer_Clear(wBipBuffer* bb);
WINPR_API BOOL BipBuffer_Grow(wBipBuffer* bb, size_t size);
WINPR_API void BipBuffer_Clear(wBipBuffer* bb);
WINPR_API size_t BipBuffer_UsedSize(wBipBuffer* bb);
WINPR_API size_t BipBuffer_BufferSize(wBipBuffer* bb);
WINPR_API size_t BipBuffer_UsedSize(wBipBuffer* bb);
WINPR_API size_t BipBuffer_BufferSize(wBipBuffer* bb);
WINPR_API BYTE* BipBuffer_WriteReserve(wBipBuffer* bb, size_t size);
WINPR_API BYTE* BipBuffer_WriteTryReserve(wBipBuffer* bb, size_t size, size_t* reserved);
WINPR_API void BipBuffer_WriteCommit(wBipBuffer* bb, size_t size);
WINPR_API BYTE* BipBuffer_WriteReserve(wBipBuffer* bb, size_t size);
WINPR_API BYTE* BipBuffer_WriteTryReserve(wBipBuffer* bb, size_t size, size_t* reserved);
WINPR_API void BipBuffer_WriteCommit(wBipBuffer* bb, size_t size);
WINPR_API BYTE* BipBuffer_ReadReserve(wBipBuffer* bb, size_t size);
WINPR_API BYTE* BipBuffer_ReadTryReserve(wBipBuffer* bb, size_t size, size_t* reserved);
WINPR_API void BipBuffer_ReadCommit(wBipBuffer* bb, size_t size);
WINPR_API BYTE* BipBuffer_ReadReserve(wBipBuffer* bb, size_t size);
WINPR_API BYTE* BipBuffer_ReadTryReserve(wBipBuffer* bb, size_t size, size_t* reserved);
WINPR_API void BipBuffer_ReadCommit(wBipBuffer* bb, size_t size);
WINPR_API int BipBuffer_Read(wBipBuffer* bb, BYTE* data, size_t size);
WINPR_API int BipBuffer_Write(wBipBuffer* bb, BYTE* data, size_t size);
WINPR_API int BipBuffer_Read(wBipBuffer* bb, BYTE* data, size_t size);
WINPR_API int BipBuffer_Write(wBipBuffer* bb, BYTE* data, size_t size);
WINPR_API wBipBuffer* BipBuffer_New(size_t size);
WINPR_API void BipBuffer_Free(wBipBuffer* bb);
WINPR_API wBipBuffer* BipBuffer_New(size_t size);
WINPR_API void BipBuffer_Free(wBipBuffer* bb);
#ifdef __cplusplus
}

View File

@ -23,6 +23,25 @@
#include <winpr/collections.h>
typedef struct _wLinkedListItem wLinkedListNode;
struct _wLinkedListItem
{
void* value;
wLinkedListNode* prev;
wLinkedListNode* next;
};
struct _wLinkedList
{
int count;
int initial;
wLinkedListNode* head;
wLinkedListNode* tail;
wLinkedListNode* current;
wObject object;
};
/**
* C equivalent of the C# LinkedList<T> Class:
* http://msdn.microsoft.com/en-us/library/he2s3bh7.aspx
@ -78,15 +97,17 @@ void* LinkedList_Last(wLinkedList* list)
BOOL LinkedList_Contains(wLinkedList* list, void* value)
{
wLinkedListNode* item;
OBJECT_EQUALS_FN keyEquals;
if (!list->head)
return FALSE;
item = list->head;
keyEquals = list->object.fnObjectEquals;
while (item)
{
if (item->value == value)
if (keyEquals(item->value, value))
break;
item = item->next;
@ -95,6 +116,34 @@ BOOL LinkedList_Contains(wLinkedList* list, void* value)
return (item) ? TRUE : FALSE;
}
static wLinkedListNode* LinkedList_FreeNode(wLinkedList* list, wLinkedListNode* node)
{
wLinkedListNode* next = node->next;
wLinkedListNode* prev = node->prev;
if (prev)
prev->next = next;
if (next)
next->prev = prev;
if (node == list->head)
list->head = node->next;
if (node == list->tail)
list->tail = node->prev;
if (list->object.fnObjectUninit)
list->object.fnObjectUninit(node);
if (list->object.fnObjectFree)
list->object.fnObjectFree(node);
free(node);
list->count--;
return next;
}
/**
* Removes all entries from the LinkedList.
*/
@ -102,7 +151,6 @@ BOOL LinkedList_Contains(wLinkedList* list, void* value)
void LinkedList_Clear(wLinkedList* list)
{
wLinkedListNode* node;
wLinkedListNode* nextNode;
if (!list->head)
return;
@ -110,29 +158,39 @@ void LinkedList_Clear(wLinkedList* list)
node = list->head;
while (node)
{
nextNode = node->next;
free(node);
node = nextNode;
}
node = LinkedList_FreeNode(list, node);
list->head = list->tail = NULL;
list->count = 0;
}
static wLinkedListNode* LinkedList_Create(wLinkedList* list, void* value)
{
wLinkedListNode* node = (wLinkedListNode*) calloc(1, sizeof(wLinkedListNode));
if (!node)
return NULL;
if (list->object.fnObjectNew)
node->value = list->object.fnObjectNew(value);
else
node->value = value;
if (list->object.fnObjectInit)
list->object.fnObjectInit(node);
return node;
}
/**
* Adds a new node containing the specified value at the start of the LinkedList.
*/
BOOL LinkedList_AddFirst(wLinkedList* list, void* value)
{
wLinkedListNode* node;
wLinkedListNode* node = LinkedList_Create(list, value);
node = (wLinkedListNode*) malloc(sizeof(wLinkedListNode));
if (!node)
return FALSE;
node->prev = node->next = NULL;
node->value = value;
if (!list->head)
{
@ -155,13 +213,10 @@ BOOL LinkedList_AddFirst(wLinkedList* list, void* value)
BOOL LinkedList_AddLast(wLinkedList* list, void* value)
{
wLinkedListNode* node;
wLinkedListNode* node = LinkedList_Create(list, value);
node = (wLinkedListNode*) malloc(sizeof(wLinkedListNode));
if (!node)
return FALSE;
node->prev = node->next = NULL;
node->value = value;
if (!list->tail)
{
@ -185,33 +240,21 @@ BOOL LinkedList_AddLast(wLinkedList* list, void* value)
BOOL LinkedList_Remove(wLinkedList* list, void* value)
{
wLinkedListNode* node;
OBJECT_EQUALS_FN keyEquals;
keyEquals = list->object.fnObjectEquals;
node = list->head;
while (node)
{
if (node->value == value)
if (keyEquals(node->value, value))
{
if (node->prev)
node->prev->next = node->next;
if (node->next)
node->next->prev = node->prev;
if (node == list->head)
list->head = node->next;
if (node == list->tail)
list->tail = node->prev;
free(node);
list->count--;
LinkedList_FreeNode(list, node);
return TRUE;
}
node = node->next;
}
return FALSE;
}
@ -221,27 +264,8 @@ BOOL LinkedList_Remove(wLinkedList* list, void* value)
void LinkedList_RemoveFirst(wLinkedList* list)
{
wLinkedListNode* node;
if (list->head)
{
node = list->head;
list->head = list->head->next;
if (!list->head)
{
list->tail = NULL;
}
else
{
list->head->prev = NULL;
}
free(node);
list->count--;
}
LinkedList_FreeNode(list, list->head);
}
/**
@ -250,27 +274,8 @@ void LinkedList_RemoveFirst(wLinkedList* list)
void LinkedList_RemoveLast(wLinkedList* list)
{
wLinkedListNode* node;
if (list->tail)
{
node = list->tail;
list->tail = list->tail->prev;
if (!list->tail)
{
list->head = NULL;
}
else
{
list->tail->next = NULL;
}
free(node);
list->count--;
}
LinkedList_FreeNode(list, list->tail);
}
/**
@ -315,16 +320,25 @@ BOOL LinkedList_Enumerator_MoveNext(wLinkedList* list)
return TRUE;
}
static BOOL default_equal_function(void* objA, void* objB)
{
return objA == objB;
}
/**
* Construction, Destruction
*/
wLinkedList* LinkedList_New()
wLinkedList* LinkedList_New(void)
{
wLinkedList* list = NULL;
list = (wLinkedList*) calloc(1, sizeof(wLinkedList));
if (list)
{
list->object.fnObjectEquals = default_equal_function;
}
return list;
}
@ -337,3 +351,10 @@ void LinkedList_Free(wLinkedList* list)
}
}
wObject* LinkedList_Object(wLinkedList* list)
{
if (!list)
return NULL;
return &list->object;
}