20 #include <winpr/config.h>
21 #include <winpr/assert.h>
22 #include <winpr/crt.h>
24 #include <winpr/collections.h>
26 typedef struct s_wListDictionaryItem wListDictionaryItem;
28 struct s_wListDictionaryItem
33 wListDictionaryItem* next;
36 struct s_wListDictionary
41 wListDictionaryItem* head;
53 WINPR_API
wObject* ListDictionary_KeyObject(wListDictionary* _dictionary)
55 WINPR_ASSERT(_dictionary);
56 return &_dictionary->objectKey;
59 WINPR_API
wObject* ListDictionary_ValueObject(wListDictionary* _dictionary)
61 WINPR_ASSERT(_dictionary);
62 return &_dictionary->objectValue;
73 size_t ListDictionary_Count(wListDictionary* listDictionary)
77 WINPR_ASSERT(listDictionary);
79 if (listDictionary->synchronized)
80 EnterCriticalSection(&listDictionary->lock);
82 if (listDictionary->head)
84 wListDictionaryItem* item = listDictionary->head;
93 if (listDictionary->synchronized)
94 LeaveCriticalSection(&listDictionary->lock);
103 void ListDictionary_Lock(wListDictionary* listDictionary)
105 WINPR_ASSERT(listDictionary);
107 EnterCriticalSection(&listDictionary->lock);
114 void ListDictionary_Unlock(wListDictionary* listDictionary)
116 WINPR_ASSERT(listDictionary);
118 LeaveCriticalSection(&listDictionary->lock);
129 size_t ListDictionary_GetKeys(wListDictionary* listDictionary, ULONG_PTR** ppKeys)
131 ULONG_PTR* pKeys = NULL;
133 WINPR_ASSERT(listDictionary);
137 if (listDictionary->synchronized)
138 EnterCriticalSection(&listDictionary->lock);
142 if (listDictionary->head)
144 wListDictionaryItem* item = listDictionary->head;
155 pKeys = (ULONG_PTR*)calloc(count,
sizeof(ULONG_PTR));
159 if (listDictionary->synchronized)
160 LeaveCriticalSection(&listDictionary->lock);
168 if (listDictionary->head)
170 wListDictionaryItem* item = listDictionary->head;
174 pKeys[index++] = (ULONG_PTR)item->key;
181 if (listDictionary->synchronized)
182 LeaveCriticalSection(&listDictionary->lock);
187 static void item_free(wListDictionary* listDictionary, wListDictionaryItem* item)
189 WINPR_ASSERT(listDictionary);
193 if (listDictionary->objectKey.fnObjectFree)
194 listDictionary->objectKey.fnObjectFree(item->key);
195 if (listDictionary->objectValue.fnObjectFree)
196 listDictionary->objectValue.fnObjectFree(item->value);
201 static void item_set(wListDictionary* listDictionary, wListDictionaryItem* item,
const void* value)
203 WINPR_ASSERT(listDictionary);
206 if (listDictionary->objectValue.fnObjectFree)
207 listDictionary->objectValue.fnObjectFree(item->value);
209 if (listDictionary->objectValue.fnObjectNew)
210 item->value = listDictionary->objectValue.fnObjectNew(value);
212 item->value = (
void*)(uintptr_t)value;
215 static wListDictionaryItem* new_item(wListDictionary* listDictionary,
const void* key,
218 wListDictionaryItem* item = (wListDictionaryItem*)calloc(1,
sizeof(wListDictionaryItem));
222 if (listDictionary->objectKey.fnObjectNew)
223 item->key = listDictionary->objectKey.fnObjectNew(key);
225 item->key = (
void*)(uintptr_t)key;
229 item_set(listDictionary, item, value);
230 if (value && !item->value)
236 item_free(listDictionary, item);
244 BOOL ListDictionary_Add(wListDictionary* listDictionary,
const void* key,
const void* value)
248 WINPR_ASSERT(listDictionary);
250 if (listDictionary->synchronized)
251 EnterCriticalSection(&listDictionary->lock);
253 wListDictionaryItem* item = new_item(listDictionary, key, value);
258 if (!listDictionary->head)
260 listDictionary->head = item;
264 wListDictionaryItem* lastItem = listDictionary->head;
266 while (lastItem->next)
267 lastItem = lastItem->next;
269 lastItem->next = item;
275 if (listDictionary->synchronized)
276 LeaveCriticalSection(&listDictionary->lock);
285 void ListDictionary_Clear(wListDictionary* listDictionary)
287 wListDictionaryItem* item = NULL;
288 wListDictionaryItem* nextItem = NULL;
290 WINPR_ASSERT(listDictionary);
292 if (listDictionary->synchronized)
293 EnterCriticalSection(&listDictionary->lock);
295 if (listDictionary->head)
297 item = listDictionary->head;
301 nextItem = item->next;
303 item_free(listDictionary, item);
307 listDictionary->head = NULL;
310 if (listDictionary->synchronized)
311 LeaveCriticalSection(&listDictionary->lock);
318 BOOL ListDictionary_Contains(wListDictionary* listDictionary,
const void* key)
320 wListDictionaryItem* item = NULL;
321 OBJECT_EQUALS_FN keyEquals = NULL;
323 WINPR_ASSERT(listDictionary);
325 if (listDictionary->synchronized)
326 EnterCriticalSection(&(listDictionary->lock));
328 keyEquals = listDictionary->objectKey.fnObjectEquals;
329 item = listDictionary->head;
333 if (keyEquals(item->key, key))
339 if (listDictionary->synchronized)
340 LeaveCriticalSection(&(listDictionary->lock));
342 return (item) ? TRUE : FALSE;
349 static void* ListDictionary_RemoveOrTake(wListDictionary* listDictionary,
const void* key,
353 wListDictionaryItem* item = NULL;
354 wListDictionaryItem* prevItem = NULL;
355 OBJECT_EQUALS_FN keyEquals = NULL;
357 WINPR_ASSERT(listDictionary);
359 if (listDictionary->synchronized)
360 EnterCriticalSection(&listDictionary->lock);
362 keyEquals = listDictionary->objectKey.fnObjectEquals;
363 item = listDictionary->head;
368 if (keyEquals(item->key, key))
371 listDictionary->head = item->next;
373 prevItem->next = item->next;
380 item_free(listDictionary, item);
388 if (listDictionary->synchronized)
389 LeaveCriticalSection(&listDictionary->lock);
394 void ListDictionary_Remove(wListDictionary* listDictionary,
const void* key)
396 ListDictionary_RemoveOrTake(listDictionary, key, FALSE);
399 void* ListDictionary_Take(wListDictionary* listDictionary,
const void* key)
401 return ListDictionary_RemoveOrTake(listDictionary, key, TRUE);
408 static void* ListDictionary_Remove_Or_Take_Head(wListDictionary* listDictionary, BOOL take)
410 wListDictionaryItem* item = NULL;
413 WINPR_ASSERT(listDictionary);
415 if (listDictionary->synchronized)
416 EnterCriticalSection(&listDictionary->lock);
418 if (listDictionary->head)
420 item = listDictionary->head;
421 listDictionary->head = listDictionary->head->next;
427 item_free(listDictionary, item);
430 if (listDictionary->synchronized)
431 LeaveCriticalSection(&listDictionary->lock);
436 void ListDictionary_Remove_Head(wListDictionary* listDictionary)
438 ListDictionary_Remove_Or_Take_Head(listDictionary, FALSE);
441 void* ListDictionary_Take_Head(wListDictionary* listDictionary)
443 return ListDictionary_Remove_Or_Take_Head(listDictionary, TRUE);
450 void* ListDictionary_GetItemValue(wListDictionary* listDictionary,
const void* key)
453 wListDictionaryItem* item = NULL;
454 OBJECT_EQUALS_FN keyEquals = NULL;
456 WINPR_ASSERT(listDictionary);
458 if (listDictionary->synchronized)
459 EnterCriticalSection(&listDictionary->lock);
461 keyEquals = listDictionary->objectKey.fnObjectEquals;
463 if (listDictionary->head)
465 item = listDictionary->head;
469 if (keyEquals(item->key, key))
476 value = (item) ? item->value : NULL;
478 if (listDictionary->synchronized)
479 LeaveCriticalSection(&listDictionary->lock);
488 BOOL ListDictionary_SetItemValue(wListDictionary* listDictionary,
const void* key,
492 wListDictionaryItem* item = NULL;
493 OBJECT_EQUALS_FN keyEquals = NULL;
495 WINPR_ASSERT(listDictionary);
497 if (listDictionary->synchronized)
498 EnterCriticalSection(&listDictionary->lock);
500 keyEquals = listDictionary->objectKey.fnObjectEquals;
502 if (listDictionary->head)
504 item = listDictionary->head;
508 if (keyEquals(item->key, key))
515 item_set(listDictionary, item, value);
517 status = (item) ? TRUE : FALSE;
520 if (listDictionary->synchronized)
521 LeaveCriticalSection(&listDictionary->lock);
526 static BOOL default_equal_function(
const void* obj1,
const void* obj2)
528 return (obj1 == obj2);
534 wListDictionary* ListDictionary_New(BOOL
synchronized)
536 wListDictionary* listDictionary = (wListDictionary*)calloc(1,
sizeof(wListDictionary));
541 listDictionary->synchronized =
synchronized;
543 if (!InitializeCriticalSectionAndSpinCount(&(listDictionary->lock), 4000))
545 free(listDictionary);
549 listDictionary->objectKey.fnObjectEquals = default_equal_function;
550 listDictionary->objectValue.fnObjectEquals = default_equal_function;
551 return listDictionary;
554 void ListDictionary_Free(wListDictionary* listDictionary)
558 ListDictionary_Clear(listDictionary);
559 DeleteCriticalSection(&listDictionary->lock);
560 free(listDictionary);
This struct contains function pointer to initialize/free objects.