1 /***************************************************************************
2 begin : Sat Nov 15 2003
3 copyright : (C) 2003 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 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29
30 #define DISABLE_DEBUGLOG
31
32
33 #include "list_p.h"
34 #include <gwenhywfar/misc.h>
35 #include <gwenhywfar/debug.h>
36
37
GWEN_INHERIT_FUNCTIONS(GWEN_LIST)38 GWEN_INHERIT_FUNCTIONS(GWEN_LIST)
39
40
41
42 GWEN_LIST_ENTRY *GWEN_ListEntry_new(void)
43 {
44 GWEN_LIST_ENTRY *le;
45
46 GWEN_NEW_OBJECT(GWEN_LIST_ENTRY, le);
47 le->usage=1;
48 return le;
49 }
50
51
52
GWEN_ListEntry_free(GWEN_LIST_ENTRY * le)53 void GWEN_ListEntry_free(GWEN_LIST_ENTRY *le)
54 {
55 if (le) {
56 if (le->usage) {
57 le->usage--;
58 if (le->usage==0) {
59 /* unlink */
60 le->previous=0;
61 le->next=0;
62 DBG_VERBOUS(GWEN_LOGDOMAIN, "Freeing entry");
63 GWEN_RefPtr_free(le->dataPtr);
64 /* really free */
65 GWEN_FREE_OBJECT(le);
66 }
67 }
68 }
69 }
70
71
72
GWEN__ListPtr_new(void)73 GWEN__LISTPTR *GWEN__ListPtr_new(void)
74 {
75 GWEN__LISTPTR *lp;
76
77 GWEN_NEW_OBJECT(GWEN__LISTPTR, lp);
78 lp->refCount=1;
79 return lp;
80 }
81
82
83
GWEN__ListPtr_free(GWEN__LISTPTR * lp)84 void GWEN__ListPtr_free(GWEN__LISTPTR *lp)
85 {
86 if (lp) {
87 assert(lp->refCount);
88 if (--(lp->refCount)==0) {
89 GWEN__ListPtr_Clear(lp);
90 GWEN_FREE_OBJECT(lp);
91 }
92 }
93 }
94
95
96
GWEN__ListPtr_Attach(GWEN__LISTPTR * lp)97 void GWEN__ListPtr_Attach(GWEN__LISTPTR *lp)
98 {
99 assert(lp);
100 assert(lp->refCount);
101 lp->refCount++;
102 }
103
104
105
GWEN__ListPtr_Clear(GWEN__LISTPTR * lp)106 void GWEN__ListPtr_Clear(GWEN__LISTPTR *lp)
107 {
108 GWEN_LIST_ENTRY *le;
109
110 assert(lp);
111 le=lp->first;
112 while (le) {
113 GWEN_LIST_ENTRY *nle;
114
115 nle=le->next;
116 GWEN_ListEntry_free(le);
117 le=nle;
118 } /* while */
119 lp->first=0;
120 lp->last=0;
121 lp->size=0;
122 }
123
124
125
GWEN__ListPtr_dup(GWEN__LISTPTR * lp)126 GWEN__LISTPTR *GWEN__ListPtr_dup(GWEN__LISTPTR *lp)
127 {
128 GWEN__LISTPTR *nlp;
129 GWEN_LIST_ENTRY *le;
130
131 nlp=GWEN__ListPtr_new();
132 assert(lp);
133 le=lp->first;
134 while (le) {
135 GWEN_LIST_ENTRY *nle;
136
137 nle=GWEN_ListEntry_new();
138 if (le->dataPtr)
139 nle->dataPtr=GWEN_RefPtr_dup(le->dataPtr);
140 /* push back */
141 nle->previous=nlp->last;
142 if (nlp->last)
143 nlp->last->next=nle;
144 nlp->last=nle;
145 if (!(nlp->first))
146 nlp->first=nle;
147 nlp->size++;
148 nle->linkCount=le->linkCount;
149
150 le=le->next;
151 } /* while */
152
153 return nlp;
154 }
155
156
157
158
159
160
161
162
GWEN_List_new(void)163 GWEN_LIST *GWEN_List_new(void)
164 {
165 GWEN_LIST *l;
166
167 GWEN_NEW_OBJECT(GWEN_LIST, l);
168 GWEN_INHERIT_INIT(GWEN_LIST, l);
169 l->listPtr=GWEN__ListPtr_new();
170 return l;
171 }
172
173
174
GWEN_List_free(GWEN_LIST * l)175 void GWEN_List_free(GWEN_LIST *l)
176 {
177 if (l) {
178 GWEN_INHERIT_FINI(GWEN_LIST, l);
179 GWEN__ListPtr_free(l->listPtr);
180 GWEN_RefPtrInfo_free(l->refPtrInfo);
181 GWEN_FREE_OBJECT(l);
182 }
183 }
184
185
186
GWEN_List_dup(const GWEN_LIST * l)187 GWEN_LIST *GWEN_List_dup(const GWEN_LIST *l)
188 {
189 GWEN_LIST *nl;
190
191 assert(l);
192 assert(l->listPtr);
193 GWEN_NEW_OBJECT(GWEN_LIST, nl);
194 GWEN_INHERIT_INIT(GWEN_LIST, nl);
195 nl->listPtr=l->listPtr;
196 GWEN__ListPtr_Attach(nl->listPtr);
197 return nl;
198 }
199
200
201
GWEN_List_GetRefPtrInfo(const GWEN_LIST * l)202 GWEN_REFPTR_INFO *GWEN_List_GetRefPtrInfo(const GWEN_LIST *l)
203 {
204 assert(l);
205 return l->refPtrInfo;
206 }
207
208
209
GWEN_List_SetRefPtrInfo(GWEN_LIST * l,GWEN_REFPTR_INFO * rpi)210 void GWEN_List_SetRefPtrInfo(GWEN_LIST *l, GWEN_REFPTR_INFO *rpi)
211 {
212 assert(l);
213 if (rpi)
214 GWEN_RefPtrInfo_Attach(rpi);
215 GWEN_RefPtrInfo_free(l->refPtrInfo);
216 l->refPtrInfo=rpi;
217 }
218
219
220
GWEN_List_PushBackRefPtr(GWEN_LIST * l,GWEN_REFPTR * rp)221 void GWEN_List_PushBackRefPtr(GWEN_LIST *l, GWEN_REFPTR *rp)
222 {
223 GWEN_LIST_ENTRY *le;
224 GWEN__LISTPTR *lp;
225
226 if (l->listPtr->refCount>1) {
227 GWEN__LISTPTR *nlp;
228
229 /* only copy the list if someone else is using it */
230 nlp=GWEN__ListPtr_dup(l->listPtr);
231 GWEN__ListPtr_free(l->listPtr);
232 l->listPtr=nlp;
233 }
234 lp=l->listPtr;
235
236 le=GWEN_ListEntry_new();
237 le->dataPtr=rp;
238 le->previous=lp->last;
239 if (lp->last)
240 lp->last->next=le;
241 lp->last=le;
242 if (!(lp->first))
243 lp->first=le;
244 lp->size++;
245 le->linkCount=1;
246 }
247
248
249
GWEN_List_PushBack(GWEN_LIST * l,void * p)250 void GWEN_List_PushBack(GWEN_LIST *l, void *p)
251 {
252 GWEN_List_PushBackRefPtr(l, GWEN_RefPtr_new(p, l->refPtrInfo));
253 }
254
255
256
GWEN_List_PushFrontRefPtr(GWEN_LIST * l,GWEN_REFPTR * rp)257 void GWEN_List_PushFrontRefPtr(GWEN_LIST *l, GWEN_REFPTR *rp)
258 {
259 GWEN_LIST_ENTRY *le;
260 GWEN__LISTPTR *lp;
261
262 if (l->listPtr->refCount>1) {
263 GWEN__LISTPTR *nlp;
264
265 /* only copy the list if someone else is using it */
266 nlp=GWEN__ListPtr_dup(l->listPtr);
267 GWEN__ListPtr_free(l->listPtr);
268 l->listPtr=nlp;
269 }
270 lp=l->listPtr;
271
272 le=GWEN_ListEntry_new();
273 le->dataPtr=rp;
274 le->next=lp->first;
275 if (lp->first)
276 lp->first->previous=le;
277 lp->first=le;
278 if (!(lp->last))
279 lp->last=le;
280 lp->size++;
281 le->linkCount=1;
282 }
283
284
285
GWEN_List_PushFront(GWEN_LIST * l,void * p)286 void GWEN_List_PushFront(GWEN_LIST *l, void *p)
287 {
288 GWEN_List_PushFrontRefPtr(l, GWEN_RefPtr_new(p, l->refPtrInfo));
289 }
290
291
292
GWEN_List_GetFront(const GWEN_LIST * l)293 void *GWEN_List_GetFront(const GWEN_LIST *l)
294 {
295 assert(l);
296 assert(l->listPtr);
297 if (l->listPtr->first)
298 return GWEN_RefPtr_GetData(l->listPtr->first->dataPtr);
299 return 0;
300 }
301
302
303
GWEN_List_GetFrontRefPtr(const GWEN_LIST * l)304 GWEN_REFPTR *GWEN_List_GetFrontRefPtr(const GWEN_LIST *l)
305 {
306 assert(l);
307 assert(l->listPtr);
308 if (l->listPtr->first)
309 return l->listPtr->first->dataPtr;
310 return 0;
311 }
312
313
314
GWEN_List_GetBack(const GWEN_LIST * l)315 void *GWEN_List_GetBack(const GWEN_LIST *l)
316 {
317 assert(l);
318 assert(l->listPtr);
319 if (l->listPtr->last)
320 return GWEN_RefPtr_GetData(l->listPtr->last->dataPtr);
321 return 0;
322 }
323
324
325
GWEN_List_GetBackRefPtr(const GWEN_LIST * l)326 GWEN_REFPTR *GWEN_List_GetBackRefPtr(const GWEN_LIST *l)
327 {
328 assert(l);
329 assert(l->listPtr);
330 if (l->listPtr->last)
331 return l->listPtr->last->dataPtr;
332 return 0;
333 }
334
335
336
GWEN_List_GetSize(const GWEN_LIST * l)337 unsigned int GWEN_List_GetSize(const GWEN_LIST *l)
338 {
339 assert(l);
340 assert(l->listPtr);
341 return l->listPtr->size;
342 }
343
GWEN_List_IsEmpty(const GWEN_LIST * l)344 int GWEN_List_IsEmpty(const GWEN_LIST *l)
345 {
346 return GWEN_List_GetSize(l) == 0;
347 }
348
349
GWEN_List_PopBack(GWEN_LIST * l)350 void GWEN_List_PopBack(GWEN_LIST *l)
351 {
352 GWEN_LIST_ENTRY *le;
353 GWEN__LISTPTR *lp;
354
355 assert(l);
356 assert(l->listPtr);
357 if (l->listPtr->last==0)
358 return;
359 if (l->listPtr->refCount>1) {
360 GWEN__LISTPTR *nlp;
361
362 /* only copy the list if someone else is using it */
363 nlp=GWEN__ListPtr_dup(l->listPtr);
364 GWEN__ListPtr_free(l->listPtr);
365 l->listPtr=nlp;
366 }
367 lp=l->listPtr;
368
369 le=lp->last;
370 if (le) {
371 le->linkCount=0;
372 lp->last=le->previous;
373 if (le->previous) {
374 le->previous->next=0;
375 }
376 else {
377 lp->last=0;
378 lp->first=0;
379 }
380 GWEN_ListEntry_free(le);
381 lp->size--;
382 }
383 }
384
385
386
GWEN_List_PopFront(GWEN_LIST * l)387 void GWEN_List_PopFront(GWEN_LIST *l)
388 {
389 GWEN_LIST_ENTRY *le;
390 GWEN__LISTPTR *lp;
391
392 assert(l);
393 assert(l->listPtr);
394 if (l->listPtr->first==0)
395 return;
396 if (l->listPtr->refCount>1) {
397 GWEN__LISTPTR *nlp;
398
399 /* only copy the list if someone else is using it */
400 nlp=GWEN__ListPtr_dup(l->listPtr);
401 GWEN__ListPtr_free(l->listPtr);
402 l->listPtr=nlp;
403 }
404 lp=l->listPtr;
405
406 le=lp->first;
407 if (le) {
408 le->linkCount=0;
409 lp->first=le->next;
410 if (le->next) {
411 le->next->previous=0;
412 }
413 else {
414 lp->first=0;
415 lp->last=0;
416 }
417 GWEN_ListEntry_free(le);
418 lp->size--;
419 }
420 }
421
422
423
GWEN_List_Clear(GWEN_LIST * l)424 void GWEN_List_Clear(GWEN_LIST *l)
425 {
426 /* GWEN__LISTPTR *lp; */
427
428 assert(l);
429 if (l->listPtr->refCount>1) {
430 GWEN__LISTPTR *nlp;
431
432 /* only copy the list if someone else is using it */
433 nlp=GWEN__ListPtr_dup(l->listPtr);
434 GWEN__ListPtr_free(l->listPtr);
435 l->listPtr=nlp;
436 }
437 else
438 GWEN__ListPtr_Clear(l->listPtr);
439 }
440
441
442
GWEN_List_ForEach(GWEN_LIST * l,GWEN_LIST_FOREACH_CB fn,void * user_data)443 void *GWEN_List_ForEach(GWEN_LIST *l,
444 GWEN_LIST_FOREACH_CB fn, void *user_data)
445 {
446 GWEN_LIST_ITERATOR *it;
447 void *el;
448 assert(l);
449
450 it=GWEN_List_First(l);
451 if (!it)
452 return 0;
453 el=GWEN_ListIterator_Data(it);
454 while (el) {
455 el=fn(el, user_data);
456 if (el) {
457 GWEN_ListIterator_free(it);
458 return el;
459 }
460 el=GWEN_ListIterator_Next(it);
461 }
462 GWEN_ListIterator_free(it);
463 return 0;
464 }
465
466
467
GWEN_List_Unshare(GWEN_LIST * l)468 void GWEN_List_Unshare(GWEN_LIST *l)
469 {
470 if (l->listPtr->refCount>1) {
471 GWEN__LISTPTR *nlp;
472
473 /* only copy the list if someone else is using it */
474 nlp=GWEN__ListPtr_dup(l->listPtr);
475 GWEN__ListPtr_free(l->listPtr);
476 l->listPtr=nlp;
477 }
478 }
479
480
481
GWEN_List_Erase(GWEN_LIST * l,GWEN_LIST_ITERATOR * it)482 void GWEN_List_Erase(GWEN_LIST *l, GWEN_LIST_ITERATOR *it)
483 {
484 GWEN_LIST_ENTRY *current;
485 GWEN__LISTPTR *lp;
486
487 assert(l);
488 assert(l->listPtr);
489 if (l->listPtr->refCount>1) {
490 GWEN_LIST_ENTRY *tle;
491 GWEN__LISTPTR *nlp;
492 int i;
493
494 /* find the position of the iterator within current list */
495 tle=it->current;
496 assert(tle);
497 i=0;
498 while (tle->previous) {
499 i++;
500 tle=tle->previous;
501 }
502
503 /* copy the list */
504 nlp=GWEN__ListPtr_dup(l->listPtr);
505 GWEN__ListPtr_free(l->listPtr);
506 l->listPtr=nlp;
507
508 /* seek and set the iterator position */
509 tle=l->listPtr->first;
510 assert(tle);
511 while (tle && i--) {
512 tle=tle->next;
513 }
514 assert(tle);
515 it->current=tle;
516 }
517 lp=l->listPtr;
518
519 assert(it);
520 if (it->current) {
521 current=it->current;
522 if (it->current->linkCount==1) {
523 /* unlink from list */
524 if (lp->first==current)
525 lp->first=current->next;
526 if (lp->last==current)
527 lp->last=current->previous;
528
529 /* unlink from next */
530 if (current->next) {
531 it->current=current->next;
532 current->next->usage++;
533 current->next->previous=current->previous;
534 }
535 else
536 it->current=0;
537 /* unlink from previous */
538 if (current->previous)
539 current->previous->next=current->next;
540 /* free */
541 current->usage--;
542 GWEN_ListEntry_free(current);
543 lp->size--;
544 }
545 else {
546 /* move iterator forwards even if the current entry has not
547 * been deleted. Thus making the return condition clear to the
548 * caller.
549 */
550 if (current->next) {
551 it->current=current->next;
552 current->next->usage++;
553 }
554 else
555 it->current=0;
556 current->usage--;
557 it->current->linkCount--;
558 }
559 }
560 }
561
562
563
GWEN_List_FindIter(GWEN_LIST * l,const void * p)564 GWEN_LIST_ITERATOR *GWEN_List_FindIter(GWEN_LIST *l, const void *p)
565 {
566 GWEN_LIST_ITERATOR *li;
567
568 li=GWEN_List_First(l);
569 if (li) {
570 void *d;
571
572 d=GWEN_ListIterator_Data(li);
573 while (d) {
574 if (d==p) {
575 return li;
576 }
577 d=GWEN_ListIterator_Next(li);
578 }
579 GWEN_ListIterator_free(li);
580 }
581 return 0;
582 }
583
584
585
GWEN_List_Contains(GWEN_LIST * l,const void * p)586 const void *GWEN_List_Contains(GWEN_LIST *l, const void *p)
587 {
588 GWEN_LIST_ITERATOR *li;
589
590 li = GWEN_List_FindIter(l, p);
591 if (li) {
592 GWEN_ListIterator_free(li);
593 return p;
594 }
595 return 0;
596 }
597
598
599
GWEN_List_Remove(GWEN_LIST * l,const void * p)600 void GWEN_List_Remove(GWEN_LIST *l, const void *p)
601 {
602 GWEN_LIST_ITERATOR *li;
603
604 li = GWEN_List_FindIter(l, p);
605 if (li) {
606 GWEN_List_Erase(l, li);
607 GWEN_ListIterator_free(li);
608 }
609 }
610
611
612
GWEN_List_First(const GWEN_LIST * l)613 GWEN_LIST_ITERATOR *GWEN_List_First(const GWEN_LIST *l)
614 {
615 GWEN_LIST_ITERATOR *li;
616
617 assert(l);
618 assert(l->listPtr);
619 if (l->listPtr->first==0)
620 return 0;
621 li=GWEN_ListIterator_new(l);
622 li->current=l->listPtr->first;
623 if (li->current) {
624 li->current->usage++;
625 }
626 return li;
627 }
628
629
630
GWEN_List_Last(const GWEN_LIST * l)631 GWEN_LIST_ITERATOR *GWEN_List_Last(const GWEN_LIST *l)
632 {
633 GWEN_LIST_ITERATOR *li;
634
635 assert(l);
636 assert(l->listPtr);
637 if (l->listPtr->last==0)
638 return 0;
639 li=GWEN_ListIterator_new(l);
640 li->current=l->listPtr->last;
641 if (li->current)
642 li->current->usage++;
643 return li;
644 }
645
646
647
GWEN_List_Dump(const GWEN_LIST * l,FILE * f,unsigned int indent)648 void GWEN_List_Dump(const GWEN_LIST *l, FILE *f, unsigned int indent)
649 {
650 GWEN_LIST_ENTRY *le;
651 unsigned int i;
652
653 fprintf(f, "List contains %d entries\n", l->listPtr->size);
654 le=l->listPtr->first;
655 while (le) {
656 for (i=0; i<indent; i++)
657 fprintf(f, " ");
658 fprintf(f, "List entry %p\n", (void *)le);
659 for (i=0; i<indent; i++)
660 fprintf(f, " ");
661 fprintf(f, " Usage : %d\n", le->usage);
662 for (i=0; i<indent; i++)
663 fprintf(f, " ");
664 fprintf(f, " Previous: %p\n", (void *)le->previous);
665 for (i=0; i<indent; i++)
666 fprintf(f, " ");
667 fprintf(f, " Next : %p\n", (void *)le->next);
668 for (i=0; i<indent; i++)
669 fprintf(f, " ");
670 fprintf(f, " Data : %p\n", (void *)GWEN_RefPtr_GetData(le->dataPtr));
671 le=le->next;
672 } /* while */
673 }
674
675
676
677
GWEN_ListIterator_new(const GWEN_LIST * l)678 GWEN_LIST_ITERATOR *GWEN_ListIterator_new(const GWEN_LIST *l)
679 {
680 GWEN_LIST_ITERATOR *li;
681
682 GWEN_NEW_OBJECT(GWEN_LIST_ITERATOR, li);
683 li->list=l;
684 return li;
685 }
686
687
688
GWEN_ListIterator_free(GWEN_LIST_ITERATOR * li)689 void GWEN_ListIterator_free(GWEN_LIST_ITERATOR *li)
690 {
691 if (li) {
692 if (li->current)
693 GWEN_ListEntry_free(li->current);
694 GWEN_FREE_OBJECT(li);
695 }
696 }
697
698
699
GWEN_ListIterator_Previous(GWEN_LIST_ITERATOR * li)700 void *GWEN_ListIterator_Previous(GWEN_LIST_ITERATOR *li)
701 {
702 GWEN_REFPTR *rp;
703
704 assert(li);
705 rp=GWEN_ListIterator_PreviousRefPtr(li);
706 if (!rp)
707 return 0;
708 return GWEN_RefPtr_GetData(rp);
709 }
710
711
712
GWEN_ListIterator_PreviousRefPtr(GWEN_LIST_ITERATOR * li)713 GWEN_REFPTR *GWEN_ListIterator_PreviousRefPtr(GWEN_LIST_ITERATOR *li)
714 {
715 GWEN_LIST_ENTRY *le;
716
717 assert(li);
718
719 le=li->current;
720 if (le)
721 le=le->previous;
722 if (li->current)
723 GWEN_ListEntry_free(li->current);
724 li->current=le;
725 if (le) {
726 le->usage++;
727 return le->dataPtr;
728 }
729 return 0;
730 }
731
732
733
GWEN_ListIterator_Next(GWEN_LIST_ITERATOR * li)734 void *GWEN_ListIterator_Next(GWEN_LIST_ITERATOR *li)
735 {
736 GWEN_REFPTR *rp;
737
738 assert(li);
739 rp=GWEN_ListIterator_NextRefPtr(li);
740 if (!rp)
741 return 0;
742 return GWEN_RefPtr_GetData(rp);
743 }
744
745
746
GWEN_ListIterator_NextRefPtr(GWEN_LIST_ITERATOR * li)747 GWEN_REFPTR *GWEN_ListIterator_NextRefPtr(GWEN_LIST_ITERATOR *li)
748 {
749 GWEN_LIST_ENTRY *le;
750
751 assert(li);
752
753 le=li->current;
754 if (le)
755 le=le->next;
756 if (li->current)
757 GWEN_ListEntry_free(li->current);
758 li->current=le;
759 if (le) {
760 le->usage++;
761 return le->dataPtr;
762 }
763 return 0;
764 }
765
766
767
GWEN_ListIterator_Data(GWEN_LIST_ITERATOR * li)768 void *GWEN_ListIterator_Data(GWEN_LIST_ITERATOR *li)
769 {
770 assert(li);
771
772 if (li->current)
773 return GWEN_RefPtr_GetData(li->current->dataPtr);
774 return 0;
775 }
776
777
778
GWEN_ListIterator_DataRefPtr(GWEN_LIST_ITERATOR * li)779 GWEN_REFPTR *GWEN_ListIterator_DataRefPtr(GWEN_LIST_ITERATOR *li)
780 {
781 assert(li);
782
783 if (li->current)
784 return li->current->dataPtr;
785 return 0;
786 }
787
788
789
GWEN_ListIterator_IncLinkCount(GWEN_LIST_ITERATOR * li)790 void GWEN_ListIterator_IncLinkCount(GWEN_LIST_ITERATOR *li)
791 {
792 assert(li);
793
794 if (li->current)
795 li->current->linkCount++;
796 }
797
798
799
GWEN_ListIterator_GetLinkCount(const GWEN_LIST_ITERATOR * li)800 unsigned int GWEN_ListIterator_GetLinkCount(const GWEN_LIST_ITERATOR *li)
801 {
802 assert(li);
803
804 assert(li->current);
805 return li->current->linkCount;
806 }
807
808
809
810
811
812
813
814
815 /* __________________________________________________________________________
816 * AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
817 * ConstList
818 * YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
819 */
820
821
822
GWEN_ConstList_new(void)823 GWEN_CONSTLIST *GWEN_ConstList_new(void)
824 {
825 return GWEN_List_new();
826 }
827
828
829
GWEN_ConstList_free(GWEN_CONSTLIST * l)830 void GWEN_ConstList_free(GWEN_CONSTLIST *l)
831 {
832 GWEN_List_free(l);
833 }
834
835
836
GWEN_ConstList_PushBack(GWEN_CONSTLIST * l,const void * p)837 void GWEN_ConstList_PushBack(GWEN_CONSTLIST *l, const void *p)
838 {
839 GWEN_List_PushBack(l, (void *)p);
840 }
841
842
843
GWEN_ConstList_PushFront(GWEN_CONSTLIST * l,const void * p)844 void GWEN_ConstList_PushFront(GWEN_CONSTLIST *l, const void *p)
845 {
846 GWEN_List_PushFront(l, (void *)p);
847 }
848
849
850
GWEN_ConstList_GetFront(const GWEN_CONSTLIST * l)851 const void *GWEN_ConstList_GetFront(const GWEN_CONSTLIST *l)
852 {
853 return GWEN_List_GetFront(l);
854 }
855
856
857
GWEN_ConstList_GetBack(const GWEN_CONSTLIST * l)858 const void *GWEN_ConstList_GetBack(const GWEN_CONSTLIST *l)
859 {
860 return GWEN_List_GetBack(l);
861 }
862
863
864
GWEN_ConstList_GetSize(const GWEN_CONSTLIST * l)865 unsigned int GWEN_ConstList_GetSize(const GWEN_CONSTLIST *l)
866 {
867 return GWEN_List_GetSize(l);
868 }
869
GWEN_ConstList_IsEmpty(const GWEN_LIST * l)870 int GWEN_ConstList_IsEmpty(const GWEN_LIST *l)
871 {
872 return GWEN_ConstList_GetSize(l) == 0;
873 }
874
875
876
GWEN_ConstList_PopBack(GWEN_CONSTLIST * l)877 void GWEN_ConstList_PopBack(GWEN_CONSTLIST *l)
878 {
879 GWEN_List_PopBack(l);
880 }
881
882
883
GWEN_ConstList_PopFront(GWEN_CONSTLIST * l)884 void GWEN_ConstList_PopFront(GWEN_CONSTLIST *l)
885 {
886 GWEN_List_PopFront(l);
887 }
888
889
890
GWEN_ConstList_Erase(GWEN_CONSTLIST * l,GWEN_CONSTLIST_ITERATOR * it)891 void GWEN_ConstList_Erase(GWEN_CONSTLIST *l, GWEN_CONSTLIST_ITERATOR *it)
892 {
893 GWEN_List_Erase(l, it);
894 }
895
896
897
GWEN_ConstList_Clear(GWEN_CONSTLIST * l)898 void GWEN_ConstList_Clear(GWEN_CONSTLIST *l)
899 {
900 GWEN_List_Clear(l);
901 }
902
903
GWEN_ConstList_ForEach(GWEN_CONSTLIST * l,GWEN_CONSTLIST_FOREACH_CB fn,void * user_data)904 const void *GWEN_ConstList_ForEach(GWEN_CONSTLIST *l,
905 GWEN_CONSTLIST_FOREACH_CB fn,
906 void *user_data)
907 {
908 GWEN_LIST_ITERATOR *it;
909 const void *el;
910 assert(l);
911
912 it = GWEN_List_First(l);
913 if (!it)
914 return 0;
915 el = GWEN_ListIterator_Data(it);
916 while (el) {
917 el = fn(el, user_data);
918 if (el) {
919 GWEN_ListIterator_free(it);
920 return el;
921 }
922 el = GWEN_ListIterator_Next(it);
923 }
924 GWEN_ListIterator_free(it);
925 return 0;
926 }
927
928
929
GWEN_ConstList_FindIter(const GWEN_CONSTLIST * l,const void * p)930 GWEN_CONSTLIST_ITERATOR *GWEN_ConstList_FindIter(const GWEN_CONSTLIST *l, const void *p)
931 {
932 GWEN_CONSTLIST_ITERATOR *li;
933
934 li=GWEN_ConstList_First(l);
935 if (li) {
936 const void *d;
937
938 d=GWEN_ConstListIterator_Data(li);
939 while (d) {
940 if (d==p) {
941 return li;
942 }
943 d=GWEN_ConstListIterator_Next(li);
944 }
945 GWEN_ConstListIterator_free(li);
946 }
947 return 0;
948 }
949
GWEN_ConstList_Contains(const GWEN_CONSTLIST * l,const void * p)950 const void *GWEN_ConstList_Contains(const GWEN_CONSTLIST *l, const void *p)
951 {
952 GWEN_CONSTLIST_ITERATOR *li;
953
954 li = GWEN_ConstList_FindIter(l, p);
955 if (li) {
956 GWEN_ConstListIterator_free(li);
957 return p;
958 }
959 return 0;
960 }
961
GWEN_ConstList_Remove(GWEN_CONSTLIST * l,const void * p)962 void GWEN_ConstList_Remove(GWEN_CONSTLIST *l, const void *p)
963 {
964 GWEN_CONSTLIST_ITERATOR *li;
965
966 li = GWEN_ConstList_FindIter(l, p);
967 if (li) {
968 GWEN_ConstList_Erase(l, li);
969 }
970 }
971
GWEN_ConstList_First(const GWEN_CONSTLIST * l)972 GWEN_CONSTLIST_ITERATOR *GWEN_ConstList_First(const GWEN_CONSTLIST *l)
973 {
974 return GWEN_List_First(l);
975 }
976
977
978
GWEN_ConstList_Last(const GWEN_CONSTLIST * l)979 GWEN_CONSTLIST_ITERATOR *GWEN_ConstList_Last(const GWEN_CONSTLIST *l)
980 {
981 return GWEN_List_Last(l);
982 }
983
984
985
GWEN_ConstListIterator_new(const GWEN_CONSTLIST * l)986 GWEN_CONSTLIST_ITERATOR *GWEN_ConstListIterator_new(const GWEN_CONSTLIST *l)
987 {
988 return GWEN_ListIterator_new(l);
989 }
990
991
992
GWEN_ConstListIterator_free(GWEN_CONSTLIST_ITERATOR * li)993 void GWEN_ConstListIterator_free(GWEN_CONSTLIST_ITERATOR *li)
994 {
995 GWEN_ListIterator_free(li);
996 }
997
998
999
GWEN_ConstListIterator_Previous(GWEN_CONSTLIST_ITERATOR * li)1000 const void *GWEN_ConstListIterator_Previous(GWEN_CONSTLIST_ITERATOR *li)
1001 {
1002 return GWEN_ListIterator_Previous(li);
1003 }
1004
1005
1006
GWEN_ConstListIterator_Next(GWEN_CONSTLIST_ITERATOR * li)1007 const void *GWEN_ConstListIterator_Next(GWEN_CONSTLIST_ITERATOR *li)
1008 {
1009 return GWEN_ListIterator_Next(li);
1010 }
1011
1012
1013
GWEN_ConstListIterator_Data(GWEN_CONSTLIST_ITERATOR * li)1014 const void *GWEN_ConstListIterator_Data(GWEN_CONSTLIST_ITERATOR *li)
1015 {
1016 return GWEN_ListIterator_Data(li);
1017 }
1018
1019
1020
1021
1022
1023
1024