gwenhywfar  5.10.1
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 #include <gwenhywfar/testframework.h>
30 #include "simpleptrlist-t.h"
31 
32 
33 #ifdef GWENHYWFAR_ENABLE_TESTCODE
34 
35 
36 #include <gwenhywfar/mdigest.h>
37 #include <string.h>
38 
39 
40 
41 
42 /* ------------------------------------------------------------------------------------------------
43  * type definitions
44  * ------------------------------------------------------------------------------------------------
45  */
46 
47 typedef struct TEST_TYPE TEST_TYPE;
48 GWEN_LIST_FUNCTION_DEFS(TEST_TYPE, TestType)
49 struct TEST_TYPE {
50  GWEN_LIST_ELEMENT(TEST_TYPE)
51  int _refCounter;
52  int testPosition;
53  char *testStringPtr;
54  uint8_t testHash[20];
55 };
56 
57 
58 
59 /* ------------------------------------------------------------------------------------------------
60  * forward declarations
61  * ------------------------------------------------------------------------------------------------
62  */
63 
64 
65 static TEST_TYPE *TestType_new(const char *s, int pos);
66 static void TestType_Attach(TEST_TYPE *tt);
67 static void TestType_free(TEST_TYPE *tt);
68 
69 static int TestType_CalcHash(TEST_TYPE *tt);
70 static int TestType_TestHash(const TEST_TYPE *tt);
71 
72 static GWENHYWFAR_CB void _attachToTestType(GWEN_SIMPLEPTRLIST *pl, void *p);
73 static GWENHYWFAR_CB void _detachFromTestType(GWEN_SIMPLEPTRLIST *pl, void *p);
74 
75 
76 static int GWENHYWFAR_CB test1(GWEN_TEST_MODULE *mod);
77 static int GWENHYWFAR_CB test2(GWEN_TEST_MODULE *mod);
78 static int GWENHYWFAR_CB test3(GWEN_TEST_MODULE *mod);
79 static int GWENHYWFAR_CB test4(GWEN_TEST_MODULE *mod);
80 static int GWENHYWFAR_CB test5(GWEN_TEST_MODULE *mod);
81 static int GWENHYWFAR_CB test6(GWEN_TEST_MODULE *mod);
82 
83 static TEST_TYPE *createTestType(int num);
84 static void dumpTestTypeList(TEST_TYPE_LIST *ttList);
85 
86 
87 
88 /* ------------------------------------------------------------------------------------------------
89  * implementations
90  * ------------------------------------------------------------------------------------------------
91  */
92 
93 
95 {
96  GWEN_TEST_MODULE *newMod;
97 
98  newMod=GWEN_Test_Module_AddModule(mod, "GWEN_SimplePtrList", NULL);
99 
100  GWEN_Test_Module_AddTest(newMod, "test1", test1, NULL);
101  GWEN_Test_Module_AddTest(newMod, "test2", test2, NULL);
102  GWEN_Test_Module_AddTest(newMod, "test3", test3, NULL);
103  GWEN_Test_Module_AddTest(newMod, "test4", test4, NULL);
104  GWEN_Test_Module_AddTest(newMod, "test5", test5, NULL);
105  GWEN_Test_Module_AddTest(newMod, "test6", test6, NULL);
106 
107  return 0;
108 }
109 
110 
111 
112 GWEN_LIST_FUNCTIONS(TEST_TYPE, TestType)
113 
114 
115 
116 
117 TEST_TYPE *TestType_new(const char *s, int pos)
118 {
119  TEST_TYPE *tt;
120 
121  GWEN_NEW_OBJECT(TEST_TYPE, tt);
122  tt->_refCounter=1;
123  GWEN_LIST_INIT(TEST_TYPE, tt);
124  if (s)
125  tt->testStringPtr=strdup(s);
126  tt->testPosition=pos;
127  return tt;
128 }
129 
130 
131 
132 void TestType_Attach(TEST_TYPE *tt)
133 {
134  assert(tt);
135  assert(tt->_refCounter);
136 
137  if (tt && tt->_refCounter) {
138  tt->_refCounter++;
139  /*DBG_ERROR(GWEN_LOGDOMAIN, "Attached (%d: refcount=%d)", tt->testPosition, tt->_refCounter);*/
140  }
141  else {
142  DBG_ERROR(GWEN_LOGDOMAIN, "NULL pointer or already freed");
143  }
144 }
145 
146 
147 
148 void TestType_free(TEST_TYPE *tt)
149 {
150  if (tt && tt->_refCounter) {
151  /*DBG_ERROR(GWEN_LOGDOMAIN, "Detaching (%d: refcount=%d)", tt->testPosition, tt->_refCounter);*/
152  if (tt->_refCounter==1) {
153  GWEN_LIST_FINI(TEST_TYPE, tt);
154  if (tt->testStringPtr)
155  free(tt->testStringPtr);
156  tt->_refCounter=0;
157  GWEN_FREE_OBJECT(tt);
158  }
159  else
160  tt->_refCounter--;
161  }
162 }
163 
164 
165 
166 int TestType_CalcHash(TEST_TYPE *tt)
167 {
168  if (tt->testStringPtr && *(tt->testStringPtr)) {
169  GWEN_MDIGEST *md;
170  int rv;
171 
173  rv=GWEN_MDigest_Digest(md,
174  (const uint8_t *)tt->testStringPtr, strlen(tt->testStringPtr),
175  tt->testHash, sizeof(tt->testHash));
176  if (rv<0) {
177  DBG_ERROR(GWEN_LOGDOMAIN, "Error on GWEN_MDigest_Begin: %s (%d)", GWEN_Error_SimpleToString(rv), rv);
178  GWEN_MDigest_free(md);
179  return rv;
180  }
181  GWEN_MDigest_free(md);
182  }
183  return 0;
184 }
185 
186 
187 
188 int TestType_TestHash(const TEST_TYPE *tt)
189 {
190  if (tt->testStringPtr && *(tt->testStringPtr)) {
191  GWEN_MDIGEST *md;
192  uint8_t hash[20];
193  int rv;
194 
196  rv=GWEN_MDigest_Digest(md,
197  (const uint8_t *)tt->testStringPtr, strlen(tt->testStringPtr),
198  hash, sizeof(hash));
199  if (rv<0) {
200  DBG_ERROR(GWEN_LOGDOMAIN, "Error on GWEN_MDigest_Digest: %s (%d)", GWEN_Error_SimpleToString(rv), rv);
201  GWEN_MDigest_free(md);
202  return rv;
203  }
204  GWEN_MDigest_free(md);
205 
206  if (memcmp(hash, tt->testHash, sizeof(hash))!=0) {
207  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid hash, object was modified.");
208  return GWEN_ERROR_GENERIC;
209  }
210  }
211  return 0;
212 }
213 
214 
215 
216 TEST_TYPE *createTestType(int num)
217 {
218  TEST_TYPE *tt;
219  char testString[256];
220  int rv;
221 
222  snprintf(testString, sizeof(testString), "This is test string number %d", num);
223  tt=TestType_new(testString, num);
224  if (tt==NULL) {
225  DBG_ERROR(GWEN_LOGDOMAIN, "Could not create test object %d", num);
226  return NULL;
227  }
228  rv=TestType_CalcHash(tt);
229  if (rv<0) {
230  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
231  TestType_free(tt);
232  return NULL;
233  }
234  return tt;
235 }
236 
237 
238 
239 void _attachToTestType(GWEN_UNUSED GWEN_SIMPLEPTRLIST *pl, void *p)
240 {
241  TEST_TYPE *tt;
242 
243  tt=(TEST_TYPE *) p;
244  TestType_Attach(tt);
245 }
246 
247 
248 
249 void _detachFromTestType(GWEN_UNUSED GWEN_SIMPLEPTRLIST *pl, void *p)
250 {
251  TEST_TYPE *tt;
252 
253  tt=(TEST_TYPE *) p;
254  TestType_free(tt);
255 }
256 
257 
258 
259 void dumpTestTypeList(TEST_TYPE_LIST *ttList)
260 {
261  TEST_TYPE *tt;
262 
263  tt=TestType_List_First(ttList);
264  while (tt) {
265  fprintf(stderr, "%5d: %3d: %s\n", tt->testPosition, tt->_refCounter, tt->testStringPtr);
266  tt=TestType_List_Next(tt);
267  }
268 }
269 
270 
271 
272 /* ------------------------------------------------------------------------------------------------
273  * test 1: test struct members after construction
274  * ------------------------------------------------------------------------------------------------
275  */
276 
278 {
279  GWEN_SIMPLEPTRLIST *pl;
280  int i;
281 
282  pl=GWEN_SimplePtrList_new(128, 128);
283  if (pl==NULL) {
284  DBG_ERROR(GWEN_LOGDOMAIN, "Could not create pointer list");
285  return GWEN_ERROR_GENERIC;
286  }
287 
288  if (pl->refCount!=1) {
289  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: refCounter");
291  return GWEN_ERROR_GENERIC;
292  }
293 
294  if (pl->maxEntries!=128) {
295  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: maxEntries");
297  return GWEN_ERROR_GENERIC;
298  }
299 
300  if (pl->usedEntries!=0) {
301  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: usedEntries");
303  return GWEN_ERROR_GENERIC;
304  }
305 
306  if (pl->steps!=128) {
307  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: steps");
309  return GWEN_ERROR_GENERIC;
310  }
311 
312 
313  if (pl->entryList->refCounter!=1) {
314  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid internal object field: refCounter");
316  return GWEN_ERROR_GENERIC;
317  }
318 
319  if (pl->entryList->storedEntries!=128) {
320  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid internal object field: storedEntries");
322  return GWEN_ERROR_GENERIC;
323  }
324 
325 
326  for (i=0; i<128; i++) {
327  if (pl->entryList->entries[i]!=NULL) {
328  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object entry: idx %d is not NULL", i);
330  return GWEN_ERROR_GENERIC;
331  }
332  }
333 
334 
336  return 0;
337 }
338 
339 
340 
341 /* ------------------------------------------------------------------------------------------------
342  * test 2: test adding pointers
343  * ------------------------------------------------------------------------------------------------
344  */
345 
347 {
348 
349  GWEN_SIMPLEPTRLIST *pl;
350  int i;
351 
352  pl=GWEN_SimplePtrList_new(128, 128);
353  for (i=0; i<1024; i++) {
354  TEST_TYPE *tt;
355  int64_t idx;
356 
357  tt=createTestType(i);
358  idx=GWEN_SimplePtrList_AddPtr(pl, tt);
359  if (idx<0) {
360  DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
362  return (int) idx;
363  }
364  } /* for */
365 
366  if (pl->maxEntries!=1024) {
367  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: maxEntries");
369  return GWEN_ERROR_GENERIC;
370  }
371 
372  if (pl->usedEntries!=1024) {
373  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: usedEntries");
375  return GWEN_ERROR_GENERIC;
376  }
377 
378  for (i=0; i<1024; i++) {
379  TEST_TYPE *tt;
380  int rv;
381 
382  tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(pl, i);
383  if (tt==NULL) {
384  DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
386  return GWEN_ERROR_GENERIC;
387  }
388 
389  rv=TestType_TestHash(tt);
390  if (rv<0) {
391  DBG_ERROR(GWEN_LOGDOMAIN, "Error testing hash of object %d: %s (%d)", i, GWEN_Error_SimpleToString(rv), rv);
393  return rv;
394  }
395  } /* for */
396 
397  /* free all objects */
398  for (i=0; i<1024; i++) {
399  TEST_TYPE *tt;
400 
401  tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(pl, i);
402  if (tt==NULL) {
403  DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
405  return GWEN_ERROR_GENERIC;
406  }
408  TestType_free(tt);
409  } /* for */
410 
412  return 0;
413 }
414 
415 
416 
417 /* ------------------------------------------------------------------------------------------------
418  * test 3: test lazy copying
419  * ------------------------------------------------------------------------------------------------
420  */
421 
423 {
424 
425  GWEN_SIMPLEPTRLIST *pl;
426  GWEN_SIMPLEPTRLIST *plCopy;
427  int i;
428 
429  pl=GWEN_SimplePtrList_new(128, 128);
430  for (i=0; i<1000; i++) {
431  TEST_TYPE *tt;
432  int64_t idx;
433 
434  tt=createTestType(i);
435  idx=GWEN_SimplePtrList_AddPtr(pl, tt);
436  if (idx<0) {
437  DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
439  return (int) idx;
440  }
441  } /* for */
442 
443  plCopy=GWEN_SimplePtrList_LazyCopy(pl);
444  if (plCopy==NULL) {
445  DBG_ERROR(GWEN_LOGDOMAIN, "Could not copy pointer list");
446  GWEN_SimplePtrList_free(plCopy);
448  return GWEN_ERROR_INVALID;
449  }
450 
451  if (!(plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE)) {
452  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: flags");
453  GWEN_SimplePtrList_free(plCopy);
455  return GWEN_ERROR_GENERIC;
456  }
457 
458  if (!(pl->flags & GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE)) {
459  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field in old list: flags");
460  GWEN_SimplePtrList_free(plCopy);
462  return GWEN_ERROR_GENERIC;
463  }
464 
465  if (plCopy->entryList != pl->entryList) {
466  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: entryList (should be the same after lazy copy)");
467  GWEN_SimplePtrList_free(plCopy);
469  return GWEN_ERROR_GENERIC;
470  }
471 
472  if (pl->entryList->refCounter!=2) {
473  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid internal object field: refCounter (should be 2)");
475  return GWEN_ERROR_GENERIC;
476  }
477 
478  for (i=1000; i<1024; i++) {
479  TEST_TYPE *tt;
480  int64_t idx;
481 
482  tt=createTestType(i);
483  idx=GWEN_SimplePtrList_AddPtr(plCopy, tt);
484  if (idx<0) {
485  DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
486  GWEN_SimplePtrList_free(plCopy);
488  return (int) idx;
489  }
490  } /* for */
491 
492  if (plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE) {
493  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: flags (should have cleared GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE)");
494  GWEN_SimplePtrList_free(plCopy);
496  return GWEN_ERROR_GENERIC;
497  }
498 
499  if (!(pl->flags & GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE)) {
501  "Invalid object field in old list: flags (should not have cleared GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE)");
502  GWEN_SimplePtrList_free(plCopy);
504  return GWEN_ERROR_GENERIC;
505  }
506 
507  if (plCopy->entryList == pl->entryList) {
508  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: entryList (should have changed)");
509  GWEN_SimplePtrList_free(plCopy);
511  return GWEN_ERROR_GENERIC;
512  }
513 
514  if (pl->entryList->refCounter!=1) {
515  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid internal object field: refCounter (should be back to 1)");
517  return GWEN_ERROR_GENERIC;
518  }
519 
520  if (plCopy->entryList->refCounter!=1) {
521  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid internal object field: refCounter (should be 1)");
523  return GWEN_ERROR_GENERIC;
524  }
525 
526  if (plCopy->maxEntries!=1024+128) {
527  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: maxEntries (should be 1152)");
529  return GWEN_ERROR_GENERIC;
530  }
531 
532  if (plCopy->usedEntries!=1024) {
533  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: usedEntries");
535  return GWEN_ERROR_GENERIC;
536  }
537 
538  if (pl->maxEntries!=1024) {
539  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: maxEntries (should still be 1024)");
541  return GWEN_ERROR_GENERIC;
542  }
543 
544  if (pl->usedEntries!=1000) {
545  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: usedEntries (should still be 1000)");
547  return GWEN_ERROR_GENERIC;
548  }
549 
550 
551  for (i=0; i<1024; i++) {
552  TEST_TYPE *tt;
553  int rv;
554 
555  tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(plCopy, i);
556  if (tt==NULL) {
557  DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
558  GWEN_SimplePtrList_free(plCopy);
560  return GWEN_ERROR_GENERIC;
561  }
562 
563  rv=TestType_TestHash(tt);
564  if (rv<0) {
565  DBG_ERROR(GWEN_LOGDOMAIN, "Error testing hash of object %d: %s (%d)", i, GWEN_Error_SimpleToString(rv), rv);
566  GWEN_SimplePtrList_free(plCopy);
568  return rv;
569  }
570  } /* for */
571 
572  /* free all objects */
573  for (i=0; i<1024; i++) {
574  TEST_TYPE *tt;
575 
576  tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(plCopy, i);
577  if (tt==NULL) {
578  DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
579  GWEN_SimplePtrList_free(plCopy);
581  return GWEN_ERROR_GENERIC;
582  }
583  GWEN_SimplePtrList_SetPtrAt(plCopy, i, NULL);
584  TestType_free(tt);
585  } /* for */
586 
587 
588  GWEN_SimplePtrList_free(plCopy);
590  return 0;
591 }
592 
593 
594 
595 /* ------------------------------------------------------------------------------------------------
596  * test 4: test adding pointers with attach/detach
597  * ------------------------------------------------------------------------------------------------
598  */
599 
601 {
602 
603  GWEN_SIMPLEPTRLIST *pl;
604  TEST_TYPE_LIST *ttList;
605  int i;
606 
607  pl=GWEN_SimplePtrList_new(128, 128);
608  GWEN_SimplePtrList_SetAttachObjectFn(pl, _attachToTestType);
609  GWEN_SimplePtrList_SetFreeObjectFn(pl, _detachFromTestType);
612 
613  ttList=TestType_List_new();
614 
615  for (i=0; i<1024; i++) {
616  TEST_TYPE *tt;
617  int64_t idx;
618 
619  tt=createTestType(i);
620  TestType_List_Add(tt, ttList);
621 
622  idx=GWEN_SimplePtrList_AddPtr(pl, tt);
623  if (idx<0) {
624  DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
626  return (int) idx;
627  }
628  } /* for */
629 
630  if (1) {
631  TEST_TYPE *tt;
632  int cnt=0;
633 
634  tt=TestType_List_First(ttList);
635  while (tt) {
636  if (tt->_refCounter!=2) {
637  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 2");
638  TestType_List_free(ttList);
640  return GWEN_ERROR_GENERIC;
641  }
642  cnt++;
643  tt=TestType_List_Next(tt);
644  }
645  if (cnt!=1024) {
646  DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
647  }
648  }
649 
650  for (i=0; i<1024; i++) {
651  TEST_TYPE *tt;
652  int rv;
653 
654  tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(pl, i);
655  if (tt==NULL) {
656  DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
657  TestType_List_free(ttList);
659  return GWEN_ERROR_GENERIC;
660  }
661 
662  rv=TestType_TestHash(tt);
663  if (rv<0) {
664  DBG_ERROR(GWEN_LOGDOMAIN, "Error testing hash of object %d: %s (%d)", i, GWEN_Error_SimpleToString(rv), rv);
665  TestType_List_free(ttList);
667  return rv;
668  }
669  } /* for */
670 
672 
673  if (1) {
674  TEST_TYPE *tt;
675  int cnt=0;
676 
677  tt=TestType_List_First(ttList);
678  while (tt) {
679  if (tt->_refCounter!=1) {
680  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 1");
681  TestType_List_free(ttList);
682  return GWEN_ERROR_GENERIC;
683  }
684  cnt++;
685  tt=TestType_List_Next(tt);
686  }
687  if (cnt!=1024) {
688  DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
689  }
690  }
691 
692  TestType_List_free(ttList);
693 
694  return 0;
695 }
696 
697 
698 
699 /* ------------------------------------------------------------------------------------------------
700  * test 5: test lazy copying with attach/detach
701  * ------------------------------------------------------------------------------------------------
702  */
703 
705 {
706 
707  GWEN_SIMPLEPTRLIST *pl;
708  GWEN_SIMPLEPTRLIST *plCopy;
709  TEST_TYPE_LIST *ttList;
710  int i;
711 
712  pl=GWEN_SimplePtrList_new(128, 128);
713  GWEN_SimplePtrList_SetAttachObjectFn(pl, _attachToTestType);
714  GWEN_SimplePtrList_SetFreeObjectFn(pl, _detachFromTestType);
717 
718  ttList=TestType_List_new();
719  for (i=0; i<1000; i++) {
720  TEST_TYPE *tt;
721  int64_t idx;
722 
723  tt=createTestType(i);
724  TestType_List_Add(tt, ttList);
725  idx=GWEN_SimplePtrList_AddPtr(pl, tt);
726  if (idx<0) {
727  DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
729  return (int) idx;
730  }
731  } /* for */
732 
733  plCopy=GWEN_SimplePtrList_LazyCopy(pl);
734  if (plCopy==NULL) {
735  DBG_ERROR(GWEN_LOGDOMAIN, "Could not copy pointer list");
736  GWEN_SimplePtrList_free(plCopy);
738  return GWEN_ERROR_INVALID;
739  }
740 
741  if (!(plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_ATTACHTOOBJECTS)) {
743  "Invalid object field in list: flags (should have set GWEN_SIMPLEPTRLIST_FLAGS_ATTACHTOOBJECTS)");
744  GWEN_SimplePtrList_free(plCopy);
746  return GWEN_ERROR_GENERIC;
747  }
748 
749  if (!(plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_DETACHFROMOBJECTS)) {
751  "Invalid object field in list: flags (should have set GWEN_SIMPLEPTRLIST_FLAGS_DETACHFROMOBJECTS)");
752  GWEN_SimplePtrList_free(plCopy);
754  return GWEN_ERROR_GENERIC;
755  }
756 
757 
758  for (i=1000; i<1024; i++) {
759  TEST_TYPE *tt;
760  int64_t idx;
761 
762  tt=createTestType(i);
763  TestType_List_Add(tt, ttList);
764  idx=GWEN_SimplePtrList_AddPtr(plCopy, tt);
765  if (idx<0) {
766  DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
767  GWEN_SimplePtrList_free(plCopy);
769  return (int) idx;
770  }
771  } /* for */
772 
773 
774  for (i=0; i<1024; i++) {
775  TEST_TYPE *tt;
776  int rv;
777 
778  tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(plCopy, i);
779  if (tt==NULL) {
780  DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
781  TestType_List_free(ttList);
782  GWEN_SimplePtrList_free(plCopy);
784  return GWEN_ERROR_GENERIC;
785  }
786 
787  rv=TestType_TestHash(tt);
788  if (rv<0) {
789  DBG_ERROR(GWEN_LOGDOMAIN, "Error testing hash of object %d: %s (%d)", i, GWEN_Error_SimpleToString(rv), rv);
790  TestType_List_free(ttList);
791  GWEN_SimplePtrList_free(plCopy);
793  return rv;
794  }
795  } /* for */
796 
797 
798  if (1) {
799  TEST_TYPE *tt;
800  int cnt=0;
801 
802  tt=TestType_List_First(ttList);
803  while (tt) {
804  if (cnt<1000) {
805  if (tt->_refCounter!=3) {
806  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object %d is not 3 (%d)", cnt, tt->_refCounter);
807  dumpTestTypeList(ttList);
808  TestType_List_free(ttList);
810  return GWEN_ERROR_GENERIC;
811  }
812  }
813  else {
814  if (tt->_refCounter!=2) {
815  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 2");
816  TestType_List_free(ttList);
818  return GWEN_ERROR_GENERIC;
819  }
820  }
821  cnt++;
822  tt=TestType_List_Next(tt);
823  }
824  if (cnt!=1024) {
825  DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
826  }
827  }
828 
829 
830  GWEN_SimplePtrList_free(plCopy);
831 
832  if (1) {
833  TEST_TYPE *tt;
834  int cnt=0;
835 
836  tt=TestType_List_First(ttList);
837  while (tt) {
838  if (cnt<1000) {
839  if (tt->_refCounter!=2) {
840  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 2");
841  TestType_List_free(ttList);
843  return GWEN_ERROR_GENERIC;
844  }
845  }
846  else {
847  if (tt->_refCounter!=1) {
848  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 1");
849  TestType_List_free(ttList);
851  return GWEN_ERROR_GENERIC;
852  }
853  }
854  cnt++;
855  tt=TestType_List_Next(tt);
856  }
857  if (cnt!=1024) {
858  DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
859  }
860  }
861 
862 
864 
865  if (1) {
866  TEST_TYPE *tt;
867  int cnt=0;
868 
869  tt=TestType_List_First(ttList);
870  while (tt) {
871  if (tt->_refCounter!=1) {
872  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 1");
873  TestType_List_free(ttList);
875  return GWEN_ERROR_GENERIC;
876  }
877  cnt++;
878  tt=TestType_List_Next(tt);
879  }
880  if (cnt!=1024) {
881  DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
882  }
883  }
884 
885  TestType_List_free(ttList);
886 
887  return 0;
888 }
889 
890 
891 
892 /* ------------------------------------------------------------------------------------------------
893  * test 6: test lazy copying with attach/detach and setPtr
894  * ------------------------------------------------------------------------------------------------
895  */
896 
898 {
899 
900  GWEN_SIMPLEPTRLIST *pl;
901  GWEN_SIMPLEPTRLIST *plCopy;
902  TEST_TYPE_LIST *ttList;
903  int i;
904 
905  pl=GWEN_SimplePtrList_new(128, 128);
906  GWEN_SimplePtrList_SetAttachObjectFn(pl, _attachToTestType);
907  GWEN_SimplePtrList_SetFreeObjectFn(pl, _detachFromTestType);
910 
911  ttList=TestType_List_new();
912  for (i=0; i<1024; i++) {
913  TEST_TYPE *tt;
914  int64_t idx;
915 
916  tt=createTestType(i);
917  TestType_List_Add(tt, ttList);
918  idx=GWEN_SimplePtrList_AddPtr(pl, tt);
919  if (idx<0) {
920  DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
922  return (int) idx;
923  }
924  } /* for */
925 
926  plCopy=GWEN_SimplePtrList_LazyCopy(pl);
927  if (plCopy==NULL) {
928  DBG_ERROR(GWEN_LOGDOMAIN, "Could not copy pointer list");
929  GWEN_SimplePtrList_free(plCopy);
931  return GWEN_ERROR_INVALID;
932  }
933 
934  if (!(plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_ATTACHTOOBJECTS)) {
936  "Invalid object field in list: flags (should have set GWEN_SIMPLEPTRLIST_FLAGS_ATTACHTOOBJECTS)");
937  GWEN_SimplePtrList_free(plCopy);
939  return GWEN_ERROR_GENERIC;
940  }
941 
942  if (!(plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_DETACHFROMOBJECTS)) {
944  "Invalid object field in list: flags (should have set GWEN_SIMPLEPTRLIST_FLAGS_DETACHFROMOBJECTS)");
945  GWEN_SimplePtrList_free(plCopy);
947  return GWEN_ERROR_GENERIC;
948  }
949 
950 
951  if (1) {
952  TEST_TYPE *tt;
953  int rv;
954 
955  tt=createTestType(1024);
956  TestType_List_Add(tt, ttList);
957  rv=GWEN_SimplePtrList_SetPtrAt(plCopy, 100, tt);
958  if (rv<0) {
959  DBG_ERROR(GWEN_LOGDOMAIN, "Error setting pointer %d in list: %s (%d)", 100, GWEN_Error_SimpleToString(rv), rv);
960  GWEN_SimplePtrList_free(plCopy);
962  return rv;
963  }
964  }
965 
966 
967  for (i=0; i<1024; i++) {
968  TEST_TYPE *tt;
969  int rv;
970 
971  tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(plCopy, i);
972  if (tt==NULL) {
973  DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
974  TestType_List_free(ttList);
975  GWEN_SimplePtrList_free(plCopy);
977  return GWEN_ERROR_GENERIC;
978  }
979 
980  rv=TestType_TestHash(tt);
981  if (rv<0) {
982  DBG_ERROR(GWEN_LOGDOMAIN, "Error testing hash of object %d: %s (%d)", i, GWEN_Error_SimpleToString(rv), rv);
983  TestType_List_free(ttList);
984  GWEN_SimplePtrList_free(plCopy);
986  return rv;
987  }
988  } /* for */
989 
990 
991  if (1) {
992  TEST_TYPE *tt;
993  int cnt=0;
994 
995  tt=TestType_List_First(ttList);
996  while (tt) {
997  if (cnt==1024 || cnt==100) {
998  if (tt->_refCounter!=2) {
999  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object %d is not 2 (%d)", cnt, tt->_refCounter);
1000  TestType_List_free(ttList);
1001  GWEN_SimplePtrList_free(plCopy);
1003  return GWEN_ERROR_GENERIC;
1004  }
1005  }
1006  else {
1007  if (tt->_refCounter!=3) {
1008  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object %d is not 3 (%d)", cnt, tt->_refCounter);
1009  TestType_List_free(ttList);
1010  GWEN_SimplePtrList_free(plCopy);
1012  return GWEN_ERROR_GENERIC;
1013  }
1014  }
1015  cnt++;
1016  tt=TestType_List_Next(tt);
1017  }
1018  if (cnt!=1025) {
1019  DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
1020  }
1021  }
1022 
1023  if (1) {
1024  TEST_TYPE *tt1;
1025  TEST_TYPE *tt2;
1026 
1027  tt1=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(plCopy, 100);
1028  tt2=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(pl, 100);
1029  if (!(tt1 && tt2 && tt1!=tt2)) {
1030  DBG_ERROR(GWEN_LOGDOMAIN, "Pointers 100 are unexpectedly equal in both lists");
1031  TestType_List_free(ttList);
1032  GWEN_SimplePtrList_free(plCopy);
1034  return GWEN_ERROR_GENERIC;
1035  }
1036 
1037  if (tt1->_refCounter!=2) {
1038  DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter in copy list object 100 is not 2 (%d)", tt1->_refCounter);
1039  TestType_List_free(ttList);
1040  GWEN_SimplePtrList_free(plCopy);
1042  return GWEN_ERROR_GENERIC;
1043  }
1044  }
1045 
1046  GWEN_SimplePtrList_free(plCopy);
1048  TestType_List_free(ttList);
1049 
1050  return 0;
1051 }
1052 
1053 
1054 
1055 
1056 
1057 
1058 
1059 #else
1060 
1062 {
1063  DBG_ERROR(GWEN_LOGDOMAIN, "Gwenhywfar was compiled without test code enabled.");
1064  return GWEN_ERROR_GENERIC;
1065 }
1066 
1067 
1068 #endif
1069 
1070 
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:38
#define GWEN_SIMPLEPTRLIST_FLAGS_ATTACHTOOBJECTS
Definition: simpleptrlist.h:33
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:181
#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:34
#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