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);
/* 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);
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;
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 */
/* 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);
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);
*
* \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
*
* \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
#define DEFINE_EVENT_BEGIN(_name) \
typedef struct _ ## _name ## EventArgs { \
- wEventArgs e;
+ wEventArgs e;
#define DEFINE_EVENT_END(_name) \
} _name ## EventArgs; \
#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 } },
-
-struct _wPubSub
-{
- CRITICAL_SECTION lock;
- BOOL synchronized;
-
- 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 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_OnEvent(wPubSub* pubSub, const char* EventName, void* context, wEventArgs* e);
-
-WINPR_API wPubSub* PubSub_New(BOOL synchronized);
-WINPR_API void PubSub_Free(wPubSub* pubSub);
-
-/* BipBuffer */
-
-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;
-
-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 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 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);
+ 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;
+
+ 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 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_OnEvent(wPubSub* pubSub, const char* EventName, void* context, wEventArgs* e);
+
+ WINPR_API wPubSub* PubSub_New(BOOL synchronized);
+ WINPR_API void PubSub_Free(wPubSub* pubSub);
+
+ /* BipBuffer */
+
+ 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;
+
+ 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 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 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);
#ifdef __cplusplus
}
#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
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;
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.
*/
void LinkedList_Clear(wLinkedList* list)
{
wLinkedListNode* node;
- wLinkedListNode* nextNode;
if (!list->head)
return;
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)
{
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)
{
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;
}
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);
}
/**
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);
}
/**
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;
}
}
}
+wObject* LinkedList_Object(wLinkedList* list)
+{
+ if (!list)
+ return NULL;
+
+ return &list->object;
+}