00001
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <string.h>
00019 #include <stdlib.h>
00020 #include <stdio.h>
00021 #include <errno.h>
00022 #include <time.h>
00023 #include <assert.h>
00024 #include <ctype.h>
00025
00026 #ifndef WIN32
00027 #include <unistd.h>
00028 #endif
00029
00030 #define _LIBRASCH_BUILD
00031 #include <ra_eval.h>
00032 #include <pl_general.h>
00033 #include <ra_linked_list.h>
00034 #include "eval.h"
00035
00036
00037 LIBRAAPI int
00038 ra_eval_edit_start(any_handle h)
00039 {
00040 return 0;
00041 }
00042
00043
00044 LIBRAAPI int
00045 ra_eval_edit_complete(any_handle h)
00046 {
00047 return 0;
00048 }
00049
00050
00051 LIBRAAPI int
00052 ra_eval_edit_cancel(any_handle h)
00053 {
00054 return 0;
00055 }
00056
00057
00058
00059
00060 LIBRAAPI int
00061 ra_eval_attribute_list(any_handle h, value_handle vh)
00062 {
00063 int ret, i, num;
00064 struct eval_head *head = (struct eval_head *)h;
00065 char **names;
00066 struct eval_attribute *curr;
00067
00068 _ra_set_error(h, RA_ERR_NONE, "libRASCH");
00069 ra_value_reset(vh);
00070
00071 num = 0;
00072 names = NULL;
00073 curr = head->meas->eval.attribute;
00074 while (curr)
00075 {
00076 if (curr->src_handle == h)
00077 {
00078 num++;
00079 names = realloc(names, sizeof(char *) * num);
00080
00081 names[num-1] = (char *)malloc(sizeof(char) * MAX_ATTRIB_LEN);
00082 strncpy(names[num-1], curr->name, MAX_ATTRIB_LEN);
00083 }
00084 curr = curr->next;
00085 }
00086
00087 if (num > 0)
00088 {
00089 ra_value_set_string_array(vh, (const char **)names, num);
00090
00091 for (i = 0; i < num; i++)
00092 free(names[i]);
00093 free(names);
00094 }
00095
00096 return ret;
00097 }
00098
00099
00108 LIBRAAPI int
00109 ra_eval_attribute_get(any_handle h, const char *id, value_handle vh)
00110 {
00111 int ret = -1;
00112 struct eval_head *head= (struct eval_head *)h;
00113 struct eval_attribute *curr;
00114
00115 _ra_set_error(h, RA_ERR_NONE, "libRASCH");
00116 ra_value_reset(vh);
00117
00118 if ((curr = find_attribute(head, id)) == NULL)
00119 {
00120 _ra_set_error(h, RA_ERR_UNKNOWN, "libRASCH");
00121 return -1;
00122 }
00123
00124 ret = ra_value_copy(vh, curr->value);
00125
00126 return ret;
00127 }
00128
00129
00138 LIBRAAPI int
00139 ra_eval_attribute_set(any_handle h, const char *id, value_handle vh)
00140 {
00141 int ret = -1;
00142 struct eval_head *head = (struct eval_head *)h;
00143 struct eval_attribute *curr;
00144
00145 _ra_set_error(h, RA_ERR_NONE, "libRASCH");
00146
00147 if ((curr = find_attribute(head, id)) == NULL)
00148 {
00149 curr = (struct eval_attribute *)calloc(1, sizeof(struct eval_attribute));
00150 ra_list_add((void **)&(head->meas->eval.attribute), curr);
00151
00152 curr->src_handle = h;
00153 strncpy(curr->name, id, MAX_ATTRIB_LEN-1);
00154 curr->value = ra_value_malloc();
00155 }
00156
00157 ret = ra_value_copy(curr->value, vh);
00158
00159 return ret;
00160 }
00161
00162
00170 LIBRAAPI int
00171 ra_eval_attribute_unset(any_handle h, const char *id)
00172 {
00173 int ret = -1;
00174 struct eval_head *head = (struct eval_head *)h;
00175 struct eval_attribute *curr;
00176
00177 _ra_set_error(h, RA_ERR_NONE, "libRASCH");
00178
00179 if ((curr = find_attribute(head, id)) == NULL)
00180 {
00181 _ra_set_error(h, RA_ERR_UNKNOWN, "libRASCH");
00182 return -1;
00183 }
00184
00185 ra_value_free(curr->value);
00186 ret = ra_list_del((void **)&(head->meas->eval.attribute), curr);
00187
00188 return ret;
00189 }
00190
00191
00192 struct eval_attribute *
00193 find_attribute(struct eval_head *h, const char *id)
00194 {
00195 struct eval_attribute *curr;
00196
00197 curr = h->meas->eval.attribute;
00198 while (curr)
00199 {
00200 if ((curr->src_handle == h) && (strncmp(curr->name, id, MAX_ATTRIB_LEN)))
00201 break;
00202
00203 curr = curr->next;
00204 }
00205
00206 return curr;
00207 }
00208
00209
00210 int
00211 delete_attributes(struct eval_head *h)
00212 {
00213 struct eval_attribute *a;
00214
00215 a = h->meas->eval.attribute;
00216 while (a)
00217 {
00218 if (a->src_handle == h)
00219 {
00220 ra_value_free(a->value);
00221 ra_list_del((void **)&(h->meas->eval.attribute), a);
00222 a = h->meas->eval.attribute;
00223 continue;
00224 }
00225
00226 a = a->next;
00227 }
00228
00229 return 0;
00230 }
00231
00232
00233
00234
00235
00245 LIBRAAPI eval_handle
00246 ra_eval_add(meas_handle mh, const char *name, const char *desc, int original)
00247 {
00248 struct ra_meas *meas = (struct ra_meas *) mh;
00249 struct eval *e = NULL;
00250 char text[EVAL_MAX_DESC];
00251 struct tm *t;
00252 time_t tt;
00253 value_handle vh = NULL;
00254
00255 _ra_set_error(mh, RA_ERR_NONE, "libRASCH");
00256
00257 if (!mh)
00258 return NULL;
00259 if (meas->handle_id != RA_HANDLE_MEAS)
00260 {
00261 _ra_set_error(mh, RA_ERR_WRONG_HANDLE, "libRASCH");
00262 return NULL;
00263 }
00264
00265
00266 if (original)
00267 {
00268 e = ra_eval_get_original(mh);
00269 if (e)
00270 {
00271 _ra_set_error(mh, RA_ERR_EVAL_WRONG_TYPE, "libRASCH");
00272 return NULL;
00273 }
00274 }
00275
00276 e = (struct eval *)calloc(1, sizeof(struct eval));
00277 ra_list_add((void **)&(meas->eval.evaluations), e);
00278
00279 e->handle_id = RA_HANDLE_EVAL;
00280 e->meas = meas;
00281 e->original = original;
00282
00283 time(&tt);
00284 t = gmtime(&tt);
00285 sprintf(text, "%02d.%02d.%4d %02d:%02d:%02d", t->tm_mday,
00286 t->tm_mon + 1, (t->tm_year + 1900), t->tm_hour, t->tm_min, t->tm_sec);
00287
00288 vh = ra_value_malloc();
00289 ra_value_set_string(vh, text);
00290 if (ra_eval_attribute_set(e, "add-timestamp", vh) != 0)
00291 goto error;
00292 if (ra_eval_attribute_set(e, "modify-timestamp", vh) != 0)
00293 goto error;
00294
00295 if (set_env(e) != 0)
00296 goto error;
00297
00298
00299 if (ra_eval_set_default(e) != 0)
00300 goto error;
00301
00302 if (name)
00303 {
00304 ra_value_set_string(vh, name);
00305 if (ra_eval_attribute_set(e, "name", vh) != 0)
00306 goto error;
00307 }
00308 if (desc)
00309 {
00310 ra_value_set_string(vh, desc);
00311 if (ra_eval_attribute_set(e, "description", vh) != 0)
00312 goto error;
00313 }
00314 ra_value_free(vh);
00315
00316 return e;
00317
00318 error:
00319 if (e)
00320 ra_list_del((void **)&(meas->eval.evaluations), e);
00321 if (vh)
00322 ra_value_free(vh);
00323
00324 return NULL;
00325 }
00326
00327
00328
00337 #ifdef LINUX
00338 int
00339 set_env(struct eval *e)
00340 {
00341 char t[EVAL_MAX_DESC];
00342 char fn[MAX_PATH_RA];
00343 FILE *f;
00344 value_handle vh;
00345
00346 vh = ra_value_malloc();
00347
00348 gethostname(t, EVAL_MAX_HOST);
00349 if (t[0] != '\0')
00350 {
00351 ra_value_set_string(vh, t);
00352 ra_eval_attribute_set(e, "add-host", vh);
00353 }
00354
00355 if (getenv("LOGNAME") != NULL)
00356 {
00357 ra_value_set_string(vh, getenv("LOGNAME"));
00358 ra_eval_attribute_set(e, "add-user", vh);
00359 }
00360
00361 sprintf(fn, "/proc/%d/status", getpid());
00362 f = fopen(fn, "r");
00363 if (f != NULL)
00364 {
00365 char *p;
00366
00367 fgets(t, 200, f);
00368 fclose(f);
00369
00370 p = strchr(t, '\t');
00371 if ((p != NULL) && (p + 1 != '\0'))
00372 {
00373 char *newline;
00374
00375 p++;
00376 newline = strchr(p, '\n');
00377 if (newline)
00378 *newline = '\0';
00379 ra_value_set_string(vh, p);
00380 ra_eval_attribute_set(e, "add-program", vh);
00381 }
00382 }
00383
00384 ra_value_free(vh);
00385
00386 return 0;
00387 }
00388
00389 #elif WIN32
00390
00391 int
00392 set_env(struct eval *e)
00393 {
00394 char t[EVAL_MAX_DESC];
00395 char full_path[MAX_PATH_RA];
00396 char *pos, *cmd;
00397 long size;
00398 value_handle vh;
00399
00400 vh = ra_value_malloc();
00401
00402 size = EVAL_MAX_DESC;
00403 GetComputerName(t, &size);
00404 ra_value_set_string(vh, t);
00405 ra_eval_attribute_set(e, "add-host", vh);
00406 size = EVAL_MAX_DESC;
00407 GetUserName(t, &size);
00408 ra_value_set_string(vh, t);
00409 ra_eval_attribute_set(e, "add-user", vh);
00410
00411 cmd = GetCommandLine();
00412 pos = strchr(cmd, ' ');
00413 if (pos == NULL)
00414 strncpy(full_path, cmd, MAX_PATH_RA);
00415 else
00416 strncpy(full_path, cmd, pos - cmd);
00417 pos = strrchr(full_path, '\\');
00418 if (pos == NULL)
00419 pos = full_path;
00420 else
00421 pos++;
00422 strncpy(t, pos, EVAL_MAX_PRG);
00423 pos = strchr(t, '\"');
00424 if (pos != NULL)
00425 *pos = '\0';
00426 ra_value_set_string(vh, t);
00427 ra_eval_attribute_set(e, "add-program", vh);
00428
00429 ra_value_free(vh);
00430
00431 return 0;
00432 }
00433
00434 #else
00435
00436 int
00437 set_env(struct eval *e)
00438 {
00439 return 0;
00440 }
00441 #endif
00442
00443
00450 LIBRAAPI int
00451 ra_eval_delete(eval_handle eh)
00452 {
00453 int ret;
00454 value_handle vh;
00455 struct eval *e = (struct eval *)eh;
00456 struct eval_info *ei;
00457
00458 _ra_set_error(eh, RA_ERR_NONE, "libRASCH");
00459
00460 if (!eh)
00461 return -1;
00462 if (e->handle_id != RA_HANDLE_EVAL)
00463 {
00464 _ra_set_error(eh, RA_ERR_WRONG_HANDLE, "libRASCH");
00465 return -1;
00466 }
00467
00468
00469 vh = ra_value_malloc();
00470 while (1)
00471 {
00472 const void **p;
00473 long n;
00474
00475 ret = ra_class_get(eh, NULL, vh);
00476 if (ret != 0)
00477 break;
00478 n = ra_value_get_num_elem(vh);
00479 if (n <= 0)
00480 break;
00481 p = ra_value_get_voidp_array(vh);
00482 ra_class_delete((class_handle)(p[0]));
00483 }
00484 ra_value_free(vh);
00485 if (ret != 0)
00486 return -1;
00487
00488
00489 delete_attributes((struct eval_head *)e);
00490
00491
00492 ei = &(e->meas->eval);
00493 ra_list_del((void **)&(ei->evaluations), e);
00494
00495 return 0;
00496 }
00497
00498
00506 LIBRAAPI int
00507 ra_eval_get_all(meas_handle mh, value_handle vh)
00508 {
00509 struct ra_meas *meas = (struct ra_meas *)mh;
00510 void **p;
00511 int i, cnt;
00512 struct eval *curr;
00513
00514 if ((!mh) || (!vh))
00515 {
00516 if (mh)
00517 _ra_set_error(mh, RA_ERR_INFO_MISSING, "libRASCH");
00518 return -1;
00519 }
00520
00521 ra_value_reset(vh);
00522 _ra_set_error(mh, RA_ERR_NONE, "libRASCH");
00523
00524 if (meas->eval.evaluations == NULL)
00525 return 0;
00526
00527 cnt = ra_list_len(meas->eval.evaluations);
00528
00529 p = (void **)calloc(cnt, sizeof(void *));
00530
00531 curr = meas->eval.evaluations;
00532 for (i = 0; i < cnt; i++)
00533 {
00534 if (curr == NULL)
00535 break;
00536 p[i] = curr;
00537 curr = curr->next;
00538 }
00539 ra_value_set_voidp_array(vh, (const void **)p, cnt);
00540
00541 free(p);
00542
00543 return 0;
00544 }
00545
00546
00553 LIBRAAPI eval_handle
00554 ra_eval_get_original(meas_handle mh)
00555 {
00556 struct ra_meas *meas = (struct ra_meas *)mh;
00557 struct eval *e = NULL;
00558
00559 if (!mh)
00560 return NULL;
00561 _ra_set_error(mh, RA_ERR_NONE, "libRASCH");
00562
00563 e = meas->eval.evaluations;
00564 while (e)
00565 {
00566 if (e->original)
00567 break;
00568 e = e->next;
00569 }
00570
00571 return e;
00572 }
00573
00574
00581 LIBRAAPI eval_handle
00582 ra_eval_get_default(meas_handle mh)
00583 {
00584 struct ra_meas *meas = (struct ra_meas *)mh;
00585 struct eval *e = NULL;
00586
00587 _ra_set_error(mh, RA_ERR_NONE, "libRASCH");
00588 if (!mh)
00589 return NULL;
00590
00591 e = meas->eval.evaluations;
00592 while (e)
00593 {
00594 if (e->def)
00595 break;
00596 e = e->next;
00597 }
00598
00599 return e;
00600 }
00601
00602
00609 LIBRAAPI int
00610 ra_eval_set_default(eval_handle eh)
00611 {
00612 struct eval *e, *e_prev;
00613
00614 if (!eh)
00615 return -1;
00616 _ra_set_error(eh, RA_ERR_NONE, "libRASCH");
00617
00618 e = (struct eval *)eh;
00619
00620 e_prev = ra_eval_get_default(ra_meas_handle_from_any_handle(eh));
00621 if (e_prev)
00622 e_prev->def = 0;
00623
00624 e->def = 1;
00625
00626 return 0;
00627 }
00628
00629
00637 LIBRAAPI eval_handle
00638 ra_eval_get_handle(class_handle clh)
00639 {
00640 struct eval_class *c = (struct eval_class *)clh;
00641
00642 if (!clh)
00643 return NULL;
00644
00645 _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
00646
00647 if (c->handle_id != RA_HANDLE_EVAL_CLASS)
00648 {
00649 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
00650 return NULL;
00651 }
00652
00653 return (eval_handle)(c->eval);
00654 }
00655
00656
00657
00658
00659
00660
00661
00675 LIBRAAPI class_handle
00676 ra_class_add(eval_handle eh, const char *id, const char *name, const char *desc)
00677 {
00678 struct eval *e = (struct eval *)eh;
00679 struct eval_class *c = NULL;
00680 value_handle vh = NULL;
00681
00682 if (!eh)
00683 return NULL;
00684
00685 if ((id == NULL) || (id[0] == '\0'))
00686 {
00687 _ra_set_error(eh, RA_ERR_INFO_MISSING, "libRASCH");
00688 return NULL;
00689 }
00690
00691 _ra_set_error(eh, RA_ERR_NONE, "libRASCH");
00692
00693 c = calloc(1, sizeof(struct eval_class));
00694 ra_list_add((void **)&(e->cl), c);
00695
00696 c->handle_id = RA_HANDLE_EVAL_CLASS;
00697 c->id = get_class_id(id);
00698 strncpy(c->ascii_id, id, MAX_ID_LEN);
00699 c->meas = e->meas;
00700 c->eval = e;
00701
00702 vh = ra_value_malloc();
00703 if (name)
00704 {
00705 ra_value_set_string(vh, name);
00706 if (ra_eval_attribute_set(c, "name", vh) != 0)
00707 goto error;
00708 }
00709 if (desc)
00710 {
00711 ra_value_set_string(vh, desc);
00712 if (ra_eval_attribute_set(c, "description", vh) != 0)
00713 goto error;
00714 }
00715 ra_value_free(vh);
00716
00717 return c;
00718
00719 error:
00720 ra_class_delete(c);
00721
00722 if (vh)
00723 ra_value_free(vh);
00724
00725 return NULL;
00726 }
00727
00728
00738 LIBRAAPI class_handle
00739 ra_class_add_predef(eval_handle eh, const char *id)
00740 {
00741 class_handle clh = NULL;
00742 value_handle vh_name, vh_desc;
00743
00744 vh_name = ra_value_malloc();
00745 vh_desc = ra_value_malloc();
00746
00747 if (fill_predef_class_info_ascii(id, vh_name, vh_desc) != 0)
00748 goto error;
00749
00750 clh = ra_class_add(eh, id, ra_value_get_string(vh_name), ra_value_get_string(vh_desc));
00751
00752 error:
00753 ra_value_free(vh_name);
00754 ra_value_free(vh_desc);
00755
00756 return clh;
00757 }
00758
00759
00766 LIBRAAPI int
00767 ra_class_delete(class_handle clh)
00768 {
00769 struct eval_class *c = (struct eval_class *)clh;
00770 struct eval *e;
00771 struct eval_property *p;
00772 struct eval_summary *s;
00773
00774 _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
00775
00776 if (!clh)
00777 return -1;
00778 if (c->handle_id != RA_HANDLE_EVAL_CLASS)
00779 {
00780 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
00781 return -1;
00782 }
00783
00784
00785 while ((p = c->prop))
00786 ra_prop_delete(p);
00787
00788
00789 while ((s = c->summaries))
00790 ra_sum_delete(s);
00791
00792
00793 if (c->ev)
00794 free(c->ev);
00795
00796
00797 delete_attributes((struct eval_head *)c);
00798
00799
00800 e = c->eval;
00801 ra_list_del((void **)&(e->cl), c);
00802
00803 return 0;
00804 }
00805
00806
00817 LIBRAAPI int
00818 ra_class_get(eval_handle eh, const char *id, value_handle vh)
00819 {
00820 struct eval *e = (struct eval *)eh;
00821 struct eval_class *c;
00822 int num;
00823 void **vp;
00824
00825 _ra_set_error(eh, RA_ERR_NONE, "libRASCH");
00826 ra_value_reset(vh);
00827
00828 if (!eh)
00829 return -1;
00830 if (e->handle_id != RA_HANDLE_EVAL)
00831 {
00832 _ra_set_error(eh, RA_ERR_WRONG_HANDLE, "libRASCH");
00833 return -1;
00834 }
00835 if (!vh)
00836 {
00837 _ra_set_error(eh, RA_ERR_INFO_MISSING, "libRASCH");
00838 return -1;
00839 }
00840
00841 c = e->cl;
00842 num = 0;
00843 vp = NULL;
00844 while (c)
00845 {
00846 int ok = 1;
00847
00848 if (id && (id[0] != '\0') && (strcmp(c->ascii_id, id) != 0))
00849 ok = 0;
00850
00851 if (ok)
00852 {
00853 num++;
00854 vp = (void **)realloc(vp, sizeof(void *) * num);
00855 vp[num-1] = c;
00856 }
00857
00858 c = c->next;
00859 }
00860
00861 if (num > 0)
00862 {
00863 ra_value_set_voidp_array(vh, (const void **)vp, num);
00864 free(vp);
00865 }
00866
00867 return 0;
00868 }
00869
00870
00882 LIBRAAPI long
00883 ra_class_add_event(class_handle clh, long start, long end)
00884 {
00885 struct eval_class *c = (struct eval_class *)clh;
00886
00887 _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
00888
00889 if (!clh)
00890 return -1;
00891 if (c->handle_id != RA_HANDLE_EVAL_CLASS)
00892 {
00893 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
00894 return -1;
00895 }
00896
00897 c->num_event++;
00898 c->ev = (struct eval_event *)realloc(c->ev, sizeof(struct eval_event) * c->num_event);
00899 c->last_id++;
00900 c->ev[c->num_event-1].id = c->last_id;
00901 c->ev[c->num_event-1].start = start;
00902 c->ev[c->num_event-1].end = end;
00903
00904 add_prop_mem(c);
00905
00906 return c->last_id;
00907 }
00908
00909
00910 int
00911 add_prop_mem(struct eval_class *c)
00912 {
00913 struct eval_property *p = c->prop;
00914 long total, added;
00915
00916 while (p)
00917 {
00918
00919 if (p->allocated_events >= c->num_event)
00920 {
00921 p = p->next;
00922 continue;
00923 }
00924
00925
00926 added = (long)((double)p->allocated_events * EVENT_MEM_ADD);
00927 if (added < 1)
00928 added = 1;
00929
00930 total = p->allocated_events + added;
00931
00932 switch (p->value_type)
00933 {
00934 case RA_VALUE_TYPE_SHORT:
00935 p->value.s = realloc(p->value.s, sizeof(short *) * total);
00936 memset(p->value.s + p->allocated_events, 0, sizeof(short *) * added);
00937 break;
00938 case RA_VALUE_TYPE_LONG:
00939 p->value.l = realloc(p->value.l, sizeof(long *) * total);
00940 memset(p->value.l + p->allocated_events, 0, sizeof(long *) * added);
00941 break;
00942 case RA_VALUE_TYPE_DOUBLE:
00943 p->value.d = realloc(p->value.d, sizeof(double *) * total);
00944 memset(p->value.d + p->allocated_events, 0, sizeof(double *) * added);
00945 break;
00946 case RA_VALUE_TYPE_CHAR:
00947 p->value.c = realloc(p->value.c, sizeof(char **) * total);
00948 memset(p->value.c + p->allocated_events, 0, sizeof(char **) * added);
00949 break;
00950 case RA_VALUE_TYPE_SHORT_ARRAY:
00951 p->value.sa = realloc(p->value.sa, sizeof(short **) * total);
00952 memset(p->value.sa + p->allocated_events, 0, sizeof(short **) * added);
00953 break;
00954 case RA_VALUE_TYPE_LONG_ARRAY:
00955 p->value.la = realloc(p->value.la, sizeof(long **) * total);
00956 memset(p->value.la + p->allocated_events, 0, sizeof(long **) * added);
00957 break;
00958 case RA_VALUE_TYPE_DOUBLE_ARRAY:
00959 p->value.da = realloc(p->value.da, sizeof(double **) * total);
00960 memset(p->value.da + p->allocated_events, 0, sizeof(double **) * added);
00961 break;
00962 case RA_VALUE_TYPE_CHAR_ARRAY:
00963 p->value.ca = realloc(p->value.ca, sizeof(char ***) * total);
00964 memset(p->value.ca + p->allocated_events, 0, sizeof(char ***) * added);
00965 break;
00966 }
00967
00968 p->ch_map = realloc(p->ch_map, sizeof(short *) * total);
00969 memset(p->ch_map + p->allocated_events, 0, sizeof(short *) * added);
00970
00971 p->num_entries = realloc(p->num_entries, sizeof(long) * total);
00972 memset(p->num_entries + p->allocated_events, 0, sizeof(long) * added);
00973
00974 p->num_elements = realloc(p->num_elements, sizeof(long *) * total);
00975 memset(p->num_elements + p->allocated_events, 0, sizeof(long *) * added);
00976
00977
00978
00979 p->allocated_events = total;
00980
00981 p = p->next;
00982 }
00983
00984 return 0;
00985 }
00986
00987
00995 LIBRAAPI int
00996 ra_class_del_event(class_handle clh, long event_id)
00997 {
00998 struct eval_class *c = (struct eval_class *)clh;
00999 long idx;
01000
01001 _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
01002
01003 if (!clh)
01004 return -1;
01005 if (c->handle_id != RA_HANDLE_EVAL_CLASS)
01006 {
01007 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
01008 return -1;
01009 }
01010 if ((event_id < 0) || (event_id > c->last_id))
01011 {
01012 _ra_set_error(clh, RA_ERR_OUT_OF_RANGE, "libRASCH");
01013 return -1;
01014 }
01015
01016 idx = get_event_idx(c, event_id);
01017 if (idx < 0)
01018 {
01019 _ra_set_error(clh, RA_ERR_WRONG_INPUT, "libRASCH");
01020 return -1;
01021 }
01022
01023 del_prop_values(c, idx);
01024
01025 if (idx == 0)
01026 memmove(c->ev, c->ev + 1, sizeof(struct eval_event) * (c->num_event - 1));
01027 else if (idx < (c->num_event-1))
01028 memmove(c->ev + idx, c->ev + idx+1, sizeof(struct eval_event) * (c->num_event - idx - 1));
01029
01030 c->num_event--;
01031
01032 c->ev = (struct eval_event *)realloc(c->ev, sizeof(struct eval_event) * c->num_event);
01033
01034 return 0;
01035 }
01036
01037
01038 long
01039 get_event_idx(struct eval_class *c, long event_id)
01040 {
01041 long idx = -1;
01042 long l;
01043
01044 for (l = 0; l < c->num_event; l++)
01045 {
01046 if (c->ev[l].id == event_id)
01047 {
01048 idx = l;
01049 break;
01050 }
01051 }
01052
01053 return idx;
01054 }
01055
01056
01057 int
01058 del_prop_values(struct eval_class *c, long idx)
01059 {
01060 long l, m;
01061 struct eval_property *p = c->prop;
01062
01063 while (p)
01064 {
01065 switch (p->value_type)
01066 {
01067 case RA_VALUE_TYPE_SHORT:
01068 free(p->value.s[idx]);
01069 if (idx < (c->num_event - 1))
01070 memmove(p->value.s + idx, p->value.s + idx+1, sizeof(short *) * (c->num_event - idx - 1));
01071 p->value.s[c->num_event-1] = NULL;
01072 break;
01073 case RA_VALUE_TYPE_LONG:
01074 free(p->value.l[idx]);
01075 if (idx < (c->num_event - 1))
01076 memmove(p->value.l + idx, p->value.l + idx+1, sizeof(long *) * (c->num_event - idx - 1));
01077 p->value.l[c->num_event-1] = NULL;
01078 break;
01079 case RA_VALUE_TYPE_DOUBLE:
01080 free(p->value.d[idx]);
01081 if (idx < (c->num_event - 1))
01082 memmove(p->value.d + idx, p->value.d + idx+1, sizeof(double *) * (c->num_event - idx - 1));
01083 p->value.d[c->num_event-1] = NULL;
01084 break;
01085 case RA_VALUE_TYPE_CHAR:
01086 for (l = 0; l < p->num_entries[idx]; l++)
01087 free(p->value.c[idx][l]);
01088 free(p->value.c[idx]);
01089 if (idx < (c->num_event - 1))
01090 memmove(p->value.c + idx, p->value.c + idx+1, sizeof(char **) * (c->num_event - idx - 1));
01091 p->value.c[c->num_event-1] = NULL;
01092 break;
01093 case RA_VALUE_TYPE_SHORT_ARRAY:
01094 for (l = 0; l < p->num_entries[idx]; l++)
01095 free(p->value.sa[idx][l]);
01096 free(p->value.sa[idx]);
01097 if (idx < (c->num_event - 1))
01098 memmove(p->value.sa + idx, p->value.sa + idx+1, sizeof(short **) * (c->num_event - idx - 1));
01099 p->value.sa[c->num_event-1] = NULL;
01100 break;
01101 case RA_VALUE_TYPE_LONG_ARRAY:
01102 for (l = 0; l < p->num_entries[idx]; l++)
01103 free(p->value.la[idx][l]);
01104 free(p->value.la[idx]);
01105 if (idx < (c->num_event - 1))
01106 memmove(p->value.la + idx, p->value.la + idx+1, sizeof(long **) * (c->num_event - idx - 1));
01107 p->value.la[c->num_event-1] = NULL;
01108 break;
01109 case RA_VALUE_TYPE_DOUBLE_ARRAY:
01110 for (l = 0; l < p->num_entries[idx]; l++)
01111 free(p->value.da[idx][l]);
01112 free(p->value.da[idx]);
01113 if (idx < (c->num_event - 1))
01114 memmove(p->value.da + idx, p->value.da + idx+1, sizeof(double **) * (c->num_event - idx - 1));
01115 p->value.da[c->num_event-1] = NULL;
01116 break;
01117 case RA_VALUE_TYPE_CHAR_ARRAY:
01118 for (l = 0; l < p->num_entries[idx]; l++)
01119 {
01120 for (m = 0; m < p->num_elements[idx][l]; m++)
01121 free(p->value.ca[idx][l][m]);
01122 free(p->value.ca[idx][l]);
01123 }
01124 free(p->value.ca[idx]);
01125 if (idx < (c->num_event - 1))
01126 memmove(p->value.ca + idx, p->value.ca + idx+1, sizeof(char ***) * (c->num_event - idx - 1));
01127 p->value.ca[c->num_event-1] = NULL;
01128 break;
01129 }
01130
01131 free(p->ch_map[idx]);
01132 free(p->num_elements[idx]);
01133
01134 if (idx < (c->num_event - 1))
01135 {
01136 memmove(p->ch_map + idx, p->ch_map + idx+1, sizeof(short *) * (c->num_event - idx - 1));
01137 memmove(p->num_entries + idx, p->num_entries + idx+1, sizeof(long) * (c->num_event - idx - 1));
01138 memmove(p->num_elements + idx, p->num_elements + idx+1, sizeof(long *) * (c->num_event - idx - 1));
01139 }
01140 p->ch_map[c->num_event-1] = NULL;
01141 p->num_entries[c->num_event-1] = 0;
01142 p->num_elements[c->num_event-1] = NULL;
01143
01144 p = p->next;
01145 }
01146
01147 return 0;
01148 }
01149
01150
01161 LIBRAAPI int
01162 ra_class_get_event_pos(class_handle clh, long event_id, long *start, long *end)
01163 {
01164 struct eval_class *c= (struct eval_class *)clh;
01165 long idx;
01166
01167 _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
01168
01169 if (!clh)
01170 return -1;
01171 if (c->handle_id != RA_HANDLE_EVAL_CLASS)
01172 {
01173 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
01174 return -1;
01175 }
01176 if ((event_id < 0) || (event_id > c->last_id))
01177 {
01178 _ra_set_error(clh, RA_ERR_OUT_OF_RANGE, "libRASCH");
01179 return -1;
01180 }
01181
01182 idx = get_event_idx(c, event_id);
01183 if (idx < 0)
01184 {
01185 _ra_set_error(clh, RA_ERR_WRONG_INPUT, "libRASCH");
01186 return -1;
01187 }
01188
01189 if (start)
01190 *start = c->ev[idx].start;
01191 if (end)
01192 *end = c->ev[idx].end;
01193
01194 return 0;
01195 }
01196
01197
01208 LIBRAAPI int
01209 ra_class_set_event_pos(class_handle clh, long event_id, long start, long end)
01210 {
01211 struct eval_class *c= (struct eval_class *)clh;
01212 long idx;
01213
01214 _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
01215
01216 if (!clh)
01217 return -1;
01218 if (c->handle_id != RA_HANDLE_EVAL_CLASS)
01219 {
01220 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
01221 return -1;
01222 }
01223 if ((event_id < 0) || (event_id > c->last_id))
01224 {
01225 _ra_set_error(clh, RA_ERR_OUT_OF_RANGE, "libRASCH");
01226 return -1;
01227 }
01228
01229 idx = get_event_idx(c, event_id);
01230 if (idx < 0)
01231 {
01232 _ra_set_error(clh, RA_ERR_WRONG_INPUT, "libRASCH");
01233 return -1;
01234 }
01235
01236 c->ev[idx].start = start;
01237 c->ev[idx].end = end;
01238
01239 return 0;
01240 }
01241
01242
01243 int
01244 comp_pos(const void* arg1, const void* arg2)
01245 {
01246 struct sort_pos *b1 = (struct sort_pos *)arg1;
01247 struct sort_pos *b2 = (struct sort_pos *)arg2;
01248
01249 return (b1->pos - b2->pos);
01250 }
01251
01252
01253
01268 LIBRAAPI int
01269 ra_class_get_events(class_handle clh, long start, long end, int complete, int sort, value_handle vh)
01270 {
01271 struct eval_class *c= (struct eval_class *)clh;
01272 struct sort_pos *sp = NULL;
01273 long *ids, l, num;
01274
01275 _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
01276 ra_value_reset(vh);
01277
01278 if (!clh)
01279 return -1;
01280 if (c->handle_id != RA_HANDLE_EVAL_CLASS)
01281 {
01282 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
01283 return -1;
01284 }
01285 if (!vh)
01286 {
01287 _ra_set_error(clh, RA_ERR_INFO_MISSING, "libRASCH");
01288 return -1;
01289 }
01290
01291 if ((start <= 0) && (end < 0))
01292 {
01293 num = c->num_event;
01294 sp = (struct sort_pos *)malloc(sizeof(struct sort_pos) * num);
01295 for (l = 0; l < num; l++)
01296 {
01297 sp[l].id = c->ev[l].id;
01298 sp[l].pos = c->ev[l].start;
01299 }
01300 }
01301 else
01302 {
01303 num = 0;
01304 for (l = 0; l < c->num_event; l++)
01305 {
01306 if ((c->ev[l].start < start) && complete)
01307 continue;
01308 if ((end != -1) && ((c->ev[l].end > end) && complete))
01309 continue;
01310 if ((end != -1) && (c->ev[l].end < start))
01311 continue;
01312 if (c->ev[l].start > end)
01313 continue;
01314
01315 num++;
01316 sp = (struct sort_pos *)realloc(sp, sizeof(struct sort_pos) * num);
01317 sp[num-1].id = c->ev[l].id;
01318 sp[num-1].pos = c->ev[l].start;
01319 }
01320 }
01321
01322 if ((num > 0) && sort)
01323 qsort(sp, num, sizeof(struct sort_pos), comp_pos);
01324
01325 if (num > 0)
01326 {
01327 ids = (long *)malloc(sizeof(long) * num);
01328 for (l = 0; l < num; l++)
01329 ids[l] = sp[l].id;
01330
01331 ra_value_set_long_array(vh, ids, num);
01332
01333 free(ids);
01334 free(sp);
01335 }
01336
01337 return 0;
01338 }
01339
01340
01347 LIBRAAPI class_handle
01348 ra_class_get_handle(prop_handle ph)
01349 {
01350 struct eval_property *p = (struct eval_property *)ph;
01351
01352 if (!ph)
01353 return NULL;
01354
01355 _ra_set_error(ph, RA_ERR_NONE, "libRASCH");
01356
01357 if (p->handle_id != RA_HANDLE_EVAL_PROP)
01358 {
01359 _ra_set_error(ph, RA_ERR_WRONG_HANDLE, "libRASCH");
01360 return NULL;
01361 }
01362
01363 return (class_handle)(p->evclass);
01364 }
01365
01366
01367
01368
01369
01370 LIBRAAPI prop_handle
01371 ra_prop_add(class_handle clh, const char *id, long value_type, long num_values, const char *name,
01372 const char *desc, const char *unit, int use_minmax, double min, double max)
01373 {
01374 struct eval_class *c = (struct eval_class *)clh;
01375 struct eval_property *p = NULL;
01376 value_handle vh = NULL;
01377
01378 _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
01379
01380 if (!clh)
01381 return NULL;
01382 if (c->handle_id != RA_HANDLE_EVAL_CLASS)
01383 {
01384 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
01385 return NULL;
01386 }
01387 if (id == NULL)
01388 {
01389 _ra_set_error(clh, RA_ERR_INFO_MISSING, "libRASCH");
01390 return NULL;
01391 }
01392
01393 p = calloc(1, sizeof(struct eval_property));
01394 ra_list_add((void **)&(c->prop), p);
01395
01396 p->handle_id = RA_HANDLE_EVAL_PROP;
01397 p->id = get_prop_id(id);
01398 strncpy(p->ascii_id, id, MAX_ID_LEN);
01399 p->meas = c->meas;
01400 p->evclass = c;
01401 p->value_type = value_type;
01402
01403 vh = ra_value_malloc();
01404 if (name)
01405 {
01406 ra_value_set_string(vh, name);
01407 if (ra_eval_attribute_set(p, "name", vh) != 0)
01408 goto error;
01409 }
01410 if (desc)
01411 {
01412 ra_value_set_string(vh, desc);
01413 if (ra_eval_attribute_set(p, "description", vh) != 0)
01414 goto error;
01415 }
01416 if (unit)
01417 {
01418 ra_value_set_string(vh, unit);
01419 if (ra_eval_attribute_set(p, "unit", vh) != 0)
01420 goto error;
01421 }
01422 if (use_minmax)
01423 {
01424 ra_value_set_long(vh, 1);
01425 if (ra_eval_attribute_set(p, "use-minmax", vh) != 0)
01426 goto error;
01427 ra_value_set_double(vh, min);
01428 if (ra_eval_attribute_set(p, "min", vh) != 0)
01429 goto error;
01430 ra_value_set_double(vh, max);
01431 if (ra_eval_attribute_set(p, "max", vh) != 0)
01432 goto error;
01433 }
01434 ra_value_free(vh);
01435
01436 if (alloc_prop_mem(p) != 0)
01437 goto error;
01438
01439 return p;
01440
01441 error:
01442 ra_prop_delete(p);
01443
01444 if (vh)
01445 ra_value_free(vh);
01446
01447 return NULL;
01448 }
01449
01450
01451 int
01452 alloc_prop_mem(struct eval_property *p)
01453 {
01454 struct eval_class *c = p->evclass;
01455
01456 p->allocated_events = c->num_event;
01457 if (c->num_event <= 0)
01458 return 0;
01459
01460 switch (p->value_type)
01461 {
01462 case RA_VALUE_TYPE_SHORT:
01463 p->value.s = calloc(c->num_event, sizeof(short *));
01464 break;
01465 case RA_VALUE_TYPE_LONG:
01466 p->value.l = calloc(c->num_event, sizeof(long *));
01467 break;
01468 case RA_VALUE_TYPE_DOUBLE:
01469 p->value.d = calloc(c->num_event, sizeof(double *));
01470 break;
01471 case RA_VALUE_TYPE_CHAR:
01472 p->value.c = calloc(c->num_event, sizeof(char **));
01473 break;
01474 case RA_VALUE_TYPE_SHORT_ARRAY:
01475 p->value.sa = calloc(c->num_event, sizeof(short **));
01476 break;
01477 case RA_VALUE_TYPE_LONG_ARRAY:
01478 p->value.la = calloc(c->num_event, sizeof(long **));
01479 break;
01480 case RA_VALUE_TYPE_DOUBLE_ARRAY:
01481 p->value.da = calloc(c->num_event, sizeof(double **));
01482 break;
01483 case RA_VALUE_TYPE_CHAR_ARRAY:
01484 p->value.ca = calloc(c->num_event, sizeof(char ***));
01485 break;
01486 }
01487
01488 p->ch_map = calloc(c->num_event, sizeof(short *));
01489 p->num_entries = calloc(c->num_event, sizeof(long));
01490 p->num_elements = calloc(c->num_event, sizeof(long *));
01491
01492 return 0;
01493 }
01494
01495
01496 LIBRAAPI prop_handle
01497 ra_prop_add_predef(class_handle clh, const char *id)
01498 {
01499 prop_handle ph = NULL;
01500 value_handle vh_type, vh_len, vh_name, vh_desc, vh_unit;
01501 value_handle vh_use_minmax, vh_min, vh_max;
01502
01503 vh_type = ra_value_malloc();
01504 vh_len = ra_value_malloc();
01505 vh_name = ra_value_malloc();
01506 vh_desc = ra_value_malloc();
01507 vh_unit = ra_value_malloc();
01508 vh_use_minmax = ra_value_malloc();
01509 vh_min = ra_value_malloc();
01510 vh_max = ra_value_malloc();
01511
01512 if (fill_predef_prop_info_ascii(id, vh_type, vh_len, vh_name, vh_desc, vh_unit,
01513 vh_use_minmax, vh_min, vh_max) != 0)
01514 {
01515 goto error;
01516 }
01517
01518
01519 ph = ra_prop_add(clh, id, ra_value_get_long(vh_type), ra_value_get_long(vh_len),
01520 ra_value_get_string(vh_name), ra_value_get_string(vh_desc), ra_value_get_string(vh_unit),
01521 ra_value_get_long(vh_use_minmax), ra_value_get_double(vh_min), ra_value_get_double(vh_max));
01522
01523 error:
01524 ra_value_free(vh_type);
01525 ra_value_free(vh_len);
01526 ra_value_free(vh_name);
01527 ra_value_free(vh_desc);
01528 ra_value_free(vh_unit);
01529 ra_value_free(vh_use_minmax);
01530 ra_value_free(vh_min);
01531 ra_value_free(vh_max);
01532
01533 return ph;
01534 }
01535
01536
01537 LIBRAAPI int
01538 ra_prop_delete(prop_handle ph)
01539 {
01540 struct eval_property *p = (struct eval_property *)ph;
01541 long l, m, n;
01542 struct eval_class *c;
01543
01544 _ra_set_error(ph, RA_ERR_NONE, "libRASCH");
01545
01546 if (!ph)
01547 return -1;
01548 if (p->handle_id != RA_HANDLE_EVAL_PROP)
01549 {
01550 _ra_set_error(ph, RA_ERR_WRONG_HANDLE, "libRASCH");
01551 return -1;
01552 }
01553
01554
01555 switch (p->value_type)
01556 {
01557 case RA_VALUE_TYPE_SHORT:
01558 for (l = 0; l < p->evclass->num_event; l++)
01559 {
01560 if (p->value.s[l])
01561 free(p->value.s[l]);
01562 }
01563 free(p->value.s);
01564 break;
01565 case RA_VALUE_TYPE_LONG:
01566 for (l = 0; l < p->evclass->num_event; l++)
01567 {
01568 if (p->value.l[l])
01569 free(p->value.l[l]);
01570 }
01571 free(p->value.l);
01572 break;
01573 case RA_VALUE_TYPE_DOUBLE:
01574 for (l = 0; l < p->evclass->num_event; l++)
01575 {
01576 if (p->value.d[l])
01577 free(p->value.d[l]);
01578 }
01579 free(p->value.d);
01580 break;
01581 case RA_VALUE_TYPE_CHAR:
01582 for (l = 0; l < p->evclass->num_event; l++)
01583 {
01584 if (p->value.c[l])
01585 {
01586 for (m = 0; m < p->num_entries[l]; m++)
01587 {
01588 if (p->value.c[l][m])
01589 free(p->value.c[l][m]);
01590 }
01591 free(p->value.c[l]);
01592 }
01593 }
01594 free(p->value.c);
01595 break;
01596 case RA_VALUE_TYPE_SHORT_ARRAY:
01597 for (l = 0; l < p->evclass->num_event; l++)
01598 {
01599 if (p->value.sa[l])
01600 {
01601 for (m = 0; m < p->num_entries[l]; m++)
01602 {
01603 if (p->value.sa[l][m])
01604 free(p->value.sa[l][m]);
01605 }
01606 free(p->value.sa[l]);
01607 }
01608 }
01609 free(p->value.sa);
01610 break;
01611 case RA_VALUE_TYPE_LONG_ARRAY:
01612 for (l = 0; l < p->evclass->num_event; l++)
01613 {
01614 if (p->value.la[l])
01615 {
01616 for (m = 0; m < p->num_entries[l]; m++)
01617 {
01618 if (p->value.la[l][m])
01619 free(p->value.la[l][m]);
01620 }
01621 free(p->value.la[l]);
01622 }
01623 }
01624 free(p->value.la);
01625 break;
01626 case RA_VALUE_TYPE_DOUBLE_ARRAY:
01627 for (l = 0; l < p->evclass->num_event; l++)
01628 {
01629 if (p->value.da[l])
01630 {
01631 for (m = 0; m < p->num_entries[l]; m++)
01632 {
01633 if (p->value.da[l][m])
01634 free(p->value.da[l][m]);
01635 }
01636 free(p->value.da[l]);
01637 }
01638 }
01639 free(p->value.da);
01640 break;
01641 case RA_VALUE_TYPE_CHAR_ARRAY:
01642 for (l = 0; l < p->evclass->num_event; l++)
01643 {
01644 if (p->value.ca[l])
01645 {
01646 for (m = 0; m < p->num_entries[l]; m++)
01647 {
01648 if (p->value.ca[l][m])
01649 {
01650 for (n = 0; n < p->num_elements[l][m]; n++)
01651 {
01652 if (p->value.ca[l][m][n])
01653 free(p->value.ca[l][m][n]);
01654 }
01655 free(p->value.ca[l][m]);
01656 }
01657 }
01658 free(p->value.ca[l]);
01659 }
01660 }
01661 free(p->value.ca);
01662 break;
01663 default:
01664 _ra_set_error(ph, RA_ERR_ERROR, "libRASCH");
01665 break;
01666 }
01667 if (p->num_entries)
01668 free(p->num_entries);
01669 if (p->ch_map)
01670 {
01671 for (l = 0; l < p->evclass->num_event; l++)
01672 {
01673 if (p->ch_map[l])
01674 free(p->ch_map[l]);
01675 }
01676 free(p->ch_map);
01677 }
01678 if (p->num_elements)
01679 {
01680 for (l = 0; l < p->evclass->num_event; l++)
01681 {
01682 if (p->num_elements[l])
01683 free(p->num_elements[l]);
01684 }
01685 free(p->num_elements);
01686 }
01687
01688
01689 delete_attributes(ph);
01690
01691
01692 c = p->evclass;
01693 ra_list_del((void **)&(c->prop), p);
01694
01695 return 0;
01696 }
01697
01698
01699 LIBRAAPI int
01700 ra_prop_get_all(class_handle clh, value_handle vh)
01701 {
01702 struct eval_class *c = (struct eval_class *)clh;
01703
01704 _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
01705 ra_value_reset(vh);
01706
01707 if (!clh)
01708 return -1;
01709 if (c->handle_id != RA_HANDLE_EVAL_CLASS)
01710 {
01711 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
01712 return -1;
01713 }
01714 if (!vh)
01715 {
01716 _ra_set_error(clh, RA_ERR_INFO_MISSING, "libRASCH");
01717 return -1;
01718 }
01719
01720 ra_value_set_voidp_array(vh, (const void **)(c->prop), ra_list_len(c->prop));
01721
01722 return 0;
01723 }
01724
01725
01726 LIBRAAPI prop_handle
01727 ra_prop_get(class_handle clh, const char *id)
01728 {
01729 struct eval_class *c = (struct eval_class *)clh;
01730 struct eval_property *p;
01731
01732 _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
01733
01734 if (!clh)
01735 return NULL;
01736 if (c->handle_id != RA_HANDLE_EVAL_CLASS)
01737 {
01738 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
01739 return NULL;
01740 }
01741 if (!id || (id[0] == '\0'))
01742 {
01743 _ra_set_error(clh, RA_ERR_INFO_MISSING, "libRASCH");
01744 return NULL;
01745 }
01746
01747 p = c->prop;
01748 while (p)
01749 {
01750 if (strcmp(p->ascii_id, id) == 0)
01751 break;
01752 p = p->next;
01753 }
01754
01755 return p;
01756 }
01757
01758
01759 LIBRAAPI int
01760 ra_prop_set_value(prop_handle ph, long event_id, long ch, value_handle vh)
01761 {
01762 struct eval_property *p = (struct eval_property *)ph;
01763 long l, idx, col;
01764 const char **ca;
01765
01766 _ra_set_error(ph, RA_ERR_NONE, "libRASCH");
01767
01768 if (p->handle_id != RA_HANDLE_EVAL_PROP)
01769 {
01770 _ra_set_error(ph, RA_ERR_WRONG_HANDLE, "libRASCH");
01771 return -1;
01772 }
01773 if (!vh || !ra_value_is_ok(vh))
01774 {
01775 _ra_set_error(ph, RA_ERR_INFO_MISSING, "libRASCH");
01776 return -1;
01777 }
01778 if (p->value_type != ra_value_get_type(vh))
01779 {
01780 _ra_set_error(ph, RA_ERR_EVAL_WRONG_TYPE, "libRASCH");
01781 return -1;
01782 }
01783
01784 idx = get_event_idx(p->evclass, event_id);
01785 if (idx < 0)
01786 {
01787 _ra_set_error(ph, RA_ERR_OUT_OF_RANGE, "libRASCH");
01788 return -1;
01789 }
01790
01791 col = -1;
01792 for (l = 0; l < p->num_entries[idx]; l++)
01793 {
01794 if (p->ch_map[idx][l] == ch)
01795 {
01796 col = l;
01797 break;
01798 }
01799 }
01800 if (col == -1)
01801 {
01802 p->num_entries[idx] += 1;
01803 col = p->num_entries[idx] - 1;
01804 p->ch_map[idx] = (short *)realloc(p->ch_map[idx], sizeof(short) * p->num_entries[idx]);
01805 p->ch_map[idx][col] = ch;
01806 p->num_elements[idx] = (long *)realloc(p->num_elements[idx], sizeof(long) * p->num_entries[idx]);
01807 p->num_elements[idx][col] = ra_value_get_num_elem(vh);
01808
01809 switch (p->value_type)
01810 {
01811 case RA_VALUE_TYPE_SHORT:
01812 p->value.s[idx] = (short *)realloc(p->value.s[idx], sizeof(short) * p->num_entries[idx]);
01813 break;
01814 case RA_VALUE_TYPE_LONG:
01815 p->value.l[idx] = (long *)realloc(p->value.l[idx], sizeof(long) * p->num_entries[idx]);
01816 break;
01817 case RA_VALUE_TYPE_DOUBLE:
01818 p->value.d[idx] = (double *)realloc(p->value.d[idx], sizeof(double) * p->num_entries[idx]);
01819 break;
01820 case RA_VALUE_TYPE_CHAR:
01821 p->value.c[idx] = (char **)realloc(p->value.c[idx], sizeof(char *) * p->num_entries[idx]);
01822 break;
01823 case RA_VALUE_TYPE_SHORT_ARRAY:
01824 p->value.sa[idx] = (short **)realloc(p->value.sa[idx], sizeof(short *) * p->num_entries[idx]);
01825 break;
01826 case RA_VALUE_TYPE_LONG_ARRAY:
01827 p->value.la[idx] = (long **)realloc(p->value.la[idx], sizeof(long *) * p->num_entries[idx]);
01828 break;
01829 case RA_VALUE_TYPE_DOUBLE_ARRAY:
01830 p->value.da[idx] = (double **)realloc(p->value.da[idx], sizeof(double *) * p->num_entries[idx]);
01831 break;
01832 case RA_VALUE_TYPE_CHAR_ARRAY:
01833 p->value.ca[idx] = (char ***)realloc(p->value.ca[idx], sizeof(char **) * p->num_entries[idx]);
01834 break;
01835 default:
01836 _ra_set_error(ph, RA_ERR_ERROR, "libRASCH");
01837 return -1;
01838 }
01839 }
01840
01841 switch (p->value_type)
01842 {
01843 case RA_VALUE_TYPE_SHORT:
01844 p->value.l[idx][col] = ra_value_get_short(vh);
01845 break;
01846 case RA_VALUE_TYPE_LONG:
01847 p->value.l[idx][col] = ra_value_get_long(vh);
01848 break;
01849 case RA_VALUE_TYPE_DOUBLE:
01850 p->value.d[idx][col] = ra_value_get_double(vh);
01851 break;
01852 case RA_VALUE_TYPE_CHAR:
01853 p->value.c[idx][col] = (char *)calloc((strlen(ra_value_get_string(vh)) + 1), sizeof(char));
01854 strcpy(p->value.c[idx][col], ra_value_get_string(vh));
01855 break;
01856 case RA_VALUE_TYPE_SHORT_ARRAY:
01857 p->value.sa[idx][col] = (short *)malloc(sizeof(short) * p->num_elements[idx][col]);
01858 memcpy(p->value.sa[idx][col], ra_value_get_short_array(vh), sizeof(short) * p->num_elements[idx][col]);
01859 break;
01860 case RA_VALUE_TYPE_LONG_ARRAY:
01861 p->value.la[idx][col] = (long *)malloc(sizeof(long) * p->num_elements[idx][col]);
01862 memcpy(p->value.la[idx][col], ra_value_get_long_array(vh), sizeof(long) * p->num_elements[idx][col]);
01863 break;
01864 case RA_VALUE_TYPE_DOUBLE_ARRAY:
01865 p->value.da[idx][col] = (double *)malloc(sizeof(double) * p->num_elements[idx][col]);
01866 memcpy(p->value.da[idx][col], ra_value_get_double_array(vh), sizeof(double) * p->num_elements[idx][col]);
01867 break;
01868 case RA_VALUE_TYPE_CHAR_ARRAY:
01869 p->value.ca[idx][col] = (char **)malloc(sizeof(char *) * p->num_elements[idx][col]);
01870 ca = ra_value_get_string_array(vh);
01871 for (l = 0; l < p->num_elements[idx][col]; l++)
01872 {
01873 p->value.ca[idx][col][l] = (char *)calloc(strlen(ca[l]) + 1, sizeof(char));
01874 strcpy(p->value.ca[idx][col][l], ca[l]);
01875 }
01876 break;
01877 default:
01878 _ra_set_error(ph, RA_ERR_ERROR, "libRASCH");
01879 return -1;
01880 }
01881
01882 return 0;
01883 }
01884
01885
01886 LIBRAAPI int
01887 ra_prop_get_ch(prop_handle ph, long event_id, value_handle vh)
01888 {
01889 struct eval_property *p = (struct eval_property *)ph;
01890 long idx;
01891
01892 _ra_set_error(ph, RA_ERR_NONE, "libRASCH");
01893
01894 if (p->handle_id != RA_HANDLE_EVAL_PROP)
01895 {
01896 _ra_set_error(ph, RA_ERR_WRONG_HANDLE, "libRASCH");
01897 return -1;
01898 }
01899 idx = get_event_idx(p->evclass, event_id);
01900 if (idx < 0)
01901 {
01902 _ra_set_error(ph, RA_ERR_OUT_OF_RANGE, "libRASCH");
01903 return -1;
01904 }
01905
01906 ra_value_set_short_array(vh, p->ch_map[idx], p->num_entries[idx]);
01907
01908 return 0;
01909 }
01910
01911
01912 LIBRAAPI int
01913 ra_prop_get_value(prop_handle ph, long event_id, long ch, value_handle vh)
01914 {
01915 struct eval_property *p = (struct eval_property *)ph;
01916 long l, idx, col;
01917
01918 _ra_set_error(ph, RA_ERR_NONE, "libRASCH");
01919
01920 if (p->handle_id != RA_HANDLE_EVAL_PROP)
01921 {
01922 _ra_set_error(ph, RA_ERR_WRONG_HANDLE, "libRASCH");
01923 return -1;
01924 }
01925 idx = get_event_idx(p->evclass, event_id);
01926 if (idx < 0)
01927 {
01928 _ra_set_error(ph, RA_ERR_OUT_OF_RANGE, "libRASCH");
01929 return -1;
01930 }
01931
01932 col = -1;
01933 for (l = 0; l < p->num_entries[idx]; l++)
01934 {
01935 if (p->ch_map[idx][l] == ch)
01936 {
01937 col = l;
01938 break;
01939 }
01940 }
01941 if (col == -1)
01942 {
01943 _ra_set_error(ph, RA_ERR_OUT_OF_RANGE, "libRASCH");
01944 return -1;
01945 }
01946
01947 switch (p->value_type)
01948 {
01949 case RA_VALUE_TYPE_SHORT:
01950 ra_value_set_short(vh, p->value.s[idx][col]);
01951 break;
01952 case RA_VALUE_TYPE_LONG:
01953 ra_value_set_long(vh, p->value.l[idx][col]);
01954 break;
01955 case RA_VALUE_TYPE_DOUBLE:
01956 ra_value_set_double(vh, p->value.d[idx][col]);
01957 break;
01958 case RA_VALUE_TYPE_CHAR:
01959 ra_value_set_string(vh, p->value.c[idx][col]);
01960 break;
01961 case RA_VALUE_TYPE_SHORT_ARRAY:
01962 ra_value_set_short_array(vh, p->value.sa[idx][col], p->num_elements[idx][col]);
01963 break;
01964 case RA_VALUE_TYPE_LONG_ARRAY:
01965 ra_value_set_long_array(vh, p->value.la[idx][col], p->num_elements[idx][col]);
01966 break;
01967 case RA_VALUE_TYPE_DOUBLE_ARRAY:
01968 ra_value_set_double_array(vh, p->value.da[idx][col], p->num_elements[idx][col]);
01969 break;
01970 case RA_VALUE_TYPE_CHAR_ARRAY:
01971 ra_value_set_string_array(vh, (const char **)p->value.ca[idx][col], p->num_elements[idx][col]);
01972 break;
01973 default:
01974 _ra_set_error(ph, RA_ERR_ERROR, "libRASCH");
01975 return -1;
01976 }
01977
01978 return 0;
01979 }
01980
01981
01982 LIBRAAPI int
01983 ra_prop_get_events(prop_handle ph, value_handle min, value_handle max, long ch, value_handle vh)
01984 {
01985 int ret = -1;
01986 struct eval_property *p = (struct eval_property *)ph;
01987 long l, m, col, col_all;
01988 int use_min, use_max;
01989 struct eval_class *cl = p->evclass;
01990 long *events, num_events;
01991
01992 _ra_set_error(ph, RA_ERR_NONE, "libRASCH");
01993 ra_value_reset(vh);
01994
01995 if (p->handle_id != RA_HANDLE_EVAL_PROP)
01996 {
01997 _ra_set_error(ph, RA_ERR_WRONG_HANDLE, "libRASCH");
01998 return -1;
01999 }
02000
02001 use_min = use_max = 0;
02002 if (min && ra_value_is_ok(min))
02003 use_min = 1;
02004 if (max && ra_value_is_ok(max))
02005 use_max = 1;
02006
02007 if ((p->value_type != RA_VALUE_TYPE_LONG) && (p->value_type != RA_VALUE_TYPE_DOUBLE))
02008 {
02009 _ra_set_error(ph, RA_ERR_UNSUPPORTED, "libRASCH");
02010 return -1;
02011 }
02012
02013 events = NULL;
02014 num_events = 0;
02015 for (l = 0; l < cl->num_event; l++)
02016 {
02017 col = -1;
02018 col_all = -1;
02019 for (m = 0; m < p->num_entries[l]; m++)
02020 {
02021 if (p->ch_map[l][m] == ch)
02022 {
02023 col = m;
02024 break;
02025 }
02026 if (p->ch_map[l][m] == -1)
02027 col_all = m;
02028 }
02029
02030
02031 if (col == -1)
02032 col = col_all;
02033
02034 if (col_all == -1)
02035 {
02036 _ra_set_error(ph, RA_ERR_OUT_OF_RANGE, "libRASCH");
02037 goto error;
02038 }
02039
02040 if (p->value_type == RA_VALUE_TYPE_LONG)
02041 {
02042 if (use_min && (p->value.l[l][col] < ra_value_get_long(min)))
02043 continue;
02044 if (use_max && (p->value.l[l][col] > ra_value_get_long(max)))
02045 continue;
02046 }
02047 else
02048 {
02049 if (use_min && (p->value.d[l][col] < ra_value_get_double(min)))
02050 continue;
02051 if (use_max && (p->value.d[l][col] > ra_value_get_double(max)))
02052 continue;
02053 }
02054 num_events++;
02055 events = (long *)realloc(events, sizeof(long) * num_events);
02056 events[num_events-1] = cl->ev[l].id;
02057 }
02058
02059 ra_value_set_long_array(vh, events, num_events);
02060
02061 ret = 0;
02062
02063 error:
02064 if (events)
02065 free(events);
02066
02067 return ret;
02068 }
02069
02070
02071
02072
02073
02074 LIBRAAPI sum_handle
02075 ra_sum_add(class_handle clh, const char *id, const char *name, const char *desc)
02076 {
02077 struct eval_class *c = (struct eval_class *)clh;
02078 value_handle vh = NULL;
02079 struct eval_summary *s = NULL;
02080
02081 if (!clh)
02082 return NULL;
02083
02084 _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
02085
02086 s = calloc(1, sizeof(struct eval_summary));
02087 ra_list_add((void **)&(c->summaries), s);
02088
02089 s->handle_id = RA_HANDLE_EVAL_SUMMARY;
02090 strncpy(s->ascii_id, id, MAX_ID_LEN);
02091 s->meas = c->meas;
02092 s->evclass = c;
02093
02094 vh = ra_value_malloc();
02095
02096 if (name)
02097 {
02098 ra_value_set_string(vh, name);
02099 if (ra_eval_attribute_set(s, "name", vh) != 0)
02100 goto error;
02101 }
02102 if (desc)
02103 {
02104 ra_value_set_string(vh, desc);
02105 if (ra_eval_attribute_set(s, "description", vh) != 0)
02106 goto error;
02107 }
02108
02109 ra_value_free(vh);
02110
02111 return s;
02112
02113 error:
02114 ra_sum_delete(s);
02115
02116 if (vh)
02117 ra_value_free(vh);
02118
02119 return NULL;
02120 }
02121
02122
02123 LIBRAAPI int
02124 ra_sum_add_ch(sum_handle sh, long ch, long fiducial_offset, long num_dim,
02125 const char **dim_unit, const char **dim_name)
02126 {
02127 long l, idx;
02128 struct eval_summary *s = (struct eval_summary *)sh;
02129 struct eval_sum_ch_desc *cd;
02130
02131 if (!sh)
02132 return -1;
02133
02134 _ra_set_error(sh, RA_ERR_NONE, "libRASCH");
02135
02136 s->num_ch++;
02137 s->ch_desc = (struct eval_sum_ch_desc *)realloc(s->ch_desc, sizeof(struct eval_sum_ch_desc) * s->num_ch);
02138 cd = &(s->ch_desc[s->num_ch - 1]);
02139
02140 cd->ch = ch;
02141 cd->num_dim = num_dim;
02142
02143 idx = s->num_data_elements;
02144
02145 if (dim_unit)
02146 cd->unit = (char **)calloc(num_dim, sizeof(char *));
02147 if (dim_name)
02148 cd->name = (char **)calloc(num_dim, sizeof(char *));
02149 cd->data_idx = (long*)malloc(sizeof(char *) * num_dim);
02150 for (l = 0; l < num_dim; l++)
02151 {
02152 if (dim_unit)
02153 {
02154 cd->unit[l] = (char *)calloc(strlen(dim_unit[l]) + 1, sizeof(char));
02155 strcpy(cd->unit[l], dim_unit[l]);
02156 }
02157 if (dim_name)
02158 {
02159 cd->name[l] = (char *)calloc(strlen(dim_name[l]) + 1, sizeof(char));
02160 strcpy(cd->name[l], dim_name[l]);
02161 }
02162 cd->data_idx[l] = idx;
02163 idx++;
02164 }
02165 cd->fiducial_offset = fiducial_offset;
02166
02167 s->num_data_elements = idx;
02168
02169 return 0;
02170 }
02171
02172
02173 LIBRAAPI int
02174 ra_sum_delete(sum_handle sh)
02175 {
02176 long l, m;
02177 struct eval_summary *s = (struct eval_summary *)sh;
02178 struct eval_sum_data *d = s->sum;
02179 struct eval_sum_ch_desc *desc;
02180
02181 if (!sh)
02182 return -1;
02183
02184 _ra_set_error(sh, RA_ERR_NONE, "libRASCH");
02185
02186 while (d)
02187 {
02188 ra_sum_del_part(sh, d->id);
02189 d = s->sum;
02190 }
02191
02192 if (s->ch_desc)
02193 {
02194 for (l = 0; l < s->num_ch; l++)
02195 {
02196 desc = s->ch_desc + l;
02197
02198 for (m = 0; m < desc->num_dim; m++)
02199 {
02200 if (desc->name && desc->name[m])
02201 free(desc->name[m]);
02202 if (desc->unit && desc->unit[m])
02203 free(desc->unit[m]);
02204 }
02205 if (desc->name)
02206 free(desc->name);
02207 if (desc->unit)
02208 free(desc->unit);
02209
02210 if (desc->data_idx)
02211 free(desc->data_idx);
02212 }
02213 free(s->ch_desc);
02214 }
02215
02216 ra_list_del((void **)&(s->evclass->summaries), s);
02217
02218 return 0;
02219 }
02220
02221
02222 LIBRAAPI int
02223 ra_sum_get(class_handle clh, const char *id, value_handle vh)
02224 {
02225 struct eval_class *c = (struct eval_class *)clh;
02226 struct eval_summary *s;
02227 long len, len_use, l;
02228 void **vp = NULL;
02229
02230 _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
02231 ra_value_reset(vh);
02232
02233 s = c->summaries;
02234
02235 if (s == NULL)
02236 return 0;
02237
02238 len = ra_list_len(c->summaries);
02239 if (len == 0)
02240 return 0;
02241
02242 vp = (void **)calloc(len, sizeof(void *));
02243 if ((id == NULL) || (id[0] == '\0'))
02244 {
02245 for (l = 0; l < len; l++)
02246 {
02247 vp[l] = (void *)s;
02248 s = s->next;
02249 }
02250 len_use = len;
02251 }
02252 else
02253 {
02254 for (l = 0; l < len; l++)
02255 {
02256 if (strcmp(s->ascii_id, id) == 0)
02257 {
02258 vp[len_use] = (void *)s;
02259 len_use++;
02260 }
02261 }
02262 }
02263
02264 ra_value_set_voidp_array(vh, (const void **)vp, len_use);
02265
02266 free(vp);
02267
02268 return 0;
02269 }
02270
02271
02272 LIBRAAPI long
02273 ra_sum_add_part(sum_handle sh, long num_events, const long *events_based_on)
02274 {
02275 long l;
02276 struct eval_summary *s = (struct eval_summary *)sh;
02277 struct eval_sum_data *d;
02278
02279 if (!sh)
02280 return -1;
02281
02282 _ra_set_error(sh, RA_ERR_NONE, "libRASCH");
02283
02284 d = (struct eval_sum_data *)malloc(sizeof(struct eval_sum_data));
02285 ra_list_add((void **)&(s->sum), d);
02286
02287 d->id = s->last_data_id;
02288 s->last_data_id++;
02289
02290 d->num_events = num_events;
02291 d->event_ids = (long *)malloc(sizeof(long) * num_events);
02292 memcpy(d->event_ids, events_based_on, sizeof(long) * num_events);
02293
02294 d->data = (value_handle *)calloc(s->num_data_elements, sizeof(value_handle));
02295 for (l = 0; l < s->num_data_elements; l++)
02296 d->data[l] = ra_value_malloc();
02297
02298 return d->id;
02299 }
02300
02301
02302 LIBRAAPI int
02303 ra_sum_del_part(sum_handle sh, long part_id)
02304 {
02305 long l;
02306 struct eval_summary *s = (struct eval_summary *)sh;
02307 struct eval_sum_data *d = s->sum;
02308
02309 if (!sh)
02310 return -1;
02311
02312 _ra_set_error(sh, RA_ERR_NONE, "libRASCH");
02313
02314 while (d)
02315 {
02316 if (d->id == part_id)
02317 break;
02318 }
02319 if (d == NULL)
02320 {
02321 _ra_set_error(sh, RA_ERR_OUT_OF_RANGE, "libRASCH");
02322 return -1;
02323 }
02324
02325 if (d->event_ids)
02326 free(d->event_ids);
02327 d->event_ids = NULL;
02328
02329 if (d->data)
02330 {
02331 for (l = 0; l < s->num_data_elements; l++)
02332 ra_value_free(d->data[l]);
02333
02334 free(d->data);
02335 d->data = NULL;
02336 }
02337
02338 ra_list_del((void **)&(s->sum), d);
02339
02340 return 0;
02341 }
02342
02343
02344 LIBRAAPI int
02345 ra_sum_set_part_data(sum_handle sh, long part_id, long channel, long dim, value_handle vh)
02346 {
02347 int ret;
02348 long data_idx = -1;
02349 struct eval_summary *s = (struct eval_summary *)sh;
02350 struct eval_sum_data *d = s->sum;
02351
02352 if (!sh)
02353 return -1;
02354
02355 _ra_set_error(sh, RA_ERR_NONE, "libRASCH");
02356
02357 data_idx = get_sum_data_idx(sh, channel, dim);
02358 if (data_idx < 0)
02359 {
02360 _ra_set_error(sh, RA_ERR_OUT_OF_RANGE, "libRASCH");
02361 return -1;
02362 }
02363
02364 while (d)
02365 {
02366 if (d->id == part_id)
02367 break;
02368 }
02369 if (d == NULL)
02370 {
02371 _ra_set_error(sh, RA_ERR_OUT_OF_RANGE, "libRASCH");
02372 return -1;
02373 }
02374
02375 ret = ra_value_copy(d->data[data_idx], vh);
02376
02377 return ret;
02378 }
02379
02380
02381 LIBRAAPI int
02382 ra_sum_get_part_data(sum_handle sh, long part_id, long channel, long dim, value_handle vh)
02383 {
02384 int ret;
02385 long data_idx = -1;
02386 struct eval_summary *s = (struct eval_summary *)sh;
02387 struct eval_sum_data *d = s->sum;
02388
02389 if (!sh)
02390 return -1;
02391
02392 _ra_set_error(sh, RA_ERR_NONE, "libRASCH");
02393
02394 data_idx = get_sum_data_idx(sh, channel, dim);
02395 if (data_idx < 0)
02396 {
02397 _ra_set_error(sh, RA_ERR_OUT_OF_RANGE, "libRASCH");
02398 return -1;
02399 }
02400
02401 while (d)
02402 {
02403 if (d->id == part_id)
02404 break;
02405 }
02406 if (d == NULL)
02407 {
02408 _ra_set_error(sh, RA_ERR_OUT_OF_RANGE, "libRASCH");
02409 return -1;
02410 }
02411
02412 ret = ra_value_copy(vh, d->data[data_idx]);
02413
02414 return ret;
02415 }
02416
02417
02418 LIBRAAPI int
02419 ra_sum_get_part_events(sum_handle sh, long part_id, value_handle vh)
02420 {
02421 struct eval_summary *s = (struct eval_summary *)sh;
02422 struct eval_sum_data *d = s->sum;
02423
02424 if (!sh)
02425 return -1;
02426
02427 _ra_set_error(sh, RA_ERR_NONE, "libRASCH");
02428
02429 while (d)
02430 {
02431 if (d->id == part_id)
02432 break;
02433 }
02434 if (d == NULL)
02435 {
02436 _ra_set_error(sh, RA_ERR_OUT_OF_RANGE, "libRASCH");
02437 return -1;
02438 }
02439
02440 ra_value_set_long_array(vh, d->event_ids, d->num_events);
02441
02442 return 0;
02443 }
02444
02445
02446 int
02447 get_sum_data_idx(sum_handle sh, long channel, long dim)
02448 {
02449 int idx = -1;
02450 long l;
02451 struct eval_summary *s = (struct eval_summary *)sh;
02452
02453 for (l = 0; l < s->num_ch; l++)
02454 {
02455 if (s->ch_desc[l].ch != channel)
02456 continue;
02457
02458 if (s->ch_desc[l].num_dim <= dim)
02459 break;
02460
02461 idx = s->ch_desc[l].data_idx[dim];
02462 }
02463
02464 return idx;
02465 }