gwenhywfar  5.1.2
simpleptrlist-t.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Fri Dec 06 2019
3  copyright : (C) 2019 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * *
8  * This library is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU Lesser General Public *
10  * License as published by the Free Software Foundation; either *
11  * version 2.1 of the License, or (at your option) any later version. *
12  * *
13  * This library is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16  * Lesser General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU Lesser General Public *
19  * License along with this library; if not, write to the Free Software *
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21  * MA 02111-1307 USA *
22  * *
23  ***************************************************************************/
24 
25 
26 /* This file is included by "simpleptrlist.c" */
27 
28 
29 #if GWENHYWFAR_ENABLE_TESTCODE
30 
31 
32 #include <gwenhywfar/mdigest.h>
33 #include <string.h>
34 
35 
36 
37 /* ------------------------------------------------------------------------------------------------
38  * type definitions
39  * ------------------------------------------------------------------------------------------------
40  */
41 
42 typedef struct TEST_TYPE TEST_TYPE;
43 GWEN_LIST_FUNCTION_DEFS(TEST_TYPE, TestType)
44 struct TEST_TYPE {
45  GWEN_LIST_ELEMENT(TEST_TYPE)
46  int _refCounter;
47  int testPosition;
48  char *testStringPtr;
49  uint8_t testHash[20];
50 };
51 
52 
53 
54 /* ------------------------------------------------------------------------------------------------
55  * forward declarations
56  * ------------------------------------------------------------------------------------------------
57  */
58 
59 
60 static TEST_TYPE *TestType_new(const char *s, int pos);
61 static void TestType_Attach(TEST_TYPE *tt);
62 static void TestType_free(TEST_TYPE *tt);
63 
64 static int TestType_CalcHash(TEST_TYPE *tt);
65 static int TestType_TestHash(const TEST_TYPE *tt);
66 
67 static GWENHYWFAR_CB void _attachToTestType(GWEN_SIMPLEPTRLIST *pl, void *p);
68 static GWENHYWFAR_CB void _detachFromTestType(GWEN_SIMPLEPTRLIST *pl, void *p);
69 
70 
71 static int GWENHYWFAR_CB test1(GWEN_TEST_MODULE *mod);
72 static int GWENHYWFAR_CB test2(GWEN_TEST_MODULE *mod);
73 static int GWENHYWFAR_CB test3(GWEN_TEST_MODULE *mod);
74 static int GWENHYWFAR_CB test4(GWEN_TEST_MODULE *mod);
75 static int GWENHYWFAR_CB test5(GWEN_TEST_MODULE *mod);
76 static int GWENHYWFAR_CB test6(GWEN_TEST_MODULE *mod);
77 
78 static TEST_TYPE *createTestType(int num);
79 static void dumpTestTypeList(TEST_TYPE_LIST *ttList);
80 
81 
82 
83 /* ------------------------------------------------------------------------------------------------
84  * implementations
85  * ------------------------------------------------------------------------------------------------
86  */
87 
88 
90 {
91  GWEN_TEST_MODULE *newMod;
92 
93  newMod=GWEN_Test_Module_AddModule(mod, "GWEN_SimplePtrList", NULL);
94 
95  GWEN_Test_Module_AddTest(newMod, "test1", test1, NULL);
96  GWEN_Test_Module_AddTest(newMod, "test2", test2, NULL);
97  GWEN_Test_Module_AddTest(newMod, "test3", test3, NULL);
98  GWEN_Test_Module_AddTest(newMod, "test4", test4, NULL);
99  GWEN_Test_Module_AddTest(newMod, "test5", test5, NULL);
100  GWEN_Test_Module_AddTest(newMod, "test6", test6, NULL);
101 
102  return 0;
103 }
104 
105 
106 
107 GWEN_LIST_FUNCTIONS(TEST_TYPE, TestType)
108 
109 
110 
111 
112 TEST_TYPE *TestType_new(const char *s, int pos)
113 {
114  TEST_TYPE *tt;
115 
116  GWEN_NEW_OBJECT(TEST_TYPE, tt);
117  tt->_refCounter=1;
118  GWEN_LIST_INIT(TEST_TYPE, tt);
119  if (s)
120  tt->testStringPtr=strdup(s);
121  tt->testPosition=pos;
122  return tt;
123 }
124 
125 
126 
127 void TestType_Attach(TEST_TYPE *tt)
128 {
129  assert(tt);
130  assert(tt->_refCounter);
131 
132  if (tt && tt->_refCounter) {
133  tt->_refCounter++;
134  /*DBG_ERROR(GWEN_LOGDOMAIN, "Attached (%d: refcount=%d)", tt->testPosition, tt->_refCounter);*/
135  }
136  else {
137  DBG_ERROR(GWEN_LOGDOMAIN, "NULL pointer or already freed");
138  }
139 }
140 
141 
142 
143 void TestType_free(TEST_TYPE *tt)
144 {
145  if (tt && tt->_refCounter) {
146  /*DBG_ERROR(GWEN_LOGDOMAIN, "Detaching (%d: refcount=%d)", tt->testPosition, tt->_refCounter);*/
147  if (tt->_refCounter==1) {
148  GWEN_LIST_FINI(TEST_TYPE, tt);
149  if (tt->testStringPtr)
150  free(tt->testStringPtr);
151  tt->_refCounter=0;
152  GWEN_FREE_OBJECT(tt);
153  }
154  else
155  tt->_refCounter--;
156  }
157 }
158 
159 
160 
161 int TestType_CalcHash(TEST_TYPE *tt)
162 {
163  if (tt->testStringPtr && *(tt->testStringPtr)) {
164  GWEN_MDIGEST *md;
165  int rv;
166 
168  rv=GWEN_MDigest_Digest(md,
169  (const uint8_t *)tt->testStringPtr, strlen(tt->testStringPtr),
170  tt->testHash, sizeof(tt->testHash));
171  if (rv<0) {
172  DBG_ERROR(GWEN_LOGDOMAIN, "Error on GWEN_MDigest_Begin: %s (%d)", GWEN_Error_SimpleToString(rv), rv);
173  GWEN_MDigest_free(md);
174  return rv;
175  }
176  GWEN_MDigest_free(md);
177  }
178  return 0;
179 }
180 
181 
182 
183 int TestType_TestHash(const TEST_TYPE *tt)
184 {
185  if (tt->testStringPtr && *(tt->testStringPtr)) {
186  GWEN_MDIGEST *md;
187  uint8_t hash[20];
188  int rv;
189 
191  rv=GWEN_MDigest_Digest(md,
192  (const uint8_t *)tt->testStringPtr, strlen(tt->testStringPtr),
193  hash, sizeof(hash));
194  if (rv<0) {
195  DBG_ERROR(GWEN_LOGDOMAIN, "Error on GWEN_MDigest_Digest: %s (%d)", GWEN_Error_SimpleToString(rv), rv);
196  GWEN_MDigest_free(md);
197  return rv;
198  }
199  GWEN_MDigest_free(md);
200 
201  if (memcmp(hash, tt->testHash, sizeof(hash))!=0) {
202  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid hash, object was modified.");
203  return GWEN_ERROR_GENERIC;
204  }
205  }
206  return 0;
207 }
208 
209 
210 
211 TEST_TYPE *createTestType(int num)
212 {
213  TEST_TYPE *tt;
214  char testString[256];
215  int rv;
216 
217  snprintf(testString, sizeof(testString), "This is test string number %d", num);
218  tt=TestType_new(testString, num);
219  if (tt==NULL) {
220  DBG_ERROR(GWEN_LOGDOMAIN, "Could not create test object %d", num);
221  return NULL;
222  }
223  rv=TestType_CalcHash(tt);
224  if (rv<0) {
225  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
226  TestType_free(tt);
227  return NULL;
228  }
229  return tt;
230 }
231 
232 
233 
234 void _attachToTestType(GWEN_UNUSED GWEN_SIMPLEPTRLIST *pl, void *p)
235 {
236  TEST_TYPE *tt;
237 
238  tt=(TEST_TYPE *) p;
239  TestType_Attach(tt);
240 }
241 
242 
243 
244 void _detachFromTestType(GWEN_UNUSED GWEN_SIMPLEPTRLIST *pl, void *p)
245 {
246  TEST_TYPE *tt;
247 
248  tt=(TEST_TYPE *) p;
249  TestType_free(tt);
250 }
251 
252 
253 
254 void dumpTestTypeList(TEST_TYPE_LIST *ttList)
255 {
256  TEST_TYPE *tt;
257 
258  tt=TestType_List_First(ttList);
259  while (tt) {
260  fprintf(stderr, "%5d: %3d: %s\n", tt->testPosition, tt->_refCounter, tt->testStringPtr);
261  tt=TestType_List_Next(tt);
262  }
263 }
264 
265 
266 
267 /* ------------------------------------------------------------------------------------------------
268  * test 1: test struct members after construction
269  * ------------------------------------------------------------------------------------------------
270  */
271 
273 {
274  GWEN_SIMPLEPTRLIST *pl;
275  int i;
276 
277  pl=GWEN_SimplePtrList_new(128, 128);
278  if (pl==NULL) {
279  DBG_ERROR(GWEN_LOGDOMAIN, "Could not create pointer list");
280  return GWEN_ERROR_GENERIC;
281  }
282 
283  if (pl->refCount!=1) {
284  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: refCounter");
286  return GWEN_ERROR_GENERIC;
287  }
288 
289  if (pl->maxEntries!=128) {
290  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: maxEntries");
292  return GWEN_ERROR_GENERIC;
293  }
294 
295  if (pl->usedEntries!=0) {
296  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: usedEntries");
298  return GWEN_ERROR_GENERIC;
299  }
300 
301  if (pl->steps!=128) {
302  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: steps");
304  return GWEN_ERROR_GENERIC;
305  }
306 
307 
308  if (pl->entryList->refCounter!=1) {
309  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid internal object field: refCounter");
311  return GWEN_ERROR_GENERIC;
312  }
313 
314  if (pl->entryList->storedEntries!=128) {
315  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid internal object field: storedEntries");
317  return GWEN_ERROR_GENERIC;
318  }
319 
320 
321  for (i=0; i<128; i++) {
322  if (pl->entryList->entries[i]!=NULL) {
323  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object entry: idx %d is not NULL", i);
325  return GWEN_ERROR_GENERIC;
326  }
327  }
328 
329 
331  return 0;
332 }
333 
334 
335 
336 /* ------------------------------------------------------------------------------------------------
337  * test 2: test adding pointers
338  * ------------------------------------------------------------------------------------------------
339  */
340 
342 {
343 
344  GWEN_SIMPLEPTRLIST *pl;
345  int i;
346 
347  pl=GWEN_SimplePtrList_new(128, 128);
348  for (i=0; i<1024; i++) {
349  TEST_TYPE *tt;
350  int64_t idx;
351 
352  tt=createTestType(i);
353  idx=GWEN_SimplePtrList_AddPtr(pl, tt);
354  if (idx<0) {
355  DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
357  return (int) idx;
358  }
359  } /* for */
360 
361  if (pl->maxEntries!=1024) {
362  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: maxEntries");
364  return GWEN_ERROR_GENERIC;
365  }
366 
367  if (pl->usedEntries!=1024) {
368  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: usedEntries");
370  return GWEN_ERROR_GENERIC;
371  }
372 
373  for (i=0; i<1024; i++) {
374  TEST_TYPE *tt;
375  int rv;
376 
377  tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(pl, i);
378  if (tt==NULL) {
379  DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
381  return GWEN_ERROR_GENERIC;
382  }
383 
384  rv=TestType_TestHash(tt);
385  if (rv<0) {
386  DBG_ERROR(GWEN_LOGDOMAIN, "Error testing hash of object %d: %s (%d)", i, GWEN_Error_SimpleToString(rv), rv);
388  return rv;
389  }
390  } /* for */
391 
392  /* free all objects */
393  for (i=0; i<1024; i++) {
394  TEST_TYPE *tt;
395 
396  tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(pl, i);
397  if (tt==NULL) {
398  DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
400  return GWEN_ERROR_GENERIC;
401  }
403  TestType_free(tt);
404  } /* for */
405 
407  return 0;
408 }
409 
410 
411 
412 /* ------------------------------------------------------------------------------------------------
413  * test 3: test lazy copying
414  * ------------------------------------------------------------------------------------------------
415  */
416 
418 {
419 
420  GWEN_SIMPLEPTRLIST *pl;
421  GWEN_SIMPLEPTRLIST *plCopy;
422  int i;
423 
424  pl=GWEN_SimplePtrList_new(128, 128);
425  for (i=0; i<1000; i++) {
426  TEST_TYPE *tt;
427  int64_t idx;
428 
429  tt=createTestType(i);
430  idx=GWEN_SimplePtrList_AddPtr(pl, tt);
431  if (idx<0) {
432  DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
434  return (int) idx;
435  }
436  } /* for */
437 
438  plCopy=GWEN_SimplePtrList_LazyCopy(pl);
439  if (plCopy==NULL) {
440  DBG_ERROR(GWEN_LOGDOMAIN, "Could not copy pointer list");
441  GWEN_SimplePtrList_free(plCopy);
443  return GWEN_ERROR_INVALID;
444  }
445 
446  if (!(plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE)) {
447  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: flags");
448  GWEN_SimplePtrList_free(plCopy);
450  return GWEN_ERROR_GENERIC;
451  }
452 
453  if (!(pl->flags & GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE)) {
454  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field in old list: flags");
455  GWEN_SimplePtrList_free(plCopy);
457  return GWEN_ERROR_GENERIC;
458  }
459 
460  if (plCopy->entryList != pl->entryList) {
461  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: entryList (should be the same after lazy copy)");
462  GWEN_SimplePtrList_free(plCopy);
464  return GWEN_ERROR_GENERIC;
465  }
466 
467  if (pl->entryList->refCounter!=2) {
468  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid internal object field: refCounter (should be 2)");
470  return GWEN_ERROR_GENERIC;
471  }
472 
473  for (i=1000; i<1024; i++) {
474  TEST_TYPE *tt;
475  int64_t idx;
476 
477  tt=createTestType(i);
478  idx=GWEN_SimplePtrList_AddPtr(plCopy, tt);
479  if (idx<0) {
480  DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
481  GWEN_SimplePtrList_free(plCopy);
483  return (int) idx;
484  }
485  } /* for */
486 
487  if (plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE) {
488  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: flags (should have cleared GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE)");
489  GWEN_SimplePtrList_free(plCopy);
491  return GWEN_ERROR_GENERIC;
492  }
493 
494  if (!(pl->flags & GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE)) {
496  "Invalid object field in old list: flags (should not have cleared GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE)");
497  GWEN_SimplePtrList_free(plCopy);
499  return GWEN_ERROR_GENERIC;
500  }
501 
502  if (plCopy->entryList == pl->entryList) {
503  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: entryList (should have changed)");
504  GWEN_SimplePtrList_free(plCopy);
506  return GWEN_ERROR_GENERIC;
507  }
508 
509  if (pl->entryList->refCounter!=1) {
510  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid internal object field: refCounter (should be back to 1)");
512  return GWEN_ERROR_GENERIC;
513  }
514 
515  if (plCopy->entryList->refCounter!=1) {
516  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid internal object field: refCounter (should be 1)");
518  return GWEN_ERROR_GENERIC;
519  }
520 
521  if (plCopy->maxEntries!=1024+128) {
522  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: maxEntries (should be 1152)");
524  return GWEN_ERROR_GENERIC;
525  }
526 
527  if (plCopy->usedEntries!=1024) {
528  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: usedEntries");
530  return GWEN_ERROR_GENERIC;
531  }
532 
533  if (pl->maxEntries!=1024) {
534  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: maxEntries (should still be 1024)");
536  return GWEN_ERROR_GENERIC;
537  }
538 
539  if (pl->usedEntries!=1000) {
540  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: usedEntries (should still be 1000)");
542  return GWEN_ERROR_GENERIC;
543  }
544 
545 
546  for (i=0; i<1024; i++) {
547  TEST_TYPE *tt;
548  int rv;
549 
550  tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(plCopy, i);
551  if (tt==NULL) {
552  DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
553  GWEN_SimplePtrList_free(plCopy);
555  return GWEN_ERROR_GENERIC;
556  }
557 
558  rv=TestType_TestHash(tt);
559  if (rv<0) {
560  DBG_ERROR(GWEN_LOGDOMAIN, "Error testing hash of object %d: %s (%d)", i, GWEN_Error_SimpleToString(rv), rv);
561  GWEN_SimplePtrList_free(plCopy);
563  return rv;
564  }
565  } /* for */
566 
567  /* free all objects */
568  for (i=0; i<1024; i++) {
569  TEST_TYPE *tt;
570 
571  tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(plCopy, i);
572  if (tt==NULL) {
573  DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
574  GWEN_SimplePtrList_free(plCopy);
576  return GWEN_ERROR_GENERIC;
577  }
578  GWEN_SimplePtrList_SetPtrAt(plCopy, i, NULL);
579  TestType_free(tt);
580  } /* for */
581 
582 
583  GWEN_SimplePtrList_free(plCopy);
585  return 0;
586 }
587 
588 
589 
590 /* ------------------------------------------------------------------------------------------------
591  * test 4: test adding pointers with attach/detach
592  * ------------------------------------------------------------------------------------------------
593  */
594 
596 {
597 
598  GWEN_SIMPLEPTRLIST *pl;
599  TEST_TYPE_LIST *ttList;
600  int i;
601 
602  pl=GWEN_SimplePtrList_new(128, 128);
603  GWEN_SimplePtrList_SetAttachObjectFn(pl, _attachToTestType);
604  GWEN_SimplePtrList_SetFreeObjectFn(pl, _detachFromTestType);
607 
608  ttList=TestType_List_new();
609 
610  for (i=0; i<1024; i++) {
611  TEST_TYPE *tt;
612  int64_t idx;
613 
614  tt=createTestType(i);
615  TestType_List_Add(tt, ttList);
616 
617  idx=GWEN_SimplePtrList_AddPtr(pl, tt);
618  if (idx<0) {
619  DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
621  return (int) idx;
622  }
623  } /* for */
624 
625  if (1) {
626  TEST_TYPE *tt;
627  int cnt=0;
628 
629  tt=TestType_List_First(ttList);
630  while (tt) {
631  if (tt->_refCounter!=2) {
632  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 2");
633  TestType_List_free(ttList);
635  return GWEN_ERROR_GENERIC;
636  }
637  cnt++;
638  tt=TestType_List_Next(tt);
639  }
640  if (cnt!=1024) {
641  DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
642  }
643  }
644 
645  for (i=0; i<1024; i++) {
646  TEST_TYPE *tt;
647  int rv;
648 
649  tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(pl, i);
650  if (tt==NULL) {
651  DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
652  TestType_List_free(ttList);
654  return GWEN_ERROR_GENERIC;
655  }
656 
657  rv=TestType_TestHash(tt);
658  if (rv<0) {
659  DBG_ERROR(GWEN_LOGDOMAIN, "Error testing hash of object %d: %s (%d)", i, GWEN_Error_SimpleToString(rv), rv);
660  TestType_List_free(ttList);
662  return rv;
663  }
664  } /* for */
665 
667 
668  if (1) {
669  TEST_TYPE *tt;
670  int cnt=0;
671 
672  tt=TestType_List_First(ttList);
673  while (tt) {
674  if (tt->_refCounter!=1) {
675  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 1");
676  TestType_List_free(ttList);
677  return GWEN_ERROR_GENERIC;
678  }
679  cnt++;
680  tt=TestType_List_Next(tt);
681  }
682  if (cnt!=1024) {
683  DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
684  }
685  }
686 
687  TestType_List_free(ttList);
688 
689  return 0;
690 }
691 
692 
693 
694 /* ------------------------------------------------------------------------------------------------
695  * test 5: test lazy copying with attach/detach
696  * ------------------------------------------------------------------------------------------------
697  */
698 
700 {
701 
702  GWEN_SIMPLEPTRLIST *pl;
703  GWEN_SIMPLEPTRLIST *plCopy;
704  TEST_TYPE_LIST *ttList;
705  int i;
706 
707  pl=GWEN_SimplePtrList_new(128, 128);
708  GWEN_SimplePtrList_SetAttachObjectFn(pl, _attachToTestType);
709  GWEN_SimplePtrList_SetFreeObjectFn(pl, _detachFromTestType);
712 
713  ttList=TestType_List_new();
714  for (i=0; i<1000; i++) {
715  TEST_TYPE *tt;
716  int64_t idx;
717 
718  tt=createTestType(i);
719  TestType_List_Add(tt, ttList);
720  idx=GWEN_SimplePtrList_AddPtr(pl, tt);
721  if (idx<0) {
722  DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
724  return (int) idx;
725  }
726  } /* for */
727 
728  plCopy=GWEN_SimplePtrList_LazyCopy(pl);
729  if (plCopy==NULL) {
730  DBG_ERROR(GWEN_LOGDOMAIN, "Could not copy pointer list");
731  GWEN_SimplePtrList_free(plCopy);
733  return GWEN_ERROR_INVALID;
734  }
735 
736  if (!(plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_ATTACHTOOBJECTS)) {
738  "Invalid object field in list: flags (should have set GWEN_SIMPLEPTRLIST_FLAGS_ATTACHTOOBJECTS)");
739  GWEN_SimplePtrList_free(plCopy);
741  return GWEN_ERROR_GENERIC;
742  }
743 
744  if (!(plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_DETACHFROMOBJECTS)) {
746  "Invalid object field in list: flags (should have set GWEN_SIMPLEPTRLIST_FLAGS_DETACHFROMOBJECTS)");
747  GWEN_SimplePtrList_free(plCopy);
749  return GWEN_ERROR_GENERIC;
750  }
751 
752 
753  for (i=1000; i<1024; i++) {
754  TEST_TYPE *tt;
755  int64_t idx;
756 
757  tt=createTestType(i);
758  TestType_List_Add(tt, ttList);
759  idx=GWEN_SimplePtrList_AddPtr(plCopy, tt);
760  if (idx<0) {
761  DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
762  GWEN_SimplePtrList_free(plCopy);
764  return (int) idx;
765  }
766  } /* for */
767 
768 
769  for (i=0; i<1024; i++) {
770  TEST_TYPE *tt;
771  int rv;
772 
773  tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(plCopy, i);
774  if (tt==NULL) {
775  DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
776  TestType_List_free(ttList);
777  GWEN_SimplePtrList_free(plCopy);
779  return GWEN_ERROR_GENERIC;
780  }
781 
782  rv=TestType_TestHash(tt);
783  if (rv<0) {
784  DBG_ERROR(GWEN_LOGDOMAIN, "Error testing hash of object %d: %s (%d)", i, GWEN_Error_SimpleToString(rv), rv);
785  TestType_List_free(ttList);
786  GWEN_SimplePtrList_free(plCopy);
788  return rv;
789  }
790  } /* for */
791 
792 
793  if (1) {
794  TEST_TYPE *tt;
795  int cnt=0;
796 
797  tt=TestType_List_First(ttList);
798  while (tt) {
799  if (cnt<1000) {
800  if (tt->_refCounter!=3) {
801  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object %d is not 3 (%d)", cnt, tt->_refCounter);
802  dumpTestTypeList(ttList);
803  TestType_List_free(ttList);
805  return GWEN_ERROR_GENERIC;
806  }
807  }
808  else {
809  if (tt->_refCounter!=2) {
810  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 2");
811  TestType_List_free(ttList);
813  return GWEN_ERROR_GENERIC;
814  }
815  }
816  cnt++;
817  tt=TestType_List_Next(tt);
818  }
819  if (cnt!=1024) {
820  DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
821  }
822  }
823 
824 
825  GWEN_SimplePtrList_free(plCopy);
826 
827  if (1) {
828  TEST_TYPE *tt;
829  int cnt=0;
830 
831  tt=TestType_List_First(ttList);
832  while (tt) {
833  if (cnt<1000) {
834  if (tt->_refCounter!=2) {
835  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 2");
836  TestType_List_free(ttList);
838  return GWEN_ERROR_GENERIC;
839  }
840  }
841  else {
842  if (tt->_refCounter!=1) {
843  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 1");
844  TestType_List_free(ttList);
846  return GWEN_ERROR_GENERIC;
847  }
848  }
849  cnt++;
850  tt=TestType_List_Next(tt);
851  }
852  if (cnt!=1024) {
853  DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
854  }
855  }
856 
857 
859 
860  if (1) {
861  TEST_TYPE *tt;
862  int cnt=0;
863 
864  tt=TestType_List_First(ttList);
865  while (tt) {
866  if (tt->_refCounter!=1) {
867  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 1");
868  TestType_List_free(ttList);
870  return GWEN_ERROR_GENERIC;
871  }
872  cnt++;
873  tt=TestType_List_Next(tt);
874  }
875  if (cnt!=1024) {
876  DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
877  }
878  }
879 
880  TestType_List_free(ttList);
881 
882  return 0;
883 }
884 
885 
886 
887 /* ------------------------------------------------------------------------------------------------
888  * test 6: test lazy copying with attach/detach and setPtr
889  * ------------------------------------------------------------------------------------------------
890  */
891 
893 {
894 
895  GWEN_SIMPLEPTRLIST *pl;
896  GWEN_SIMPLEPTRLIST *plCopy;
897  TEST_TYPE_LIST *ttList;
898  int i;
899 
900  pl=GWEN_SimplePtrList_new(128, 128);
901  GWEN_SimplePtrList_SetAttachObjectFn(pl, _attachToTestType);
902  GWEN_SimplePtrList_SetFreeObjectFn(pl, _detachFromTestType);
905 
906  ttList=TestType_List_new();
907  for (i=0; i<1024; i++) {
908  TEST_TYPE *tt;
909  int64_t idx;
910 
911  tt=createTestType(i);
912  TestType_List_Add(tt, ttList);
913  idx=GWEN_SimplePtrList_AddPtr(pl, tt);
914  if (idx<0) {
915  DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
917  return (int) idx;
918  }
919  } /* for */
920 
921  plCopy=GWEN_SimplePtrList_LazyCopy(pl);
922  if (plCopy==NULL) {
923  DBG_ERROR(GWEN_LOGDOMAIN, "Could not copy pointer list");
924  GWEN_SimplePtrList_free(plCopy);
926  return GWEN_ERROR_INVALID;
927  }
928 
929  if (!(plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_ATTACHTOOBJECTS)) {
931  "Invalid object field in list: flags (should have set GWEN_SIMPLEPTRLIST_FLAGS_ATTACHTOOBJECTS)");
932  GWEN_SimplePtrList_free(plCopy);
934  return GWEN_ERROR_GENERIC;
935  }
936 
937  if (!(plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_DETACHFROMOBJECTS)) {
939  "Invalid object field in list: flags (should have set GWEN_SIMPLEPTRLIST_FLAGS_DETACHFROMOBJECTS)");
940  GWEN_SimplePtrList_free(plCopy);
942  return GWEN_ERROR_GENERIC;
943  }
944 
945 
946  if (1) {
947  TEST_TYPE *tt;
948  int rv;
949 
950  tt=createTestType(1024);
951  TestType_List_Add(tt, ttList);
952  rv=GWEN_SimplePtrList_SetPtrAt(plCopy, 100, tt);
953  if (rv<0) {
954  DBG_ERROR(GWEN_LOGDOMAIN, "Error setting pointer %d in list: %s (%d)", 100, GWEN_Error_SimpleToString(rv), rv);
955  GWEN_SimplePtrList_free(plCopy);
957  return rv;
958  }
959  }
960 
961 
962  for (i=0; i<1024; i++) {
963  TEST_TYPE *tt;
964  int rv;
965 
966  tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(plCopy, i);
967  if (tt==NULL) {
968  DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
969  TestType_List_free(ttList);
970  GWEN_SimplePtrList_free(plCopy);
972  return GWEN_ERROR_GENERIC;
973  }
974 
975  rv=TestType_TestHash(tt);
976  if (rv<0) {
977  DBG_ERROR(GWEN_LOGDOMAIN, "Error testing hash of object %d: %s (%d)", i, GWEN_Error_SimpleToString(rv), rv);
978  TestType_List_free(ttList);
979  GWEN_SimplePtrList_free(plCopy);
981  return rv;
982  }
983  } /* for */
984 
985 
986  if (1) {
987  TEST_TYPE *tt;
988  int cnt=0;
989 
990  tt=TestType_List_First(ttList);
991  while (tt) {
992  if (cnt==1024 || cnt==100) {
993  if (tt->_refCounter!=2) {
994  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object %d is not 2 (%d)", cnt, tt->_refCounter);
995  TestType_List_free(ttList);
996  GWEN_SimplePtrList_free(plCopy);
998  return GWEN_ERROR_GENERIC;
999  }
1000  }
1001  else {
1002  if (tt->_refCounter!=3) {
1003  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object %d is not 3 (%d)", cnt, tt->_refCounter);
1004  TestType_List_free(ttList);
1005  GWEN_SimplePtrList_free(plCopy);
1007  return GWEN_ERROR_GENERIC;
1008  }
1009  }
1010  cnt++;
1011  tt=TestType_List_Next(tt);
1012  }
1013  if (cnt!=1025) {
1014  DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
1015  }
1016  }
1017 
1018  if (1) {
1019  TEST_TYPE *tt1;
1020  TEST_TYPE *tt2;
1021 
1022  tt1=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(plCopy, 100);
1023  tt2=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(pl, 100);
1024  if (!(tt1 && tt2 && tt1!=tt2)) {
1025  DBG_ERROR(GWEN_LOGDOMAIN, "Pointers 100 are unexpectedly equal in both lists");
1026  TestType_List_free(ttList);
1027  GWEN_SimplePtrList_free(plCopy);
1029  return GWEN_ERROR_GENERIC;
1030  }
1031 
1032  if (tt1->_refCounter!=2) {
1033  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter in copy list object 100 is not 2 (%d)", tt1->_refCounter);
1034  TestType_List_free(ttList);
1035  GWEN_SimplePtrList_free(plCopy);
1037  return GWEN_ERROR_GENERIC;
1038  }
1039  }
1040 
1041  GWEN_SimplePtrList_free(plCopy);
1043  TestType_List_free(ttList);
1044 
1045  return 0;
1046 }
1047 
1048 
1049 
1050 
1051 
1052 
1053 
1054 #else
1055 
1057 {
1058  DBG_ERROR(GWEN_LOGDOMAIN, "Gwenhywfar was compiled without test code enabled.");
1059  return GWEN_ERROR_GENERIC;
1060 }
1061 
1062 
1063 #endif
1064 
1065 
void * GWEN_SimplePtrList_GetPtrAt(const GWEN_SIMPLEPTRLIST *pl, uint64_t idx)
int test5(int argc, char **argv)
int test3(int argc, char **argv)
Definition: libtest.m:204
void GWEN_MDigest_free(GWEN_MDIGEST *md)
Definition: mdigest.c:54
#define GWEN_ERROR_INVALID
Definition: error.h:67
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
int test6(int argc, char **argv)
int GWEN_MDigest_Digest(GWEN_MDIGEST *md, const uint8_t *srcBuf, unsigned int srcLen, uint8_t *dstBuf, unsigned int dstLen)
Definition: mdigest.c:165
int GWEN_SimplePtrList_AddTests(GWEN_TEST_MODULE *mod)
#define GWEN_LOGDOMAIN
Definition: logger.h:35
#define GWEN_LIST_FUNCTION_DEFS(t, pr)
Definition: list1.h:357
int test2(int argc, char **argv)
GWEN_TEST_MODULE * GWEN_Test_Module_AddTest(GWEN_TEST_MODULE *st, const char *tName, GWEN_TEST_MODULE_TEST_FN fn, const char *tDescr)
Definition: testmodule.c:424
int GWEN_SimplePtrList_SetPtrAt(GWEN_SIMPLEPTRLIST *pl, uint64_t idx, void *p)
#define GWEN_LIST_ELEMENT(t)
Definition: list1.h:255
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
GWENHYWFAR_API GWEN_MDIGEST * GWEN_MDigest_Rmd160_new(void)
Definition: mdigestgc.c:158
#define GWENHYWFAR_CB
Definition: gwenhywfarapi.h:89
GWEN_SIMPLEPTRLIST * GWEN_SimplePtrList_LazyCopy(GWEN_SIMPLEPTRLIST *oldList)
Definition: simpleptrlist.c:88
struct GWEN_TEST_MODULE GWEN_TEST_MODULE
Definition: testmodule.h:65
#define GWEN_ERROR_GENERIC
Definition: error.h:62
struct GWEN_MDIGEST GWEN_MDIGEST
Definition: mdigest.h:25
struct GWEN_SIMPLEPTRLIST GWEN_SIMPLEPTRLIST
Definition: simpleptrlist.h:39
#define GWEN_SIMPLEPTRLIST_FLAGS_ATTACHTOOBJECTS
Definition: simpleptrlist.h:34
int test1()
Definition: libtest.m:63
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
void GWEN_SimplePtrList_AddFlags(GWEN_SIMPLEPTRLIST *pl, uint32_t f)
GWEN_SIMPLEPTRLIST * GWEN_SimplePtrList_new(uint64_t startEntries, uint64_t steps)
Definition: simpleptrlist.c:71
int test4(int argc, char **argv)
GWEN_SIMPLEPTRLIST_FREEOBJECT_FN GWEN_SimplePtrList_SetFreeObjectFn(GWEN_SIMPLEPTRLIST *pl, GWEN_SIMPLEPTRLIST_FREEOBJECT_FN fn)
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:178
#define GWEN_LIST_INIT(t, element)
Definition: list1.h:465
GWEN_SIMPLEPTRLIST_ATTACHOBJECT_FN GWEN_SimplePtrList_SetAttachObjectFn(GWEN_SIMPLEPTRLIST *pl, GWEN_SIMPLEPTRLIST_ATTACHOBJECT_FN fn)
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition: list1.h:366
GWEN_TEST_MODULE * GWEN_Test_Module_AddModule(GWEN_TEST_MODULE *st, const char *tName, const char *tDescr)
Definition: testmodule.c:440
int64_t GWEN_SimplePtrList_AddPtr(GWEN_SIMPLEPTRLIST *pl, void *p)
#define GWEN_SIMPLEPTRLIST_FLAGS_DETACHFROMOBJECTS
Definition: simpleptrlist.h:35
#define GWEN_LIST_FINI(t, element)
Definition: list1.h:474
#define GWEN_UNUSED
void GWEN_SimplePtrList_free(GWEN_SIMPLEPTRLIST *pl)
const char * GWEN_Error_SimpleToString(int i)
Returns a (very) short string describing the given GWEN error code, or "Unknown error" for unknown co...
Definition: error.c:95