xref: /dragonfly/usr.sbin/installer/libdfui/decode.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
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