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 <libxml/parser.h>
00028 #include "mime64.h"
00029
00030 #ifndef WIN32
00031 #include <unistd.h>
00032 #endif
00033
00034 #define _LIBRASCH_BUILD
00035 #define _DEFINE_INFO_STRUCTS_PROP
00036 #include <ra_priv.h>
00037 #undef _DEFINE_INFO_STRUCTS
00038 #include <pl_general.h>
00039 #include <ra_linked_list.h>
00040
00041
00042
00051 LIBRAAPI int
00052 ra_eval_loadxml(meas_handle mh, const char *file)
00053 {
00054 struct ra_meas *mm = (struct ra_meas *) mh;
00055 char fn[MAX_PATH_RA];
00056 int ret;
00057 xmlDocPtr doc;
00058 FILE *fp;
00059
00060 if (!mm)
00061 return -1;
00062
00063 if (file)
00064 strncpy(fn, file, MAX_PATH_RA);
00065 else
00066 get_eval_file_xml(mm, fn);
00067
00068
00069 fp = fopen(fn, "r");
00070 if (fp == NULL)
00071 return 0;
00072 fclose(fp);
00073
00074 if ((doc = xmlParseFile(fn)) == NULL)
00075 {
00076 _ra_set_error(mh, RA_ERR_READ_EVAL, "libRASCH");
00077 return -1;
00078 }
00079 if (!doc->children || ((xmlStrcmp(doc->children->name, (xmlChar *)"libRASCH") != 0) && (xmlStrcmp(doc->children->name, (xmlChar *)"libMTK") != 0)))
00080 {
00081 xmlFreeDoc(doc);
00082 _ra_set_error(mh, RA_ERR_EVAL_FILE_CORRUPT, "libRASCH");
00083 return -1;
00084 }
00085
00086 ret = read_evals_xml(mm, doc->children);
00087
00088 xmlFreeDoc(doc);
00089
00090 return ret;
00091 }
00092
00093
00102 int
00103 get_eval_file_xml(meas_handle mh, char *f)
00104 {
00105 long dir = 0;
00106 value_handle vh;
00107 rec_handle rh;
00108
00109 rh = ra_rec_get_first(mh, 0);
00110 vh = ra_value_malloc();
00111 if (ra_info_get(rh, RA_INFO_REC_GEN_DIR_L, vh) != 0)
00112 {
00113 ra_value_free(vh);
00114 return -1;
00115 }
00116 dir = ra_value_get_long(vh);
00117
00118 if (ra_info_get(rh, RA_INFO_REC_GEN_PATH_C, vh) != 0)
00119 {
00120 ra_value_free(vh);
00121 return -1;
00122 }
00123
00124 if (dir)
00125 sprintf(f, "%s%ceval_ra.mte", ra_value_get_string(vh), SEPERATOR);
00126 else
00127 sprintf(f, "%s.mte", ra_value_get_string(vh));
00128
00129 ra_value_free(vh);
00130
00131 return 0;
00132 }
00133
00134
00142 int
00143 read_evals_xml(meas_handle mh, xmlNodePtr parent)
00144 {
00145 struct ra_meas *mm = (struct ra_meas *) mh;
00146 struct eval *e;
00147 int ret = 0;
00148 xmlNodePtr node, child;
00149 xmlChar *c;
00150
00151 node = parent->children;
00152 while (node)
00153 {
00154 if (xmlStrcmp(node->name, (xmlChar *)"Evaluation") != 0)
00155 {
00156 node = node->next;
00157 continue;
00158 }
00159
00160 e = calloc(1, sizeof(struct eval));
00161 e->handle_id = RA_HANDLE_EVAL;
00162 e->mm = mm;
00163 ra_list_add((void **) &(mm->evals), e);
00164 mm->num_evals++;
00165
00166 child = get_node(node, "Flags");
00167 if (child)
00168 {
00169 if (xmlHasProp(child, (xmlChar *)"original") != NULL)
00170 e->original = 1;
00171 if (xmlHasProp(child, (xmlChar *)"default") != NULL)
00172 e->def = 1;
00173 }
00174
00175 c = xmlGetProp(node, (xmlChar *)"name");
00176 if (c != NULL)
00177 {
00178 strncpy(e->name, (const char *)c, EVAL_MAX_NAME);
00179 xmlFree(c);
00180 }
00181
00182 child = get_node(node, "comment");
00183 c = xmlNodeGetContent(child);
00184 if (c != NULL)
00185 {
00186 strncpy(e->comment, (const char *)c, EVAL_MAX_DESC);
00187 xmlFree(c);
00188 }
00189
00190 child = get_node(node, "add-ts");
00191 c = xmlNodeGetContent(child);
00192 if (c != NULL)
00193 {
00194 strncpy(e->add_timestamp, (const char *)c, EVAL_MAX_TS);
00195 xmlFree(c);
00196 }
00197 child = get_node(node, "modify-ts");
00198 c = xmlNodeGetContent(child);
00199 if (c != NULL)
00200 {
00201 strncpy(e->modify_timestamp, (const char *)c, EVAL_MAX_TS);
00202 xmlFree(c);
00203 }
00204 child = get_node(node, "user");
00205 c = xmlNodeGetContent(child);
00206 if (c != NULL)
00207 {
00208 strncpy(e->add_user, (const char *)c, EVAL_MAX_USER);
00209 xmlFree(c);
00210 }
00211 child = get_node(node, "host");
00212 c = xmlNodeGetContent(child);
00213 if (c != NULL)
00214 {
00215 strncpy(e->add_host, (const char *)c, EVAL_MAX_HOST);
00216 xmlFree(c);
00217 }
00218 child = get_node(node, "program");
00219 c = xmlNodeGetContent(child);
00220 if (c != NULL)
00221 {
00222 strncpy(e->add_program, (const char *)c, EVAL_MAX_PRG);
00223 xmlFree(c);
00224 }
00225
00226 if ((ret = read_sets_xml(e, node)) != 0)
00227 return ret;
00228
00229 node = node->next;
00230 }
00231
00232 return ret;
00233 }
00234
00235
00244 xmlNodePtr
00245 get_node(xmlNodePtr parent, char *name)
00246 {
00247 xmlNodePtr child = parent->children;
00248
00249 while (child)
00250 {
00251 if (xmlStrcmp(child->name, (xmlChar *)name) == 0)
00252 return child;
00253 child = child->next;
00254 }
00255
00256 return NULL;
00257 }
00258
00259
00267 int
00268 read_sets_xml(struct eval *e, xmlNodePtr parent)
00269 {
00270 int ret = 0;
00271 struct event_set *set;
00272 xmlNodePtr child, node = parent->children;
00273 xmlChar *c;
00274 int use_ascii = 0;
00275
00276 while (node)
00277 {
00278 if (xmlStrcmp(node->name, (xmlChar *)"Event-Set") != 0)
00279 {
00280 node = node->next;
00281 continue;
00282 }
00283
00284 set = calloc(1, sizeof(struct event_set));
00285 set->handle_id = RA_HANDLE_EVSET;
00286 set->eval = e;
00287 ra_list_add((void **) &(e->set), set);
00288 e->num_sets++;
00289
00290 c = xmlGetProp(node, (xmlChar *)"name");
00291 if (c)
00292 {
00293 strncpy(set->name, (const char *)c, EVAL_MAX_NAME);
00294 strncpy(set->id_ascii, (const char *)c, EVAL_MAX_NAME);
00295 xmlFree(c);
00296 }
00297
00298 c = xmlGetProp(node, (xmlChar *)"type");
00299 if (c)
00300 {
00301 if (xmlStrcmp(c, (xmlChar *)"discrete") == 0)
00302 set->type = EVENT_TYPE_DISC;
00303 else if (xmlStrcmp(c, (xmlChar *)"continues") == 0)
00304 set->type = EVENT_TYPE_CONT;
00305 else
00306 {
00307 _ra_set_error(e, RA_ERR_EVAL_FILE_CORRUPT, "libRASCH");
00308 return -1;
00309 }
00310
00311 xmlFree(c);
00312 }
00313
00314 c = xmlGetProp(node, (xmlChar *)"event-encoding");
00315 if (c && (xmlStrcmp(c, (xmlChar *)"ascii") == 0))
00316 use_ascii = 1;
00317
00318 child = get_node(node, "desc");
00319 c = xmlNodeGetContent(child);
00320 if (c)
00321 {
00322 strncpy(set->desc, (const char *)c, EVAL_MAX_DESC);
00323 xmlFree(c);
00324 }
00325
00326 child = get_node(node, "number-events");
00327 c = xmlNodeGetContent(child);
00328 if (c)
00329 {
00330 set->num_events = set->num_events_alloc = atol((const char *)c);
00331 xmlFree(c);
00332 }
00333
00334 if (set->type == EVENT_TYPE_CONT)
00335 ret = read_events_start_end_xml(set, node);
00336 if (ret != 0)
00337 break;
00338
00339 if ((ret = read_props_xml(set, node, use_ascii)) != 0)
00340 break;
00341
00342 if (read_templates_xml(set, node) != 0)
00343 return -1;
00344
00345 node = node->next;
00346 }
00347
00348 return ret;
00349 }
00350
00351
00360 int
00361 read_events_start_end_xml(struct event_set *set, xmlNodePtr parent)
00362 {
00363 xmlChar *c;
00364 void *t;
00365 long size;
00366 xmlNodePtr curr;
00367 long data_size;
00368
00369 data_size = set->num_events * sizeof(long);
00370
00371 curr = get_node(parent, "event-start");
00372 c = xmlNodeGetContent(curr);
00373 if (!c)
00374 {
00375 _ra_set_error(set, RA_ERR_EVAL_FILE_CORRUPT, "libRASCH");
00376 return -1;
00377 }
00378 decode_base64(c, strlen((const char *)c), &t, &size, data_size);
00379 set->start = malloc(size);
00380 memcpy(set->start, t, size);
00381 xmlFree(c);
00382 free(t);
00383
00384 curr = get_node(parent, "event-end");
00385 c = xmlNodeGetContent(curr);
00386 if (!c)
00387 {
00388 _ra_set_error(set, RA_ERR_EVAL_FILE_CORRUPT, "libRASCH");
00389 return -1;
00390 }
00391 decode_base64(c, strlen((const char *)c), &t, &size, data_size);
00392 set->end = malloc(size);
00393 memcpy(set->end, t, size);
00394 xmlFree(c);
00395 free(t);
00396
00397 if (size != data_size)
00398 {
00399 _ra_set_error(set, RA_ERR_EVAL_FILE_CORRUPT, "libRASCH");
00400 return -1;
00401 }
00402
00403 return 0;
00404 }
00405
00406
00416 int
00417 read_props_xml(struct event_set *set, xmlNodePtr parent, int use_ascii)
00418 {
00419 xmlNodePtr child, node = parent->children;
00420 xmlChar *c;
00421
00422 while (node)
00423 {
00424 struct event_property *prop;
00425
00426 if (xmlStrcmp(node->name, (xmlChar *)"Event-Property") != 0)
00427 {
00428 node = node->next;
00429 continue;
00430 }
00431
00432 prop = calloc(1, sizeof(struct event_property));
00433 prop->handle_id = RA_HANDLE_EVPROP;
00434 prop->set = set;
00435 prop->eval = set->eval;
00436 ra_list_add((void **) &(set->eval->prop), prop);
00437 set->eval->num_props++;
00438
00439 c = xmlGetProp(node, (xmlChar *)"name");
00440 if (c)
00441 {
00442 strncpy(prop->name, (const char *)c, EVAL_MAX_NAME);
00443 strncpy(prop->id_ascii, (const char *)c, EVAL_MAX_NAME);
00444 xmlFree(c);
00445 }
00446 c = xmlGetProp(node, (xmlChar *)"val-type");
00447 if (c)
00448 {
00449 if (xmlStrcmp(c, (xmlChar *)"short") == 0)
00450 prop->val_type = EVPROP_TYPE_SHORT;
00451 else if (xmlStrcmp(c, (xmlChar *)"long") == 0)
00452 prop->val_type = EVPROP_TYPE_LONG;
00453 else if (xmlStrcmp(c, (xmlChar *)"double") == 0)
00454 prop->val_type = EVPROP_TYPE_DOUBLE;
00455 else if (xmlStrcmp(c, (xmlChar *)"char") == 0)
00456 prop->val_type = EVPROP_TYPE_CHAR;
00457 else if (xmlStrcmp(c, (xmlChar *)"short-array") == 0)
00458 prop->val_type = EVPROP_TYPE_SHORT_ARRAY;
00459 else if (xmlStrcmp(c, (xmlChar *)"long-array") == 0)
00460 prop->val_type = EVPROP_TYPE_LONG_ARRAY;
00461 else if (xmlStrcmp(c, (xmlChar *)"double-array") == 0)
00462 prop->val_type = EVPROP_TYPE_DOUBLE_ARRAY;
00463 else
00464 {
00465 _ra_set_error(set, RA_ERR_EVAL_FILE_CORRUPT, "libRASCH");
00466 return -1;
00467 }
00468
00469 xmlFree(c);
00470 }
00471 c = xmlGetProp(node, (xmlChar *)"use-minmax");
00472 if (c)
00473 {
00474 if (c[0] == '1')
00475 prop->use_minmax = 1;
00476 else
00477 prop->use_minmax = 0;
00478 xmlFree(c);
00479 }
00480 c = xmlGetProp(node, (xmlChar *)"min-value");
00481 if (c)
00482 {
00483 prop->min_value = atof((const char *)c);
00484 xmlFree(c);
00485 }
00486 c = xmlGetProp(node, (xmlChar *)"max-value");
00487 if (c)
00488 {
00489 prop->max_value = atof((const char *)c);
00490 xmlFree(c);
00491 }
00492
00493 c = xmlGetProp(node, (xmlChar *)"unit");
00494 if (c)
00495 {
00496 strncpy(prop->unit, (const char *)c, EVAL_MAX_UNIT);
00497 xmlFree(c);
00498 }
00499
00500 child = get_node(node, "desc");
00501 c = xmlNodeGetContent(child);
00502 if (c)
00503 {
00504 strncpy(prop->desc, (const char *)c, EVAL_MAX_DESC);
00505 xmlFree(c);
00506 }
00507
00508 read_events_xml(prop, node, use_ascii);
00509
00510 node = node->next;
00511 }
00512
00513 return 0;
00514 }
00515
00516
00526 int
00527 read_events_xml(struct event_property *prop, xmlNodePtr parent, int use_ascii)
00528 {
00529 int ret = 0;
00530 xmlNodePtr curr;
00531 xmlChar *c;
00532
00533 curr = get_node(parent, "events");
00534
00535
00536 if (use_ascii)
00537 return handle_value_events_ascii(prop, curr);
00538
00539
00540 c = xmlNodeGetContent(curr);
00541 if (!c)
00542 {
00543 _ra_set_error(prop, RA_ERR_EVAL_FILE_CORRUPT, "libRASCH");
00544 return -1;
00545 }
00546
00547
00548 if (prop->val_type == EVPROP_TYPE_CHAR)
00549 ret = handle_char_events(prop, c);
00550 else
00551 ret = handle_value_events(prop, c);
00552
00553 xmlFree(c);
00554
00555 return ret;
00556 }
00557
00558
00567 int
00568 handle_value_events_ascii(struct event_property *prop, xmlNodePtr parent)
00569 {
00570 struct event_set *set = prop->set;
00571 long l, idx;
00572 xmlNodePtr node;
00573 xmlChar *c;
00574
00575
00576
00577 idx = -1;
00578 for (l = 0; l < (sizeof(ra_event_props) / sizeof(struct event_prop_desc)); l++)
00579 {
00580 if (strcmp(ra_event_props[l].id_ascii, prop->id_ascii) == 0)
00581 {
00582 idx = l;
00583 break;
00584 }
00585 }
00586 if (idx != -1)
00587 prop->val_type = ra_event_props[idx].val_type;
00588
00589
00590 switch (prop->val_type)
00591 {
00592 case EVPROP_TYPE_SHORT:
00593 prop->idx = set->n_short;
00594 set->n_short += 1;
00595 set->s = realloc(set->s, sizeof(short *) * set->n_short);
00596 set->s[prop->idx] = malloc(sizeof(short) * set->num_events);
00597 break;
00598 case EVPROP_TYPE_LONG:
00599 prop->idx = set->n_long;
00600 set->n_long += 1;
00601 set->l = realloc(set->l, sizeof(long *) * set->n_long);
00602 set->l[prop->idx] = malloc(sizeof(long) * set->num_events);
00603 break;
00604 case EVPROP_TYPE_DOUBLE:
00605 prop->idx = set->n_double;
00606 set->n_double += 1;
00607 set->d = realloc(set->d, sizeof(double *) * set->n_double);
00608 set->d[prop->idx] = malloc(sizeof(double) * set->num_events);
00609 break;
00610 case EVPROP_TYPE_CHAR:
00611 prop->idx = set->n_char;
00612 set->n_char += 1;
00613 set->c = realloc(set->d, sizeof(char **) * set->n_char);
00614 set->c[prop->idx] = malloc(sizeof(char *) * set->num_events);
00615 break;
00616 case EVPROP_TYPE_SHORT_ARRAY:
00617 prop->idx = set->n_short_array;
00618 set->n_short_array += 1;
00619 set->sa = realloc(set->sa, sizeof(short **) * set->n_short_array);
00620 set->sa[prop->idx] = malloc(sizeof(short *) * set->num_events);
00621 set->sa_ch = realloc(set->sa_ch, sizeof(short **) * set->n_short_array);
00622 set->sa_ch[prop->idx] = malloc(sizeof(short *) * set->num_events);
00623 set->sa_num_elem = realloc(set->sa_num_elem, sizeof(long *) * set->n_short_array);
00624 set->sa_num_elem[prop->idx] = malloc(sizeof(long) * set->num_events);
00625 break;
00626 case EVPROP_TYPE_LONG_ARRAY:
00627 prop->idx = set->n_long_array;
00628 set->n_long_array += 1;
00629 set->la = realloc(set->la, sizeof(long **) * set->n_long_array);
00630 set->la[prop->idx] = malloc(sizeof(long *) * set->num_events);
00631 set->la_ch = realloc(set->sa_ch, sizeof(short **) * set->n_short_array);
00632 set->la_ch[prop->idx] = malloc(sizeof(short *) * set->num_events);
00633 set->la_num_elem = realloc(set->la_num_elem, sizeof(long *) * set->n_long_array);
00634 set->la_num_elem[prop->idx] = malloc(sizeof(long) * set->num_events);
00635 break;
00636 case EVPROP_TYPE_DOUBLE_ARRAY:
00637 prop->idx = set->n_double_array;
00638 set->n_double_array += 1;
00639 set->da = realloc(set->da, sizeof(double **) * set->n_double_array);
00640 set->da[prop->idx] = malloc(sizeof(double *) * set->num_events);
00641 set->da_ch = realloc(set->sa_ch, sizeof(short **) * set->n_short_array);
00642 set->da_ch[prop->idx] = malloc(sizeof(short *) * set->num_events);
00643 set->da_num_elem = realloc(set->da_num_elem, sizeof(long *) * set->n_double_array);
00644 set->da_num_elem[prop->idx] = malloc(sizeof(long) * set->num_events);
00645 break;
00646 }
00647
00648 node = parent->children;
00649 while (node)
00650 {
00651 long idx;
00652 c = xmlGetProp(node, (xmlChar *)"index");
00653 idx = atol((const char *)c);
00654 xmlFree(c);
00655 if (idx >= set->num_events)
00656 return -1;
00657
00658 switch (prop->val_type)
00659 {
00660 case EVPROP_TYPE_SHORT:
00661 read_short(node, prop, idx);
00662 break;
00663 case EVPROP_TYPE_LONG:
00664 read_long(node, prop, idx);
00665 break;
00666 case EVPROP_TYPE_DOUBLE:
00667 read_double(node, prop, idx);
00668 break;
00669 case EVPROP_TYPE_CHAR:
00670 read_char(node, prop, idx);
00671 break;
00672 case EVPROP_TYPE_SHORT_ARRAY:
00673 read_short_array(node, prop, idx);
00674 break;
00675 case EVPROP_TYPE_LONG_ARRAY:
00676 read_long_array(node, prop, idx);
00677 break;
00678 case EVPROP_TYPE_DOUBLE_ARRAY:
00679 read_double_array(node, prop, idx);
00680 break;
00681 default:
00682 return -1;
00683 break;
00684 }
00685
00686
00687 node = node->next;
00688 }
00689
00690 return 0;
00691 }
00692
00693
00703 int
00704 read_short(xmlNodePtr node, struct event_property *prop, long idx)
00705 {
00706 xmlNodePtr content;
00707 xmlChar *c;
00708 struct event_set *set = prop->set;
00709
00710 content = node->children;
00711 if (!content)
00712 return -1;
00713
00714 c = xmlNodeGetContent(content);
00715 set->s[prop->idx][idx] = (short)atoi((const char *)c);
00716 xmlFree(c);
00717
00718 return 0;
00719 }
00720
00721
00731 int
00732 read_long(xmlNodePtr node, struct event_property *prop, long idx)
00733 {
00734 xmlNodePtr content;
00735 xmlChar *c;
00736 struct event_set *set = prop->set;
00737
00738 content = node->children;
00739 if (!content)
00740 return -1;
00741
00742 c = xmlNodeGetContent(content);
00743 set->l[prop->idx][idx] = (long)atol((const char *)c);
00744 xmlFree(c);
00745
00746 return 0;
00747 }
00748
00749
00759 int
00760 read_double(xmlNodePtr node, struct event_property *prop, long idx)
00761 {
00762 xmlNodePtr content;
00763 xmlChar *c;
00764 struct event_set *set = prop->set;
00765
00766 content = node->children;
00767 if (!content)
00768 return -1;
00769
00770 c = xmlNodeGetContent(content);
00771 set->d[prop->idx][idx] = xmlXPathCastStringToNumber(c);
00772 xmlFree(c);
00773
00774 return 0;
00775 }
00776
00777
00787 int
00788 read_char(xmlNodePtr node, struct event_property *prop, long idx)
00789 {
00790 xmlNodePtr content;
00791 xmlChar *c;
00792 struct event_set *set = prop->set;
00793
00794 content = node->children;
00795 if (!content)
00796 return -1;
00797
00798 c = xmlNodeGetContent(content);
00799 set->c[prop->idx][idx] = calloc(strlen((const char *)c) + 1, sizeof(char));
00800 strncpy(set->c[prop->idx][idx], (const char *)c, strlen((const char *)c));
00801 xmlFree(c);
00802
00803 return 0;
00804 }
00805
00806
00816 int
00817 read_short_array(xmlNodePtr node, struct event_property *prop, long idx)
00818 {
00819 xmlNodePtr content;
00820 struct event_set *set = prop->set;
00821 long n_elem = 0;
00822 short *buf = NULL;
00823 short *ch_buf = NULL;
00824 xmlChar *c;
00825
00826 content = node->children;
00827 if (!content)
00828 return -1;
00829
00830 while (content)
00831 {
00832 long idx2;
00833 c = xmlGetProp(content, (xmlChar *)"index");
00834 idx2 = atol((const char *)c);
00835 xmlFree(c);
00836 if ((idx2+1) > n_elem)
00837 {
00838 n_elem = idx2 + 1;
00839 buf = realloc(buf, sizeof(short) * n_elem);
00840 ch_buf = realloc(ch_buf, sizeof(short) * n_elem);
00841 }
00842
00843 c = xmlGetProp(content, (xmlChar *)"ch");
00844 ch_buf[idx2] = (short)atol((const char *)c);
00845 xmlFree(c);
00846
00847 c = xmlNodeGetContent(content);
00848 buf[idx2] = (short)atoi((const char *)c);
00849 xmlFree(c);
00850
00851 content = content->next;
00852 }
00853 if (buf)
00854 {
00855 set->sa[prop->idx][idx] = buf;
00856 set->sa_ch[prop->idx][idx] = ch_buf;
00857 set->sa_num_elem[prop->idx][idx] = n_elem;
00858 }
00859
00860 return 0;
00861 }
00862
00863
00873 int
00874 read_long_array(xmlNodePtr node, struct event_property *prop, long idx)
00875 {
00876 xmlNodePtr content;
00877 struct event_set *set = prop->set;
00878 long n_elem = 0;
00879 long *buf = NULL;
00880 short *ch_buf = NULL;
00881 xmlChar *c;
00882
00883 content = node->children;
00884 if (!content)
00885 return -1;
00886
00887 while (content)
00888 {
00889 long idx2;
00890 c = xmlGetProp(content, (xmlChar *)"index");
00891 idx2 = atol((const char *)c);
00892 xmlFree(c);
00893 if ((idx2+1) > n_elem)
00894 {
00895 n_elem = idx2 + 1;
00896 buf = realloc(buf, sizeof(long) * n_elem);
00897 }
00898
00899 c = xmlGetProp(content, (xmlChar *)"ch");
00900 ch_buf[idx2] = (short)atol((const char *)c);
00901 xmlFree(c);
00902
00903 c = xmlNodeGetContent(content);
00904 buf[idx2] = (long)atol((const char *)c);
00905 xmlFree(c);
00906
00907 content = content->next;
00908 }
00909 if (buf)
00910 {
00911 set->la[prop->idx][idx] = buf;
00912 set->la_ch[prop->idx][idx] = ch_buf;
00913 set->la_num_elem[prop->idx][idx] = n_elem;
00914 }
00915
00916 return 0;
00917 }
00918
00919
00929 int
00930 read_double_array(xmlNodePtr node, struct event_property *prop, long idx)
00931 {
00932 xmlNodePtr content;
00933 struct event_set *set = prop->set;
00934 long n_elem = 0;
00935 double *buf = NULL;
00936 short *ch_buf = NULL;
00937 xmlChar *c;
00938
00939 content = node->children;
00940 if (!content)
00941 return -1;
00942
00943 while (content)
00944 {
00945 long idx2;
00946 c = xmlGetProp(content, (xmlChar *)"index");
00947 idx2 = atol((const char *)c);
00948 xmlFree(c);
00949 if ((idx2+1) > n_elem)
00950 {
00951 n_elem = idx2 + 1;
00952 buf = realloc(buf, sizeof(double) * n_elem);
00953 }
00954
00955 c = xmlGetProp(content, (xmlChar *)"ch");
00956 ch_buf[idx2] = (short)atol((const char *)c);
00957 xmlFree(c);
00958
00959 c = xmlNodeGetContent(content);
00960 buf[idx2] = xmlXPathCastStringToNumber(c);
00961 xmlFree(c);
00962
00963 content = content->next;
00964 }
00965 if (buf)
00966 {
00967 set->da[prop->idx][idx] = buf;
00968 set->da_ch[prop->idx][idx] = ch_buf;
00969 set->da_num_elem[prop->idx][idx] = n_elem;
00970 }
00971
00972 return 0;
00973 }
00974
00975
00984 int
00985 handle_char_events(struct event_property *prop, xmlChar *c)
00986 {
00987 int ret = 0;
00988 struct event_set *set = prop->set;
00989 char *p_curr, *p_next;
00990 long cnt;
00991
00992 prop->idx = set->n_char;
00993 set->n_char += 1;
00994 set->c = realloc(set->c, sizeof(char **) * set->n_char);
00995 memset(&(set->c[prop->idx]), 0, sizeof(char *));
00996
00997 p_curr = (char *)c;
00998 p_next = find_next_string(p_curr);
00999 cnt = 0;
01000 while (p_curr)
01001 {
01002 set->c[prop->idx] = realloc(set->c[prop->idx], sizeof(char *) * (cnt + 1));
01003
01004 set->c[prop->idx][cnt] = calloc(strlen(p_curr) + 1, sizeof(char));
01005 strncpy(set->c[prop->idx][cnt], p_curr, strlen(p_curr));
01006 cnt++;
01007
01008 if (!p_next)
01009 break;
01010
01011 p_curr = p_next;
01012 p_next = find_next_string(p_curr);
01013 }
01014
01015 if (set->num_events == 0)
01016 set->num_events = cnt;
01017 else
01018 {
01019
01020 if (set->num_events > cnt)
01021 set->num_events = cnt;
01022 }
01023
01024 return ret;
01025 }
01026
01027
01034 char *
01035 find_next_string(char *s)
01036 {
01037 char *p = s;
01038 int len = strlen(s);
01039
01040 while ((p = strchr(p, 10)))
01041 {
01042 if ((!p) || ((p - s) >= (len - 2)))
01043 {
01044 if (p)
01045 *p = '\0';
01046 return NULL;
01047 }
01048
01049 if ((p[1] == '.') && (p[2] == 10))
01050 {
01051 *p = '\0';
01052 p += 3;
01053 break;
01054 }
01055
01056 p++;
01057 }
01058
01059 if (p >= (s + len))
01060 return NULL;
01061
01062 return p;
01063 }
01064
01065
01074 int
01075 handle_value_events(struct event_property *prop, xmlChar *c)
01076 {
01077 int ret = 0;
01078 void *t = NULL;
01079 long size, cnt;
01080 struct event_set *set = prop->set;
01081 long data_size, l, idx;
01082 double *buf = NULL;
01083
01084
01085 switch (prop->val_type)
01086 {
01087 case EVPROP_TYPE_SHORT:
01088 data_size = set->num_events * sizeof(short);
01089 decode_base64(c, strlen((const char *)c), &t, &size, data_size);
01090 cnt = set->num_events_alloc = size / sizeof(short);
01091 buf = malloc(sizeof(double) * set->num_events);
01092 for (l = 0; l < set->num_events; l++)
01093 buf[l] = (double)((short *)t)[l];
01094 break;
01095 case EVPROP_TYPE_LONG:
01096 data_size = set->num_events * sizeof(long);
01097 decode_base64(c, strlen((const char *)c), &t, &size, data_size);
01098 cnt = set->num_events_alloc = size / sizeof(long);
01099 buf = malloc(sizeof(double) * set->num_events);
01100 for (l = 0; l < set->num_events; l++)
01101 buf[l] = (double)((long *)t)[l];
01102 break;
01103 case EVPROP_TYPE_DOUBLE:
01104 data_size = set->num_events * sizeof(double);
01105 decode_base64(c, strlen((const char *)c), &t, &size, data_size);
01106 cnt = set->num_events_alloc = size / sizeof(double);
01107 buf = malloc(sizeof(double) * set->num_events);
01108 memcpy(buf, t, size);
01109 break;
01110 }
01111 if (t)
01112 free(t);
01113
01114 if (set->num_events == 0)
01115 set->num_events = cnt;
01116 else
01117 {
01118
01119 if (set->num_events > cnt)
01120 set->num_events = cnt;
01121 }
01122
01123
01124
01125 idx = -1;
01126 for (l = 0; l < (sizeof(ra_event_props) / sizeof(struct event_prop_desc)); l++)
01127 {
01128 if (strcmp(ra_event_props[l].id_ascii, prop->id_ascii) == 0)
01129 {
01130 idx = l;
01131 break;
01132 }
01133 }
01134
01135 if (idx != -1)
01136 prop->val_type = ra_event_props[idx].val_type;
01137
01138 switch (prop->val_type)
01139 {
01140 case EVPROP_TYPE_SHORT:
01141 prop->idx = set->n_short;
01142 set->n_short += 1;
01143 set->s = realloc(set->s, sizeof(short *) * set->n_short);
01144
01145 set->s[prop->idx] = malloc(sizeof(short) * set->num_events);
01146 for (l = 0; l < set->num_events; l++)
01147 set->s[prop->idx][l] = (short)buf[l];
01148 break;
01149 case EVPROP_TYPE_LONG:
01150 prop->idx = set->n_long;
01151 set->n_long += 1;
01152 set->l = realloc(set->l, sizeof(long *) * set->n_long);
01153
01154 set->l[prop->idx] = malloc(sizeof(long) * set->num_events);
01155 for (l = 0; l < set->num_events; l++)
01156 set->l[prop->idx][l] = (long)buf[l];
01157 break;
01158 case EVPROP_TYPE_DOUBLE:
01159 prop->idx = set->n_double;
01160 set->n_double += 1;
01161 set->d = realloc(set->d, sizeof(double *) * set->n_double);
01162
01163 set->d[prop->idx] = malloc(sizeof(double) * set->num_events);
01164 memcpy(set->d[prop->idx], buf, sizeof(double) * set->num_events);
01165 break;
01166 }
01167 if (buf)
01168 free(buf);
01169
01170 if (size != data_size)
01171 {
01172 _ra_set_error(prop, RA_ERR_EVAL_FILE_CORRUPT, "libRASCH");
01173 return -1;
01174 }
01175
01176 return ret;
01177 }
01178
01179
01187 int
01188 read_templates_xml(struct event_set *set, xmlNodePtr parent)
01189 {
01190 xmlNodePtr child, node = parent->children;
01191 xmlChar *c;
01192 struct template_struct *templ = set->templ;
01193
01194 while (node)
01195 {
01196 if (xmlStrcmp(node->name, (xmlChar *)"Template") != 0)
01197 {
01198 node = node->next;
01199 continue;
01200 }
01201
01202 templ = calloc(1, sizeof(struct template_struct));
01203 templ->handle_id = RA_HANDLE_TEMPLATE;
01204 templ->set = set;
01205 ra_list_add((void **) &(set->templ), templ);
01206 set->num_templates++;
01207
01208 child = node->children;
01209 while (child)
01210 {
01211 if (xmlStrcmp(child->name, (xmlChar *)"Channel") != 0)
01212 {
01213 child = child->next;
01214 continue;
01215 }
01216
01217 templ->num_ch++;
01218 templ->ch = realloc(templ->ch, sizeof(int) * templ->num_ch);
01219 templ->template_size =
01220 realloc(templ->template_size, sizeof(int) * templ->num_ch);
01221 c = xmlGetProp(child, (xmlChar *)"number");
01222 if (c)
01223 {
01224 templ->ch[templ->num_ch - 1] = atoi((const char *)c);
01225 xmlFree(c);
01226 }
01227 c = xmlGetProp(child, (xmlChar *)"size");
01228 if (c)
01229 {
01230 templ->template_size[templ->num_ch - 1] = atoi((const char *)c);
01231 xmlFree(c);
01232 }
01233
01234 child = child->next;
01235 }
01236
01237 c = xmlGetProp(node, (xmlChar *)"event-prop");
01238 if (c)
01239 {
01240 struct event_property *prop = find_prop(set->eval, (const char *)c);
01241 if (prop)
01242 prop->templ = templ;
01243 xmlFree(c);
01244 }
01245
01246 if (read_single_template_xml(templ, node) != 0)
01247 {
01248 _ra_set_error(set, RA_ERR_EVAL_FILE_CORRUPT, "libRASCH");
01249 return -1;
01250 }
01251
01252 node = node->next;
01253 }
01254
01255 return 0;
01256 }
01257
01258
01266 prop_handle
01267 find_prop(struct eval *e, const char *name)
01268 {
01269 struct event_property *prop = e->prop;
01270
01271 while (prop)
01272 {
01273 if (strcmp(prop->id_ascii, name) == 0)
01274 return prop;
01275
01276 prop = prop->next;
01277 }
01278
01279 return NULL;
01280 }
01281
01282
01290 int
01291 read_single_template_xml(struct template_struct *templ, xmlNodePtr parent)
01292 {
01293 void *t;
01294 long size;
01295 xmlChar *c;
01296 xmlNodePtr curr, node = parent->children;
01297
01298 while (node)
01299 {
01300 if (xmlStrcmp(node->name, (xmlChar *)"single") != 0)
01301 {
01302 node = node->next;
01303 continue;
01304 }
01305
01306 templ->num_templates++;
01307 templ->st = realloc(templ->st, sizeof(struct single_template) * templ->num_templates);
01308
01309 c = xmlGetProp(node, (xmlChar *)"number");
01310 if (c)
01311 {
01312 templ->st[templ->num_templates - 1].num = atol((const char *)c);
01313 xmlFree(c);
01314 }
01315 c = xmlGetProp(node, (xmlChar *)"fiducial-offset");
01316 if (c)
01317 {
01318 templ->st[templ->num_templates - 1].fiducial_offset = atoi((const char *)c);
01319 xmlFree(c);
01320 }
01321 c = xmlGetProp(node, (xmlChar *)"type");
01322 if (c)
01323 {
01324 templ->st[templ->num_templates - 1].type = atol((const char *)c);
01325 xmlFree(c);
01326 }
01327
01328 templ->st[templ->num_templates - 1].data = malloc(sizeof(double *) * templ->num_ch);
01329 curr = node->children;
01330 while (curr)
01331 {
01332 int idx;
01333
01334 if (xmlStrcmp(curr->name, (xmlChar *)"data") != 0)
01335 {
01336 curr = curr->next;
01337 continue;
01338 }
01339
01340 c = xmlGetProp(curr, (xmlChar *)"ch-index");
01341 if (!c)
01342 return -1;
01343 idx = atoi((const char *)c);
01344 xmlFree(c);
01345 if ((idx >= templ->num_ch) || (idx < 0))
01346 return -1;
01347 c = xmlNodeGetContent(curr);
01348 if (!c)
01349 return -1;
01350 decode_base64(c, strlen((const char *)c), &t, &size, -1);
01351 templ->st[templ->num_templates - 1].data[idx] = malloc(size);
01352 memcpy(templ->st[templ->num_templates - 1].data[idx], t, size);
01353 xmlFree(c);
01354 free(t);
01355
01356 curr = curr->next;
01357 }
01358
01359 node = node->next;
01360 }
01361
01362 return 0;
01363 }