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