FreeRDP
Loading...
Searching...
No Matches
TestHashTable.c
1
2#include <winpr/crt.h>
3#include <winpr/tchar.h>
4#include <winpr/collections.h>
5
6static char* key1 = "key1";
7static char* key2 = "key2";
8static char* key3 = "key3";
9
10static char* val1 = "val1";
11static char* val2 = "val2";
12static char* val3 = "val3";
13
14static int test_hash_table_pointer(void)
15{
16 int rc = -1;
17 size_t count = 0;
18 char* value = nullptr;
19 wHashTable* table = nullptr;
20 table = HashTable_New(TRUE);
21
22 if (!table)
23 return -1;
24
25 if (!HashTable_Insert(table, key1, val1))
26 goto fail;
27 if (!HashTable_Insert(table, key2, val2))
28 goto fail;
29 if (!HashTable_Insert(table, key3, val3))
30 goto fail;
31 count = HashTable_Count(table);
32
33 if (count != 3)
34 {
35 printf("HashTable_Count: Expected : 3, Actual: %" PRIuz "\n", count);
36 goto fail;
37 }
38
39 if (!HashTable_Remove(table, key2))
40 goto fail;
41 count = HashTable_Count(table);
42
43 if (count != 2)
44 {
45 printf("HashTable_Count: Expected : 2, Actual: %" PRIuz "\n", count);
46 goto fail;
47 }
48
49 if (!HashTable_Remove(table, key3))
50 goto fail;
51 count = HashTable_Count(table);
52
53 if (count != 1)
54 {
55 printf("HashTable_Count: Expected : 1, Actual: %" PRIuz "\n", count);
56 goto fail;
57 }
58
59 if (!HashTable_Remove(table, key1))
60 goto fail;
61 count = HashTable_Count(table);
62
63 if (count != 0)
64 {
65 printf("HashTable_Count: Expected : 0, Actual: %" PRIuz "\n", count);
66 goto fail;
67 }
68
69 if (!HashTable_Insert(table, key1, val1))
70 goto fail;
71 if (!HashTable_Insert(table, key2, val2))
72 goto fail;
73 if (!HashTable_Insert(table, key3, val3))
74 goto fail;
75 count = HashTable_Count(table);
76
77 if (count != 3)
78 {
79 printf("HashTable_Count: Expected : 3, Actual: %" PRIuz "\n", count);
80 goto fail;
81 }
82
83 value = (char*)HashTable_GetItemValue(table, key1);
84
85 if (strcmp(value, val1) != 0)
86 {
87 printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val1, value);
88 goto fail;
89 }
90
91 value = (char*)HashTable_GetItemValue(table, key2);
92
93 if (strcmp(value, val2) != 0)
94 {
95 printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val2, value);
96 goto fail;
97 }
98
99 value = (char*)HashTable_GetItemValue(table, key3);
100
101 if (strcmp(value, val3) != 0)
102 {
103 printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val3, value);
104 goto fail;
105 }
106
107 if (!HashTable_SetItemValue(table, key2, "apple"))
108 goto fail;
109 value = (char*)HashTable_GetItemValue(table, key2);
110
111 if (strcmp(value, "apple") != 0)
112 {
113 printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", "apple", value);
114 goto fail;
115 }
116
117 if (!HashTable_Contains(table, key2))
118 {
119 printf("HashTable_Contains: Expected : TRUE, Actual: FALSE\n");
120 goto fail;
121 }
122
123 if (!HashTable_Remove(table, key2))
124 {
125 printf("HashTable_Remove: Expected : TRUE, Actual: FALSE\n");
126 goto fail;
127 }
128
129 if (HashTable_Remove(table, key2))
130 {
131 printf("HashTable_Remove: Expected : FALSE, Actual: TRUE\n");
132 goto fail;
133 }
134
135 HashTable_Clear(table);
136 count = HashTable_Count(table);
137
138 if (count != 0)
139 {
140 printf("HashTable_Count: Expected : 0, Actual: %" PRIuz "\n", count);
141 goto fail;
142 }
143
144 rc = 1;
145fail:
146 HashTable_Free(table);
147 return rc;
148}
149
150static int test_hash_table_string(void)
151{
152 int rc = -1;
153 size_t count = 0;
154 char* value = nullptr;
155 wHashTable* table = HashTable_New(TRUE);
156
157 if (!table)
158 return -1;
159
160 if (!HashTable_SetupForStringData(table, TRUE))
161 goto fail;
162
163 if (!HashTable_Insert(table, key1, val1))
164 goto fail;
165 if (!HashTable_Insert(table, key2, val2))
166 goto fail;
167 if (!HashTable_Insert(table, key3, val3))
168 goto fail;
169 count = HashTable_Count(table);
170
171 if (count != 3)
172 {
173 printf("HashTable_Count: Expected : 3, Actual: %" PRIuz "\n", count);
174 goto fail;
175 }
176
177 if (!HashTable_Remove(table, key2))
178 goto fail;
179 count = HashTable_Count(table);
180
181 if (count != 2)
182 {
183 printf("HashTable_Count: Expected : 3, Actual: %" PRIuz "\n", count);
184 goto fail;
185 }
186
187 if (!HashTable_Remove(table, key3))
188 goto fail;
189 count = HashTable_Count(table);
190
191 if (count != 1)
192 {
193 printf("HashTable_Count: Expected : 1, Actual: %" PRIuz "\n", count);
194 goto fail;
195 }
196
197 if (!HashTable_Remove(table, key1))
198 goto fail;
199 count = HashTable_Count(table);
200
201 if (count != 0)
202 {
203 printf("HashTable_Count: Expected : 0, Actual: %" PRIuz "\n", count);
204 goto fail;
205 }
206
207 if (!HashTable_Insert(table, key1, val1))
208 goto fail;
209 if (!HashTable_Insert(table, key2, val2))
210 goto fail;
211 if (!HashTable_Insert(table, key3, val3))
212 goto fail;
213 count = HashTable_Count(table);
214
215 if (count != 3)
216 {
217 printf("HashTable_Count: Expected : 3, Actual: %" PRIuz "\n", count);
218 goto fail;
219 }
220
221 value = (char*)HashTable_GetItemValue(table, key1);
222
223 if (strcmp(value, val1) != 0)
224 {
225 printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val1, value);
226 goto fail;
227 }
228
229 value = (char*)HashTable_GetItemValue(table, key2);
230
231 if (strcmp(value, val2) != 0)
232 {
233 printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val2, value);
234 goto fail;
235 }
236
237 value = (char*)HashTable_GetItemValue(table, key3);
238
239 if (strcmp(value, val3) != 0)
240 {
241 printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val3, value);
242 goto fail;
243 }
244
245 if (!HashTable_SetItemValue(table, key2, "apple"))
246 goto fail;
247 value = (char*)HashTable_GetItemValue(table, key2);
248
249 if (strcmp(value, "apple") != 0)
250 {
251 printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", "apple", value);
252 goto fail;
253 }
254
255 if (!HashTable_Contains(table, key2))
256 {
257 printf("HashTable_Contains: Expected : TRUE, Actual: FALSE\n");
258 goto fail;
259 }
260
261 if (!HashTable_Remove(table, key2))
262 {
263 printf("HashTable_Remove: Expected : TRUE, Actual: FALSE\n");
264 goto fail;
265 }
266
267 if (HashTable_Remove(table, key2))
268 {
269 printf("HashTable_Remove: Expected : FALSE, Actual: TRUE\n");
270 goto fail;
271 }
272
273 HashTable_Clear(table);
274 count = HashTable_Count(table);
275
276 if (count != 0)
277 {
278 printf("HashTable_Count: Expected : 0, Actual: %" PRIuz "\n", count);
279 goto fail;
280 }
281
282 rc = 1;
283fail:
284 HashTable_Free(table);
285 return rc;
286}
287
288typedef struct
289{
290 wHashTable* table;
291 size_t strlenCounter;
292 size_t foreachCalls;
293
294 BOOL test3error;
295} ForeachData;
296
297static BOOL foreachFn1(const void* key, void* value, void* arg)
298{
299 ForeachData* d = (ForeachData*)arg;
300 WINPR_UNUSED(key);
301 d->strlenCounter += strlen((const char*)value);
302 return TRUE;
303}
304
305static BOOL foreachFn2(const void* key, void* value, void* arg)
306{
307 ForeachData* d = (ForeachData*)arg;
308 WINPR_UNUSED(key);
309 WINPR_UNUSED(value);
310 d->foreachCalls++;
311
312 return (d->foreachCalls != 2);
313}
314
315static BOOL foreachFn3(const void* key, void* value, void* arg)
316{
317 const char* keyStr = (const char*)key;
318
319 ForeachData* d = (ForeachData*)arg;
320 ForeachData d2;
321
322 WINPR_UNUSED(value);
323 WINPR_ASSERT(keyStr);
324
325 if (strcmp(keyStr, "key1") == 0)
326 {
327 /* when we pass on key1, let's remove key2 and check that the value is not
328 * visible anymore (even if has just been marked for removal)*/
329 HashTable_Remove(d->table, "key2");
330
331 if (HashTable_Contains(d->table, "key2"))
332 {
333 d->test3error = TRUE;
334 return FALSE;
335 }
336
337 if (HashTable_ContainsValue(d->table, "value2"))
338 {
339 d->test3error = TRUE;
340 return FALSE;
341 }
342
343 /* number of elements of the table shall be correct too */
344 if (HashTable_Count(d->table) != 2)
345 {
346 d->test3error = TRUE;
347 return FALSE;
348 }
349
350 /* we try recursive HashTable_Foreach */
351 d2.table = d->table;
352 d2.strlenCounter = 0;
353
354 if (!HashTable_Foreach(d->table, foreachFn1, &d2))
355 {
356 d->test3error = TRUE;
357 return FALSE;
358 }
359 if (d2.strlenCounter != 8)
360 {
361 d->test3error = TRUE;
362 return FALSE;
363 }
364 }
365 return TRUE;
366}
367
368static int test_hash_foreach(void)
369{
370 ForeachData foreachData;
371 wHashTable* table = nullptr;
372 int retCode = 0;
373
374 foreachData.table = table = HashTable_New(TRUE);
375 if (!table)
376 return -1;
377
378 if (!HashTable_SetupForStringData(table, TRUE))
379 goto out;
380
381 if (HashTable_Insert(table, key1, val1) < 0 || HashTable_Insert(table, key2, val2) < 0 ||
382 HashTable_Insert(table, key3, val3) < 0)
383 {
384 retCode = -2;
385 goto out;
386 }
387
388 /* let's try a first trivial foreach */
389 foreachData.strlenCounter = 0;
390 if (!HashTable_Foreach(table, foreachFn1, &foreachData))
391 {
392 retCode = -10;
393 goto out;
394 }
395 if (foreachData.strlenCounter != 12)
396 {
397 retCode = -11;
398 goto out;
399 }
400
401 /* interrupted foreach */
402 foreachData.foreachCalls = 0;
403 if (HashTable_Foreach(table, foreachFn2, &foreachData))
404 {
405 retCode = -20;
406 goto out;
407 }
408 if (foreachData.foreachCalls != 2)
409 {
410 retCode = -21;
411 goto out;
412 }
413
414 /* let's try a foreach() call that will remove a value from the table in the callback */
415 foreachData.test3error = FALSE;
416 if (!HashTable_Foreach(table, foreachFn3, &foreachData))
417 {
418 retCode = -30;
419 goto out;
420 }
421 if (foreachData.test3error)
422 {
423 retCode = -31;
424 goto out;
425 }
426
427out:
428 HashTable_Free(table);
429 return retCode;
430}
431
432int TestHashTable(int argc, char* argv[])
433{
434 WINPR_UNUSED(argc);
435 WINPR_UNUSED(argv);
436
437 if (test_hash_table_pointer() < 0)
438 return 1;
439
440 if (test_hash_table_string() < 0)
441 return 2;
442
443 if (test_hash_foreach() < 0)
444 return 3;
445 return 0;
446}