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 35 extern "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 */ 676