00001
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include <errno.h>
00022 #include <time.h>
00023 #include <assert.h>
00024
00025 #include <libxml/tree.h>
00026 #include <libxml/xpath.h>
00027 #include "mime64.h"
00028
00029 #ifndef WIN32
00030 #include <unistd.h>
00031 #endif
00032
00033 #define _LIBRASCH_BUILD
00034 #include <ra_eval.h>
00035 #include <pl_general.h>
00036
00037
00049 LIBRAAPI int
00050 ra_eval_savexml(meas_handle mh, const char *file, int use_ascii)
00051 {
00052 struct ra_meas *mm = (struct ra_meas *) mh;
00053 char fn[MAX_PATH_RA];
00054 int ret;
00055 xmlDocPtr doc;
00056
00057 if (!mm)
00058 return -1;
00059
00060 if (file)
00061 strncpy(fn, file, MAX_PATH_RA);
00062 else
00063 get_eval_file_xml(mm, fn);
00064
00065 doc = xmlNewDoc((xmlChar *)"1.0");
00066 doc->children = xmlNewDocNode(doc, NULL, (xmlChar *)"libRASCH", NULL);
00067
00068 ret = write_evals_xml(mm, doc->children, use_ascii);
00069 if (ret != 0)
00070 return ret;
00071
00072 if ((ret = xmlSaveFile(fn, doc)) == -1)
00073 _ra_set_error(mh, RA_ERR_SAVE_FILE, "libRASCH");
00074 else
00075 ret = 0;
00076
00077 xmlFreeDoc(doc);
00078
00079 return ret;
00080 }
00081
00082
00092 int
00093 write_evals_xml(meas_handle mh, xmlNodePtr parent, int use_ascii)
00094 {
00095 struct ra_meas *mm = (struct ra_meas *)mh;
00096 struct eval *e;
00097 int ret = 0;
00098 xmlNodePtr node;
00099 xmlNodePtr values;
00100 value_handle vh;
00101 char max_samplerate_s[100];
00102
00103 vh = ra_value_malloc();
00104 ra_info_get(mh, RA_INFO_MAX_SAMPLERATE_D, vh);
00105 sprintf(max_samplerate_s, "%f", ra_value_get_double(vh));
00106 ra_value_free(vh);
00107
00108 e = mm->evals;
00109 while (e)
00110 {
00111 node = xmlNewChild(parent, NULL, (xmlChar *)"Evaluation", NULL);
00112
00113 values = xmlNewChild(node, NULL, (xmlChar *)"Flags", NULL);
00114 if (e->original)
00115 xmlSetProp(values, (xmlChar *)"original", (xmlChar *)"1");
00116 if (e->def)
00117 xmlSetProp(values, (xmlChar *)"default", (xmlChar *)"1");
00118
00119 if (e->modified)
00120 {
00121 time_t tt;
00122 struct tm *t;
00123 time(&tt);
00124 t = gmtime(&tt);
00125
00126 sprintf(e->modify_timestamp,
00127 "%02d.%02d.%4d %02d:%02d:%02d", t->tm_mday,
00128 t->tm_mon + 1, (t->tm_year + 1900), t->tm_hour,
00129 t->tm_min, t->tm_sec);
00130 }
00131
00132 xmlSetProp(node, (xmlChar *)"name", (xmlChar *)e->name);
00133 xmlNewChild(node, NULL, (xmlChar *)"comment", (xmlChar *)e->comment);
00134 xmlNewChild(node, NULL, (xmlChar *)"user", (xmlChar *)e->add_user);
00135 xmlNewChild(node, NULL, (xmlChar *)"host", (xmlChar *)e->add_host);
00136 xmlNewChild(node, NULL, (xmlChar *)"program", (xmlChar *)e->add_program);
00137 xmlNewChild(node, NULL, (xmlChar *)"add-ts", (xmlChar *)e->add_timestamp);
00138 xmlNewChild(node, NULL, (xmlChar *)"modify-ts", (xmlChar *)e->modify_timestamp);
00139 xmlNewChild(node, NULL, (xmlChar *)"max-samplerate", (xmlChar *)max_samplerate_s);
00140
00141 if ((ret = write_sets_xml(e, node, use_ascii)) != 0)
00142 return ret;
00143
00144 e = e->next;
00145 }
00146
00147 return ret;
00148 }
00149
00150
00160 int
00161 write_sets_xml(struct eval *e, xmlNodePtr parent, int use_ascii)
00162 {
00163 int ret = 0;
00164 char s[100];
00165 struct event_set *set = e->set;
00166
00167 while (set)
00168 {
00169 xmlNodePtr node;
00170
00171 if (set->num_events <= 0)
00172 {
00173 set = set->next;
00174 continue;
00175 }
00176
00177 node = xmlNewChild(parent, NULL, (xmlChar *)"Event-Set", NULL);
00178
00179 xmlSetProp(node, (xmlChar *)"name", (xmlChar *)set->id_ascii);
00180 xmlNewChild(node, NULL, (xmlChar *)"desc", (xmlChar *)set->desc);
00181
00182 sprintf(s, "%ld", set->num_events);
00183 xmlNewChild(node, NULL, (xmlChar *)"number-events", (xmlChar *)s);
00184
00185 switch (set->type)
00186 {
00187 case EVENT_TYPE_DISC:
00188 xmlSetProp(node, (xmlChar *)"type", (xmlChar *)"discrete");
00189 break;
00190 case EVENT_TYPE_CONT:
00191 xmlSetProp(node, (xmlChar *)"type", (xmlChar *)"continues");
00192 break;
00193 }
00194
00195 if (use_ascii)
00196 xmlSetProp(node, (xmlChar *)"event-encoding", (xmlChar *)"ascii");
00197
00198 if (set->type == EVENT_TYPE_CONT)
00199 write_events_start_end_xml(set, node);
00200
00201 if ((ret = write_props_xml(set, node, use_ascii)) != 0)
00202 return ret;
00203
00204 if (write_templates_xml(set, node) != 0)
00205 return -1;
00206
00207 set = set->next;
00208 }
00209
00210 return ret;
00211 }
00212
00213
00222 int
00223 write_events_start_end_xml(struct event_set *set, xmlNodePtr parent)
00224 {
00225 char *t = NULL;
00226 long size;
00227 xmlNodePtr curr;
00228
00229 encode_base64(set->start, (sizeof(long) * set->num_events), &t, &size);
00230 if (t)
00231 {
00232 curr = xmlNewTextChild(parent, NULL, (xmlChar *)"event-start", (xmlChar *)t);
00233 free(t);
00234 }
00235
00236 encode_base64(set->end, (sizeof(long) * set->num_events), &t, &size);
00237 if (t)
00238 {
00239 curr = xmlNewTextChild(parent, NULL, (xmlChar *)"event-end", (xmlChar *)t);
00240 free(t);
00241 }
00242
00243 return 0;
00244 }
00245
00246
00256 int
00257 write_props_xml(struct event_set *set, xmlNodePtr parent, int use_ascii)
00258 {
00259 struct event_property *prop = set->eval->prop;
00260 char t[20];
00261
00262 while (prop)
00263 {
00264 xmlNodePtr node;
00265
00266 if (prop->set != set)
00267 {
00268 prop = prop->next;
00269 continue;
00270 }
00271
00272 node = xmlNewChild(parent, NULL, (xmlChar *)"Event-Property", NULL);
00273
00274 xmlSetProp(node, (xmlChar *)"name", (xmlChar *)prop->id_ascii);
00275 switch (prop->val_type)
00276 {
00277 case EVPROP_TYPE_SHORT:
00278 xmlSetProp(node, (xmlChar *)"val-type", (xmlChar *)"short");
00279 break;
00280 case EVPROP_TYPE_LONG:
00281 xmlSetProp(node, (xmlChar *)"val-type", (xmlChar *)"long");
00282 break;
00283 case EVPROP_TYPE_DOUBLE:
00284 xmlSetProp(node, (xmlChar *)"val-type", (xmlChar *)"double");
00285 break;
00286 case EVPROP_TYPE_CHAR:
00287 xmlSetProp(node, (xmlChar *)"val-type", (xmlChar *)"char");
00288 break;
00289 case EVPROP_TYPE_SHORT_ARRAY:
00290 xmlSetProp(node, (xmlChar *)"val-type", (xmlChar *)"short-array");
00291 break;
00292 case EVPROP_TYPE_LONG_ARRAY:
00293 xmlSetProp(node, (xmlChar *)"val-type", (xmlChar *)"long-array");
00294 break;
00295 case EVPROP_TYPE_DOUBLE_ARRAY:
00296 xmlSetProp(node, (xmlChar *)"val-type", (xmlChar *)"double-array");
00297 break;
00298 default:
00299 assert(0);
00300 }
00301 if (prop->use_minmax)
00302 {
00303 xmlSetProp(node, (xmlChar *)"use-minmax", (xmlChar *)"1");
00304 sprintf(t, "%f", prop->min_value);
00305 xmlSetProp(node, (xmlChar *)"min-value", (xmlChar *)t);
00306 sprintf(t, "%f", prop->max_value);
00307 xmlSetProp(node, (xmlChar *)"max-value", (xmlChar *)t);
00308 }
00309 else
00310 xmlSetProp(node, (xmlChar *)"use-minmax", (xmlChar *)"0");
00311
00312 xmlSetProp(node, (xmlChar *)"unit", (xmlChar *)prop->unit);
00313
00314 xmlNewChild(node, NULL, (xmlChar *)"desc", (xmlChar *)prop->desc);
00315
00316 if (use_ascii)
00317 write_events_xml_ascii(prop, node);
00318 else
00319 write_events_xml(prop, node);
00320
00321 prop = prop->next;
00322 }
00323
00324 return 0;
00325 }
00326
00327
00336 int
00337 write_events_xml(struct event_property *prop, xmlNodePtr parent)
00338 {
00339 char *t = NULL;
00340 long size, l;
00341 xmlNodePtr curr;
00342 struct event_set *set = prop->set;
00343
00344 switch (prop->val_type)
00345 {
00346 case EVPROP_TYPE_SHORT:
00347 encode_base64(set->s[prop->idx], (sizeof(short) * set->num_events), &t, &size);
00348 break;
00349 case EVPROP_TYPE_LONG:
00350 encode_base64(set->l[prop->idx], (sizeof(long) * set->num_events), &t, &size);
00351 break;
00352 case EVPROP_TYPE_DOUBLE:
00353 encode_base64(set->d[prop->idx], (sizeof(double) * set->num_events), &t, &size);
00354 break;
00355 case EVPROP_TYPE_CHAR:
00356 size = 0;
00357 for (l = 0; l < set->num_events; l++)
00358 {
00359 long len;
00360
00361 len = strlen(set->c[prop->idx][l]);
00362 size += len + 3;
00363 t = realloc(t, size);
00364 strncpy(&(t[size-len-3]), set->c[prop->idx][l], len);
00365 t[size-3] = 10;
00366 t[size-2] = '.';
00367 t[size-1] = 10;
00368 }
00369 break;
00370 default:
00371 assert(0);
00372 break;
00373 }
00374
00375 if (t)
00376 {
00377 t = realloc(t, size+1);
00378 t[size] = '\0';
00379 curr = xmlNewTextChild(parent, NULL, (xmlChar *)"events", (xmlChar *)t);
00380 free(t);
00381 }
00382
00383 return 0;
00384 }
00385
00386
00395 int
00396 write_events_xml_ascii(struct event_property *prop, xmlNodePtr parent)
00397 {
00398 xmlNodePtr curr;
00399 struct event_set *set = prop->set;
00400
00401 curr = xmlNewTextChild(parent, NULL, (xmlChar *)"events", NULL);
00402
00403 switch (prop->val_type)
00404 {
00405 case EVPROP_TYPE_SHORT:
00406 write_ascii_short(curr, set->s[prop->idx], set->num_events, "event");
00407 break;
00408 case EVPROP_TYPE_LONG:
00409 write_ascii_long(curr, set->l[prop->idx], set->num_events, "event");
00410 break;
00411 case EVPROP_TYPE_DOUBLE:
00412 write_ascii_double(curr, set->d[prop->idx], set->num_events, "event");
00413 break;
00414 case EVPROP_TYPE_CHAR:
00415 write_ascii_char(curr, set->c[prop->idx], set->num_events, "event");
00416 break;
00417 case EVPROP_TYPE_SHORT_ARRAY:
00418 write_ascii_short_array(curr, set->sa[prop->idx], set->sa_ch[prop->idx], set->sa_num_elem[prop->idx], set->num_events, "event");
00419 break;
00420 case EVPROP_TYPE_LONG_ARRAY:
00421 write_ascii_long_array(curr, set->la[prop->idx], set->la_ch[prop->idx], set->la_num_elem[prop->idx], set->num_events, "event");
00422 break;
00423 case EVPROP_TYPE_DOUBLE_ARRAY:
00424 write_ascii_double_array(curr, set->da[prop->idx], set->da_ch[prop->idx], set->da_num_elem[prop->idx], set->num_events, "event");
00425 break;
00426 }
00427
00428 return 0;
00429 }
00430
00431
00442 int
00443 write_ascii_short(xmlNodePtr p, short *data, long n, char *tag_name)
00444 {
00445 long l;
00446 char t[20];
00447 xmlNodePtr curr;
00448
00449 for (l = 0; l < n; l++)
00450 {
00451 curr = xmlNewTextChild(p, NULL, (xmlChar *)tag_name, NULL);
00452 sprintf(t, "%ld", l);
00453 xmlSetProp(curr, (xmlChar *)"index", (xmlChar *)t);
00454
00455 sprintf(t, "%d", data[l]);
00456 curr = xmlNewTextChild(curr, NULL, (xmlChar *)"content", (xmlChar *)t);
00457 xmlSetProp(curr, (xmlChar *)"index", (xmlChar *)"0");
00458 }
00459
00460 return 0;
00461 }
00462
00463
00474 int
00475 write_ascii_long(xmlNodePtr p, long *data, long n, char *tag_name)
00476 {
00477 long l;
00478 char t[20];
00479 xmlNodePtr curr;
00480
00481 for (l = 0; l < n; l++)
00482 {
00483 curr = xmlNewTextChild(p, NULL, (xmlChar *)tag_name, NULL);
00484 sprintf(t, "%ld", l);
00485 xmlSetProp(curr, (xmlChar *)"index", (xmlChar *)t);
00486
00487 sprintf(t, "%ld", data[l]);
00488 curr = xmlNewTextChild(curr, NULL, (xmlChar *)"content", (xmlChar *)t);
00489 xmlSetProp(curr, (xmlChar *)"index", (xmlChar *)"0");
00490 }
00491
00492 return 0;
00493 }
00494
00495
00506 int
00507 write_ascii_double(xmlNodePtr p, double *data, long n, char *tag_name)
00508 {
00509 long l;
00510 char t[20];
00511 xmlNodePtr curr;
00512
00513 for (l = 0; l < n; l++)
00514 {
00515 xmlChar *c;
00516
00517 curr = xmlNewTextChild(p, NULL, (xmlChar *)tag_name, NULL);
00518 sprintf(t, "%ld", l);
00519 xmlSetProp(curr, (xmlChar *)"index", (xmlChar *)t);
00520
00521 c = xmlXPathCastNumberToString(data[l]);
00522 curr = xmlNewTextChild(curr, NULL, (xmlChar *)"content", c);
00523 xmlFree(c);
00524 xmlSetProp(curr, (xmlChar *)"index", (xmlChar *)"0");
00525 }
00526
00527 return 0;
00528 }
00529
00530
00541 int
00542 write_ascii_char(xmlNodePtr p, char **data, long n, char *tag_name)
00543 {
00544 long l;
00545 char t[20];
00546 xmlNodePtr curr;
00547
00548 for (l = 0; l < n; l++)
00549 {
00550 curr = xmlNewTextChild(p, NULL, (xmlChar *)tag_name, NULL);
00551 sprintf(t, "%ld", l);
00552 xmlSetProp(curr, (xmlChar *)"index", (xmlChar *)t);
00553
00554 curr = xmlNewTextChild(curr, NULL, (xmlChar *)"content", (xmlChar *)(data[l]));
00555
00556 xmlSetProp(curr, (xmlChar *)"index", (xmlChar *)"0");
00557 }
00558
00559 return 0;
00560 }
00561
00562
00576 int
00577 write_ascii_short_array(xmlNodePtr p, short **data, short **ch, long *elem, long n, char *tag_name)
00578 {
00579 long l, m;
00580 char t[20];
00581 xmlNodePtr curr;
00582
00583 for (l = 0; l < n; l++)
00584 {
00585 curr = xmlNewTextChild(p, NULL, (xmlChar *)tag_name, NULL);
00586 sprintf(t, "%ld", l);
00587 xmlSetProp(curr, (xmlChar *)"index", (xmlChar *)t);
00588
00589 for (m = 0; m < elem[l]; m++)
00590 {
00591 sprintf(t, "%d", data[l][m]);
00592 curr = xmlNewTextChild(curr, NULL, (xmlChar *)"content", (xmlChar *)t);
00593 sprintf(t, "%ld", m);
00594 xmlSetProp(curr, (xmlChar *)"index", (xmlChar *)t);
00595 sprintf(t, "%d", ch[l][m]);
00596 xmlSetProp(curr, (xmlChar *)"ch", (xmlChar *)t);
00597 }
00598 }
00599
00600 return 0;
00601 }
00602
00603
00617 int
00618 write_ascii_long_array(xmlNodePtr p, long **data, short **ch, long *elem, long n, char *tag_name)
00619 {
00620 long l, m;
00621 char t[20];
00622 xmlNodePtr curr;
00623
00624 for (l = 0; l < n; l++)
00625 {
00626 curr = xmlNewTextChild(p, NULL, (xmlChar *)tag_name, NULL);
00627 sprintf(t, "%ld", l);
00628 xmlSetProp(curr, (xmlChar *)"index", (xmlChar *)t);
00629
00630 for (m = 0; m < elem[l]; m++)
00631 {
00632 sprintf(t, "%ld", data[l][m]);
00633 curr = xmlNewTextChild(curr, NULL, (xmlChar *)"content", (xmlChar *)t);
00634 sprintf(t, "%ld", m);
00635 xmlSetProp(curr, (xmlChar *)"index", (xmlChar *)t);
00636 sprintf(t, "%d", ch[l][m]);
00637 xmlSetProp(curr, (xmlChar *)"ch", (xmlChar *)t);
00638 }
00639 }
00640
00641 return 0;
00642 }
00643
00644
00658 int
00659 write_ascii_double_array(xmlNodePtr p, double **data, short **ch, long *elem, long n, char *tag_name)
00660 {
00661 long l, m;
00662 char t[20];
00663 xmlNodePtr curr;
00664
00665 for (l = 0; l < n; l++)
00666 {
00667 curr = xmlNewTextChild(p, NULL, (xmlChar *)tag_name, NULL);
00668 sprintf(t, "%ld", l);
00669 xmlSetProp(curr, (xmlChar *)"index", (xmlChar *)t);
00670
00671 for (m = 0; m < elem[l]; m++)
00672 {
00673 xmlChar *c = xmlXPathCastNumberToString(data[l][m]);
00674 curr = xmlNewTextChild(curr, NULL, (xmlChar *)"content", c);
00675 xmlFree(c);
00676 sprintf(t, "%ld", m);
00677 xmlSetProp(curr, (xmlChar *)"index", (xmlChar *)t);
00678 sprintf(t, "%d", ch[l][m]);
00679 xmlSetProp(curr, (xmlChar *)"ch", (xmlChar *)t);
00680 }
00681 }
00682
00683 return 0;
00684 }
00685
00686
00694 int
00695 write_templates_xml(struct event_set *set, xmlNodePtr parent)
00696 {
00697 struct template_struct *templ = set->templ;
00698
00699 while (templ)
00700 {
00701 int i;
00702 xmlNodePtr node;
00703 char prop_name[EVAL_MAX_NAME];
00704
00705 node = xmlNewChild(parent, NULL, (xmlChar *)"Template", NULL);
00706
00707 if (find_prop_name(set->eval, templ, prop_name) != 0)
00708 return -1;
00709 xmlSetProp(node, (xmlChar *)"event-prop", (xmlChar *)prop_name);
00710
00711 for (i = 0; i < templ->num_ch; i++)
00712 {
00713 xmlNodePtr ch;
00714 char t[20];
00715 ch = xmlNewChild(node, NULL, (xmlChar *)"Channel", NULL);
00716
00717 sprintf(t, "%d", templ->ch[i]);
00718 xmlSetProp(ch, (xmlChar *)"number", (xmlChar *)t);
00719 sprintf(t, "%d", templ->template_size[i]);
00720 xmlSetProp(ch, (xmlChar *)"size", (xmlChar *)t);
00721 }
00722
00723 for (i = 0; i < templ->num_templates; i++)
00724 write_single_template_xml(templ, i, &(templ->st[i]), node);
00725
00726 templ = templ->next;
00727 }
00728
00729 return 0;
00730 }
00731
00732
00743 int
00744 find_prop_name(struct eval *e, struct template_struct *templ, char *name)
00745 {
00746 struct event_property *prop = e->prop;
00747 int found = 0;
00748
00749 while (prop)
00750 {
00751 if (prop->templ == templ)
00752 {
00753 strncpy(name, prop->id_ascii, EVAL_MAX_NAME);
00754 found = 1;
00755 break;
00756 }
00757
00758 prop = prop->next;
00759 }
00760
00761 return !found;
00762 }
00763
00764
00774 int
00775 write_single_template_xml(struct template_struct *templ, int index,
00776 struct single_template *st, xmlNodePtr parent)
00777 {
00778 int i;
00779 char t[20];
00780 xmlNodePtr node;
00781
00782 node = xmlNewChild(parent, NULL, (xmlChar *)"single", NULL);
00783
00784 sprintf(t, "%d", index);
00785 xmlSetProp(node, (xmlChar *)"index", (xmlChar *)t);
00786 sprintf(t, "%ld", st->num);
00787 xmlSetProp(node, (xmlChar *)"number", (xmlChar *)t);
00788 sprintf(t, "%d", st->fiducial_offset);
00789 xmlSetProp(node, (xmlChar *)"fiducial-offset", (xmlChar *)t);
00790 sprintf(t, "%ld", st->type);
00791 xmlSetProp(node, (xmlChar *)"type", (xmlChar *)t);
00792
00793 for (i = 0; i < templ->num_ch; i++)
00794 {
00795 char *data = NULL;
00796 long size;
00797 xmlNodePtr curr;
00798
00799 encode_base64(st->data[i], (sizeof(double) * templ->template_size[i]), &data, &size);
00800 if (data)
00801 {
00802 curr = xmlNewTextChild(node, NULL, (xmlChar *)"data", (xmlChar *)data);
00803 free(data);
00804 sprintf(t, "%d", i);
00805 xmlSetProp(curr, (xmlChar *)"ch-index", (xmlChar *)t);
00806 }
00807 }
00808
00809 return 0;
00810 }