1 #include "config.h"
2
3 #ifdef HAVE_UNISTD_H
4 #include <unistd.h>
5 #endif
6 #ifdef HAVE_MALLOC_H
7 #include <malloc.h>
8 #endif
9 #ifdef HAVE_STRING_H
10 #include <string.h>
11 #endif
12 #include <sys/types.h>
13 #include <ctype.h>
14 #include <stdlib.h>
15 #ifdef HAVE_MEMORY_H
16 #include <memory.h>
17 #endif
18 #ifdef HAVE_NETDB_H
19 #include <netdb.h>
20 #endif
21 #include "unix_defs.h"
22 #include <limits.h>
23
24 #include "assert.h"
25 #include "ffs.h"
26 #include "ffs_internal.h"
27
28 struct _xml_output_info {
29 char *prestring; /* output this before this field */
30 int field_num;
31 IOFieldPtr field_ptr;
32 IOdata_type base_type;
33 IOVarInfoStruct *iovar; /* for dynamic arrays, array size */
34 char *element_prestring;
35 char *element_poststring;
36 char *poststring; /* output this after this field */
37 };
38
39 typedef struct dstring {
40 char *string;
41 int length;
42 int max_alloc;
43 } *ffs_dstring;
44
45 static int get_int_attr(int *int_ptr, char *name, char *start, char *end);
46 static int get_str_attr(char **str_ptr, char *name, char *start, char *end);
47 static void internal_record_to_XML_string(IOFormat ioformat, void *data,
48 void *string_base, ffs_dstring ds,
49 int encoded);
50 static void
51 generic_field_to_XML ARGS((IOFile iofile, IOFormat ioformat, int field,
52 void *data, void *string_base, int encode,
53 ffs_dstring ds));
54
55
56 static int
is_tag(char * tag,char * xml_stream)57 is_tag(char *tag, char *xml_stream)
58 {
59 int len = strlen(tag);
60 if (strncmp(xml_stream, tag, len) != 0) return 0;
61 if (isalnum((int)xml_stream[len])) return 0; /* not end of stream tag */
62 if (xml_stream[len] == '_') return 0;
63 if (xml_stream[len] == '-') return 0;
64 return 1;
65 }
66
67 extern void
free_XML_output_info(xml_output_info info)68 free_XML_output_info(xml_output_info info)
69 {
70 int i = 0;
71 while(info[i].field_ptr == NULL) {
72 if (info[i].prestring != NULL) free(info[i].prestring);
73 if (info[i].poststring != NULL) free(info[i].poststring);
74 if (info[i].element_prestring != NULL)
75 free(info[i].element_prestring);
76 if (info[i].element_poststring != NULL)
77 free(info[i].element_poststring);
78 }
79 free(info);
80 }
81
82
83
84 static void
expand_dstring(ffs_dstring ds,int min)85 expand_dstring(ffs_dstring ds, int min)
86 {
87 int len = ds->max_alloc;
88 int add = ds->max_alloc >> 3; /* add an eighth */
89 if (add < min) add = min;
90 if (add < 128) add = 128;
91 ds->string = realloc(ds->string, len + add);
92 ds->max_alloc = len + add;
93 }
94
95 static void
dcatstr(ffs_dstring ds,char * str)96 dcatstr(ffs_dstring ds, char *str)
97 {
98 int len = strlen(str);
99 if (ds->length + len + 1 > ds->max_alloc) {
100 expand_dstring(ds, len + 1);
101 }
102 strcat(&ds->string[ds->length], str);
103 ds->length += len;
104 }
105
106 static ffs_dstring
new_dstring()107 new_dstring()
108 {
109 ffs_dstring dstr = malloc(sizeof(struct dstring));
110 dstr->string = malloc(64);
111 dstr->string[0] = 0;
112 dstr->length = 0;
113 dstr->max_alloc = 64;
114 return dstr;
115 }
116
117 static ffs_dstring
record_to_XML_string(IOFormat ioformat,void * data,int encoded)118 record_to_XML_string(IOFormat ioformat, void *data, int encoded)
119 {
120 ffs_dstring dstr = new_dstring();
121 internal_record_to_XML_string(ioformat, data, data, dstr, encoded);
122 return dstr;
123 }
124
125 static ffs_dstring
raw_to_XML_string(iofile,ioformat,data,encoded)126 raw_to_XML_string(iofile, ioformat, data, encoded)
127 IOFile iofile;
128 IOFormat ioformat;
129 void *data;
130 int encoded;
131 {
132 int index;
133 ffs_dstring ds;
134 if (IOhas_XML_info(ioformat)) {
135 return record_to_XML_string(ioformat, data, encoded);
136 }
137 ds = new_dstring();
138 dcatstr(ds, "<");
139 dcatstr(ds, ioformat->body->format_name);
140 dcatstr(ds, ">\n");
141 for (index = 0; index < ioformat->body->field_count; index++) {
142 generic_field_to_XML(iofile, ioformat, index, data, data,
143 encoded, ds);
144 }
145 dcatstr(ds, "</");
146 dcatstr(ds, ioformat->body->format_name);
147 dcatstr(ds, ">\n");
148 return ds;
149 }
150
151 extern void
152 dump_raw_IOrecord_as_XML(iofile, ioformat, data)
153 IOFile iofile;
154 IOFormat ioformat;
155 void *data;
156 {
157 ffs_dstring dstr = raw_to_XML_string(iofile, ioformat, data, 1);
158 printf("%s", dstr->string);
159 }
160
161 extern char*
IOencoded_to_XML_string(IOContext iocontext,void * data)162 IOencoded_to_XML_string(IOContext iocontext, void *data)
163 {
164 IOFormat ioformat = get_format_IOcontext(iocontext, data);
165 int header_size;
166 ffs_dstring dstr = NULL;
167 char *str = NULL;
168
169 if (ioformat == NULL) return NULL;
170 header_size = header_size_IOformat(ioformat);
171 dstr = raw_to_XML_string((IOFile)iocontext, ioformat,
172 (char*)data + header_size, 1);
173 str = dstr->string;
174 free(dstr);
175 return str;
176 }
177
178 extern char*
IOunencoded_to_XML_string(IOContext iocontext,IOFormat ioformat,void * data)179 IOunencoded_to_XML_string(IOContext iocontext, IOFormat ioformat, void *data)
180 {
181 ffs_dstring dstr = raw_to_XML_string((IOFile)iocontext, ioformat, data, 0);
182 char *str = dstr->string;
183 free(dstr);
184 return str;
185 }
186
187 extern void
dump_encoded_as_XML(IOContext context,void * data)188 dump_encoded_as_XML(IOContext context, void *data)
189 {
190 IOFormat ioformat = get_format_IOcontext(context, data);
191 int header_size;
192 if (ioformat == NULL) {
193 printf("Encoded record has no valid IOFormat\n");
194 return;
195 }
196 header_size = header_size_IOformat(ioformat);
197 dump_XML_record(ioformat, (char*)data + header_size, 1);
198 }
199
200 extern void
internal_dump_XML_record(IOFormat ioformat,void * data,void * string_base,int encoded)201 internal_dump_XML_record(IOFormat ioformat, void *data, void *string_base, int encoded)
202 {
203 struct dstring ds;
204 ds.string = malloc(64);
205 ds.string[0] = 0;
206 ds.length = 0;
207 ds.max_alloc = 64;
208 internal_record_to_XML_string(ioformat, data, string_base, &ds, encoded);
209 printf("%s", ds.string);
210 free(ds.string);
211 }
212
213 static void
internal_record_to_XML_string(IOFormat ioformat,void * data,void * string_base,ffs_dstring ds,int encoded)214 internal_record_to_XML_string(IOFormat ioformat, void *data, void *string_base, ffs_dstring ds, int encoded)
215
216 {
217 int i = -1;
218 xml_output_info info;
219 if (!IOhas_XML_info(ioformat)) {
220 dump_raw_IOrecord_as_XML(ioformat->context, ioformat, data);
221 return;
222 }
223 info = ioformat->body->xml_out;
224 while(info[++i].field_ptr != NULL) {
225 int j;
226 int array_dimen = get_static_array_element_count(info[i].iovar);
227 void *base = (char*)data;
228 IOFieldPtr field_ptr = info[i].field_ptr;
229 struct _IOgetFieldStruct dummy_ptr;
230 if (info[i].prestring != NULL) {
231 dcatstr(ds, info[i].prestring);
232 /* printf("%s", info[i].prestring);*/
233 }
234 if (array_dimen == -1) {
235 array_dimen = get_array_element_count(info[i].iovar, base, 1);
236 dummy_ptr = *field_ptr;
237 dummy_ptr.size = ioformat->body->pointer_size;
238 dummy_ptr.data_type = integer_type;
239 base = get_IOaddr(&dummy_ptr, base, string_base, encoded);
240 dummy_ptr = *field_ptr;
241 field_ptr = &dummy_ptr;
242 dummy_ptr.offset = 0;
243 }
244 for(j=0; j<array_dimen; j++) {
245 if (info[i].element_prestring != NULL) {
246 dcatstr(ds, info[i].element_prestring);
247 /* printf("%s", info[i].element_prestring);*/
248 }
249 switch(info[i].base_type) {
250 case integer_type:
251 {
252 char tmp[64];
253 long l;
254 l = get_IOlong(field_ptr, base);
255 sprintf(tmp, "%ld", l);
256 dcatstr(ds, tmp);
257 break;
258 }
259 case unsigned_type:
260 case enumeration_type:
261 {
262 char tmp[64];
263 unsigned long l;
264 l = get_IOulong(field_ptr, base);
265 sprintf(tmp, "%lu", l);
266 dcatstr(ds, tmp);
267 break;
268 }
269 case boolean_type:
270 {
271 unsigned long l;
272 l = get_IOulong(field_ptr, base);
273 if (l)
274 dcatstr(ds, "true");
275 else
276 dcatstr(ds, "false");
277 break;
278 }
279 case float_type:
280 {
281 char tmp[64];
282 double d;
283 d = get_IOdouble(field_ptr, base);
284 sprintf(tmp, "%g", d);
285 dcatstr(ds, tmp);
286 break;
287 }
288 case char_type:
289 {
290 char tmp[2];
291 tmp[0] = get_IOchar(field_ptr, base);
292 tmp[1] = 0;
293 dcatstr(ds, tmp);
294 break;
295 }
296 case string_type:
297 {
298 char *s;
299 s = get_IOaddr(field_ptr, base, string_base, encoded);
300 if (s) dcatstr(ds, s);
301 break;
302 }
303 case unknown_type:
304 {
305 int field = info[i].field_num;
306 int offset = field_ptr->offset;
307 IOFormat sub = ioformat->field_subformats[field];
308 if (sub != NULL) {
309 internal_record_to_XML_string(sub, (char*)base+offset,
310 string_base, ds, encoded);
311 } else {
312 dcatstr(ds, "<INCONSISTENCY! SUBFORMAT NOT FOUND FOR FIELD TYPE \"");
313 dcatstr(ds, (char*)ioformat->body->field_list[field].field_type);
314 dcatstr(ds, "\">\n");
315 }
316 break;
317 }
318 } /* end switch */
319 if (info[i].element_poststring != NULL) {
320 dcatstr(ds, info[i].element_poststring);
321 }
322 if ((info[i].element_prestring == NULL) &&
323 (info[i].element_poststring == NULL)
324 && (info[i].base_type != unknown_type)) {
325 dcatstr(ds, " ");
326 }
327
328 base = (char *) base + field_ptr->size;
329 }
330 if (info[i].poststring != NULL) {
331 dcatstr(ds, info[i].poststring);
332 }
333 }
334 }
335
336 extern void
dump_XML_record(IOFormat ioformat,void * data,int encoded)337 dump_XML_record(IOFormat ioformat, void *data, int encoded)
338 {
339 internal_dump_XML_record(ioformat, data, data, encoded);
340 }
341
342 static int
get_field_num(int * field_num_ptr,IOFormat ioformat,char * left,char * right)343 get_field_num(int* field_num_ptr, IOFormat ioformat, char *left, char *right)
344 {
345 char *field_name = NULL;
346 int field_num;
347 if (!get_str_attr(&field_name, "field_name", left, right)) {
348 if (!get_int_attr(&field_num, "field_id", left, right)) {
349 printf("Neither Field_name nor Field_id attribute found\n");
350 return 0;
351 }
352 } else {
353 field_num = 0;
354 while(strcmp(ioformat->body->field_list[field_num].field_name,
355 field_name) != 0) {
356 field_num++;
357 if (field_num >= ioformat->body->field_count) {
358 printf("Field name %s not found in format\n", field_name);
359 free(field_name);
360 return 0;
361 }
362 }
363 free(field_name);
364 }
365 if (field_num >= ioformat->body->field_count) {
366 printf("Field number %d too big\n", field_num);
367 return 0;
368 }
369 *field_num_ptr = field_num;
370 return 1;
371 }
372
373 extern void *
get_optinfo_IOFormat(IOFormat ioformat,int info_type,int * len_p)374 get_optinfo_IOFormat(IOFormat ioformat, int info_type, int *len_p)
375 {
376 int i = 0;
377 if (ioformat->body->opt_info == NULL) return NULL;
378 while(ioformat->body->opt_info[i].info_type != 0) {
379 if (ioformat->body->opt_info[i].info_type == info_type) {
380 *len_p = ioformat->body->opt_info[i].info_len;
381 return ioformat->body->opt_info[i].info_block;
382 }
383 i++;
384 }
385 return NULL;
386 }
387
388 static xml_output_info
build_XML_output_info(IOFormat ioformat)389 build_XML_output_info(IOFormat ioformat)
390 {
391 int i = 0, last_mark;
392 char *XML_opt_data = NULL;
393 int XML_data_len = 0;
394 xml_output_info info = NULL;
395 int info_count = 0;
396
397 XML_opt_data = get_optinfo_IOFormat(ioformat, 0x584D4C20, &XML_data_len);
398
399 if (XML_opt_data == NULL) return NULL;
400 last_mark = 0;
401 i = -1;
402 while (++i < XML_data_len) {
403 if (XML_opt_data[i] != '<') {
404 continue;
405 }
406 if (is_tag("/FFS:array", &XML_opt_data[i+1])) {
407 /* array termination */
408 int post_len = i - last_mark + 1;
409 info[info_count].element_poststring = malloc(post_len);
410 strncpy(info[info_count].element_poststring,
411 &XML_opt_data[last_mark], post_len -1);
412 info[info_count].element_poststring[post_len -1] = 0;
413 info_count++;
414 i += 13;
415 last_mark = i;
416 continue;
417 }
418 if (is_tag("FFS:data", &XML_opt_data[i+1])) {
419 int pre_len = i - last_mark;
420 IOdata_type data_type;
421 int field_num;
422 long junk;
423 char *right_end = strchr(&XML_opt_data[i+9], '>');
424 char *prestring = malloc(pre_len + 1);
425 IOFieldPtr field_ptr = NULL;
426
427 strncpy(prestring, &XML_opt_data[last_mark], pre_len);
428 prestring[pre_len] = 0;
429 if (!get_field_num(&field_num, ioformat, XML_opt_data + i + 9,
430 right_end)) {
431 i = right_end - XML_opt_data;
432 continue;
433 }
434 data_type = array_str_to_data_type(ioformat->body->field_list[field_num].field_type,
435 &junk);
436 field_ptr = io_malloc(sizeof(struct _IOgetFieldStruct));
437 field_ptr->offset = ioformat->body->field_list[field_num].field_offset;
438 field_ptr->size = ioformat->body->field_list[field_num].field_size;
439 field_ptr->data_type = data_type;
440 field_ptr->byte_swap = ioformat->body->byte_reversal;
441 field_ptr->src_float_format = ioformat->body->float_format;
442 field_ptr->target_float_format = ffs_my_float_format;
443 if (info_count == 0) {
444 info = malloc(sizeof(*info) * 2);
445 } else {
446 info = realloc(info, sizeof(*info) * (info_count + 2));
447 }
448 info[info_count+1].field_ptr = NULL;
449 info[info_count].prestring = prestring;
450 info[info_count].field_ptr = field_ptr;
451 info[info_count].base_type = data_type;
452 info[info_count].poststring = NULL;
453 info[info_count].field_num = field_num;
454 info[info_count].iovar = &ioformat->body->var_list[field_num];
455 info[info_count].element_prestring = NULL;
456 info[info_count].element_poststring = NULL;
457 info_count++;
458 i = right_end - XML_opt_data;
459 last_mark = i + 1;
460 continue;
461 }
462 if (is_tag("FFS:array", &XML_opt_data[i+1])) {
463 /* array termination */
464 int pre_len = i - last_mark;
465 char *right_end = strchr(&XML_opt_data[i+10], '>');
466 char *prestring = malloc(pre_len + 1);
467
468 strncpy(prestring, &XML_opt_data[last_mark], pre_len);
469 prestring[pre_len] = 0;
470 if (info_count == 0) {
471 info = malloc(sizeof(*info) * 2);
472 } else {
473 info = realloc(info, sizeof(*info) * (info_count + 2));
474 }
475 info[info_count+1].field_ptr = NULL;
476 info[info_count].prestring = prestring;
477 info[info_count].poststring = NULL;
478 i = right_end - XML_opt_data;
479 last_mark = i + 1;
480 continue;
481 }
482 if (is_tag("FFS:array_data_mark", &XML_opt_data[i+1])) {
483 /* array termination */
484 int pre_len = i - last_mark;
485 int field_num;
486 char *right_end = strchr(&XML_opt_data[i+9], '>');
487 char *prestring = malloc(pre_len + 1);
488 long elements;
489 IOdata_type data_type;
490 IOFieldPtr field_ptr = NULL;
491
492 strncpy(prestring, &XML_opt_data[last_mark], pre_len);
493 prestring[pre_len] = 0;
494 if (!get_field_num(&field_num, ioformat, XML_opt_data + i + 9,
495 right_end)) {
496 i = right_end - XML_opt_data;
497 continue;
498 }
499 info[info_count].element_prestring = prestring;
500 data_type = array_str_to_data_type(ioformat->body->field_list[field_num].field_type,
501 &elements);
502 info[info_count].iovar = &ioformat->body->var_list[field_num];
503 info[info_count].base_type = data_type;
504 info[info_count].field_num = field_num;
505 field_ptr = io_malloc(sizeof(struct _IOgetFieldStruct));
506 field_ptr->offset = ioformat->body->field_list[field_num].field_offset;
507 field_ptr->size = ioformat->body->field_list[field_num].field_size;
508 field_ptr->data_type = data_type;
509 field_ptr->byte_swap = ioformat->body->byte_reversal;
510 field_ptr->src_float_format = ioformat->body->float_format;
511 field_ptr->target_float_format = ffs_my_float_format;
512 info[info_count].field_ptr = field_ptr;
513 i = right_end - XML_opt_data;
514 last_mark = i + 1;
515 continue;
516 }
517 }
518 if (info_count != 0) {
519 int post_len = XML_data_len - last_mark;
520 char *poststring = malloc(post_len + 1);
521 strncpy(poststring, &XML_opt_data[last_mark], post_len);
522 poststring[post_len] = 0;
523 info[info_count-1].poststring = poststring;
524 info[info_count].field_ptr = NULL;
525 /* for(i=0; i < info_count; i++) {
526 printf("XML field info:\n");
527 printf(" prestring = \"%s\"\n", info[i].prestring);
528 printf(" field num = \"%d\"\n", info[i].field_num);
529 printf(" field name = \"%s\"\n",
530 ioformat->body->field_list[info[i].field_num].field_name);
531 printf(" poststring = \"%s\"\n", info[i].poststring == NULL ?
532 "(NULL)":info[i].poststring);
533 }*/
534 return info;
535 } else {
536 return NULL;
537 }
538 }
539
540 static int
get_int_attr(int * int_ptr,char * name,char * start,char * end)541 get_int_attr(int *int_ptr, char *name, char *start, char *end)
542 {
543 int name_len = strlen(name);
544 start -= 1;
545 while(++start < (end - name_len)) {
546 if (*start == *name) {
547 /* first char eq, check further */
548 if (is_tag(name, start)) {
549 char *point = &start[name_len];
550 char *tmp;
551 while (isspace((int)*point)) point++;
552 if (point > end) continue;
553 if (*point != '=') continue;
554 point++;
555 *int_ptr = strtol(point, &tmp, 10);
556 if (tmp != point) {
557 return 1;
558 } else {
559 return 0;
560 }
561 }
562 }
563 }
564 return 0;
565 }
566
567 static int
get_str_attr(char ** str_ptr,char * name,char * start,char * end)568 get_str_attr(char **str_ptr, char *name, char *start, char *end)
569 {
570 int name_len = strlen(name);
571 start -= 1;
572 while(++start < (end - name_len)) {
573 if (*start == *name) {
574 /* first char eq, check further */
575 if (is_tag(name, start)) {
576 char *point = &start[name_len];
577 char *attr = NULL;
578 while (isspace((int)*point)) point++;
579 if (point > end) continue;
580 if (*point != '=') continue;
581 point++;
582 while (isspace((int)*point)) point++;
583 if (point > end) continue;
584 if (*point == '"') {
585 /* begin quote */
586 char *end_quote = strchr(point+1, '"');
587 point++;
588 if ((end_quote == 0) || (end_quote > end)) continue;
589 attr = malloc(end_quote - point + 1);
590 strncpy(attr, point, end_quote - point);
591 attr[end_quote - point] = 0;
592 *str_ptr = attr;
593 return 1;
594 } else {
595 char *next_space = point;
596 while(isalnum((int)*next_space) || (*next_space=='_'))
597 next_space++;
598 attr = malloc(next_space - point+1);
599 strncpy(attr, point, next_space - point);
600 attr[next_space - point] = 0;
601 *str_ptr = attr;
602 return 1;
603 }
604 }
605 }
606 }
607 return 0;
608 }
609
610 extern int
IOhas_XML_info(IOFormat ioformat)611 IOhas_XML_info(IOFormat ioformat)
612 {
613 if (ioformat->body->xml_out == (void*) -1) return 0;
614 if (ioformat->body->xml_out == NULL) {
615 /* search opt info */
616 ioformat->body->xml_out = build_XML_output_info(ioformat);
617 if (ioformat->body->xml_out == NULL) {
618 ioformat->body->xml_out = (void*)-1;
619 return 0;
620 }
621 }
622 return 1;
623 }
624
625 extern void
626 dump_IOfield_as_XML(iofile, ioformat, field, data, string_base, encode, verbose)
627 IOFile iofile;
628 IOFormat ioformat;
629 int field;
630 void *data;
631 void *string_base;
632 int encode;
633 int verbose;
634 {
635 ffs_dstring ds = new_dstring();
636 generic_field_to_XML(iofile, ioformat, field, data, string_base, encode,
637 ds);
638 printf("%s", ds->string);
639 free(ds->string);
640 free(ds);
641 }
642
643 extern int
644 add_single_value_as_XML(field_type, field_size, field_offset, iofile,
645 data, string_base, byte_reversal, float_format,
646 encode, ds)
647 char *field_type;
648 int field_size;
649 int field_offset;
650 IOFile iofile;
651 void *data;
652 void *string_base;
653 int byte_reversal;
654 int float_format;
655 int encode;
656 ffs_dstring ds;
657 {
658 IOgetFieldStruct descr; /* OK */
659 char str[64];
660 descr.offset = field_offset;
661 descr.size = field_size;
662 descr.data_type = str_to_data_type(field_type);
663 descr.byte_swap = byte_reversal;
664 descr.src_float_format = float_format;
665 descr.target_float_format = ffs_my_float_format;
666
667 str[0] = 0;
668 if (descr.data_type == integer_type) {
669 if (field_size <= sizeof(long)) {
670 long tmp = get_IOlong(&descr, data);
671 sprintf(str, "%ld", tmp);
672 } else if (field_size == 2 * sizeof(long) && field_size == 8) {
673 unsigned long low_long;
674 long high_long;
675 get_IOlong8(&descr, data, &low_long, &high_long);
676 if (high_long == 0) {
677 sprintf(str, "%ld ", low_long);
678 } else {
679 sprintf(str, "0x%lx%08lx ", high_long, low_long);
680 }
681 } else if (field_size > sizeof(long)) {
682 sprintf(str, "<scalar type=\"long\" />");
683 } else {
684 sprintf(str, "<scalar type=\"int\" size=\"%d\" />", field_size);
685 }
686 } else if (descr.data_type == unsigned_type) {
687 if (field_size <= sizeof(unsigned long)) {
688 unsigned long tmp = get_IOulong(&descr, data);
689 sprintf(str, "%lu ", tmp);
690 } else if (field_size == 2 * sizeof(long) && field_size == 8) {
691 unsigned long low_long, high_long;
692 get_IOulong8(&descr, data, &low_long, &high_long);
693 if (high_long == 0) {
694 sprintf(str, "%lu ", low_long);
695 } else {
696 sprintf(str, "0x%lx%08lx ", high_long, low_long);
697 }
698 } else if (field_size > sizeof(long)) {
699 sprintf(str, "<scalar type=\"unsignedLong\" />");
700 } else {
701 sprintf(str, "<scalar type=\"unsignedInt\" size=\"%d\" />", field_size);
702 }
703 } else if (descr.data_type == enumeration_type) {
704 sprintf(str, "%u ", *(int *) ((char *) data + field_offset));
705 } else if (descr.data_type == boolean_type) {
706 if (*(int *) ((char *) data + field_offset) == 0) {
707 strcpy(str, "false ");
708 } else {
709 strcpy(str, "true ");
710 }
711 } else if (descr.data_type == float_type) {
712 if (field_size == sizeof(float)) {
713 float tmp = get_IOfloat(&descr, data);
714 sprintf(str, "%g ", tmp);
715 } else if (field_size == sizeof(double)) {
716 double tmp = get_IOdouble(&descr, data);
717 sprintf(str, "%g ", tmp);
718 #if SIZEOF_LONG_DOUBLE != 0 && SIZEOF_LONG_DOUBLE != SIZEOF_DOUBLE
719 } else if (field_size == sizeof(long double)) {
720 long double tmp;
721 memcpy(&tmp, (float *) ((char *) data + field_offset),
722 sizeof(double));
723 sprintf(str, "%Lg ", tmp);
724 #endif
725 } else {
726 if (field_size < sizeof(float)) {
727 sprintf(str, "<scalar type=\"small-float\" />");
728 } else if (field_size > sizeof(double)) {
729 sprintf(str, "<scalar type=\"big-float\" />");
730 } else {
731 sprintf(str, "<scalar type=\"float\" size=\"%u\" />", field_size);
732 }
733 }
734 } else if (descr.data_type == char_type) {
735 sprintf(str, "%c ", *(char *) ((char *) data + field_offset));
736 } else if (descr.data_type == string_type) {
737 char *tmp_str = (char *) get_IOaddr(&descr, data, string_base, encode);
738 if (tmp_str != 0) {
739 dcatstr(ds, tmp_str);
740 return 1;
741 }
742 } else {
743 return 0;
744 }
745 dcatstr(ds, str);
746 return 1;
747 }
748
749 static void
add_value_as_XML(field_type,field_size,field_offset,iofile,data,string_base,byte_reversal,float_format,encode,in_array,ds)750 add_value_as_XML(field_type, field_size, field_offset, iofile, data,
751 string_base, byte_reversal, float_format, encode,
752 in_array, ds)
753 char *field_type;
754 int field_size;
755 int field_offset;
756 IOFile iofile;
757 void *data;
758 void *string_base;
759 int byte_reversal;
760 int float_format;
761 int encode;
762 int in_array;
763 ffs_dstring ds;
764 {
765 IOFormat ioformat;
766 if (add_single_value_as_XML(field_type, field_size, field_offset,
767 iofile, data, string_base, byte_reversal,
768 float_format, encode, ds)) {
769 /* nothing */
770 } else {
771 char *typ = base_data_type(field_type);
772 if ((ioformat = get_IOformat_by_name(iofile, typ)) != NULL) {
773 int index;
774 if (in_array) {
775 dcatstr(ds, "<");
776 dcatstr(ds, ioformat->body->format_name);
777 dcatstr(ds, ">\n");
778 } else {
779 dcatstr(ds, "\n");
780 }
781 for (index = 0; index < ioformat->body->field_count; index++) {
782 generic_field_to_XML(iofile, ioformat, index,
783 (void *) ((char *) data + field_offset),
784 string_base, encode, ds);
785 }
786 if (in_array) {
787 dcatstr(ds, "</");
788 dcatstr(ds, ioformat->body->format_name);
789 dcatstr(ds, ">\n");
790 }
791 } else {
792 printf("<scalar type=\"unknown\" />\n");
793 }
794 free(typ);
795 }
796 }
797
798 static void
generic_field_to_XML(iofile,ioformat,field,data,string_base,encode,ds)799 generic_field_to_XML(iofile, ioformat, field, data, string_base, encode, ds)
800 IOFile iofile;
801 IOFormat ioformat;
802 int field;
803 void *data;
804 void *string_base;
805 int encode;
806 ffs_dstring ds;
807 {
808 IOFieldList iofield = &ioformat->body->field_list[field];
809 IOVarInfoList iovar = &ioformat->body->var_list[field];
810 int field_offset = iofield->field_offset;
811 int field_size = iofield->field_size;
812 const char *field_type = iofield->field_type;
813 int byte_reversal = ioformat->body->byte_reversal;
814 int float_format = ioformat->body->float_format;
815 char *left_paren = NULL;
816
817 if (encode == 0) byte_reversal = 0;
818
819 dcatstr(ds, "<");
820 dcatstr(ds, (char*)iofield->field_name);
821 dcatstr(ds, ">");
822 if ((left_paren = strchr(field_type, '[')) == NULL) {
823 add_value_as_XML(field_type, field_size, field_offset, iofile, data,
824 string_base, byte_reversal, float_format,
825 encode, 0, ds);
826 } else if (strchr(left_paren + 1, '[') == NULL) {
827 /* single dimen array */
828 long dimension = 0;
829 char sub_type[64];
830 int sub_field_size;
831 int offset = iofield->field_offset;
832 dcatstr(ds, "\n");
833 *left_paren = 0;
834 strcpy(sub_type, field_type);
835 *left_paren = '[';
836 dimension = strtol(left_paren + 1, NULL, 10);
837
838 if ((dimension == LONG_MIN) || (dimension == LONG_MAX) ||
839 (dimension == 0)) {
840 if (iovar->var_array != TRUE) {
841 fprintf(stderr, "Couldn't parse array size in \"%s\"\n",
842 field_type);
843 return;
844 } else {
845 IOgetFieldStruct descr; /* OK */
846 long tmp_offset;
847 descr.offset = iofield->field_offset;
848 descr.size = ioformat->body->pointer_size;
849 descr.data_type = integer_type;
850 descr.byte_swap = byte_reversal;
851
852 dimension = get_IOlong(iovar->dimens[0].control_field, data);
853
854 tmp_offset = get_IOlong(&descr, data);
855 if (encode) {
856 data = (char *) string_base + tmp_offset;
857 } else {
858 data = (void *) tmp_offset;
859 }
860 offset = 0;
861 }
862 sub_field_size = iofield->field_size;
863 } else {
864 /* normal internal array */
865 if (ioformat->body->IOversion <= 3) {
866 sub_field_size = iofield->field_size / dimension;
867 } else {
868 sub_field_size = iofield->field_size;
869 }
870 }
871 for (; dimension > 0; dimension--) {
872 add_value_as_XML(sub_type, sub_field_size, offset, iofile, data,
873 string_base, byte_reversal, float_format,
874 encode, 1, ds);
875 offset += sub_field_size;
876 }
877 } else {
878 /* double dimen array */
879 long dimension1 = 0;
880 long dimension2 = 0;
881 char *temp_ptr;
882 char sub_type[64];
883 int sub_field_size, offset = iofield->field_offset;
884 dcatstr(ds, "\n");
885 *left_paren = 0;
886 strcpy(sub_type, field_type);
887 dimension1 = strtol(left_paren + 1, &temp_ptr, 10);
888 dimension2 = strtol(temp_ptr + 2, &temp_ptr, 10);
889
890 if ((dimension2 == LONG_MIN) || (dimension2 == LONG_MAX) ||
891 (dimension2 == 0) || (dimension1 == 0)) {
892 *left_paren = '[';
893 fprintf(stderr, "Couldn't parse array size in \"%s\"\n",
894 field_type);
895 return;
896 }
897 *left_paren = '[';
898 if (ioformat->body->IOversion <= 3) {
899 sub_field_size = iofield->field_size / (dimension1 * dimension2);
900 } else {
901 sub_field_size = iofield->field_size;
902 }
903 for (; dimension2 > 0; dimension2--) {
904 int i = 0;
905 for (; i < dimension1; i++) {
906 add_value_as_XML(sub_type, sub_field_size, offset, iofile,
907 data, string_base, byte_reversal,
908 float_format, encode, 1, ds);
909 offset += sub_field_size;
910 }
911 }
912 }
913
914 dcatstr(ds, "</");
915 dcatstr(ds, (char*)iofield->field_name);
916 dcatstr(ds, ">\n");
917 }
918
919