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