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