]> git.meshlink.io Git - catta/blob - avahi-common/strlst.c
hide some more files
[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
30 #include "strlst.h"
31 #include "malloc.h"
32
33 AvahiStringList*avahi_string_list_add_anonymous(AvahiStringList *l, size_t size) {
34     AvahiStringList *n;
35
36     if (!(n = avahi_malloc(sizeof(AvahiStringList) + size)))
37         return NULL;
38     
39     n->next = l;
40     n->size = size;
41     
42     return n;
43 }
44
45 AvahiStringList *avahi_string_list_add_arbitrary(AvahiStringList *l, const uint8_t*text, size_t size) {
46     AvahiStringList *n;
47
48     assert(text);
49
50     if (!(n = avahi_string_list_add_anonymous(l, size)))
51         return NULL;
52
53     if (size > 0)
54         memcpy(n->text, text, size);
55     
56     return n;
57 }
58
59 AvahiStringList *avahi_string_list_add(AvahiStringList *l, const char *text) {
60     assert(text);
61
62     return avahi_string_list_add_arbitrary(l, (const uint8_t*) text, strlen(text));
63 }
64
65 AvahiStringList *avahi_string_list_parse(const void* data, size_t size) {
66     AvahiStringList *r = NULL;
67     const uint8_t *c;
68     
69     assert(data);
70
71     c = data;
72     for (;;) {
73         size_t k;
74         
75         if (size < 1)
76             break;
77
78         k = *(c++);
79         r = avahi_string_list_add_arbitrary(r, c, k);
80         c += k;
81
82         size -= 1 + k;
83     }
84
85     return r;
86 }
87
88 void avahi_string_list_free(AvahiStringList *l) {
89     AvahiStringList *n;
90
91     while (l) {
92         n = l->next;
93         avahi_free(l);
94         l = n;
95     }
96 }
97
98 AvahiStringList* avahi_string_list_reverse(AvahiStringList *l) {
99     AvahiStringList *r = NULL, *n;
100
101     while (l) {
102         n = l->next;
103         l->next = r;
104         r = l;
105         l = n;
106     }
107
108     return r;
109 }
110
111 char* avahi_string_list_to_string(AvahiStringList *l) {
112     AvahiStringList *n;
113     size_t s = 0;
114     char *t, *e;
115
116     l = avahi_string_list_reverse(l);
117     
118     for (n = l; n; n = n->next) {
119         if (n != l)
120             s ++;
121
122         s += n->size+2;
123     }
124
125     if (!(t = e = avahi_new(char, s+1))) {
126         l = avahi_string_list_reverse(l);
127         return NULL;
128     }
129
130     for (n = l; n; n = n->next) {
131         if (n != l)
132             *(e++) = ' ';
133
134         *(e++) = '"';
135         strncpy(e, (char*) n->text, n->size);
136         e[n->size] = 0;
137         e = strchr(e, 0);
138         *(e++) = '"';
139
140         assert(e);
141     }
142
143     l = avahi_string_list_reverse(l);
144     
145     *e = 0;
146
147     return t;
148 }
149
150 size_t avahi_string_list_serialize(AvahiStringList *l, void *data, size_t size) {
151     size_t used = 0;
152
153     if (data) {
154         uint8_t *c;
155         AvahiStringList *n;
156     
157         assert(data);
158         
159         l = avahi_string_list_reverse(l);
160         c = data;
161         
162         for (n = l; n; n = n->next) {
163             size_t k;
164             if (size < 1)
165                 break;
166             
167             k = n->size;
168             if (k > 255)
169                 k = 255;
170             
171             if (k > size-1)
172                 k = size-1;
173             
174             *(c++) = k;
175             memcpy(c, n->text, k);
176             c += k;
177             
178             used += 1+ k;
179         }
180         
181         l = avahi_string_list_reverse(l);
182     } else {
183         AvahiStringList *n;
184
185         for (n = l; n; n = n->next) {
186             size_t k;
187         
188             k = n->size;
189             if (k > 255)
190                 k = 255;
191             
192             used += 1+k;
193         }
194     }
195
196     return used;
197 }
198
199 int avahi_string_list_equal(const AvahiStringList *a, const AvahiStringList *b) {
200
201     for (;;) {
202         if (!a && !b)
203             return 1;
204
205         if (!a || !b)
206             return 0;
207
208         if (a->size != b->size)
209             return 0;
210
211         if (a->size != 0 && memcmp(a->text, b->text, a->size) != 0)
212             return 0;
213
214         a = a->next;
215         b = b->next;
216     }
217 }
218
219 AvahiStringList *avahi_string_list_add_many(AvahiStringList *r, ...) {
220     va_list va;
221
222     va_start(va, r);
223     r = avahi_string_list_add_many_va(r, va);
224     va_end(va);
225     
226     return r;
227 }
228
229 AvahiStringList *avahi_string_list_add_many_va(AvahiStringList *r, va_list va) {
230     const char *txt;
231
232     while ((txt = va_arg(va, const char*)))
233         r = avahi_string_list_add(r, txt);
234
235     return r;
236 }
237
238 AvahiStringList *avahi_string_list_new(const char *txt, ...) {
239     va_list va;
240     AvahiStringList *r = NULL;
241
242     if (txt) {
243         r = avahi_string_list_add(r, txt);
244
245         va_start(va, txt);
246         r = avahi_string_list_add_many_va(r, va);
247         va_end(va);
248     }
249
250     return r;
251 }
252
253 AvahiStringList *avahi_string_list_new_va(va_list va) {
254     return avahi_string_list_add_many_va(NULL, va);
255 }
256
257 AvahiStringList *avahi_string_list_copy(const AvahiStringList *l) {
258     AvahiStringList *r = NULL;
259
260     for (; l; l = l->next)
261         r = avahi_string_list_add_arbitrary(r, l->text, l->size);
262
263     return avahi_string_list_reverse(r);
264 }
265
266 AvahiStringList *avahi_string_list_new_from_array(const char *array[], int length) {
267     AvahiStringList *r = NULL;
268     int i;
269
270     assert(array);
271
272     for (i = 0; length >= 0 ? i < length : !!array[i]; i++)
273         r = avahi_string_list_add(r, array[i]);
274
275     return r;
276 }
277
278 unsigned avahi_string_list_length(const AvahiStringList *l) {
279     unsigned n = 0;
280
281     for (; l; l = l->next)
282         n++;
283
284     return n;
285 }