]> git.meshlink.io Git - catta/blob - strlst.c
assorted work:
[catta] / strlst.c
1 #include <string.h>
2 #include <stdarg.h>
3
4 #include "strlst.h"
5
6 static flxStringList *string_list_add_internal(flxStringList *l, const gchar *text, guint size) {
7     flxStringList *n;
8
9     g_assert(text);
10
11     n = g_malloc(sizeof(flxStringList) + size);
12     n->next = l;
13     strncpy(n->text, text, size);
14     n->text[size] = 0;
15     
16     return n;
17 }
18
19 flxStringList *flx_string_list_add(flxStringList *l, const gchar *text) {
20     g_assert(text);
21
22     return string_list_add_internal(l, text, strlen(text));
23 }
24
25 flxStringList *flx_string_list_parse(gconstpointer data, guint size) {
26     flxStringList *r = NULL;
27     const guint8 *c;
28     g_assert(data);
29
30     c = data;
31     for (;;) {
32         guint k;
33         
34         if (size < 1)
35             break;
36
37         k = *(c++);
38         r = string_list_add_internal(r, (const gchar*) c, k);
39         c += k;
40
41         size -= 1 + k;
42     }
43
44     return r;
45 }
46
47 void flx_string_list_free(flxStringList *l) {
48     flxStringList *n;
49
50     while (l) {
51         n = l->next;
52         g_free(l);
53         l = n;
54     }
55 }
56
57
58 static flxStringList* string_list_reverse(flxStringList *l) {
59     flxStringList *r = NULL, *n;
60
61     while (l) {
62         n = l->next;
63         l->next = r;
64         r = l;
65         l = n;
66     }
67
68     return r;
69 }
70
71 gchar* flx_string_list_to_string(flxStringList *l) {
72     flxStringList *n;
73     guint s = 0;
74     gchar *t, *e;
75
76     l = string_list_reverse(l);
77     
78     for (n = l; n; n = n->next) {
79         if (n != l)
80             s ++;
81
82         s += strlen(n->text)+2;
83     }
84
85     t = e = g_new(gchar, s+1);
86
87     for (n = l; n; n = n->next) {
88         if (n != l)
89             *(e++) = ' ';
90
91         *(e++) = '"';
92         strcpy(e, n->text);
93         e += strlen(n->text);
94         *(e++) = '"';
95     }
96
97     l = string_list_reverse(l);
98
99     *e = 0;
100
101     return t;
102 }
103
104 guint flx_string_list_serialize(flxStringList *l, gpointer data, guint size) {
105     guint used = 0;
106
107     if (data) {
108         guint8 *c;
109         flxStringList *n;
110     
111         g_assert(data);
112         
113         l = string_list_reverse(l);
114         c = data;
115         
116         for (n = l; n; n = n->next) {
117             guint k;
118             if (size < 1)
119                 break;
120             
121             k = strlen(n->text);
122             if (k > 255)
123                 k = 255;
124             
125             if (k > size-1)
126                 k = size-1;
127             
128             *(c++) = k;
129             memcpy(c, n->text, k);
130             c += k;
131             
132             used += 1+ k;
133         }
134         
135         l = string_list_reverse(l);
136     } else {
137         flxStringList *n;
138
139         for (n = l; n; n = n->next) {
140             guint k;
141         
142             k = strlen(n->text);
143             if (k > 255)
144                 k = 255;
145             
146             used += 1+k;
147         }
148     }
149
150     return used;
151 }
152
153 gboolean flx_string_list_equal(flxStringList *a, flxStringList *b) {
154
155     for (;;) {
156         if (!a && !b)
157             return TRUE;
158
159         if (!a || !b)
160             return FALSE;
161
162         if (strcmp(a->text, b->text) != 0)
163             return FALSE;
164
165         a = a->next;
166         b = b->next;
167     }
168 }
169
170 flxStringList *flx_string_list_add_many(flxStringList *r, ...) {
171     va_list va;
172
173     va_start(va, r);
174     r = flx_string_list_add_many_va(r, va);
175     va_end(va);
176     
177     return r;
178 }
179
180 flxStringList *flx_string_list_add_many_va(flxStringList *r, va_list va) {
181     const gchar *txt;
182
183     while ((txt = va_arg(va, const gchar*)))
184         r = flx_string_list_add(r, txt);
185
186     return r;
187 }
188
189 flxStringList *flx_string_list_new(const gchar *txt, ...) {
190     va_list va;
191     flxStringList *r = NULL;
192
193     if (txt) {
194         r = flx_string_list_add(r, txt);
195
196         va_start(va, txt);
197         r = flx_string_list_add_many_va(r, va);
198         va_end(va);
199     }
200
201     return r;
202 }
203
204 flxStringList *flx_string_list_new_va(va_list va) {
205     return flx_string_list_add_many_va(NULL, va);
206 }
207
208 flxStringList *flx_string_list_copy(flxStringList *l) {
209     flxStringList *r;
210
211     for (; l; l = l->next)
212         r = flx_string_list_add(l, l->text);
213
214     return string_list_reverse(r);
215 }