1 /*
2 * Copyright (c)2004 Cat's Eye Technologies. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * Neither the name of Cat's Eye Technologies nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 * OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /*
35 * decode.c
36 * $Id: decode.c,v 1.11 2005/02/07 06:39:59 cpressey Exp $
37 */
38
39 #include <ctype.h>
40 #include <stdlib.h>
41
42 #include <libaura/mem.h>
43 #include <libaura/buffer.h>
44
45 #define NEEDS_DFUI_STRUCTURE_DEFINITIONS
46 #include "dfui.h"
47 #undef NEEDS_DFUI_STRUCTURE_DEFINITIONS
48 #include "encoding.h"
49 #include "dump.h"
50
51 /*** BASIC TYPES ***/
52
53 /*
54 * This function returns a newly-allocated string. It is the
55 * caller's responsibility that it be free()'ed.
56 */
57 char *
dfui_decode_string(struct aura_buffer * e)58 dfui_decode_string(struct aura_buffer *e)
59 {
60 char *str;
61 int i = 0;
62 int len = 0;
63
64 while (isdigit(aura_buffer_peek_char(e)) && !aura_buffer_eof(e)) {
65 len = len * 10 + aura_buffer_scan_char(e) - '0';
66 }
67
68 str = aura_malloc(len + 1, "decoded string");
69
70 if (!aura_buffer_expect(e, ":")) return(NULL);
71 while (len > 0 && !aura_buffer_eof(e)) {
72 str[i++] = aura_buffer_scan_char(e);
73 len--;
74 }
75
76 str[i] = '\0';
77
78 return(str);
79 }
80
81 int
dfui_decode_int(struct aura_buffer * e)82 dfui_decode_int(struct aura_buffer *e)
83 {
84 int x = 0;
85
86 while (isdigit(aura_buffer_peek_char(e)) && !aura_buffer_eof(e)) {
87 x = x * 10 + aura_buffer_scan_char(e) - '0';
88 }
89 if (aura_buffer_expect(e, " ")) {
90 return(x);
91 } else {
92 return(0);
93 }
94 }
95
96 int
dfui_decode_bool(struct aura_buffer * e)97 dfui_decode_bool(struct aura_buffer *e)
98 {
99 char c;
100
101 c = aura_buffer_scan_char(e);
102
103 if (c == 'Y')
104 return(1);
105 else if (c == 'N')
106 return(0);
107 else /* XXX ??? error */
108 return(0);
109 }
110
111 /*** FORM TYPES ***/
112
113 struct dfui_info *
dfui_decode_info(struct aura_buffer * e)114 dfui_decode_info(struct aura_buffer *e)
115 {
116 char *name, *short_desc, *long_desc;
117 struct dfui_info *i;
118
119 name = dfui_decode_string(e);
120 short_desc = dfui_decode_string(e);
121 long_desc = dfui_decode_string(e);
122
123 i = dfui_info_new(name, short_desc, long_desc);
124
125 free(name);
126 free(short_desc);
127 free(long_desc);
128
129 return(i);
130 }
131
132 struct dfui_field *
dfui_decode_field(struct aura_buffer * e)133 dfui_decode_field(struct aura_buffer *e)
134 {
135 char *id;
136 struct dfui_info *i;
137 struct dfui_field *fi;
138
139 id = dfui_decode_string(e);
140 i = dfui_decode_info(e);
141
142 fi = dfui_field_new(id, i);
143 fi->option_head = dfui_decode_options(e);
144 fi->property_head = dfui_decode_properties(e);
145 free(id);
146
147 return(fi);
148 }
149
150 struct dfui_field *
dfui_decode_fields(struct aura_buffer * e)151 dfui_decode_fields(struct aura_buffer *e)
152 {
153 struct dfui_field *head = NULL, *fi;
154
155 if (!aura_buffer_expect(e, "f{")) return(NULL);
156 while (aura_buffer_peek_char(e) != '}') {
157 fi = dfui_decode_field(e);
158 fi->next = head;
159 head = fi;
160 }
161 aura_buffer_expect(e, "}");
162
163 return(head);
164 }
165
166 struct dfui_option *
dfui_decode_option(struct aura_buffer * e)167 dfui_decode_option(struct aura_buffer *e)
168 {
169 char *value;
170
171 value = dfui_decode_string(e);
172
173 return(dfui_option_new(value));
174 }
175
176 struct dfui_option *
dfui_decode_options(struct aura_buffer * e)177 dfui_decode_options(struct aura_buffer *e)
178 {
179 struct dfui_option *head = NULL, *o;
180
181 if (!aura_buffer_expect(e, "O{")) return(NULL);
182 while (aura_buffer_peek_char(e) != '}') {
183 o = dfui_decode_option(e);
184 o->next = head;
185 head = o;
186 }
187 aura_buffer_expect(e, "}");
188
189 return(head);
190 }
191
192 struct dfui_action *
dfui_decode_action(struct aura_buffer * e)193 dfui_decode_action(struct aura_buffer *e)
194 {
195 char *id;
196 struct dfui_info *i;
197 struct dfui_action *a;
198
199 id = dfui_decode_string(e);
200 i = dfui_decode_info(e);
201 a = dfui_action_new(id, i);
202 a->property_head = dfui_decode_properties(e);
203 free(id);
204
205 return(a);
206 }
207
208 struct dfui_action *
dfui_decode_actions(struct aura_buffer * e)209 dfui_decode_actions(struct aura_buffer *e)
210 {
211 struct dfui_action *head = NULL, *a;
212
213 if (!aura_buffer_expect(e, "a{")) return(NULL);
214 while (aura_buffer_peek_char(e) != '}') {
215 a = dfui_decode_action(e);
216 a->next = head;
217 head = a;
218 }
219 aura_buffer_expect(e, "}");
220
221 return(head);
222 }
223
224 struct dfui_celldata *
dfui_decode_celldata(struct aura_buffer * e)225 dfui_decode_celldata(struct aura_buffer *e)
226 {
227 char *field_id;
228 char *value;
229 struct dfui_celldata *c;
230
231 field_id = dfui_decode_string(e);
232 value = dfui_decode_string(e);
233
234 c = dfui_celldata_new(field_id, value);
235
236 free(field_id);
237 free(value);
238
239 return(c);
240 }
241
242 struct dfui_celldata *
dfui_decode_celldatas(struct aura_buffer * e)243 dfui_decode_celldatas(struct aura_buffer *e)
244 {
245 struct dfui_celldata *c, *head = NULL;
246
247 if (!aura_buffer_expect(e, "d{")) return(NULL);
248 while (aura_buffer_peek_char(e) != '}') {
249 c = dfui_decode_celldata(e);
250 c->next = head;
251 head = c;
252 }
253 aura_buffer_expect(e, "}");
254
255 return(head);
256 }
257
258 struct dfui_property *
dfui_decode_property(struct aura_buffer * e)259 dfui_decode_property(struct aura_buffer *e)
260 {
261 char *name, *value;
262 struct dfui_property *h;
263
264 name = dfui_decode_string(e);
265 value = dfui_decode_string(e);
266
267 h = dfui_property_new(name, value);
268
269 free(value);
270 free(name);
271
272 return(h);
273 }
274
275 struct dfui_property *
dfui_decode_properties(struct aura_buffer * e)276 dfui_decode_properties(struct aura_buffer *e)
277 {
278 struct dfui_property *h, *head = NULL;
279
280 if (!aura_buffer_expect(e, "p{")) return(NULL);
281 while (aura_buffer_peek_char(e) != '}') {
282 h = dfui_decode_property(e);
283 h->next = head;
284 head = h;
285 }
286 aura_buffer_expect(e, "}");
287
288 return(head);
289 }
290
291 struct dfui_dataset *
dfui_decode_dataset(struct aura_buffer * e)292 dfui_decode_dataset(struct aura_buffer *e)
293 {
294 struct dfui_dataset *ds;
295
296 ds = dfui_dataset_new();
297 ds->celldata_head = dfui_decode_celldatas(e);
298
299 return(ds);
300 }
301
302 struct dfui_dataset *
dfui_decode_datasets(struct aura_buffer * e)303 dfui_decode_datasets(struct aura_buffer *e)
304 {
305 struct dfui_dataset *head = NULL, *ds;
306
307 if (!aura_buffer_expect(e, "D{")) return(NULL);
308 while (aura_buffer_peek_char(e) != '}') {
309 ds = dfui_decode_dataset(e);
310 ds->next = head;
311 head = ds;
312 }
313 aura_buffer_expect(e, "}");
314
315 return(head);
316 }
317
318 struct dfui_form *
dfui_decode_form(struct aura_buffer * e)319 dfui_decode_form(struct aura_buffer *e)
320 {
321 char *id;
322 struct dfui_info *i;
323 struct dfui_form *f;
324
325 if (!aura_buffer_expect(e, "F{")) return(NULL);
326
327 id = dfui_decode_string(e);
328 i = dfui_decode_info(e);
329
330 f = dfui_form_new(id, i);
331
332 dfui_form_set_multiple(f, dfui_decode_bool(e));
333 dfui_form_set_extensible(f, dfui_decode_bool(e));
334
335 f->field_head = dfui_decode_fields(e);
336 f->action_head = dfui_decode_actions(e);
337 f->dataset_head = dfui_decode_datasets(e);
338 f->property_head = dfui_decode_properties(e);
339
340 aura_buffer_expect(e, "}");
341 free(id);
342
343 return(f);
344 }
345
346 struct dfui_response *
dfui_decode_response(struct aura_buffer * e)347 dfui_decode_response(struct aura_buffer *e)
348 {
349 char *form_id;
350 char *action_id;
351 struct dfui_response *r;
352
353 if (!aura_buffer_expect(e, "R{")) return(NULL);
354
355 form_id = dfui_decode_string(e);
356 action_id = dfui_decode_string(e);
357 r = dfui_response_new(form_id, action_id);
358 r->dataset_head = dfui_decode_datasets(e);
359 free(form_id);
360 free(action_id);
361
362 aura_buffer_expect(e, "}");
363
364 return(r);
365 }
366
367 struct dfui_progress *
dfui_decode_progress(struct aura_buffer * e)368 dfui_decode_progress(struct aura_buffer *e)
369 {
370 struct dfui_info *i;
371 int amount, streaming;
372 char *msg_line;
373 struct dfui_progress *pr;
374
375 i = dfui_decode_info(e);
376 amount = dfui_decode_int(e);
377 streaming = dfui_decode_int(e);
378 msg_line = dfui_decode_string(e);
379
380 pr = dfui_progress_new(i, amount);
381 dfui_progress_set_streaming(pr, streaming);
382 dfui_progress_set_msg_line(pr, msg_line);
383
384 free(msg_line);
385
386 return(pr);
387 }
388