00001 #include <stdio.h>
00002 #include <ctype.h>
00003 #include <string.h>
00004 #include <stdlib.h>
00005
00006 #include "cgns_io.h"
00007 #include "getargs.h"
00008
00009 #define INDENT 2
00010 #define THRESHOLD 0
00011 #define ADF_DTD "ADFXfile.dtd"
00012 #define ADF_XSD "ADFXfile.xsd"
00013 #define ADF_XMLNS "http://www.cgns.org/ADFXfile"
00014
00015 static int use_schema = 0;
00016 static int show_data = 1;
00017 static char prefix[33] = "";
00018 static int indent = INDENT;
00019 static int follow_links = 0;
00020 static int threshold = THRESHOLD;
00021 static int idcounter = 0;
00022 static char ByteOrder[3];
00023
00024 static char data_map[] =
00025 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00026
00027 static char options[] = "xn:i:ft:d";
00028 static char *usgmsg[] = {
00029 "usage : cgns2xml [options] ADFfile",
00030 "options:",
00031 " -x = use XML Schema",
00032 " -n<ns> = use namespace ns",
00033 " -i<cnt> = set indent level (default 2)",
00034 " -f = follow links",
00035 " -t<size> = formatted output up to this size in bytes",
00036 " -d = don't print data",
00037 NULL
00038 };
00039
00040 #define print_indent(I) if((I)>0)printf("%*.*s",I,I," ")
00041
00042
00043
00044 static void print_string (char *str, int cnt)
00045 {
00046 while (cnt-- > 0 && *str) {
00047 if (*str == '"')
00048 printf (""");
00049 else if (*str == '\'')
00050 printf ("'");
00051 else if (*str == '&')
00052 printf ("&");
00053 else if (*str == '<')
00054 printf ("<");
00055 else if (*str == '>')
00056 printf (">");
00057 else
00058 putchar (*str);
00059 str++;
00060 }
00061 }
00062
00063
00064
00065 static size_t data_size (char *type, int ndim, int *dims)
00066 {
00067 int n;
00068 size_t bytes;
00069
00070 if (ndim < 1) return 0;
00071 if (0 == strcmp (type, "C1") ||
00072 0 == strcmp (type, "B1"))
00073 bytes = sizeof(char);
00074 else if (0 == strcmp (type, "I4") ||
00075 0 == strcmp (type, "U4"))
00076 bytes = sizeof(int);
00077 else if (0 == strcmp (type, "I8") ||
00078 0 == strcmp (type, "U8"))
00079 bytes = sizeof(long);
00080 else if (0 == strcmp (type, "R4"))
00081 bytes = sizeof(float);
00082 else if (0 == strcmp (type, "R8"))
00083 bytes = sizeof(double);
00084 else
00085 return 0;
00086
00087 for (n = 0; n < ndim; n++)
00088 bytes *= (size_t)dims[n];
00089 return bytes;
00090 }
00091
00092
00093
00094 static void print_C1 (char *data, int cnt, int inlen)
00095 {
00096 print_indent (inlen);
00097 #ifdef USE_OPTIONAL
00098 if (cnt == 0) {
00099 if (use_schema && *prefix)
00100 printf ("<%s:C1 Size=\"0\"/>\n", prefix);
00101 else
00102 printf ("<C1 Size=\"0\"/>\n");
00103 return;
00104 }
00105 if (use_schema && *prefix) {
00106 printf ("<%s:C1 Size=\"%d\">", prefix, cnt);
00107 print_string (data, cnt);
00108 printf ("</%s:C1>\n", prefix);
00109 }
00110 else {
00111 printf ("<C1 Size=\"%d\">", cnt);
00112 print_string (data, cnt);
00113 printf ("</C1>\n");
00114 }
00115 #else
00116 if (cnt == 0) {
00117 if (use_schema && *prefix)
00118 printf ("<%s:C1/>\n", prefix);
00119 else
00120 printf ("<C1/>\n");
00121 return;
00122 }
00123 if (use_schema && *prefix) {
00124 printf ("<%s:C1>", prefix);
00125 print_string (data, cnt);
00126 printf ("</%s:C1>\n", prefix);
00127 }
00128 else {
00129 printf ("<C1>");
00130 print_string (data, cnt);
00131 printf ("</C1>\n");
00132 }
00133 #endif
00134 }
00135
00136
00137
00138 static void print_I4 (int *data, int cnt, int inlen)
00139 {
00140 int n;
00141
00142 print_indent (inlen);
00143 #ifdef USE_OPTIONAL
00144 if (cnt == 0) {
00145 if (use_schema && *prefix)
00146 printf ("<%s:I4 Size=\"0\"/>\n", prefix);
00147 else
00148 printf ("<I4 Size=\"0\"/>\n");
00149 return;
00150 }
00151 if (use_schema && *prefix)
00152 printf ("<%s:I4 Size=\"%d\">\n", prefix, cnt);
00153 else
00154 printf ("<I4 Size=\"%d\">\n", cnt);
00155 #else
00156 if (cnt == 0) {
00157 if (use_schema && *prefix)
00158 printf ("<%s:I4/>\n", prefix);
00159 else
00160 printf ("<I4/>\n");
00161 return;
00162 }
00163 if (use_schema && *prefix)
00164 printf ("<%s:I4>\n", prefix);
00165 else
00166 printf ("<I4>\n");
00167 #endif
00168 for (n = 0; n < cnt; n++) {
00169 if ((n % 20) == 0) {
00170 if (n) putchar ('\n');
00171 print_indent (inlen + indent - 1);
00172 }
00173 printf (" %d", data[n]);
00174 }
00175 putchar ('\n');
00176 print_indent (inlen);
00177 if (use_schema && *prefix)
00178 printf ("</%s:I4>\n", prefix);
00179 else
00180 printf ("</I4>\n");
00181 }
00182
00183
00184
00185 static void print_R4 (float *data, int cnt, int inlen)
00186 {
00187 int n;
00188
00189 print_indent (inlen);
00190 #ifdef USE_OPTIONAL
00191 if (cnt == 0) {
00192 if (use_schema && *prefix)
00193 printf ("<%s:R4 Size=\"0\"/>\n", prefix);
00194 else
00195 printf ("<R4 Size=\"0\"/>\n");
00196 return;
00197 }
00198 if (use_schema && *prefix)
00199 printf ("<%s:R4 Size=\"%d\">\n", prefix, cnt);
00200 else
00201 printf ("<R4 Size=\"%d\">\n", cnt);
00202 #else
00203 if (cnt == 0) {
00204 if (use_schema && *prefix)
00205 printf ("<%s:R4/>\n", prefix);
00206 else
00207 printf ("<R4/>\n");
00208 return;
00209 }
00210 if (use_schema && *prefix)
00211 printf ("<%s:R4>\n", prefix);
00212 else
00213 printf ("<R4>\n");
00214 #endif
00215 for (n = 0; n < cnt; n++) {
00216 if ((n % 10) == 0) {
00217 if (n) putchar ('\n');
00218 print_indent (inlen + indent - 1);
00219 }
00220 printf (" %g", data[n]);
00221 }
00222 putchar ('\n');
00223 print_indent (inlen);
00224 if (use_schema && *prefix)
00225 printf ("</%s:R4>\n", prefix);
00226 else
00227 printf ("</R4>\n");
00228 }
00229
00230
00231
00232 static void print_R8 (double *data, int cnt, int inlen)
00233 {
00234 int n;
00235
00236 print_indent (inlen);
00237 #ifdef USE_OPTIONAL
00238 if (cnt == 0) {
00239 if (use_schema && *prefix)
00240 printf ("<%s:R8 Size=\"0\"/>\n", prefix);
00241 else
00242 printf ("<R8 Size=\"0\"/>\n");
00243 return;
00244 }
00245 if (use_schema && *prefix)
00246 printf ("<%s:R8 Size=\"%d\">\n", prefix, cnt);
00247 else
00248 printf ("<R8 Size=\"%d\">\n", cnt);
00249 #else
00250 if (cnt == 0) {
00251 if (use_schema && *prefix)
00252 printf ("<%s:R8/>\n", prefix);
00253 else
00254 printf ("<R8/>\n");
00255 return;
00256 }
00257 if (use_schema && *prefix)
00258 printf ("<%s:R8>\n", prefix);
00259 else
00260 printf ("<R8>\n");
00261 #endif
00262 for (n = 0; n < cnt; n++) {
00263 if ((n % 10) == 0) {
00264 if (n) putchar ('\n');
00265 print_indent (inlen + indent - 1);
00266 }
00267 printf (" %g", data[n]);
00268 }
00269 putchar ('\n');
00270 print_indent (inlen);
00271 if (use_schema && *prefix)
00272 printf ("</%s:R8>\n", prefix);
00273 else
00274 printf ("</R8>\n");
00275 }
00276
00277
00278
00279 static int can_encode (char *type)
00280 {
00281 int bytes;
00282
00283 if (*ByteOrder == 0) return 0;
00284 if (0 == strcmp (type, "C1")) {
00285 bytes = sizeof(char);
00286 return (bytes == 1);
00287 }
00288 if (0 == strcmp (type, "I4")) {
00289 bytes = sizeof(int);
00290 return (bytes == 4);
00291 }
00292 if (0 == strcmp (type, "R4")) {
00293 bytes = sizeof(float);
00294 return (bytes == 4);
00295 }
00296 if (0 == strcmp (type, "R8")) {
00297 bytes = sizeof(int);
00298 return (bytes == 8);
00299 }
00300 return 0;
00301 }
00302
00303
00304
00305 static void print_base64 (char *type, unsigned char *data, int cnt, int inlen)
00306 {
00307 int c, i, j = 0, n = 0;
00308 int buff[3];
00309
00310 print_indent (inlen);
00311 #ifdef USE_OPTIONAL
00312 if (cnt == 0) {
00313 if (use_schema && *prefix)
00314 printf ("<%s:B64 Size=\"0\" ByteOrder=\"%s\" DataType=\"%s\"/>\n",
00315 prefix, ByteOrder, type);
00316 else
00317 printf ("<B64 Size=\"0\" ByteOrder=\"%s\" DataType=\"%s\"/>\n",
00318 ByteOrder, type);
00319 return;
00320 }
00321 i = ((cnt + 2)/3) << 2;
00322 if (use_schema && *prefix)
00323 printf ("<%s:B64 Size=\"%d\" ByteOrder=\"%s\" DataType=\"%s\">\n",
00324 prefix, i, ByteOrder, type);
00325 else
00326 printf ("<B64 Size=\"%d\" ByteOrder=\"%s\" DataType=\"%s\">\n",
00327 i, ByteOrder, type);
00328 #else
00329 if (cnt == 0) {
00330 if (use_schema && *prefix)
00331 printf ("<%s:B64 ByteOrder=\"%s\"/>\n", prefix, ByteOrder);
00332 else
00333 printf ("<B64 ByteOrder=\"%s\"/>\n", ByteOrder);
00334 return;
00335 }
00336 if (use_schema && *prefix)
00337 printf ("<%s:B64 ByteOrder=\"%s\">\n", prefix, ByteOrder);
00338 else
00339 printf ("<B64 ByteOrder=\"%s\">\n", ByteOrder);
00340 #endif
00341 print_indent (inlen + indent);
00342 while (n < cnt) {
00343 for (i = 0; i < 3; i++)
00344 buff[i] = 0;
00345 for (i = 0; i < 3; i++) {
00346 if (n >= cnt) break;
00347 buff[i] = data[n++];
00348 }
00349 if (j == 100) {
00350 putchar('\n');
00351 print_indent (inlen + indent);
00352 j = 0;
00353 }
00354 c = (buff[0] & 0xfc) >> 2;
00355 putchar (data_map[c]);
00356 c = ((buff[0] & 0x03) << 4) | ((buff[1] & 0xf0) >> 4);
00357 putchar (data_map[c]);
00358 if (1 == i) {
00359 putchar ('=');
00360 putchar ('=');
00361 break;
00362 }
00363 c = ((buff[1] & 0x0f) << 2) | ((buff[2] & 0xc0) >> 6);
00364 putchar (data_map[c]);
00365 if (2 == i) {
00366 putchar ('=');
00367 break;
00368 }
00369 c = buff[2] & 0x3f;
00370 putchar (data_map[c]);
00371 j += 4;
00372 }
00373 putchar ('\n');
00374 print_indent (inlen);
00375 if (use_schema && *prefix)
00376 printf ("</%s:B64>\n", prefix);
00377 else
00378 printf ("</B64>\n");
00379 }
00380
00381
00382
00383 static void print_data (int cgio, double id, char *type,
00384 int ndim, int *dims, int inlen)
00385 {
00386 size_t bytes = 0;
00387 void *data = NULL;
00388
00389 if (0 == strcmp (type, "MT")) return;
00390 if (show_data) {
00391 bytes = data_size (type, ndim, dims);
00392 if (bytes > 0) {
00393 data = malloc (bytes);
00394 if (data == NULL) {
00395 fprintf (stderr, "malloc failed for %ld bytes\n", bytes);
00396 exit (1);
00397 }
00398 if (cgio_read_all_data (cgio, id, data))
00399 cgio_error_exit ("cgio_read_all_data");
00400 }
00401 }
00402
00403 if (0 == strcmp (type, "C1"))
00404 print_C1 (data, bytes, inlen);
00405 else if (threshold && bytes > threshold && can_encode (type))
00406 print_base64 (type, data, bytes, inlen);
00407 else if (0 == strcmp (type, "I4"))
00408 print_I4 (data, bytes / sizeof(int), inlen);
00409 else if (0 == strcmp (type, "R4"))
00410 print_R4 (data, bytes / sizeof(float), inlen);
00411 else if (0 == strcmp (type, "R8"))
00412 print_R8 (data, bytes / sizeof(double), inlen);
00413 else {
00414 fprintf (stderr, "unknown data type %s\n", type);
00415 exit (1);
00416 }
00417
00418 if (data != NULL) free (data);
00419 }
00420
00421
00422
00423 static void print_link (int cgio, double id, int len_file, int len_name,
00424 int inlen)
00425 {
00426 char name_in_file[CGIO_MAX_LINK_LENGTH+1];
00427 char file_name[CGIO_MAX_FILE_LENGTH+1];
00428
00429 if (cgio_get_link (cgio, id, file_name, name_in_file))
00430 cgio_error_exit ("cgio_get_link");
00431
00432 print_indent (inlen);
00433 #ifdef USE_OPTIONAL
00434 if (use_schema && *prefix)
00435 printf ("<%s:LK Size=\"%d\">%s|%s</%s:LK>\n",
00436 prefix, len_name + len_file + 1,
00437 file_name, name_in_file, prefix);
00438 else
00439 printf ("<LK Size=\"%d\">%s|%s</LK>\n",
00440 len_name + len_file + 1, file_name, name_in_file);
00441 #else
00442 if (use_schema && *prefix)
00443 printf ("<%s:LK>%s|%s</%s:LK>\n", prefix,
00444 file_name, name_in_file, prefix);
00445 else
00446 printf ("<LK>%s|%s</LK>\n",
00447 file_name, name_in_file);
00448 #endif
00449 }
00450
00451
00452
00453 static void print_children (int cgio, double parent_id, int inlen)
00454 {
00455 int n, nc, nchildren, len_file, len_name;
00456 int pidnum, ndim, dims[CGIO_MAX_DIMENSIONS];
00457 char node[25];
00458 char name[CGIO_MAX_NAME_LENGTH+1];
00459 char label[CGIO_MAX_NAME_LENGTH+1];
00460 char type[CGIO_MAX_NAME_LENGTH+1];
00461 double id;
00462
00463 if (cgio_number_children (cgio, parent_id, &nchildren))
00464 cgio_error_exit ("cgio_number_children");
00465 if (!nchildren) return;
00466
00467 pidnum = idcounter;
00468
00469 for (nc = 1; nc <= nchildren; nc++) {
00470 if (cgio_children_ids (cgio, parent_id, nc, 1, &n, &id))
00471 cgio_error_exit ("cgio_children_ids");
00472 if (cgio_get_name (cgio, id, name))
00473 cgio_error_exit ("cgio_get_name");
00474 if (cgio_get_label (cgio, id, label))
00475 cgio_error_exit ("cgio_get_label");
00476 if (cgio_get_data_type (cgio, id, type))
00477 cgio_error_exit ("cgio_get_data_type");
00478 if (cgio_is_link (cgio, id, &len_name))
00479 cgio_error_exit ("cgio_is_link");
00480 if (len_name > 0) {
00481 if (cgio_link_size (cgio, id, &len_file, &len_name))
00482 cgio_error_exit ("cgio_link_size");
00483 }
00484 if (len_name > 0 && (len_file == 0 || follow_links == 0)) {
00485 ndim = 1;
00486 dims[0] = len_name + len_file + 1;
00487 if (use_schema && *prefix)
00488 sprintf (node, "%s:LinkNode", prefix);
00489 else
00490 strcpy (node, "LinkNode");
00491 strcpy (type, "LK");
00492 }
00493 else if (0 == strcmp (type, "MT")) {
00494 ndim = 0;
00495 if (use_schema && *prefix)
00496 sprintf (node, "%s:ContNode", prefix);
00497 else
00498 strcpy (node, "ContNode");
00499 }
00500 else {
00501 if (cgio_get_dimensions (cgio, id, &ndim, dims))
00502 cgio_error_exit ("cgio_get_dimensions");
00503 if (use_schema && *prefix)
00504 sprintf (node, "%s:DataNode", prefix);
00505 else
00506 strcpy (node, "DataNode");
00507 }
00508
00509 print_indent (inlen);
00510 printf ("<%s ID=\"n%d\" PID=\"n%d\" Name=\"",
00511 node, ++idcounter, pidnum);
00512 print_string (name, strlen(name));
00513 if (strcmp (type, "LK")) {
00514 printf ("\" Label=\"");
00515 print_string (label, strlen(label));
00516 }
00517 putchar ('"');
00518 #ifndef USE_OPTIONAL
00519 if (strcmp (type, "MT") && strcmp (type, "LK"))
00520 #endif
00521 printf (" DataType=\"%s\"", type);
00522
00523 if (ndim > 0) {
00524 printf (" Dimensions=\"%d", dims[0]);
00525 for (n = 1; n < ndim; n++)
00526 printf (" %d", dims[n]);
00527 putchar ('"');
00528 }
00529 printf (">\n");
00530
00531 if (0 == strcmp (type, "LK")) {
00532 print_link (cgio, id, len_file, len_name, inlen + indent);
00533 }
00534 else {
00535 print_data (cgio, id, type, ndim, dims, inlen + indent);
00536 print_children (cgio, id, inlen + indent);
00537 }
00538 print_indent (inlen);
00539 printf ("</%s>\n", node);
00540 }
00541 }
00542
00543
00544
00545 static void get_encoding ()
00546 {
00547 int one = 1;
00548 unsigned char *cc = (unsigned char *)&one;
00549
00550 if (cc[0] == 1)
00551 strcpy (ByteOrder, "LE");
00552 else if (cc[sizeof(int)-1] == 1)
00553 strcpy (ByteOrder, "BE");
00554 else {
00555 *ByteOrder = 0;
00556 threshold = 0;
00557 }
00558 }
00559
00560
00561
00562 int main (int argc, char *argv[])
00563 {
00564 double root_id;
00565 int n, cgio;
00566 char rootname[CGIO_MAX_NAME_LENGTH+1];
00567
00568 if (argc < 2)
00569 print_usage (usgmsg, NULL);
00570 while ((n = getargs (argc, argv, options)) > 0) {
00571 switch (n) {
00572 case 'x':
00573 use_schema = 1;
00574 break;
00575 case 'n':
00576 strcpy (prefix, argarg);
00577 break;
00578 case 'i':
00579 indent = atoi (argarg);
00580 break;
00581 case 'f':
00582 follow_links = 1;
00583 break;
00584 case 't':
00585 threshold = atoi (argarg);
00586 break;
00587 case 'd':
00588 show_data = 0;
00589 break;
00590 }
00591 }
00592
00593 if (argind == argc)
00594 print_usage (usgmsg, "ADFfile not given");
00595 get_encoding ();
00596
00597 if (cgio_open_file (argv[argind], 'r', CGIO_FILE_NONE, &cgio))
00598 cgio_error_exit ("cgio_open_file");
00599 if (cgio_get_root_id (cgio, &root_id))
00600 cgio_error_exit ("cgio_get_root_id");
00601 if (cgio_get_name (cgio, root_id, rootname))
00602 cgio_error_exit ("cgio_get_name");
00603
00604 printf ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
00605 if (use_schema) {
00606 if (*prefix)
00607 printf ("<%s:ADFXfile\n", prefix);
00608 else
00609 printf ("<ADFXfile\n");
00610 printf ("\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
00611 printf ("\txsi:schemaLocation=\"%s %s.xsd\"\n", ADF_XMLNS, ADF_XMLNS);
00612 if (*prefix) {
00613 #ifdef USE_OPTIONAL
00614 printf ("\txmlns:%s=\"%s\"\n", prefix, ADF_XMLNS);
00615 printf ("\tVersion=\"1.1\"\n>\n");
00616 printf ("<%s:RootNode ID=\"n%d\" Name=\"/\" Label=\"%s\">\n",
00617 prefix, idcounter, rootname);
00618 #else
00619 printf ("\txmlns:%s=\"%s\"\n>\n", prefix, ADF_XMLNS);
00620 printf ("<%s:RootNode ID=\"n%d\">\n", prefix, idcounter);
00621 #endif
00622 print_children (cgio, root_id, indent);
00623 printf ("</%s:RootNode>\n</%s:ADFXfile>\n", prefix, prefix);
00624 }
00625 else {
00626 #ifdef USE_OPTIONAL
00627 printf ("\txmlns=\"%s\"\n", ADF_XMLNS);
00628 printf ("\tVersion=\"1.1\"\n>\n");
00629 printf ("<RootNode ID=\"n%d\" Name=\"/\" Label=\"%s\">\n",
00630 idcounter, rootname);
00631 #else
00632 printf ("\txmlns=\"%s\"\n>\n", ADF_XMLNS);
00633 printf ("<RootNode ID=\"n%d\">\n", idcounter);
00634 #endif
00635 print_children (cgio, root_id, indent);
00636 printf ("</RootNode>\n</ADFXfile>\n");
00637 }
00638 }
00639 else {
00640 *prefix = 0;
00641 printf ("<!DOCTYPE ADFXfile SYSTEM \"%s\">\n", ADF_DTD);
00642 #ifdef USE_OPTIONAL
00643 printf ("<ADFXfile Version=\"1.1\">\n");
00644 printf ("<RootNode ID=\"n%d\" Name=\"/\" Label=\"%s\">\n",
00645 idcounter, rootname);
00646 #else
00647 printf ("<ADFXfile>\n");
00648 printf ("<RootNode ID=\"n%d\">\n", idcounter);
00649 #endif
00650 print_children (cgio, root_id, indent);
00651 printf ("</RootNode>\n</ADFXfile>\n");
00652 }
00653
00654 if (cgio_close_file (cgio))
00655 cgio_error_exit ("cgio_close_file");
00656 return 0;
00657 }
00658