FreeRDP
TestHashTable.c
1 
2 #include <winpr/crt.h>
3 #include <winpr/tchar.h>
4 #include <winpr/collections.h>
5 
6 static char* key1 = "key1";
7 static char* key2 = "key2";
8 static char* key3 = "key3";
9 
10 static char* val1 = "val1";
11 static char* val2 = "val2";
12 static char* val3 = "val3";
13 
14 static int test_hash_table_pointer(void)
15 {
16  int rc = -1;
17  size_t count = 0;
18  char* value = NULL;
19  wHashTable* table = NULL;
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;
145 fail:
146  HashTable_Free(table);
147  return rc;
148 }
149 
150 static int test_hash_table_string(void)
151 {
152  int rc = -1;
153  size_t count = 0;
154  char* value = NULL;
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;
283 fail:
284  HashTable_Free(table);
285  return rc;
286 }
287 
288 typedef struct
289 {
290  wHashTable* table;
291  size_t strlenCounter;
292  size_t foreachCalls;
293 
294  BOOL test3error;
295 } ForeachData;
296 
297 static 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 
305 static 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  if (d->foreachCalls == 2)
313  return FALSE;
314  return TRUE;
315 }
316 
317 static BOOL foreachFn3(const void* key, void* value, void* arg)
318 {
319  const char* keyStr = (const char*)key;
320 
321  ForeachData* d = (ForeachData*)arg;
322  ForeachData d2;
323 
324  WINPR_UNUSED(value);
325  WINPR_ASSERT(keyStr);
326 
327  if (strcmp(keyStr, "key1") == 0)
328  {
329  /* when we pass on key1, let's remove key2 and check that the value is not
330  * visible anymore (even if has just been marked for removal)*/
331  HashTable_Remove(d->table, "key2");
332 
333  if (HashTable_Contains(d->table, "key2"))
334  {
335  d->test3error = TRUE;
336  return FALSE;
337  }
338 
339  if (HashTable_ContainsValue(d->table, "value2"))
340  {
341  d->test3error = TRUE;
342  return FALSE;
343  }
344 
345  /* number of elements of the table shall be correct too */
346  if (HashTable_Count(d->table) != 2)
347  {
348  d->test3error = TRUE;
349  return FALSE;
350  }
351 
352  /* we try recursive HashTable_Foreach */
353  d2.table = d->table;
354  d2.strlenCounter = 0;
355 
356  if (!HashTable_Foreach(d->table, foreachFn1, &d2))
357  {
358  d->test3error = TRUE;
359  return FALSE;
360  }
361  if (d2.strlenCounter != 8)
362  {
363  d->test3error = TRUE;
364  return FALSE;
365  }
366  }
367  return TRUE;
368 }
369 
370 static int test_hash_foreach(void)
371 {
372  ForeachData foreachData;
373  wHashTable* table = NULL;
374  int retCode = 0;
375 
376  foreachData.table = table = HashTable_New(TRUE);
377  if (!table)
378  return -1;
379 
380  if (!HashTable_SetupForStringData(table, TRUE))
381  goto out;
382 
383  if (HashTable_Insert(table, key1, val1) < 0 || HashTable_Insert(table, key2, val2) < 0 ||
384  HashTable_Insert(table, key3, val3) < 0)
385  {
386  retCode = -2;
387  goto out;
388  }
389 
390  /* let's try a first trivial foreach */
391  foreachData.strlenCounter = 0;
392  if (!HashTable_Foreach(table, foreachFn1, &foreachData))
393  {
394  retCode = -10;
395  goto out;
396  }
397  if (foreachData.strlenCounter != 12)
398  {
399  retCode = -11;
400  goto out;
401  }
402 
403  /* interrupted foreach */
404  foreachData.foreachCalls = 0;
405  if (HashTable_Foreach(table, foreachFn2, &foreachData))
406  {
407  retCode = -20;
408  goto out;
409  }
410  if (foreachData.foreachCalls != 2)
411  {
412  retCode = -21;
413  goto out;
414  }
415 
416  /* let's try a foreach() call that will remove a value from the table in the callback */
417  foreachData.test3error = FALSE;
418  if (!HashTable_Foreach(table, foreachFn3, &foreachData))
419  {
420  retCode = -30;
421  goto out;
422  }
423  if (foreachData.test3error)
424  {
425  retCode = -31;
426  goto out;
427  }
428 
429 out:
430  HashTable_Free(table);
431  return retCode;
432 }
433 
434 int TestHashTable(int argc, char* argv[])
435 {
436  WINPR_UNUSED(argc);
437  WINPR_UNUSED(argv);
438 
439  if (test_hash_table_pointer() < 0)
440  return 1;
441 
442  if (test_hash_table_string() < 0)
443  return 2;
444 
445  if (test_hash_foreach() < 0)
446  return 3;
447  return 0;
448 }