cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

collections.h (20892B)


      1/**
      2 * WinPR: Windows Portable Runtime
      3 * Collections
      4 *
      5 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
      6 *
      7 * Licensed under the Apache License, Version 2.0 (the "License");
      8 * you may not use this file except in compliance with the License.
      9 * You may obtain a copy of the License at
     10 *
     11 *     http://www.apache.org/licenses/LICENSE-2.0
     12 *
     13 * Unless required by applicable law or agreed to in writing, software
     14 * distributed under the License is distributed on an "AS IS" BASIS,
     15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16 * See the License for the specific language governing permissions and
     17 * limitations under the License.
     18 */
     19
     20#ifndef WINPR_COLLECTIONS_H
     21#define WINPR_COLLECTIONS_H
     22
     23#include <stdio.h>
     24#include <stdlib.h>
     25#include <string.h>
     26
     27#include <winpr/winpr.h>
     28#include <winpr/wtypes.h>
     29
     30#include <winpr/crt.h>
     31#include <winpr/synch.h>
     32#include <winpr/stream.h>
     33
     34#ifdef __cplusplus
     35extern "C"
     36{
     37#endif
     38
     39	typedef void* (*OBJECT_NEW_FN)(void* val);
     40	typedef void (*OBJECT_INIT_FN)(void* obj);
     41	typedef void (*OBJECT_UNINIT_FN)(void* obj);
     42	typedef void (*OBJECT_FREE_FN)(void* obj);
     43	typedef BOOL (*OBJECT_EQUALS_FN)(const void* objA, const void* objB);
     44
     45	struct _wObject
     46	{
     47		OBJECT_NEW_FN fnObjectNew;
     48		OBJECT_INIT_FN fnObjectInit;
     49		OBJECT_UNINIT_FN fnObjectUninit;
     50		OBJECT_FREE_FN fnObjectFree;
     51		OBJECT_EQUALS_FN fnObjectEquals;
     52	};
     53	typedef struct _wObject wObject;
     54
     55	/* System.Collections.Queue */
     56
     57	struct _wQueue
     58	{
     59		int capacity;
     60		int growthFactor;
     61		BOOL synchronized;
     62
     63		int head;
     64		int tail;
     65		int size;
     66		void** array;
     67		CRITICAL_SECTION lock;
     68		HANDLE event;
     69
     70		wObject object;
     71	};
     72	typedef struct _wQueue wQueue;
     73
     74	WINPR_API int Queue_Count(wQueue* queue);
     75
     76	WINPR_API void Queue_Lock(wQueue* queue);
     77	WINPR_API void Queue_Unlock(wQueue* queue);
     78
     79	WINPR_API HANDLE Queue_Event(wQueue* queue);
     80
     81#define Queue_Object(_queue) (&_queue->object)
     82
     83	WINPR_API void Queue_Clear(wQueue* queue);
     84
     85	WINPR_API BOOL Queue_Contains(wQueue* queue, void* obj);
     86
     87	WINPR_API BOOL Queue_Enqueue(wQueue* queue, void* obj);
     88	WINPR_API void* Queue_Dequeue(wQueue* queue);
     89
     90	WINPR_API void* Queue_Peek(wQueue* queue);
     91
     92	WINPR_API wQueue* Queue_New(BOOL synchronized, int capacity, int growthFactor);
     93	WINPR_API void Queue_Free(wQueue* queue);
     94
     95	/* System.Collections.Stack */
     96
     97	struct _wStack
     98	{
     99		int size;
    100		int capacity;
    101		void** array;
    102		CRITICAL_SECTION lock;
    103		BOOL synchronized;
    104		wObject object;
    105	};
    106	typedef struct _wStack wStack;
    107
    108	WINPR_API int Stack_Count(wStack* stack);
    109	WINPR_API BOOL Stack_IsSynchronized(wStack* stack);
    110
    111#define Stack_Object(_stack) (&_stack->object)
    112
    113	WINPR_API void Stack_Clear(wStack* stack);
    114	WINPR_API BOOL Stack_Contains(wStack* stack, void* obj);
    115
    116	WINPR_API void Stack_Push(wStack* stack, void* obj);
    117	WINPR_API void* Stack_Pop(wStack* stack);
    118
    119	WINPR_API void* Stack_Peek(wStack* stack);
    120
    121	WINPR_API wStack* Stack_New(BOOL synchronized);
    122	WINPR_API void Stack_Free(wStack* stack);
    123
    124	/* System.Collections.ArrayList */
    125
    126	struct _wArrayList
    127	{
    128		int capacity;
    129		int growthFactor;
    130		BOOL synchronized;
    131
    132		int size;
    133		void** array;
    134		CRITICAL_SECTION lock;
    135
    136		wObject object;
    137	};
    138	typedef struct _wArrayList wArrayList;
    139
    140	WINPR_API int ArrayList_Capacity(wArrayList* arrayList);
    141	WINPR_API int ArrayList_Count(wArrayList* arrayList);
    142	WINPR_API int ArrayList_Items(wArrayList* arrayList, ULONG_PTR** ppItems);
    143	WINPR_API BOOL ArrayList_IsFixedSized(wArrayList* arrayList);
    144	WINPR_API BOOL ArrayList_IsReadOnly(wArrayList* arrayList);
    145	WINPR_API BOOL ArrayList_IsSynchronized(wArrayList* arrayList);
    146
    147	WINPR_API void ArrayList_Lock(wArrayList* arrayList);
    148	WINPR_API void ArrayList_Unlock(wArrayList* arrayList);
    149
    150	WINPR_API void* ArrayList_GetItem(wArrayList* arrayList, int index);
    151	WINPR_API void ArrayList_SetItem(wArrayList* arrayList, int index, void* obj);
    152
    153#define ArrayList_Object(_arrayList) (&_arrayList->object)
    154
    155#define ArrayList_ForEach(_lst, _type, index, value)                                       \
    156	for (index = 0;                                                                        \
    157	     index < ArrayList_Count(_lst) && (value = (_type)ArrayList_GetItem(_lst, index)); \
    158	     index++)
    159
    160	WINPR_API void ArrayList_Clear(wArrayList* arrayList);
    161	WINPR_API BOOL ArrayList_Contains(wArrayList* arrayList, void* obj);
    162
    163	WINPR_API int ArrayList_Add(wArrayList* arrayList, void* obj);
    164	WINPR_API BOOL ArrayList_Insert(wArrayList* arrayList, int index, void* obj);
    165
    166	WINPR_API BOOL ArrayList_Remove(wArrayList* arrayList, void* obj);
    167	WINPR_API BOOL ArrayList_RemoveAt(wArrayList* arrayList, int index);
    168
    169	WINPR_API int ArrayList_IndexOf(wArrayList* arrayList, void* obj, int startIndex, int count);
    170	WINPR_API int ArrayList_LastIndexOf(wArrayList* arrayList, void* obj, int startIndex,
    171	                                    int count);
    172
    173	WINPR_API wArrayList* ArrayList_New(BOOL synchronized);
    174	WINPR_API void ArrayList_Free(wArrayList* arrayList);
    175
    176	/* System.Collections.DictionaryBase */
    177
    178	struct _wDictionary
    179	{
    180		BOOL synchronized;
    181		CRITICAL_SECTION lock;
    182	};
    183	typedef struct _wDictionary wDictionary;
    184
    185	/* System.Collections.Specialized.ListDictionary */
    186
    187	typedef struct _wListDictionaryItem wListDictionaryItem;
    188
    189	struct _wListDictionaryItem
    190	{
    191		void* key;
    192		void* value;
    193
    194		wListDictionaryItem* next;
    195	};
    196
    197	struct _wListDictionary
    198	{
    199		BOOL synchronized;
    200		CRITICAL_SECTION lock;
    201
    202		wListDictionaryItem* head;
    203		wObject objectKey;
    204		wObject objectValue;
    205	};
    206	typedef struct _wListDictionary wListDictionary;
    207
    208#define ListDictionary_KeyObject(_dictionary) (&_dictionary->objectKey)
    209#define ListDictionary_ValueObject(_dictionary) (&_dictionary->objectValue)
    210
    211	WINPR_API int ListDictionary_Count(wListDictionary* listDictionary);
    212
    213	WINPR_API void ListDictionary_Lock(wListDictionary* listDictionary);
    214	WINPR_API void ListDictionary_Unlock(wListDictionary* listDictionary);
    215
    216	WINPR_API BOOL ListDictionary_Add(wListDictionary* listDictionary, const void* key,
    217	                                  void* value);
    218	WINPR_API void* ListDictionary_Remove(wListDictionary* listDictionary, const void* key);
    219	WINPR_API void* ListDictionary_Remove_Head(wListDictionary* listDictionary);
    220	WINPR_API void ListDictionary_Clear(wListDictionary* listDictionary);
    221
    222	WINPR_API BOOL ListDictionary_Contains(wListDictionary* listDictionary, const void* key);
    223	WINPR_API int ListDictionary_GetKeys(wListDictionary* listDictionary, ULONG_PTR** ppKeys);
    224
    225	WINPR_API void* ListDictionary_GetItemValue(wListDictionary* listDictionary, const void* key);
    226	WINPR_API BOOL ListDictionary_SetItemValue(wListDictionary* listDictionary, const void* key,
    227	                                           void* value);
    228
    229	WINPR_API wListDictionary* ListDictionary_New(BOOL synchronized);
    230	WINPR_API void ListDictionary_Free(wListDictionary* listDictionary);
    231
    232	/* System.Collections.Generic.LinkedList<T> */
    233
    234	typedef struct _wLinkedList wLinkedList;
    235
    236	WINPR_API int LinkedList_Count(wLinkedList* list);
    237	WINPR_API void* LinkedList_First(wLinkedList* list);
    238	WINPR_API void* LinkedList_Last(wLinkedList* list);
    239
    240	WINPR_API BOOL LinkedList_Contains(wLinkedList* list, void* value);
    241	WINPR_API void LinkedList_Clear(wLinkedList* list);
    242
    243	WINPR_API BOOL LinkedList_AddFirst(wLinkedList* list, void* value);
    244	WINPR_API BOOL LinkedList_AddLast(wLinkedList* list, void* value);
    245
    246	WINPR_API BOOL LinkedList_Remove(wLinkedList* list, void* value);
    247	WINPR_API void LinkedList_RemoveFirst(wLinkedList* list);
    248	WINPR_API void LinkedList_RemoveLast(wLinkedList* list);
    249
    250	WINPR_API void LinkedList_Enumerator_Reset(wLinkedList* list);
    251	WINPR_API void* LinkedList_Enumerator_Current(wLinkedList* list);
    252	WINPR_API BOOL LinkedList_Enumerator_MoveNext(wLinkedList* list);
    253
    254	WINPR_API wLinkedList* LinkedList_New(void);
    255	WINPR_API void LinkedList_Free(wLinkedList* list);
    256
    257	WINPR_API wObject* LinkedList_Object(wLinkedList* list);
    258
    259	/* System.Collections.Generic.KeyValuePair<TKey,TValue> */
    260
    261	typedef struct _wKeyValuePair wKeyValuePair;
    262
    263	struct _wKeyValuePair
    264	{
    265		void* key;
    266		void* value;
    267
    268		wKeyValuePair* next;
    269	};
    270
    271	/* Reference Table */
    272
    273	struct _wReference
    274	{
    275		UINT32 Count;
    276		void* Pointer;
    277	};
    278	typedef struct _wReference wReference;
    279
    280	typedef int (*REFERENCE_FREE)(void* context, void* ptr);
    281
    282	struct _wReferenceTable
    283	{
    284		UINT32 size;
    285		CRITICAL_SECTION lock;
    286		void* context;
    287		BOOL synchronized;
    288		wReference* array;
    289		REFERENCE_FREE ReferenceFree;
    290	};
    291	typedef struct _wReferenceTable wReferenceTable;
    292
    293	WINPR_API UINT32 ReferenceTable_Add(wReferenceTable* referenceTable, void* ptr);
    294	WINPR_API UINT32 ReferenceTable_Release(wReferenceTable* referenceTable, void* ptr);
    295
    296	WINPR_API wReferenceTable* ReferenceTable_New(BOOL synchronized, void* context,
    297	                                              REFERENCE_FREE ReferenceFree);
    298	WINPR_API void ReferenceTable_Free(wReferenceTable* referenceTable);
    299
    300	/* Countdown Event */
    301
    302	struct _wCountdownEvent
    303	{
    304		DWORD count;
    305		CRITICAL_SECTION lock;
    306		HANDLE event;
    307		DWORD initialCount;
    308	};
    309	typedef struct _wCountdownEvent wCountdownEvent;
    310
    311	WINPR_API DWORD CountdownEvent_CurrentCount(wCountdownEvent* countdown);
    312	WINPR_API DWORD CountdownEvent_InitialCount(wCountdownEvent* countdown);
    313	WINPR_API BOOL CountdownEvent_IsSet(wCountdownEvent* countdown);
    314	WINPR_API HANDLE CountdownEvent_WaitHandle(wCountdownEvent* countdown);
    315
    316	WINPR_API void CountdownEvent_AddCount(wCountdownEvent* countdown, DWORD signalCount);
    317	WINPR_API BOOL CountdownEvent_Signal(wCountdownEvent* countdown, DWORD signalCount);
    318	WINPR_API void CountdownEvent_Reset(wCountdownEvent* countdown, DWORD count);
    319
    320	WINPR_API wCountdownEvent* CountdownEvent_New(DWORD initialCount);
    321	WINPR_API void CountdownEvent_Free(wCountdownEvent* countdown);
    322
    323	/* Hash Table */
    324
    325	typedef UINT32 (*HASH_TABLE_HASH_FN)(void* key);
    326	typedef BOOL (*HASH_TABLE_KEY_COMPARE_FN)(void* key1, void* key2);
    327	typedef BOOL (*HASH_TABLE_VALUE_COMPARE_FN)(void* value1, void* value2);
    328	typedef void* (*HASH_TABLE_KEY_CLONE_FN)(void* key);
    329	typedef void* (*HASH_TABLE_VALUE_CLONE_FN)(void* value);
    330	typedef void (*HASH_TABLE_KEY_FREE_FN)(void* key);
    331	typedef void (*HASH_TABLE_VALUE_FREE_FN)(void* value);
    332
    333	struct _wHashTable
    334	{
    335		BOOL synchronized;
    336		CRITICAL_SECTION lock;
    337
    338		int numOfBuckets;
    339		int numOfElements;
    340		float idealRatio;
    341		float lowerRehashThreshold;
    342		float upperRehashThreshold;
    343		wKeyValuePair** bucketArray;
    344
    345		HASH_TABLE_HASH_FN hash;
    346		HASH_TABLE_KEY_COMPARE_FN keyCompare;
    347		HASH_TABLE_VALUE_COMPARE_FN valueCompare;
    348		HASH_TABLE_KEY_CLONE_FN keyClone;
    349		HASH_TABLE_VALUE_CLONE_FN valueClone;
    350		HASH_TABLE_KEY_FREE_FN keyFree;
    351		HASH_TABLE_VALUE_FREE_FN valueFree;
    352	};
    353	typedef struct _wHashTable wHashTable;
    354
    355	WINPR_API int HashTable_Count(wHashTable* table);
    356	WINPR_API int HashTable_Add(wHashTable* table, void* key, void* value);
    357	WINPR_API BOOL HashTable_Remove(wHashTable* table, void* key);
    358	WINPR_API void HashTable_Clear(wHashTable* table);
    359	WINPR_API BOOL HashTable_Contains(wHashTable* table, void* key);
    360	WINPR_API BOOL HashTable_ContainsKey(wHashTable* table, void* key);
    361	WINPR_API BOOL HashTable_ContainsValue(wHashTable* table, void* value);
    362	WINPR_API void* HashTable_GetItemValue(wHashTable* table, void* key);
    363	WINPR_API BOOL HashTable_SetItemValue(wHashTable* table, void* key, void* value);
    364	WINPR_API int HashTable_GetKeys(wHashTable* table, ULONG_PTR** ppKeys);
    365
    366	WINPR_API UINT32 HashTable_PointerHash(void* pointer);
    367	WINPR_API BOOL HashTable_PointerCompare(void* pointer1, void* pointer2);
    368
    369	WINPR_API UINT32 HashTable_StringHash(void* key);
    370	WINPR_API BOOL HashTable_StringCompare(void* string1, void* string2);
    371	WINPR_API void* HashTable_StringClone(void* str);
    372	WINPR_API void HashTable_StringFree(void* str);
    373
    374	WINPR_API wHashTable* HashTable_New(BOOL synchronized);
    375	WINPR_API void HashTable_Free(wHashTable* table);
    376
    377	/* BufferPool */
    378
    379	struct _wBufferPoolItem
    380	{
    381		int size;
    382		void* buffer;
    383	};
    384	typedef struct _wBufferPoolItem wBufferPoolItem;
    385
    386	struct _wBufferPool
    387	{
    388		int fixedSize;
    389		DWORD alignment;
    390		BOOL synchronized;
    391		CRITICAL_SECTION lock;
    392
    393		int size;
    394		int capacity;
    395		void** array;
    396
    397		int aSize;
    398		int aCapacity;
    399		wBufferPoolItem* aArray;
    400
    401		int uSize;
    402		int uCapacity;
    403		wBufferPoolItem* uArray;
    404	};
    405	typedef struct _wBufferPool wBufferPool;
    406
    407	WINPR_API int BufferPool_GetPoolSize(wBufferPool* pool);
    408	WINPR_API int BufferPool_GetBufferSize(wBufferPool* pool, void* buffer);
    409
    410	WINPR_API void* BufferPool_Take(wBufferPool* pool, int bufferSize);
    411	WINPR_API BOOL BufferPool_Return(wBufferPool* pool, void* buffer);
    412	WINPR_API void BufferPool_Clear(wBufferPool* pool);
    413
    414	WINPR_API wBufferPool* BufferPool_New(BOOL synchronized, int fixedSize, DWORD alignment);
    415	WINPR_API void BufferPool_Free(wBufferPool* pool);
    416
    417	/* ObjectPool */
    418
    419	struct _wObjectPool
    420	{
    421		int size;
    422		int capacity;
    423		void** array;
    424		CRITICAL_SECTION lock;
    425		wObject object;
    426		BOOL synchronized;
    427	};
    428	typedef struct _wObjectPool wObjectPool;
    429
    430	WINPR_API void* ObjectPool_Take(wObjectPool* pool);
    431	WINPR_API void ObjectPool_Return(wObjectPool* pool, void* obj);
    432	WINPR_API void ObjectPool_Clear(wObjectPool* pool);
    433
    434#define ObjectPool_Object(_pool) (&_pool->object)
    435
    436	WINPR_API wObjectPool* ObjectPool_New(BOOL synchronized);
    437	WINPR_API void ObjectPool_Free(wObjectPool* pool);
    438
    439	/* Message Queue */
    440
    441	typedef struct _wMessage wMessage;
    442
    443	typedef void (*MESSAGE_FREE_FN)(wMessage* message);
    444
    445	struct _wMessage
    446	{
    447		UINT32 id;
    448		void* context;
    449		void* wParam;
    450		void* lParam;
    451		UINT64 time;
    452		MESSAGE_FREE_FN Free;
    453	};
    454
    455	struct _wMessageQueue
    456	{
    457		int head;
    458		int tail;
    459		int size;
    460		int capacity;
    461		wMessage* array;
    462		CRITICAL_SECTION lock;
    463		HANDLE event;
    464
    465		wObject object;
    466	};
    467	typedef struct _wMessageQueue wMessageQueue;
    468
    469#define WMQ_QUIT 0xFFFFFFFF
    470
    471	WINPR_API HANDLE MessageQueue_Event(wMessageQueue* queue);
    472	WINPR_API BOOL MessageQueue_Wait(wMessageQueue* queue);
    473	WINPR_API int MessageQueue_Size(wMessageQueue* queue);
    474
    475	WINPR_API BOOL MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message);
    476	WINPR_API BOOL MessageQueue_Post(wMessageQueue* queue, void* context, UINT32 type, void* wParam,
    477	                                 void* lParam);
    478	WINPR_API BOOL MessageQueue_PostQuit(wMessageQueue* queue, int nExitCode);
    479
    480	WINPR_API int MessageQueue_Get(wMessageQueue* queue, wMessage* message);
    481	WINPR_API int MessageQueue_Peek(wMessageQueue* queue, wMessage* message, BOOL remove);
    482
    483	/*! \brief Clears all elements in a message queue.
    484	 *
    485	 *  \note If dynamically allocated data is part of the messages,
    486	 *        a custom cleanup handler must be passed in the 'callback'
    487	 *        argument for MessageQueue_New.
    488	 *
    489	 *  \param queue The queue to clear.
    490	 *
    491	 *  \return 0 in case of success or a error code otherwise.
    492	 */
    493	WINPR_API int MessageQueue_Clear(wMessageQueue* queue);
    494
    495	/*! \brief Creates a new message queue.
    496	 * 				 If 'callback' is null, no custom cleanup will be done
    497	 * 				 on message queue deallocation.
    498	 * 				 If the 'callback' argument contains valid uninit or
    499	 * 				 free functions those will be called by
    500	 * 				 'MessageQueue_Clear'.
    501	 *
    502	 * \param callback a pointer to custom initialization / cleanup functions.
    503	 * 								 Can be NULL if not used.
    504	 *
    505	 * \return A pointer to a newly allocated MessageQueue or NULL.
    506	 */
    507	WINPR_API wMessageQueue* MessageQueue_New(const wObject* callback);
    508
    509	/*! \brief Frees resources allocated by a message queue.
    510	 * 				 This function will only free resources allocated
    511	 *				 internally.
    512	 *
    513	 * \note Empty the queue before calling this function with
    514	 * 			 'MessageQueue_Clear', 'MessageQueue_Get' or
    515	 * 			 'MessageQueue_Peek' to free all resources allocated
    516	 * 			 by the message contained.
    517	 *
    518	 * \param queue A pointer to the queue to be freed.
    519	 */
    520	WINPR_API void MessageQueue_Free(wMessageQueue* queue);
    521
    522	/* Message Pipe */
    523
    524	struct _wMessagePipe
    525	{
    526		wMessageQueue* In;
    527		wMessageQueue* Out;
    528	};
    529	typedef struct _wMessagePipe wMessagePipe;
    530
    531	WINPR_API void MessagePipe_PostQuit(wMessagePipe* pipe, int nExitCode);
    532
    533	WINPR_API wMessagePipe* MessagePipe_New(void);
    534	WINPR_API void MessagePipe_Free(wMessagePipe* pipe);
    535
    536	/* Publisher/Subscriber Pattern */
    537
    538	struct _wEventArgs
    539	{
    540		DWORD Size;
    541		const char* Sender;
    542	};
    543	typedef struct _wEventArgs wEventArgs;
    544
    545	typedef void (*pEventHandler)(void* context, wEventArgs* e);
    546
    547#define MAX_EVENT_HANDLERS 32
    548
    549	struct _wEventType
    550	{
    551		const char* EventName;
    552		wEventArgs EventArgs;
    553		int EventHandlerCount;
    554		pEventHandler EventHandlers[MAX_EVENT_HANDLERS];
    555	};
    556	typedef struct _wEventType wEventType;
    557
    558#define EventArgsInit(_event_args, _sender)                  \
    559	memset(_event_args, 0, sizeof(*_event_args));            \
    560	((wEventArgs*)_event_args)->Size = sizeof(*_event_args); \
    561	((wEventArgs*)_event_args)->Sender = _sender
    562
    563#define DEFINE_EVENT_HANDLER(_name) \
    564	typedef void (*p##_name##EventHandler)(void* context, _name##EventArgs* e)
    565
    566#define DEFINE_EVENT_RAISE(_name)                                                           \
    567	static INLINE int PubSub_On##_name(wPubSub* pubSub, void* context, _name##EventArgs* e) \
    568	{                                                                                       \
    569		return PubSub_OnEvent(pubSub, #_name, context, (wEventArgs*)e);                     \
    570	}
    571
    572#define DEFINE_EVENT_SUBSCRIBE(_name)                                              \
    573	static INLINE int PubSub_Subscribe##_name(wPubSub* pubSub,                     \
    574	                                          p##_name##EventHandler EventHandler) \
    575	{                                                                              \
    576		return PubSub_Subscribe(pubSub, #_name, (pEventHandler)EventHandler);      \
    577	}
    578
    579#define DEFINE_EVENT_UNSUBSCRIBE(_name)                                              \
    580	static INLINE int PubSub_Unsubscribe##_name(wPubSub* pubSub,                     \
    581	                                            p##_name##EventHandler EventHandler) \
    582	{                                                                                \
    583		return PubSub_Unsubscribe(pubSub, #_name, (pEventHandler)EventHandler);      \
    584	}
    585
    586#define DEFINE_EVENT_BEGIN(_name)      \
    587	typedef struct _##_name##EventArgs \
    588	{                                  \
    589		wEventArgs e;
    590
    591#define DEFINE_EVENT_END(_name)   \
    592	}                             \
    593	_name##EventArgs;             \
    594	DEFINE_EVENT_HANDLER(_name);  \
    595	DEFINE_EVENT_RAISE(_name)     \
    596	DEFINE_EVENT_SUBSCRIBE(_name) \
    597	DEFINE_EVENT_UNSUBSCRIBE(_name)
    598
    599#define DEFINE_EVENT_ENTRY(_name) { #_name, { sizeof(_name##EventArgs), NULL }, 0, { NULL } },
    600
    601	struct _wPubSub
    602	{
    603		CRITICAL_SECTION lock;
    604		BOOL synchronized;
    605
    606		int size;
    607		int count;
    608		wEventType* events;
    609	};
    610	typedef struct _wPubSub wPubSub;
    611
    612	WINPR_API void PubSub_Lock(wPubSub* pubSub);
    613	WINPR_API void PubSub_Unlock(wPubSub* pubSub);
    614
    615	WINPR_API wEventType* PubSub_GetEventTypes(wPubSub* pubSub, int* count);
    616	WINPR_API void PubSub_AddEventTypes(wPubSub* pubSub, wEventType* events, int count);
    617	WINPR_API wEventType* PubSub_FindEventType(wPubSub* pubSub, const char* EventName);
    618
    619	WINPR_API int PubSub_Subscribe(wPubSub* pubSub, const char* EventName,
    620	                               pEventHandler EventHandler);
    621	WINPR_API int PubSub_Unsubscribe(wPubSub* pubSub, const char* EventName,
    622	                                 pEventHandler EventHandler);
    623
    624	WINPR_API int PubSub_OnEvent(wPubSub* pubSub, const char* EventName, void* context,
    625	                             wEventArgs* e);
    626
    627	WINPR_API wPubSub* PubSub_New(BOOL synchronized);
    628	WINPR_API void PubSub_Free(wPubSub* pubSub);
    629
    630	/* BipBuffer */
    631
    632	struct _wBipBlock
    633	{
    634		size_t index;
    635		size_t size;
    636	};
    637	typedef struct _wBipBlock wBipBlock;
    638
    639	struct _wBipBuffer
    640	{
    641		size_t size;
    642		BYTE* buffer;
    643		size_t pageSize;
    644		wBipBlock blockA;
    645		wBipBlock blockB;
    646		wBipBlock readR;
    647		wBipBlock writeR;
    648	};
    649	typedef struct _wBipBuffer wBipBuffer;
    650
    651	WINPR_API BOOL BipBuffer_Grow(wBipBuffer* bb, size_t size);
    652	WINPR_API void BipBuffer_Clear(wBipBuffer* bb);
    653
    654	WINPR_API size_t BipBuffer_UsedSize(wBipBuffer* bb);
    655	WINPR_API size_t BipBuffer_BufferSize(wBipBuffer* bb);
    656
    657	WINPR_API BYTE* BipBuffer_WriteReserve(wBipBuffer* bb, size_t size);
    658	WINPR_API BYTE* BipBuffer_WriteTryReserve(wBipBuffer* bb, size_t size, size_t* reserved);
    659	WINPR_API void BipBuffer_WriteCommit(wBipBuffer* bb, size_t size);
    660
    661	WINPR_API BYTE* BipBuffer_ReadReserve(wBipBuffer* bb, size_t size);
    662	WINPR_API BYTE* BipBuffer_ReadTryReserve(wBipBuffer* bb, size_t size, size_t* reserved);
    663	WINPR_API void BipBuffer_ReadCommit(wBipBuffer* bb, size_t size);
    664
    665	WINPR_API SSIZE_T BipBuffer_Read(wBipBuffer* bb, BYTE* data, size_t size);
    666	WINPR_API SSIZE_T BipBuffer_Write(wBipBuffer* bb, const BYTE* data, size_t size);
    667
    668	WINPR_API wBipBuffer* BipBuffer_New(size_t size);
    669	WINPR_API void BipBuffer_Free(wBipBuffer* bb);
    670
    671#ifdef __cplusplus
    672}
    673#endif
    674
    675#endif /* WINPR_COLLECTIONS_H */