1 /***************************************************************************
2  $RCSfile$
3  -------------------
4  cvs         : $Id$
5  begin       : Thu Apr 03 2003
6  copyright   : (C) 2003 by Martin Preuss
7  email       : martin@libchipcard.de
8 
9  ***************************************************************************
10  *                                                                         *
11  *   This library is free software; you can redistribute it and/or         *
12  *   modify it under the terms of the GNU Lesser General Public            *
13  *   License as published by the Free Software Foundation; either          *
14  *   version 2.1 of the License, or (at your option) any later version.    *
15  *                                                                         *
16  *   This library is distributed in the hope that it will be useful,       *
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
19  *   Lesser General Public License for more details.                       *
20  *                                                                         *
21  *   You should have received a copy of the GNU Lesser General Public      *
22  *   License along with this library; if not, write to the Free Software   *
23  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
24  *   MA  02111-1307  USA                                                   *
25  *                                                                         *
26  ***************************************************************************/
27 
28 
29 #ifdef HAVE_CONFIG_H
30 # include <config.h>
31 #endif
32 
33 #include <gwenhywfar/gwenhywfarapi.h>
34 #include <gwenhywfar/misc.h>
35 #include "stringlist2_p.h"
36 #include "debug.h"
37 #include <stdlib.h>
38 #include <assert.h>
39 #include <string.h>
40 #ifdef HAVE_STRINGS_H
41 # include <strings.h>
42 #endif
43 
44 
GWEN_StringList2_new(void)45 GWEN_STRINGLIST2 *GWEN_StringList2_new(void)
46 {
47   GWEN_STRINGLIST2 *sl2;
48   GWEN_REFPTR_INFO *rpi;
49 
50   GWEN_NEW_OBJECT(GWEN_STRINGLIST2, sl2);
51   rpi=GWEN_RefPtrInfo_new();
52   GWEN_RefPtrInfo_SetFreeFn(rpi,
53                             (GWEN_REFPTR_INFO_FREE_FN)free);
54   sl2->listPtr=GWEN_List_new();
55   GWEN_List_SetRefPtrInfo(sl2->listPtr, rpi);
56   GWEN_RefPtrInfo_free(rpi);
57 
58   return sl2;
59 }
60 
61 
62 
GWEN_StringList2_free(GWEN_STRINGLIST2 * sl2)63 void GWEN_StringList2_free(GWEN_STRINGLIST2 *sl2)
64 {
65   if (sl2) {
66     GWEN_List_free(sl2->listPtr);
67     GWEN_FREE_OBJECT(sl2);
68   }
69 }
70 
71 
72 
GWEN_StringList2_dup(GWEN_STRINGLIST2 * sl2)73 GWEN_STRINGLIST2 *GWEN_StringList2_dup(GWEN_STRINGLIST2 *sl2)
74 {
75   GWEN_STRINGLIST2 *nsl2;
76 
77   GWEN_NEW_OBJECT(GWEN_STRINGLIST2, nsl2);
78   nsl2->listPtr=GWEN_List_dup(sl2->listPtr);
79   nsl2->senseCase=sl2->senseCase;
80 
81   return nsl2;
82 }
83 
84 
85 
GWEN_StringList2_toDb(GWEN_STRINGLIST2 * sl2,GWEN_DB_NODE * db,const char * name)86 int GWEN_StringList2_toDb(GWEN_STRINGLIST2 *sl2, GWEN_DB_NODE *db, const char *name)
87 {
88   GWEN_DB_DeleteVar(db, name);
89 
90   if (sl2) {
91     GWEN_STRINGLIST2_ITERATOR *it;
92 
93     it=GWEN_StringList2_First(sl2);
94     if (it) {
95       const char *s;
96 
97       s=GWEN_StringList2Iterator_Data(it);
98       while (s) {
99         int rv;
100 
101         rv=GWEN_DB_SetCharValue(db, 0, name, s);
102         if (rv<0) {
103           DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
104           return rv;
105         }
106 
107         s=GWEN_StringList2Iterator_Next(it);
108       }
109       GWEN_StringList2Iterator_free(it);
110     }
111   }
112 
113   return 0;
114 }
115 
116 
117 
GWEN_StringList2_fromDb(GWEN_DB_NODE * db,const char * name,GWEN_STRINGLIST2_INSERTMODE m)118 GWEN_STRINGLIST2 *GWEN_StringList2_fromDb(GWEN_DB_NODE *db, const char *name, GWEN_STRINGLIST2_INSERTMODE m)
119 {
120   GWEN_STRINGLIST2 *sl2;
121   int i;
122 
123   sl2=GWEN_StringList2_new();
124   for (i=0; ; i++) {
125     const char *s;
126 
127     s=GWEN_DB_GetCharValue(db, name, i, NULL);
128     if (!s)
129       break;
130     GWEN_StringList2_AppendString(sl2, s, 0, m);
131   }
132 
133   return sl2;
134 }
135 
136 
137 
GWEN_StringList2_toXml(GWEN_STRINGLIST2 * sl2,GWEN_XMLNODE * node)138 int GWEN_StringList2_toXml(GWEN_STRINGLIST2 *sl2, GWEN_XMLNODE *node)
139 {
140   GWEN_STRINGLIST2_ITERATOR *it;
141 
142   it=GWEN_StringList2_First(sl2);
143   if (it) {
144     const char *s;
145 
146     s=GWEN_StringList2Iterator_Data(it);
147     while (s) {
148       GWEN_XMLNode_SetCharValue(node, "elem", s);
149       s=GWEN_StringList2Iterator_Next(it);
150     }
151     GWEN_StringList2Iterator_free(it);
152   }
153 
154   return 0;
155 }
156 
157 
158 
GWEN_StringList2_fromXml(GWEN_XMLNODE * node,GWEN_STRINGLIST2_INSERTMODE m)159 GWEN_STRINGLIST2 *GWEN_StringList2_fromXml(GWEN_XMLNODE *node, GWEN_STRINGLIST2_INSERTMODE m)
160 {
161   GWEN_STRINGLIST2 *sl2;
162   GWEN_XMLNODE *n;
163 
164   sl2=GWEN_StringList2_new();
165 
166 
167   n=GWEN_XMLNode_GetFirstTag(node);
168   while (n) {
169     GWEN_XMLNODE *dn;
170 
171     dn=GWEN_XMLNode_GetFirstData(n);
172     if (dn) {
173       const char *s;
174 
175       s=GWEN_XMLNode_GetData(dn);
176       if (s) {
177         GWEN_StringList2_AppendString(sl2, s, 0, m);
178       }
179     }
180     n=GWEN_XMLNode_GetNextTag(n);
181   }
182 
183   return sl2;
184 }
185 
186 
187 
GWEN_StringList2_SetSenseCase(GWEN_STRINGLIST2 * sl2,int i)188 void GWEN_StringList2_SetSenseCase(GWEN_STRINGLIST2 *sl2, int i)
189 {
190   assert(sl2);
191   sl2->senseCase=i;
192 }
193 
194 
195 
GWEN_StringList2_AppendString(GWEN_STRINGLIST2 * sl2,const char * s,int take,GWEN_STRINGLIST2_INSERTMODE m)196 int GWEN_StringList2_AppendString(GWEN_STRINGLIST2 *sl2,
197                                   const char *s,
198                                   int take,
199                                   GWEN_STRINGLIST2_INSERTMODE m)
200 {
201   GWEN_REFPTR *rp;
202 
203   assert(sl2);
204   assert(s);
205 
206   if (m!=GWEN_StringList2_IntertMode_AlwaysAdd) {
207     GWEN_STRINGLIST2_ITERATOR *it;
208 
209     it=GWEN_StringList2__GetString(sl2, s);
210     if (it) {
211       if (m==GWEN_StringList2_IntertMode_NoDouble) {
212         if (take)
213           free((void *)s);
214         GWEN_StringList2Iterator_free(it);
215         return 0;
216       }
217       if (m==GWEN_StringList2_IntertMode_Reuse) {
218         GWEN_ListIterator_IncLinkCount((GWEN_LIST_ITERATOR *)it);
219         if (take)
220           free((void *)s);
221         GWEN_StringList2Iterator_free(it);
222         return 0;
223       }
224       GWEN_StringList2Iterator_free(it);
225     }
226   }
227 
228   if (take)
229     rp=GWEN_RefPtr_new((void *)s, GWEN_List_GetRefPtrInfo(sl2->listPtr));
230   else
231     rp=GWEN_RefPtr_new(strdup(s), GWEN_List_GetRefPtrInfo(sl2->listPtr));
232   GWEN_RefPtr_AddFlags(rp, GWEN_REFPTR_FLAGS_AUTODELETE);
233   GWEN_List_PushBackRefPtr(sl2->listPtr, rp);
234   return 1;
235 }
236 
237 
238 
GWEN_StringList2_InsertString(GWEN_STRINGLIST2 * sl2,const char * s,int take,GWEN_STRINGLIST2_INSERTMODE m)239 int GWEN_StringList2_InsertString(GWEN_STRINGLIST2 *sl2,
240                                   const char *s,
241                                   int take,
242                                   GWEN_STRINGLIST2_INSERTMODE m)
243 {
244   GWEN_REFPTR *rp;
245 
246   assert(sl2);
247   assert(s);
248 
249   if (m!=GWEN_StringList2_IntertMode_AlwaysAdd) {
250     GWEN_STRINGLIST2_ITERATOR *it;
251 
252     it=GWEN_StringList2__GetString(sl2, s);
253     if (it) {
254       if (m==GWEN_StringList2_IntertMode_NoDouble) {
255         if (take)
256           free((void *)s);
257         GWEN_StringList2Iterator_free(it);
258         return 0;
259       }
260       if (m==GWEN_StringList2_IntertMode_Reuse) {
261         GWEN_ListIterator_IncLinkCount((GWEN_LIST_ITERATOR *)it);
262         if (take)
263           free((void *)s);
264         GWEN_StringList2Iterator_free(it);
265         return 0;
266       }
267       GWEN_StringList2Iterator_free(it);
268     }
269   }
270 
271   if (take)
272     rp=GWEN_RefPtr_new((void *)s, GWEN_List_GetRefPtrInfo(sl2->listPtr));
273   else
274     rp=GWEN_RefPtr_new(strdup(s), GWEN_List_GetRefPtrInfo(sl2->listPtr));
275   GWEN_RefPtr_AddFlags(rp, GWEN_REFPTR_FLAGS_AUTODELETE);
276   GWEN_List_PushFrontRefPtr(sl2->listPtr, rp);
277   return 1;
278 }
279 
280 
281 
GWEN_StringList2_RemoveString(GWEN_STRINGLIST2 * sl2,const char * s)282 int GWEN_StringList2_RemoveString(GWEN_STRINGLIST2 *sl2,
283                                   const char *s)
284 {
285   GWEN_STRINGLIST2_ITERATOR *it;
286 
287   it=GWEN_StringList2__GetString(sl2, s);
288   if (it) {
289     int lc;
290 
291     lc=GWEN_ListIterator_GetLinkCount(it);
292     GWEN_List_Erase(sl2->listPtr, it);
293     GWEN_StringList2Iterator_free(it);
294     if (lc<2)
295       return 1;
296   }
297 
298   return 0;
299 }
300 
301 
302 
GWEN_StringList2_HasString(const GWEN_STRINGLIST2 * sl2,const char * s)303 int GWEN_StringList2_HasString(const GWEN_STRINGLIST2 *sl2,
304                                const char *s)
305 {
306   GWEN_STRINGLIST2_ITERATOR *it;
307   int gotIt;
308 
309   it=GWEN_StringList2_First(sl2);
310   gotIt=0;
311   if (it) {
312     const char *t;
313 
314     t=GWEN_StringList2Iterator_Data(it);
315     if (sl2->senseCase) {
316       while (t) {
317         if (strcmp(s, t)) {
318           gotIt=1;
319           break;
320         }
321         t=GWEN_StringList2Iterator_Next(it);
322       }
323     }
324     else {
325       while (t) {
326         if (strcasecmp(s, t)) {
327           gotIt=1;
328           break;
329         }
330         t=GWEN_StringList2Iterator_Next(it);
331       }
332     }
333     GWEN_StringList2Iterator_free(it);
334   }
335 
336   return gotIt;
337 }
338 
339 
340 
GWEN_StringList2__GetString(const GWEN_STRINGLIST2 * sl2,const char * s)341 GWEN_STRINGLIST2_ITERATOR *GWEN_StringList2__GetString(const GWEN_STRINGLIST2 *sl2,
342                                                        const char *s)
343 {
344   GWEN_STRINGLIST2_ITERATOR *it;
345   GWEN_REFPTR *rp;
346 
347   it=GWEN_StringList2_First(sl2);
348   if (it) {
349     rp=GWEN_ListIterator_DataRefPtr((GWEN_LIST_ITERATOR *)it);
350 
351     if (sl2->senseCase) {
352       while (rp) {
353         const char *t;
354 
355         t=(const char *)GWEN_RefPtr_GetData(rp);
356         assert(t);
357         if (strcmp(s, t)==0)
358           return it;
359         rp=GWEN_ListIterator_NextRefPtr((GWEN_LIST_ITERATOR *)it);
360       }
361     }
362     else {
363       while (rp) {
364         const char *t;
365 
366         t=(const char *)GWEN_RefPtr_GetData(rp);
367         assert(t);
368         if (strcasecmp(s, t)==0)
369           return it;
370         rp=GWEN_ListIterator_NextRefPtr((GWEN_LIST_ITERATOR *)it);
371       }
372     }
373     GWEN_StringList2Iterator_free(it);
374   }
375 
376   return 0;
377 }
378 
379 
380 
GWEN_StringList2_GetStringAt(const GWEN_STRINGLIST2 * sl2,int idx)381 const char *GWEN_StringList2_GetStringAt(const GWEN_STRINGLIST2 *sl2, int idx)
382 {
383   GWEN_STRINGLIST2_ITERATOR *it;
384   GWEN_REFPTR *rp;
385 
386   it=GWEN_StringList2_First(sl2);
387   if (it) {
388     rp=GWEN_ListIterator_DataRefPtr((GWEN_LIST_ITERATOR *)it);
389 
390     while (rp) {
391       const char *t;
392 
393       t=(const char *)GWEN_RefPtr_GetData(rp);
394       assert(t);
395       if (idx--==0) {
396         GWEN_StringList2Iterator_free(it);
397         return t;
398       }
399       rp=GWEN_ListIterator_NextRefPtr((GWEN_LIST_ITERATOR *)it);
400     }
401     GWEN_StringList2Iterator_free(it);
402   }
403 
404   return NULL;
405 }
406 
407 
408 
409 
410 
411 
412 
413 
414 
415 
416 
417 
418 
GWEN_StringList2_First(const GWEN_STRINGLIST2 * l)419 GWEN_STRINGLIST2_ITERATOR *GWEN_StringList2_First(const GWEN_STRINGLIST2 *l)
420 {
421   assert(l);
422   return (GWEN_STRINGLIST2_ITERATOR *) GWEN_List_First(l->listPtr);
423 }
424 
425 
426 
GWEN_StringList2_Last(const GWEN_STRINGLIST2 * l)427 GWEN_STRINGLIST2_ITERATOR *GWEN_StringList2_Last(const GWEN_STRINGLIST2 *l)
428 {
429   assert(l);
430   return (GWEN_STRINGLIST2_ITERATOR *) GWEN_List_Last(l->listPtr);
431 }
432 
433 
434 
GWEN_StringList2Iterator_free(GWEN_STRINGLIST2_ITERATOR * li)435 void GWEN_StringList2Iterator_free(GWEN_STRINGLIST2_ITERATOR *li)
436 {
437   assert(li);
438   GWEN_ListIterator_free((GWEN_LIST_ITERATOR *)li);
439 }
440 
441 
GWEN_StringList2Iterator_Previous(GWEN_STRINGLIST2_ITERATOR * li)442 const char *GWEN_StringList2Iterator_Previous(GWEN_STRINGLIST2_ITERATOR *li)
443 {
444   assert(li);
445   return (const char *) GWEN_ListIterator_Previous((GWEN_LIST_ITERATOR *)li);
446 }
447 
448 
GWEN_StringList2Iterator_Next(GWEN_STRINGLIST2_ITERATOR * li)449 const char *GWEN_StringList2Iterator_Next(GWEN_STRINGLIST2_ITERATOR *li)
450 {
451   assert(li);
452   return (const char *) GWEN_ListIterator_Next((GWEN_LIST_ITERATOR *)li);
453 }
454 
455 
GWEN_StringList2Iterator_Data(GWEN_STRINGLIST2_ITERATOR * li)456 const char *GWEN_StringList2Iterator_Data(GWEN_STRINGLIST2_ITERATOR *li)
457 {
458   assert(li);
459   return (const char *) GWEN_ListIterator_Data((GWEN_LIST_ITERATOR *)li);
460 }
461 
462 
463 
GWEN_StringList2Iterator_DataRefPtr(GWEN_STRINGLIST2_ITERATOR * li)464 GWEN_REFPTR *GWEN_StringList2Iterator_DataRefPtr(GWEN_STRINGLIST2_ITERATOR *li)
465 {
466   assert(li);
467   return (GWEN_REFPTR *) GWEN_ListIterator_DataRefPtr((GWEN_LIST_ITERATOR *)li);
468 }
469 
470 
471 
GWEN_StringList2Iterator_GetLinkCount(const GWEN_STRINGLIST2_ITERATOR * li)472 unsigned int GWEN_StringList2Iterator_GetLinkCount(const GWEN_STRINGLIST2_ITERATOR *li)
473 {
474   assert(li);
475   return GWEN_ListIterator_GetLinkCount((const GWEN_LIST_ITERATOR *)li);
476 }
477 
478 
479 
GWEN_StringList2_GetCount(const GWEN_STRINGLIST2 * l)480 unsigned int GWEN_StringList2_GetCount(const GWEN_STRINGLIST2 *l)
481 {
482   assert(l);
483   return GWEN_List_GetSize(l->listPtr);
484 }
485 
486 
487 
GWEN_StringList2_Dump(const GWEN_STRINGLIST2 * sl2)488 void GWEN_StringList2_Dump(const GWEN_STRINGLIST2 *sl2)
489 {
490   GWEN_STRINGLIST2_ITERATOR *it;
491 
492   it=GWEN_StringList2_First(sl2);
493   if (it) {
494     const char *t;
495     int i;
496 
497     t=GWEN_StringList2Iterator_Data(it);
498     i=0;
499     while (t) {
500       fprintf(stderr, "String %d: \"%s\" [%d]\n", i, t,
501               GWEN_StringList2Iterator_GetLinkCount(it));
502       t=GWEN_StringList2Iterator_Next(it);
503     }
504     GWEN_StringList2Iterator_free(it);
505   }
506   else {
507     fprintf(stderr, "Empty string list.\n");
508   }
509 }
510 
511 
512 
513 
514 
515 
516 
517 
518 
519