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 * 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 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 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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