]> git.meshlink.io Git - catta/blob - avahi-common/strlst.c
* add two new functions:
[catta] / avahi-common / strlst.c
1 /* $Id$ */
2
3 /***
4   This file is part of avahi.
5  
6   avahi is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as
8   published by the Free Software Foundation; either version 2.1 of the
9   License, or (at your option) any later version.
10  
11   avahi is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
14   Public License for more details.
15  
16   You should have received a copy of the GNU Lesser General Public
17   License along with avahi; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19   USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <string.h>
27 #include <stdarg.h>
28 #include <assert.h>
29 #include <stdio.h>
30
31 #include "strlst.h"
32 #include "malloc.h"
33
34 AvahiStringList*avahi_string_list_add_anonymous(AvahiStringList *l, size_t size) {
35     AvahiStringList *n;
36
37     if (!(n = avahi_malloc(sizeof(AvahiStringList) + size)))
38         return NULL;
39     
40     n->next = l;
41     n->size = size;
42
43     /* NUL terminate strings, just to make sure */
44     n->text[size] = 0;
45
46     return n;
47 }
48
49 AvahiStringList *avahi_string_list_add_arbitrary(AvahiStringList *l, const uint8_t*text, size_t size) {
50     AvahiStringList *n;
51
52     assert(text);
53
54     if (!(n = avahi_string_list_add_anonymous(l, size)))
55         return NULL;
56
57     if (size > 0)
58         memcpy(n->text, text, size);
59
60     return n;
61 }
62
63 AvahiStringList *avahi_string_list_add(AvahiStringList *l, const char *text) {
64     assert(text);
65
66     return avahi_string_list_add_arbitrary(l, (const uint8_t*) text, strlen(text));
67 }
68
69 AvahiStringList *avahi_string_list_parse(const void* data, size_t size) {
70     AvahiStringList *r = NULL;
71     const uint8_t *c;
72     
73     assert(data);
74
75     c = data;
76     for (;;) {
77         size_t k;
78         
79         if (size < 1)
80             break;
81
82         k = *(c++);
83         r = avahi_string_list_add_arbitrary(r, c, k);
84         c += k;
85
86         size -= 1 + k;
87     }
88
89     return r;
90 }
91
92 void avahi_string_list_free(AvahiStringList *l) {
93     AvahiStringList *n;
94
95     while (l) {
96         n = l->next;
97         avahi_free(l);
98         l = n;
99     }
100 }
101
102 AvahiStringList* avahi_string_list_reverse(AvahiStringList *l) {
103     AvahiStringList *r = NULL, *n;
104
105     while (l) {
106         n = l->next;
107         l->next = r;
108         r = l;
109         l = n;
110     }
111
112     return r;
113 }
114
115 char* avahi_string_list_to_string(AvahiStringList *l) {
116     AvahiStringList *n;
117     size_t s = 0;
118     char *t, *e;
119
120     l = avahi_string_list_reverse(l);
121     
122     for (n = l; n; n = n->next) {
123         if (n != l)
124             s ++;
125
126         s += n->size+2;
127     }
128
129     if (!(t = e = avahi_new(char, s+1))) {
130         l = avahi_string_list_reverse(l);
131         return NULL;
132     }
133
134     for (n = l; n; n = n->next) {
135         if (n != l)
136             *(e++) = ' ';
137
138         *(e++) = '"';
139         strncpy(e, (char*) n->text, n->size);
140         e[n->size] = 0;
141         e = strchr(e, 0);
142         *(e++) = '"';
143
144         assert(e);
145     }
146
147     l = avahi_string_list_reverse(l);
148     
149     *e = 0;
150
151     return t;
152 }
153
154 size_t avahi_string_list_serialize(AvahiStringList *l, void *data, size_t size) {
155     size_t used = 0;
156
157     if (data) {
158         uint8_t *c;
159         AvahiStringList *n;
160     
161         assert(data);
162         
163         l = avahi_string_list_reverse(l);
164         c = data;
165         
166         for (n = l; n; n = n->next) {
167             size_t k;
168             if (size < 1)
169                 break;
170             
171             k = n->size;
172             if (k > 255)
173                 k = 255;
174             
175             if (k > size-1)
176                 k = size-1;
177             
178             *(c++) = k;
179             memcpy(c, n->text, k);
180             c += k;
181             
182             used += 1+ k;
183         }
184         
185         l = avahi_string_list_reverse(l);
186     } else {
187         AvahiStringList *n;
188
189         for (n = l; n; n = n->next) {
190             size_t k;
191         
192             k = n->size;
193             if (k > 255)
194                 k = 255;
195             
196             used += 1+k;
197         }
198     }
199
200     return used;
201 }
202
203 int avahi_string_list_equal(const AvahiStringList *a, const AvahiStringList *b) {
204
205     for (;;) {
206         if (!a && !b)
207             return 1;
208
209         if (!a || !b)
210             return 0;
211
212         if (a->size != b->size)
213             return 0;
214
215         if (a->size != 0 && memcmp(a->text, b->text, a->size) != 0)
216             return 0;
217
218         a = a->next;
219         b = b->next;
220     }
221 }
222
223 AvahiStringList *avahi_string_list_add_many(AvahiStringList *r, ...) {
224     va_list va;
225
226     va_start(va, r);
227     r = avahi_string_list_add_many_va(r, va);
228     va_end(va);
229     
230     return r;
231 }
232
233 AvahiStringList *avahi_string_list_add_many_va(AvahiStringList *r, va_list va) {
234     const char *txt;
235
236     while ((txt = va_arg(va, const char*)))
237         r = avahi_string_list_add(r, txt);
238
239     return r;
240 }
241
242 AvahiStringList *avahi_string_list_new(const char *txt, ...) {
243     va_list va;
244     AvahiStringList *r = NULL;
245
246     if (txt) {
247         r = avahi_string_list_add(r, txt);
248
249         va_start(va, txt);
250         r = avahi_string_list_add_many_va(r, va);
251         va_end(va);
252     }
253
254     return r;
255 }
256
257 AvahiStringList *avahi_string_list_new_va(va_list va) {
258     return avahi_string_list_add_many_va(NULL, va);
259 }
260
261 AvahiStringList *avahi_string_list_copy(const AvahiStringList *l) {
262     AvahiStringList *r = NULL;
263
264     for (; l; l = l->next)
265         r = avahi_string_list_add_arbitrary(r, l->text, l->size);
266
267     return avahi_string_list_reverse(r);
268 }
269
270 AvahiStringList *avahi_string_list_new_from_array(const char *array[], int length) {
271     AvahiStringList *r = NULL;
272     int i;
273
274     assert(array);
275
276     for (i = 0; length >= 0 ? i < length : !!array[i]; i++)
277         r = avahi_string_list_add(r, array[i]);
278
279     return r;
280 }
281
282 unsigned avahi_string_list_length(const AvahiStringList *l) {
283     unsigned n = 0;
284
285     for (; l; l = l->next)
286         n++;
287
288     return n;
289 }
290
291 AvahiStringList *avahi_string_list_add_vprintf(AvahiStringList *l, const char *format, va_list va) {
292     size_t len = 80;
293     AvahiStringList *r;
294     
295     assert(format);
296
297     if (!(r = avahi_malloc(sizeof(AvahiStringList) + len)))
298         return NULL;
299
300     for (;;) {
301         int n;
302         AvahiStringList *nr;
303         
304         n = vsnprintf((char*) r->text, len+1, format, va);
305
306         if (n >= 0 && n < (int) len)
307             break;
308
309         if (n >= 0)
310             len = n+1;
311         else
312             len *= 2;
313
314         if (!(nr = avahi_realloc(r, sizeof(AvahiStringList) + len))) {
315             avahi_free(r);
316             return NULL;
317         }
318
319         r = nr;
320     }
321
322     
323     r->next = l;
324     r->size = strlen((char*) r->text); 
325
326     return r;
327 }
328
329 AvahiStringList *avahi_string_list_add_printf(AvahiStringList *l, const char *format, ...) {
330     va_list va;
331     
332     assert(format);
333
334     va_start(va, format);
335     l  = avahi_string_list_add_vprintf(l, format, va);
336     va_end(va);
337
338     return l;    
339 }