00001
00002
00003 #include <string.h>
00004 #define DRMS_TYPES_C
00005 #include "drms.h"
00006 #include "drms_priv.h"
00007 #undef DRMS_TYPES_C
00008 #include "xmem.h"
00009 #include "timeio.h"
00010 #include "atoinc.h"
00011
00012 const char kDRMS_MISSING_VALUE[] = "DRMS_MISSING_VALUE";
00013
00014 static HContainer_t *gSlotEpochHC = NULL;
00015 struct TimeEpochStrings_struct
00016 {
00017 DRMS_TimeEpoch_t type;
00018 const char *str;
00019 const char *timestr;
00020 TIME internalTime;
00021 };
00022
00023 typedef struct TimeEpochStrings_struct TimeEpochStrings_t;
00024 static TimeEpochStrings_t gSEpochS[] =
00025 {
00026 {kTimeEpoch_DRMS, "DRMS_EPOCH", DRMS_EPOCH_S, DRMS_EPOCH},
00027 {kTimeEpoch_MDI, "MDI_EPOCH", MDI_EPOCH_S, MDI_EPOCH},
00028 {kTimeEpoch_WSO, "WSO_EPOCH", WSO_EPOCH_S, WSO_EPOCH},
00029 {kTimeEpoch_TAI, "TAI_EPOCH", TAI_EPOCH_S, TAI_EPOCH},
00030 {kTimeEpoch_MJD, "MJD_EPOCH", MJD_EPOCH_S, MJD_EPOCH},
00031 {kTimeEpoch_TSEQ, "TSEQ_EPOCH", TSEQ_EPOCH_S, TSEQ_EPOCH},
00032 {(DRMS_TimeEpoch_t)-99, ""}
00033 };
00034
00035
00036 static int IsHexString(const char *str)
00037 {
00038 int ishex = 0;
00039 char *s = strdup(str);
00040
00041
00042 while (isspace(*s))
00043 {
00044 ++s;
00045 }
00046
00047
00048 if (s[0] == '0' && toupper(s[1]) == 'X')
00049 {
00050 ishex = 1;
00051 }
00052
00053 free(s);
00054
00055 return ishex;
00056 }
00057
00058 DB_Type_t drms2dbtype(DRMS_Type_t type)
00059 {
00060 switch(type)
00061 {
00062 case DRMS_TYPE_CHAR:
00063 return DB_CHAR;
00064 break;
00065 case DRMS_TYPE_SHORT:
00066 return DB_INT2;
00067 break;
00068 case DRMS_TYPE_INT:
00069 return DB_INT4;
00070 break;
00071 case DRMS_TYPE_LONGLONG:
00072 return DB_INT8;
00073 break;
00074 case DRMS_TYPE_FLOAT:
00075 return DB_FLOAT;
00076 break;
00077 case DRMS_TYPE_DOUBLE:
00078 case DRMS_TYPE_TIME:
00079 return DB_DOUBLE;
00080 break;
00081 case DRMS_TYPE_STRING:
00082 return DB_STRING;
00083 default:
00084 fprintf(stderr, "ERROR: Unhandled DRMS type %d\n",(int)type);
00085 XASSERT(0);
00086 return DB_STRING;
00087 break;
00088 }
00089 }
00090
00091
00092
00093 int drms_copy_db2drms(DRMS_Type_t drms_type, DRMS_Type_Value_t *drms_dst,
00094 DB_Type_t db_type, char *db_src)
00095 {
00096 int len;
00097
00098
00099 switch(drms_type)
00100 {
00101 case DRMS_TYPE_CHAR:
00102 drms_dst->char_val = dbtype2char(db_type,db_src);
00103 break;
00104 case DRMS_TYPE_SHORT:
00105 drms_dst->short_val = dbtype2short(db_type,db_src);
00106 break;
00107 case DRMS_TYPE_INT:
00108 drms_dst->int_val = dbtype2longlong(db_type,db_src);
00109 break;
00110 case DRMS_TYPE_LONGLONG:
00111 drms_dst->longlong_val = dbtype2longlong(db_type,db_src);
00112 break;
00113 case DRMS_TYPE_FLOAT:
00114 drms_dst->float_val = dbtype2float(db_type,db_src);
00115 break;
00116 case DRMS_TYPE_DOUBLE:
00117 drms_dst->double_val = dbtype2double(db_type,db_src);
00118 break;
00119 case DRMS_TYPE_TIME:
00120 drms_dst->time_val = dbtype2double(db_type,db_src);
00121 break;
00122 case DRMS_TYPE_STRING:
00123 if (drms_dst->string_val)
00124 free(drms_dst->string_val);
00125 if (db_type == DB_STRING || db_type == DB_VARCHAR)
00126 drms_dst->string_val = strdup((char *)db_src);
00127 else
00128 {
00129 len = db_binary_default_width(db_type);
00130 drms_dst->string_val = malloc(len);
00131 XASSERT(drms_dst->string_val);
00132 dbtype2str(db_type,db_src,len,drms_dst->string_val);
00133 }
00134 break;
00135 default:
00136 fprintf(stderr, "ERROR: Unhandled DRMS type %d\n",(int)drms_type);
00137 XASSERT(0);
00138 return -1;
00139 break;
00140 }
00141 return 0;
00142 }
00143
00144
00145
00146
00147
00148 void drms_copy_drms2drms(DRMS_Type_t type, DRMS_Type_Value_t *dst,
00149 DRMS_Type_Value_t *src)
00150 {
00151 if (type==DRMS_TYPE_STRING)
00152 copy_string(&dst->string_val, src->string_val);
00153 else
00154 memcpy(dst, src, sizeof(DRMS_Type_Value_t));
00155 }
00156
00157
00158 DRMS_Type_t drms_str2type(const char *str)
00159 {
00160 if (!strncasecmp(str,drms_type_names[DRMS_TYPE_CHAR],DRMS_MAXTYPENAMELEN))
00161 return DRMS_TYPE_CHAR;
00162 else if (!strncasecmp(str,drms_type_names[DRMS_TYPE_SHORT],
00163 DRMS_MAXTYPENAMELEN))
00164 return DRMS_TYPE_SHORT;
00165 else if (!strncasecmp(str,drms_type_names[DRMS_TYPE_INT],
00166 DRMS_MAXTYPENAMELEN))
00167 return DRMS_TYPE_INT;
00168 else if (!strncasecmp(str,drms_type_names[DRMS_TYPE_LONGLONG],
00169 DRMS_MAXTYPENAMELEN))
00170 return DRMS_TYPE_LONGLONG;
00171 else if (!strncasecmp(str,drms_type_names[DRMS_TYPE_FLOAT],
00172 DRMS_MAXTYPENAMELEN))
00173 return DRMS_TYPE_FLOAT;
00174 else if (!strncasecmp(str,drms_type_names[DRMS_TYPE_DOUBLE],
00175 DRMS_MAXTYPENAMELEN))
00176 return DRMS_TYPE_DOUBLE;
00177 else if (!strncasecmp(str,drms_type_names[DRMS_TYPE_TIME],
00178 DRMS_MAXTYPENAMELEN))
00179 return DRMS_TYPE_TIME;
00180 else if (!strncasecmp(str,drms_type_names[DRMS_TYPE_STRING],
00181 DRMS_MAXTYPENAMELEN))
00182 return DRMS_TYPE_STRING;
00183 else
00184 {
00185 fprintf(stderr, "ERROR: Unhandled DRMS type '%s'\n",str);
00186 XASSERT(0);
00187 return DRMS_TYPE_RAW;
00188 }
00189 }
00190
00191
00192 const char *drms_type2str(DRMS_Type_t type)
00193 {
00194 return drms_type_names[(int) type];
00195 }
00196
00197
00198
00199 int drms_sizeof(DRMS_Type_t type)
00200 {
00201 switch(type)
00202 {
00203 case DRMS_TYPE_CHAR:
00204 case DRMS_TYPE_SHORT:
00205 case DRMS_TYPE_INT:
00206 case DRMS_TYPE_LONGLONG:
00207 case DRMS_TYPE_FLOAT:
00208 case DRMS_TYPE_DOUBLE:
00209 case DRMS_TYPE_TIME:
00210 return db_sizeof(drms2dbtype(type));
00211 break;
00212 case DRMS_TYPE_STRING:
00213 return sizeof(char *);
00214 break;
00215 default:
00216 fprintf(stderr, "ERROR: Unhandled DRMS type %d\n",(int)type);
00217 XASSERT(0);
00218 return 0;
00219 break;
00220 }
00221 }
00222
00223 int drms_equal(DRMS_Type_t type, DRMS_Type_Value_t *x, DRMS_Type_Value_t *y)
00224 {
00225 switch(type)
00226 {
00227 case DRMS_TYPE_CHAR:
00228 return x->char_val == y->char_val;
00229 break;
00230 case DRMS_TYPE_SHORT:
00231 return x->short_val == y->short_val;
00232 break;
00233 case DRMS_TYPE_INT:
00234 return x->int_val == y->int_val;
00235 break;
00236 case DRMS_TYPE_LONGLONG:
00237 return x->longlong_val == y->longlong_val;
00238 break;
00239 case DRMS_TYPE_FLOAT:
00240 if (isnan(x->float_val) && isnan(y->float_val))
00241 {
00242 return 1;
00243 }
00244 else if (isnan(x->float_val) || isnan(y->float_val))
00245 {
00246 return 0;
00247 }
00248 return x->float_val == y->float_val;
00249 break;
00250 case DRMS_TYPE_DOUBLE:
00251 if (isnan(x->double_val) && isnan(y->double_val))
00252 {
00253 return 1;
00254 }
00255 else if (isnan(x->double_val) || isnan(y->double_val))
00256 {
00257 return 0;
00258 }
00259 return x->double_val == y->double_val;
00260 break;
00261 case DRMS_TYPE_TIME:
00262 if (isnan(x->time_val) && isnan(y->time_val))
00263 {
00264 return 1;
00265 }
00266 else if (isnan(x->time_val) || isnan(y->time_val))
00267 {
00268 return 0;
00269 }
00270 return x->time_val == y->time_val;
00271 break;
00272 case DRMS_TYPE_STRING:
00273 if (x->string_val == NULL && y->string_val == NULL)
00274 {
00275 return 1;
00276 }
00277 else if (x->string_val == NULL || y->string_val == NULL)
00278 {
00279 return 0;
00280 }
00281 return !strcmp(x->string_val, y->string_val);
00282 break;
00283 default:
00284 fprintf(stderr, "ERROR: Unhandled DRMS type %d\n",(int)type);
00285 return 0;
00286 }
00287 }
00288
00289 void drms_missing(DRMS_Type_t type, DRMS_Type_Value_t *val)
00290 {
00291 switch(type)
00292 {
00293 case DRMS_TYPE_CHAR:
00294 val->char_val = DRMS_MISSING_CHAR;
00295 break;
00296 case DRMS_TYPE_SHORT:
00297 val->short_val = DRMS_MISSING_SHORT;
00298 break;
00299 case DRMS_TYPE_INT:
00300 val->int_val = DRMS_MISSING_INT;
00301 break;
00302 case DRMS_TYPE_LONGLONG:
00303 val->longlong_val = DRMS_MISSING_LONGLONG;
00304 break;
00305 case DRMS_TYPE_FLOAT:
00306 val->float_val = DRMS_MISSING_FLOAT;
00307 break;
00308 case DRMS_TYPE_DOUBLE:
00309 val->double_val = DRMS_MISSING_DOUBLE;
00310 break;
00311 case DRMS_TYPE_TIME:
00312 val->time_val = DRMS_MISSING_TIME;
00313 break;
00314 case DRMS_TYPE_STRING:
00315 copy_string(&(val->string_val), DRMS_MISSING_STRING);
00316 break;
00317 default:
00318 fprintf(stderr, "ERROR: Unhandled DRMS type %d\n",(int)type);
00319 XASSERT(0);
00320 }
00321 }
00322
00323 void drms_missing_vp(DRMS_Type_t type, void *val)
00324 {
00325 switch(type)
00326 {
00327 case DRMS_TYPE_CHAR:
00328 *((char *)val) = DRMS_MISSING_CHAR;
00329 break;
00330 case DRMS_TYPE_SHORT:
00331 *((short *)val) = DRMS_MISSING_SHORT;
00332 break;
00333 case DRMS_TYPE_INT:
00334 *((int *)val) = DRMS_MISSING_INT;
00335 break;
00336 case DRMS_TYPE_LONGLONG:
00337 *((long long *)val) = DRMS_MISSING_LONGLONG;
00338 break;
00339 case DRMS_TYPE_FLOAT:
00340 *((float *)val) = DRMS_MISSING_FLOAT;
00341 break;
00342 case DRMS_TYPE_DOUBLE:
00343 *((double *)val) = DRMS_MISSING_DOUBLE;
00344 break;
00345 case DRMS_TYPE_TIME:
00346 *((double *)val) = DRMS_MISSING_TIME;
00347 break;
00348 case DRMS_TYPE_STRING:
00349 copy_string((char **)val, DRMS_MISSING_STRING);
00350 break;
00351 default:
00352 fprintf(stderr, "ERROR: Unsupported DRMS type %d\n",(int)type);
00353 XASSERT(0);
00354 }
00355 }
00356
00357 int drms_strval(DRMS_Type_t type, DRMS_Type_Value_t *val, char *str)
00358 {
00359 switch(type)
00360 {
00361 case DRMS_TYPE_CHAR:
00362 val->char_val = str[0];
00363 break;
00364 case DRMS_TYPE_SHORT:
00365 val->short_val = (short)strtol(str, NULL, 0);
00366 break;
00367 case DRMS_TYPE_INT:
00368 val->int_val = (int)strtol(str, NULL, 0);
00369 break;
00370 case DRMS_TYPE_LONGLONG:
00371 val->longlong_val = strtoll(str, NULL, 0);
00372 break;
00373 case DRMS_TYPE_FLOAT:
00374 val->float_val = (float) atof(str);
00375 break;
00376 case DRMS_TYPE_DOUBLE:
00377 val->double_val = (double) atof(str);
00378 break;
00379 case DRMS_TYPE_TIME:
00380 val->time_val = sscan_time (str);
00381 break;
00382 case DRMS_TYPE_STRING:
00383 copy_string(&val->string_val, str);
00384 break;
00385 default:
00386 fprintf(stderr, "ERROR: Unhandled DRMS type %d\n",(int)type);
00387 XASSERT(0);
00388 }
00389 return 0;
00390 }
00391
00392
00393
00394
00395
00396 int drms_sprintfval_format(char *dst, DRMS_Type_t type, DRMS_Type_Value_t *val,
00397 char *format, int internal)
00398 {
00399 if (format==NULL)
00400 return drms_sprintfval(dst, type, val, internal);
00401 else
00402 {
00403 switch(type)
00404 {
00405 case DRMS_TYPE_CHAR:
00406 return sprintf(dst, format, val->char_val);
00407 break;
00408 case DRMS_TYPE_SHORT:
00409 return sprintf(dst, format, val->short_val );
00410 break;
00411 case DRMS_TYPE_INT:
00412 return sprintf(dst, format, val->int_val );
00413 break;
00414 case DRMS_TYPE_LONGLONG:
00415 return sprintf(dst, format, val->longlong_val);
00416 break;
00417 case DRMS_TYPE_FLOAT:
00418 return sprintf(dst, format, val->float_val);
00419 break;
00420 case DRMS_TYPE_DOUBLE:
00421 return sprintf(dst, format, val->double_val);
00422 break;
00423 case DRMS_TYPE_TIME:
00424 if (internal)
00425 return sprintf(dst, "%lf", val->time_val);
00426 else
00427 {
00428
00429
00430 sprint_time(dst, val->time_val, format, 3);
00431 return strlen(dst);
00432 }
00433 break;
00434 case DRMS_TYPE_STRING:
00435 return sprintf(dst, format, val->string_val);
00436 break;
00437 default:
00438 fprintf(stderr, "ERROR: Unhandled DRMS type %d\n",(int)type);
00439 XASSERT(0);
00440 }
00441 return 0;
00442 }
00443 }
00444
00445
00446
00447 int drms_sprintfval(char *dst, DRMS_Type_t type, DRMS_Type_Value_t *val,
00448 int internal)
00449 {
00450 switch(type)
00451 {
00452 case DRMS_TYPE_CHAR:
00453 return sprintf(dst, "%hhd", val->char_val);
00454 break;
00455 case DRMS_TYPE_SHORT:
00456 return sprintf(dst, "%hd", val->short_val );
00457 break;
00458 case DRMS_TYPE_INT:
00459 return sprintf(dst, "%d", val->int_val );
00460 break;
00461 case DRMS_TYPE_LONGLONG:
00462 return sprintf(dst, "%lld", val->longlong_val);
00463 break;
00464 case DRMS_TYPE_FLOAT:
00465 return sprintf(dst, "%.9g", val->float_val);
00466 break;
00467 case DRMS_TYPE_DOUBLE:
00468 return sprintf(dst, "%.17lg", val->double_val);
00469 break;
00470 case DRMS_TYPE_TIME:
00471 if (!internal)
00472 {
00473 sprint_time(dst, val->time_val, "UTC", 0);
00474 return strlen(dst);
00475 }
00476 else
00477 return sprintf(dst, "%lf", val->time_val);
00478 break;
00479 case DRMS_TYPE_STRING:
00480 return sprintf(dst, "'%s'", val->string_val);
00481 break;
00482 default:
00483 fprintf(stderr, "ERROR: Unhandled DRMS type %d\n",(int)type);
00484 XASSERT(0);
00485 }
00486 return 0;
00487 }
00488
00489
00490
00491
00492 int drms_printfval(DRMS_Type_t type, DRMS_Type_Value_t *val) {
00493 return drms_fprintfval(stdout, type, val);
00494 }
00495
00496 int drms_fprintfval(FILE *keyfile, DRMS_Type_t type, DRMS_Type_Value_t *val) {
00497 switch(type) {
00498 case DRMS_TYPE_CHAR:
00499 return fprintf(keyfile, "%hhd", val->char_val);
00500 break;
00501 case DRMS_TYPE_SHORT:
00502 return fprintf(keyfile, "%hd", val->short_val );
00503 break;
00504 case DRMS_TYPE_INT:
00505 return fprintf(keyfile, "%d", val->int_val );
00506 break;
00507 case DRMS_TYPE_LONGLONG:
00508 return fprintf(keyfile, "%lld", val->longlong_val);
00509 break;
00510 case DRMS_TYPE_FLOAT:
00511 return fprintf(keyfile, "%15.9g", val->float_val);
00512 break;
00513 case DRMS_TYPE_TIME:
00514 {
00515 char buf[128];
00516 sprint_time(buf, val->time_val, "UTC", 0);
00517 fprintf(keyfile, "%s",buf);
00518 }
00519 break;
00520 case DRMS_TYPE_DOUBLE:
00521 return fprintf(keyfile, "%24.17lg", val->double_val);
00522 break;
00523 case DRMS_TYPE_STRING:
00524 return fprintf(keyfile, "'%s'", val->string_val);
00525 break;
00526 default:
00527 fprintf(stderr, "ERROR: Unhandled DRMS type %d\n",(int)type);
00528 XASSERT(0);
00529 }
00530 return 0;
00531 }
00532
00533
00534
00535 int drms_printfval_raw(DRMS_Type_t type, void *val)
00536 {
00537 return drms_fprintfval_raw(stdout, type, val);
00538 }
00539
00540 int drms_fprintfval_raw(FILE *keyfile, DRMS_Type_t type, void *val)
00541 {
00542 switch(type)
00543 {
00544 case DRMS_TYPE_CHAR:
00545 return fprintf(keyfile, "%hhd", *((char *)val));
00546 break;
00547 case DRMS_TYPE_SHORT:
00548 return fprintf(keyfile, "%hd", *((short *)val));
00549 break;
00550 case DRMS_TYPE_INT:
00551 return fprintf(keyfile, "%d", *((int *)val));
00552 break;
00553 case DRMS_TYPE_LONGLONG:
00554 return fprintf(keyfile, "%lld", *((long long *)val));
00555 break;
00556 case DRMS_TYPE_FLOAT:
00557 return fprintf(keyfile, "%15.9g", *((float *)val));
00558 break;
00559 case DRMS_TYPE_TIME:
00560 {
00561 char buf[128];
00562 sprint_time(buf, *((double *)val), "UTC", 0);
00563 fprintf(keyfile, "%s",buf);
00564 }
00565 break;
00566 case DRMS_TYPE_DOUBLE:
00567 return fprintf(keyfile, "%24.17lg", *((double *)val));
00568 break;
00569 case DRMS_TYPE_STRING:
00570 return fprintf(keyfile, "'%s'", (char *)val);
00571 break;
00572 default:
00573 fprintf(stderr, "ERROR: Unhandled DRMS type %d\n",(int)type);
00574 XASSERT(0);
00575 }
00576 return 0;
00577 }
00578
00579
00580
00581 long long drms_types_strtoll(const char *str, DRMS_Type_t inttype, int *consumed, int *status)
00582 {
00583 int ishex = 0;
00584 int istat = 0;
00585 long long ival = 0;
00586 char *endptr = 0;
00587
00588 if (str)
00589 {
00590 if (inttype == DRMS_TYPE_LONGLONG)
00591 {
00592 ival = strtoll(str, &endptr, 0);
00593
00594 if (ival==0 && endptr==str)
00595 {
00596 istat = 1;
00597 }
00598 else
00599 {
00600 *consumed = endptr - str;
00601 }
00602 }
00603 else
00604 {
00605 const char *pc = str;
00606
00607
00608 while (isspace(*pc))
00609 {
00610 ++pc;
00611 }
00612
00613
00614 if (*pc == '+' || *pc == '-')
00615 {
00616 ++pc;
00617 }
00618
00619 if (strstr(pc, "0X") == pc || (strstr(pc, "0x") == pc))
00620 {
00621 ishex = 1;
00622 }
00623
00624 if (ishex)
00625 {
00626
00627 ival = strtoll(str, &endptr, 16);
00628 switch (inttype)
00629 {
00630 case DRMS_TYPE_CHAR:
00631 if ((ival==0 && endptr==str) || ival > UCHAR_MAX)
00632 {
00633 istat = 1;
00634 }
00635 else
00636 {
00637 ival = (char)ival;
00638 *consumed = endptr - str;
00639 }
00640 break;
00641 case DRMS_TYPE_SHORT:
00642 if ((ival==0 && endptr==str) || ival > USHRT_MAX)
00643 {
00644 istat = 1;
00645 }
00646 else
00647 {
00648 ival = (short)ival;
00649 *consumed = endptr - str;
00650 }
00651 break;
00652 case DRMS_TYPE_INT:
00653 if ((ival==0 && endptr==str) || ival > UINT_MAX)
00654 {
00655 istat = 1;
00656 }
00657 else
00658 {
00659 ival = (int)ival;
00660 *consumed = endptr - str;
00661 }
00662 break;
00663 default:
00664 fprintf(stderr, "ERROR: Unsupported DRMS integer type %d\n", (int)inttype);
00665 istat = 1;
00666 }
00667 }
00668 else
00669 {
00670
00671 ival = strtoll(str, &endptr, 10);
00672 switch (inttype)
00673 {
00674 case DRMS_TYPE_CHAR:
00675 if ((ival==0 && endptr==str) || ival < SCHAR_MIN || ival > SCHAR_MAX)
00676 {
00677 istat = 1;
00678 }
00679 else
00680 {
00681 *consumed = endptr - str;
00682 }
00683 break;
00684 case DRMS_TYPE_SHORT:
00685 if ((ival==0 && endptr==str) || ival < SHRT_MIN || ival > SHRT_MAX)
00686 {
00687 istat = 1;
00688 }
00689 else
00690 {
00691 *consumed = endptr - str;
00692 }
00693 break;
00694 case DRMS_TYPE_INT:
00695 if ((ival==0 && endptr==str) || ival < INT_MIN || ival > INT_MAX)
00696 {
00697 istat = 1;
00698 }
00699 else
00700 {
00701 *consumed = endptr - str;
00702 }
00703 break;
00704 default:
00705 fprintf(stderr, "ERROR: Unsupported DRMS integer type %d\n", (int)inttype);
00706 istat = 1;
00707 }
00708 }
00709 }
00710 }
00711
00712 if (status)
00713 {
00714 *status = istat;
00715 }
00716
00717 return ival;
00718 }
00719
00720
00721
00722
00723 static int drms_sscanf_int(const char *str,
00724 DRMS_Type_t dsttype,
00725 DRMS_Type_Value_t *dst,
00726 int silent) {
00727 int status = DRMS_SUCCESS;
00728 const TIME *te = NULL;
00729 char *endptr = 0;
00730 long long ival;
00731 float fval;
00732 double dval;
00733 int usemissing = 0;
00734 int usemissinglen = strlen(kDRMS_MISSING_VALUE);
00735 int consumed = 0;
00736
00737 if (!strncasecmp(kDRMS_MISSING_VALUE, str, usemissinglen))
00738 {
00739 usemissing = 1;
00740 }
00741
00742 switch (dsttype) {
00743 case DRMS_TYPE_CHAR:
00744 if (usemissing)
00745 {
00746 dst->char_val = DRMS_MISSING_CHAR;
00747 return usemissinglen;
00748 }
00749 else
00750 {
00751 ival = drms_types_strtoll(str, DRMS_TYPE_CHAR, &consumed, &status);
00752
00753 if (status)
00754 {
00755 if (!silent)
00756 {
00757 fprintf (stderr, "Integer constant '%s' is not a signed char.\n", str);
00758 }
00759
00760 return -1;
00761 }
00762 else
00763 {
00764 dst->char_val = (char)ival;
00765 }
00766
00767 return consumed;
00768 }
00769 case DRMS_TYPE_SHORT:
00770 if (usemissing)
00771 {
00772 dst->short_val = DRMS_MISSING_SHORT;
00773 return usemissinglen;
00774 }
00775 else
00776 {
00777 ival = drms_types_strtoll(str, DRMS_TYPE_SHORT, &consumed, &status);
00778
00779 if (status)
00780 {
00781 if (!silent)
00782 {
00783 fprintf (stderr, "Integer constant '%s' is not a signed short.\n", str);
00784 }
00785
00786 return -1;
00787 }
00788 else
00789 {
00790 dst->short_val = (short)ival;
00791 }
00792
00793 return consumed;
00794 }
00795 case DRMS_TYPE_INT:
00796 if (usemissing)
00797 {
00798 dst->int_val = DRMS_MISSING_INT;
00799 return usemissinglen;
00800 }
00801 else
00802 {
00803 ival = drms_types_strtoll(str, DRMS_TYPE_INT, &consumed, &status);
00804
00805 if (status)
00806 {
00807 if (!silent)
00808 {
00809 fprintf (stderr, "Integer constant '%s' is not a signed integer.\n", str);
00810 }
00811
00812 return -1;
00813 }
00814 else
00815 {
00816 dst->int_val = (int)ival;
00817 }
00818
00819 return consumed;
00820 }
00821 case DRMS_TYPE_LONGLONG:
00822 if (usemissing)
00823 {
00824 dst->longlong_val = DRMS_MISSING_LONGLONG;
00825 return usemissinglen;
00826 }
00827 else
00828 {
00829 ival = drms_types_strtoll(str, DRMS_TYPE_LONGLONG, &consumed, &status);
00830
00831 if (status)
00832 {
00833 if (!silent)
00834 {
00835 fprintf (stderr, "Integer constant '%s' is not a signed long long.\n", str);
00836 }
00837
00838 return -1;
00839 }
00840 else
00841 {
00842 dst->longlong_val = ival;
00843 }
00844
00845 return consumed;
00846 }
00847 case DRMS_TYPE_FLOAT:
00848 if (usemissing)
00849 {
00850 dst->float_val = DRMS_MISSING_FLOAT;
00851 return usemissinglen;
00852 }
00853 else
00854 {
00855 fval = strtof(str,&endptr);
00856
00857 if ((IsZeroF(fval) && endptr==str) ||
00858 ((IsPosHugeValF(fval) || IsNegHugeValF(fval)) && errno==ERANGE)) {
00859 if (!silent)
00860 fprintf (stderr, "Real constant '%s' is not a float.\n", str);
00861 return -1;
00862 } else dst->float_val = (float) fval;
00863 return (int)(endptr-str);
00864 }
00865 case DRMS_TYPE_DOUBLE:
00866 if (usemissing)
00867 {
00868 dst->double_val = DRMS_MISSING_DOUBLE;
00869 return usemissinglen;
00870 }
00871 else
00872 {
00873 dval = strtod(str,&endptr);
00874 if ((IsZero(dval) && endptr==str) ||
00875 ((IsPosHugeVal(dval) || IsNegHugeVal(dval)) && errno==ERANGE)) {
00876 if (!silent)
00877 fprintf (stderr, "Real constant '%s' is not a double.\n", str);
00878 return -1;
00879 } else dst->double_val = (double) dval;
00880 return (int)(endptr-str);
00881 }
00882 case DRMS_TYPE_TIME:
00883 if (usemissing)
00884 {
00885 dst->time_val = DRMS_MISSING_TIME;
00886 return usemissinglen;
00887 }
00888 else if ((te = drms_time_getepoch(str, NULL, &status)) != NULL)
00889 {
00890
00891
00892 dst->time_val = *te;
00893 return strlen(str);
00894 }
00895 else
00896 {
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917 char *tokenstr = strdup(str);
00918 int ret = -1;
00919
00920 if (tokenstr)
00921 {
00922
00923 ret = sscan_time_ext(tokenstr, &dst->time_val);
00924 free(tokenstr);
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939 if (time_is_invalid(dst->time_val) && ret == 0)
00940 {
00941 fprintf (stderr, "Invalid time string '%s'.\n", str);
00942 return -1;
00943 }
00944 }
00945
00946 return ret;
00947 }
00948 case DRMS_TYPE_STRING:
00949 if (*str == '\0')
00950 {
00951
00952 dst->string_val = strdup("");
00953 return 0;
00954 }
00955 else if (usemissing)
00956 {
00957 dst->string_val = strdup(DRMS_MISSING_STRING);
00958 return usemissinglen;
00959 }
00960 else
00961 {
00962 char wrk[DRMS_MAXPATHLEN];
00963 if (dst->string_val) free(dst->string_val);
00964 if (sscanf(str,"%[^],]",wrk)!=1) {
00965 if (!silent)
00966 fprintf (stderr, "String value not found at %s.\n", str);
00967 return -1;
00968 }
00969 dst->string_val = strdup(wrk);
00970 return strlen(dst->string_val);
00971 }
00972 default:
00973 if (!silent)
00974 fprintf(stderr, "ERROR: Unhandled DRMS type %d\n",(int)dsttype);
00975 XASSERT(0);
00976 }
00977 return -1;
00978 }
00979
00980
00981
00982
00983 int drms_sscanf_str(const char *str, const char *delim, DRMS_Type_Value_t *dst) {
00984 int usemissing = 0;
00985 int usemissinglen = strlen(kDRMS_MISSING_VALUE);
00986
00987 if (!strncasecmp(kDRMS_MISSING_VALUE, str, usemissinglen))
00988 {
00989 usemissing = 1;
00990 }
00991
00992 if (*str == '\0')
00993 {
00994
00995 dst->string_val = strdup("");
00996 return 0;
00997 }
00998 else if (usemissing)
00999 {
01000 dst->string_val = strdup(DRMS_MISSING_STRING);
01001 return usemissinglen;
01002 }
01003 else
01004 {
01005
01006
01007 int state = 0;
01008
01009
01010
01011
01012
01013 int len = strlen(str);
01014 char *actstr = malloc(len + 1);
01015 char *pactstr = actstr;
01016 const char *pstr = str;
01017 int quotetype = 0;
01018
01019
01020
01021 while (state != 4)
01022 {
01023 if (!*pstr)
01024 {
01025 if (state == 1 || state == 0)
01026 {
01027
01028 state = 4;
01029 }
01030
01031
01032 break;
01033 }
01034 if (state == 0)
01035 {
01036 while (pstr && (*pstr == ' ' || *pstr == '\t'))
01037 {
01038
01039 pstr++;
01040 }
01041
01042 if (*pstr == '\'' || *pstr == '"')
01043 {
01044 if (*pstr == '\'')
01045 {
01046 quotetype = 1;
01047 }
01048 else
01049 {
01050 quotetype = 2;
01051 }
01052
01053 state = 2;
01054 pstr++;
01055 }
01056 else
01057 {
01058 state = 1;
01059 }
01060 }
01061 else if (state == 1)
01062 {
01063 int isdelim = 0;
01064 if (delim)
01065 {
01066 const char *pdelim = delim;
01067 while (*pdelim)
01068 {
01069 if (*pstr == *pdelim)
01070 {
01071 isdelim = 1;
01072 break;
01073 }
01074
01075 pdelim++;
01076 }
01077 }
01078
01079 if (isdelim || *pstr == ' ')
01080 {
01081
01082 state = 4;
01083 }
01084 else
01085 {
01086 *pactstr = *pstr;
01087 pactstr++;
01088 pstr++;
01089 }
01090 }
01091 else if (state == 2)
01092 {
01093
01094
01095
01096
01097
01098 if (*pstr == '\\')
01099 {
01100 state = 3;
01101 pstr++;
01102 }
01103 else if ((quotetype == 1 && *pstr == '\'') || (quotetype == 2 && *pstr == '"'))
01104 {
01105
01106 pstr++;
01107 state = 4;
01108 }
01109 else
01110 {
01111 *pactstr = *pstr;
01112 pactstr++;
01113 pstr++;
01114 }
01115 }
01116 else if (state == 3)
01117 {
01118 if (*pstr == 't')
01119 {
01120 *pactstr = '\t';
01121 }
01122 else if (*pstr == 'n')
01123 {
01124 *pactstr = '\n';
01125 }
01126 else if (*pstr == '\\')
01127 {
01128 *pactstr = '\\';
01129 }
01130 else if (*pstr == '"')
01131 {
01132 *pactstr = '"';
01133 }
01134 else if (*pstr == '\'')
01135 {
01136 *pactstr = '\'';
01137 }
01138 else
01139 {
01140
01141 *pactstr = *pstr;
01142 }
01143
01144 state = 2;
01145 pactstr++;
01146 pstr++;
01147 }
01148 }
01149
01150 *pactstr = '\0';
01151
01152 if (state != 4)
01153 {
01154 if (actstr)
01155 {
01156 free(actstr);
01157 }
01158
01159 return -1;
01160 }
01161 else
01162 {
01163 if (dst->string_val) free(dst->string_val);
01164
01165 if (actstr)
01166 {
01167
01168 dst->string_val = actstr;
01169 }
01170 }
01171
01172 return pstr - str;
01173 }
01174 }
01175
01176
01177
01178 int drms_sscanf2(const char *str, const char *delim, int silent, DRMS_Type_t dsttype, DRMS_Value_t *dst)
01179 {
01180 DRMS_Type_Value_t idst;
01181 int err = 0;
01182 int ret;
01183
01184
01185 memset(&(idst), 0, sizeof(DRMS_Type_Value_t));
01186
01187 if (dsttype == DRMS_TYPE_STRING)
01188 {
01189 if ((ret = drms_sscanf_str(str, delim, &idst)) < 0)
01190 {
01191 err = 1;
01192 }
01193 }
01194 else
01195 {
01196 ret = drms_sscanf_int(str, dsttype, &idst, silent);
01197
01198 if (dsttype == DRMS_TYPE_TIME)
01199 {
01200
01201
01202 if (ret < 0)
01203 {
01204 err = 1;
01205 }
01206 }
01207 else if (ret <= 0)
01208 {
01209 err = 1;
01210 }
01211 }
01212
01213 if (!err)
01214 {
01215 if (dst)
01216 {
01217 (*dst).value = idst;
01218 (*dst).type = dsttype;
01219 }
01220 }
01221 else
01222 {
01223 ret = -1;
01224 }
01225
01226 return ret;
01227 }
01228
01229 void drms_memset(DRMS_Type_t type, int n, void *array,
01230 DRMS_Type_Value_t val)
01231 {
01232 int i;
01233
01234 switch(type)
01235 {
01236 case DRMS_TYPE_CHAR:
01237 { char *p;
01238 p = (char *) array;
01239 for (i=0; i<n; i++)
01240 *p++ = val.char_val;
01241 }
01242 break;
01243 case DRMS_TYPE_SHORT:
01244 { short *p;
01245 p = (short *) array;
01246 for (i=0; i<n; i++)
01247 *p++ = val.short_val;
01248 }
01249 break;
01250 case DRMS_TYPE_INT:
01251 { int *p;
01252 p = (int *) array;
01253 for (i=0; i<n; i++)
01254 *p++ = val.int_val;
01255 }
01256 break;
01257 case DRMS_TYPE_LONGLONG:
01258 { long long *p;
01259 p = (long long *) array;
01260 for (i=0; i<n; i++)
01261 *p++ = val.longlong_val;
01262 }
01263 break;
01264 case DRMS_TYPE_FLOAT:
01265 { float *p;
01266 p = (float *) array;
01267 for (i=0; i<n; i++)
01268 *p++ = val.float_val;
01269 }
01270 break;
01271 case DRMS_TYPE_TIME:
01272 case DRMS_TYPE_DOUBLE:
01273 { double *p;
01274 p = (double *) array;
01275 for (i=0; i<n; i++)
01276 *p++ = val.double_val;
01277 }
01278 break;
01279 default:
01280 fprintf(stderr, "ERROR: Unhandled DRMS type %d\n",(int)type);
01281 XASSERT(0);
01282 }
01283 }
01284
01285
01286
01287 void *drms_addr(DRMS_Type_t type, DRMS_Type_Value_t *val)
01288 {
01289 switch(type)
01290 {
01291 case DRMS_TYPE_CHAR:
01292 return (void *) &(val->char_val);
01293 break;
01294 case DRMS_TYPE_SHORT:
01295 return (void *) &(val->short_val);
01296 break;
01297 case DRMS_TYPE_INT:
01298 return (void *) &(val->int_val);
01299 break;
01300 case DRMS_TYPE_LONGLONG:
01301 return (void *) &(val->longlong_val);
01302 break;
01303 case DRMS_TYPE_FLOAT:
01304 return (void *) &(val->float_val);
01305 break;
01306 case DRMS_TYPE_TIME:
01307 case DRMS_TYPE_DOUBLE:
01308 return (void *) &(val->double_val);
01309 break;
01310 case DRMS_TYPE_STRING:
01311 return (void *) val->string_val;
01312 break;
01313 default:
01314 fprintf(stderr, "ERROR: Unhandled DRMS type %d\n",(int)type);
01315 XASSERT(0);
01316 }
01317 return NULL;
01318 }
01319
01320
01321
01322 int drms_convert(DRMS_Type_t dsttype, DRMS_Type_Value_t *dst,
01323 DRMS_Type_t srctype, DRMS_Type_Value_t *src)
01324 {
01325 int status;
01326
01327 switch(dsttype)
01328 {
01329 case DRMS_TYPE_CHAR:
01330 dst->char_val = drms2char(srctype, src, &status);
01331 break;
01332 case DRMS_TYPE_SHORT:
01333 dst->short_val = drms2short(srctype, src, &status);
01334 break;
01335 case DRMS_TYPE_INT:
01336 dst->int_val = drms2int(srctype, src, &status);
01337 break;
01338 case DRMS_TYPE_LONGLONG:
01339 dst->longlong_val = drms2longlong(srctype, src, &status);
01340 break;
01341 case DRMS_TYPE_FLOAT:
01342 dst->float_val = drms2float(srctype, src, &status);
01343 break;
01344 case DRMS_TYPE_TIME:
01345 dst->time_val = drms2time(srctype, src, &status);
01346 break;
01347 case DRMS_TYPE_DOUBLE:
01348 dst->double_val = drms2double(srctype, src, &status);
01349 break;
01350 case DRMS_TYPE_STRING:
01351 if (dst->string_val)
01352 free(dst->string_val);
01353 dst->string_val = drms2string(srctype, src, &status);
01354 break;
01355 default:
01356 fprintf(stderr, "ERROR: Unhandled DRMS type %d\n",(int)dsttype);
01357 XASSERT(0);
01358 }
01359 return status;
01360 }
01361
01362
01363
01364
01365 char drms2char(DRMS_Type_t type, DRMS_Type_Value_t *value, int *status)
01366 {
01367 int stat;
01368 int ustat;
01369 volatile char result;
01370 long long val;
01371 char *endptr;
01372
01373 result = DRMS_MISSING_CHAR;
01374 stat = DRMS_RANGE;
01375 switch(type)
01376 {
01377 case DRMS_TYPE_CHAR:
01378 stat = DRMS_SUCCESS;
01379 result = value->char_val;
01380 break;
01381 case DRMS_TYPE_SHORT:
01382 if (value->short_val == DRMS_MISSING_SHORT)
01383 {
01384 stat = DRMS_SUCCESS;
01385 result = DRMS_MISSING_CHAR;
01386 }
01387 else if (!(value->short_val < SCHAR_MIN ||
01388 value->short_val > SCHAR_MAX))
01389 {
01390 stat = DRMS_SUCCESS;
01391 result = (char) value->short_val;
01392 }
01393 break;
01394 case DRMS_TYPE_INT:
01395 if (value->int_val == DRMS_MISSING_INT)
01396 {
01397 stat = DRMS_SUCCESS;
01398 result = DRMS_MISSING_CHAR;
01399 }
01400 else if (!(value->int_val < SCHAR_MIN ||
01401 value->int_val > SCHAR_MAX))
01402 {
01403 stat = DRMS_SUCCESS;
01404 result = (char) value->int_val;
01405 }
01406 break;
01407 case DRMS_TYPE_LONGLONG:
01408 if (value->longlong_val == DRMS_MISSING_LONGLONG)
01409 {
01410 stat = DRMS_SUCCESS;
01411 result = DRMS_MISSING_CHAR;
01412 }
01413 else if (!(value->longlong_val < SCHAR_MIN ||
01414 value->longlong_val > SCHAR_MAX))
01415 {
01416 stat = DRMS_SUCCESS;
01417 result = (char) value->longlong_val;
01418 }
01419 break;
01420 case DRMS_TYPE_FLOAT:
01421 if (isnan(value->float_val))
01422 {
01423 stat = DRMS_SUCCESS;
01424 result = DRMS_MISSING_CHAR;
01425 }
01426 else if (!(value->float_val < SCHAR_MIN ||
01427 value->float_val > SCHAR_MAX))
01428 {
01429 result = (char)FloatToLongLong(value->float_val, &ustat);
01430 stat = (ustat == kExact) ? DRMS_SUCCESS : DRMS_INEXACT;
01431 }
01432 break;
01433 case DRMS_TYPE_TIME:
01434 if (drms_ismissing_time(value->time_val))
01435 {
01436 stat = DRMS_SUCCESS;
01437 result = DRMS_MISSING_CHAR;
01438 }
01439 else if (!(value->double_val < SCHAR_MIN ||
01440 value->double_val > SCHAR_MAX))
01441 {
01442 result = (char)DoubleToLongLong(value->double_val, &ustat);
01443 stat = (ustat == kExact) ? DRMS_SUCCESS : DRMS_INEXACT;
01444 }
01445 break;
01446 case DRMS_TYPE_DOUBLE:
01447 if (isnan(value->double_val))
01448 {
01449 stat = DRMS_SUCCESS;
01450 result = DRMS_MISSING_CHAR;
01451 }
01452 else if (!(value->double_val < SCHAR_MIN ||
01453 value->double_val > SCHAR_MAX))
01454 {
01455 result = (char)DoubleToLongLong(value->double_val, &ustat);
01456 stat = (ustat == kExact) ? DRMS_SUCCESS : DRMS_INEXACT;
01457 }
01458 break;
01459 case DRMS_TYPE_STRING:
01460 val = (long long)strtoll(value->string_val, &endptr, 0);
01461 if (val==0 && endptr==value->string_val)
01462 {
01463 stat = DRMS_BADSTRING;
01464 result = DRMS_MISSING_CHAR;
01465 }
01466 else if ((IsHexString(value->string_val) &&
01467 ((val & 0xFFFFFFFFFFFFFF00) != 0) &&
01468 ((val & 0xFFFFFFFFFFFFFF00) != 0xFFFFFFFFFFFFFF00)) ||
01469 (!IsHexString(value->string_val) && (val < SCHAR_MIN || val > SCHAR_MAX)))
01470 {
01471 stat = DRMS_RANGE;
01472 result = DRMS_MISSING_CHAR;
01473 }
01474 else {
01475 stat = DRMS_SUCCESS;
01476 result = (char) val;
01477 }
01478 break;
01479 default:
01480 stat = DRMS_RANGE;
01481 result = DRMS_MISSING_CHAR;
01482 }
01483 if (status)
01484 *status = stat;
01485 return result;
01486 }
01487
01488
01489 short drms2short(DRMS_Type_t type, DRMS_Type_Value_t *value, int *status)
01490 {
01491 int stat;
01492 int ustat;
01493 volatile short result;
01494 long long val;
01495 char *endptr;
01496
01497 result = DRMS_MISSING_SHORT;
01498 stat = DRMS_RANGE;
01499 switch(type)
01500 {
01501 case DRMS_TYPE_CHAR:
01502 if (value->char_val == DRMS_MISSING_CHAR)
01503 {
01504 stat = DRMS_SUCCESS;
01505 result = DRMS_MISSING_SHORT;
01506 }
01507 else
01508 {
01509 stat = DRMS_SUCCESS;
01510 result = (short) value->char_val;
01511 }
01512 break;
01513 case DRMS_TYPE_SHORT:
01514 stat = DRMS_SUCCESS;
01515 result = value->short_val;
01516 break;
01517 case DRMS_TYPE_INT:
01518 if (value->int_val == DRMS_MISSING_INT)
01519 {
01520 stat = DRMS_SUCCESS;
01521 result = DRMS_MISSING_SHORT;
01522 }
01523 else if (!(value->int_val < SHRT_MIN ||
01524 value->int_val > SHRT_MAX))
01525 {
01526 stat = DRMS_SUCCESS;
01527 result = (short) value->int_val;
01528 }
01529 break;
01530 case DRMS_TYPE_LONGLONG:
01531 if (value->longlong_val == DRMS_MISSING_LONGLONG)
01532 {
01533 stat = DRMS_SUCCESS;
01534 result = DRMS_MISSING_SHORT;
01535 }
01536 else if (!(value->longlong_val < SHRT_MIN ||
01537 value->longlong_val > SHRT_MAX))
01538 {
01539 stat = DRMS_SUCCESS;
01540 result = (short) value->longlong_val;
01541 }
01542 break;
01543 case DRMS_TYPE_FLOAT:
01544 if (isnan(value->float_val))
01545 {
01546 stat = DRMS_SUCCESS;
01547 result = DRMS_MISSING_SHORT;
01548 }
01549 else if (!(value->float_val < SHRT_MIN ||
01550 value->float_val > SHRT_MAX))
01551 {
01552 result = (short)FloatToLongLong(value->float_val, &ustat);
01553 stat = (ustat == kExact) ? DRMS_SUCCESS : DRMS_INEXACT;
01554 }
01555 break;
01556 case DRMS_TYPE_TIME:
01557 if (drms_ismissing_time(value->time_val))
01558 {
01559 stat = DRMS_SUCCESS;
01560 result = DRMS_MISSING_SHORT;
01561 }
01562 else if (!(value->double_val < SHRT_MIN ||
01563 value->double_val > SHRT_MAX))
01564 {
01565 result = (short)DoubleToLongLong(value->double_val, &ustat);
01566 stat = (ustat == kExact) ? DRMS_SUCCESS : DRMS_INEXACT;
01567 }
01568 break;
01569 case DRMS_TYPE_DOUBLE:
01570 if (isnan(value->double_val))
01571 {
01572 stat = DRMS_SUCCESS;
01573 result = DRMS_MISSING_SHORT;
01574 }
01575 else if (!(value->double_val < SHRT_MIN ||
01576 value->double_val > SHRT_MAX))
01577 {
01578 result = (short)DoubleToLongLong(value->double_val, &ustat);
01579 stat = (ustat == kExact) ? DRMS_SUCCESS : DRMS_INEXACT;
01580 }
01581 break;
01582 case DRMS_TYPE_STRING:
01583 val = strtoll(value->string_val, &endptr, 0);
01584 if (val==0 && endptr==value->string_val)
01585 {
01586 stat = DRMS_BADSTRING;
01587 result = DRMS_MISSING_SHORT;
01588 }
01589 else if ((IsHexString(value->string_val) &&
01590 ((val & 0xFFFFFFFFFFFF0000) != 0) &&
01591 ((val & 0xFFFFFFFFFFFF0000) != 0xFFFFFFFFFFFF0000)) ||
01592 (!IsHexString(value->string_val) && (val < SHRT_MIN || val > SHRT_MAX)))
01593 {
01594 stat = DRMS_RANGE;
01595 result = DRMS_MISSING_SHORT;
01596 }
01597 else {
01598 stat = DRMS_SUCCESS;
01599 result = (short) val;
01600 }
01601 break;
01602 default:
01603 stat = DRMS_RANGE;
01604 result = DRMS_MISSING_SHORT;
01605 }
01606 if (status)
01607 *status = stat;
01608 return result;
01609 }
01610
01611
01612 int drms2int(DRMS_Type_t type, DRMS_Type_Value_t *value, int *status)
01613 {
01614 int stat;
01615 int ustat;
01616 volatile int result;
01617 long long val;
01618 char *endptr;
01619
01620 result = DRMS_MISSING_INT;
01621 stat = DRMS_RANGE;
01622 switch(type)
01623 {
01624 case DRMS_TYPE_CHAR:
01625 if (value->char_val == DRMS_MISSING_CHAR)
01626 {
01627 stat = DRMS_SUCCESS;
01628 result = DRMS_MISSING_INT;
01629 }
01630 else
01631 { stat = DRMS_SUCCESS;
01632 result = (int) value->char_val;
01633 }
01634 break;
01635 case DRMS_TYPE_SHORT:
01636 if (value->short_val == DRMS_MISSING_SHORT)
01637 {
01638 stat = DRMS_SUCCESS;
01639 result = DRMS_MISSING_INT;
01640 }
01641 else
01642 {
01643 stat = DRMS_SUCCESS;
01644 result = value->short_val;
01645 }
01646 break;
01647 case DRMS_TYPE_INT:
01648 stat = DRMS_SUCCESS;
01649 result = (int) value->int_val;
01650 break;
01651 case DRMS_TYPE_LONGLONG:
01652 if (value->longlong_val == DRMS_MISSING_LONGLONG)
01653 {
01654 stat = DRMS_SUCCESS;
01655 result = DRMS_MISSING_INT;
01656 }
01657 else
01658 if (!(value->longlong_val < INT_MIN ||
01659 value->longlong_val > INT_MAX))
01660 {
01661 stat = DRMS_SUCCESS;
01662 result = (int) value->longlong_val;
01663 }
01664
01665 break;
01666 case DRMS_TYPE_FLOAT:
01667 if (isnan(value->float_val))
01668 {
01669 stat = DRMS_SUCCESS;
01670 result = DRMS_MISSING_INT;
01671 }
01672 else if (!(value->float_val < INT_MIN ||
01673 value->float_val > INT_MAX))
01674 {
01675 result = (int)FloatToLongLong(value->float_val, &ustat);
01676 stat = (ustat == kExact) ? DRMS_SUCCESS : DRMS_INEXACT;
01677 }
01678 break;
01679 case DRMS_TYPE_TIME:
01680 if (drms_ismissing_time(value->time_val))
01681 {
01682 stat = DRMS_SUCCESS;
01683 result = DRMS_MISSING_INT;
01684 }
01685 else if (!(value->double_val < INT_MIN ||
01686 value->double_val > INT_MAX))
01687 {
01688 result = (int)DoubleToLongLong(value->double_val, &ustat);
01689 stat = (ustat == kExact) ? DRMS_SUCCESS : DRMS_INEXACT;
01690 }
01691 break;
01692 case DRMS_TYPE_DOUBLE:
01693 if (isnan(value->double_val))
01694 {
01695 stat = DRMS_SUCCESS;
01696 result = DRMS_MISSING_INT;
01697 }
01698 else if (!(value->double_val < INT_MIN ||
01699 value->double_val > INT_MAX))
01700 {
01701 result = (int)DoubleToLongLong(value->double_val, &ustat);
01702 stat = (ustat == kExact) ? DRMS_SUCCESS : DRMS_INEXACT;
01703 }
01704 break;
01705 case DRMS_TYPE_STRING:
01706 val = strtoll(value->string_val, &endptr, 0);
01707 if (val==0 && endptr==value->string_val )
01708 {
01709 stat = DRMS_BADSTRING;
01710 result = DRMS_MISSING_INT;
01711 }
01712 else if ((IsHexString(value->string_val) &&
01713 ((val & 0xFFFFFFFF00000000) != 0) &&
01714 ((val & 0xFFFFFFFF00000000) != 0xFFFFFFFF00000000)) ||
01715 (!IsHexString(value->string_val) && (val < INT_MIN || val > INT_MAX)))
01716 {
01717 stat = DRMS_RANGE;
01718 result = DRMS_MISSING_INT;
01719 }
01720 else {
01721 stat = DRMS_SUCCESS;
01722 result = (int) val;
01723 }
01724 break;
01725 default:
01726 stat = DRMS_RANGE;
01727 result = DRMS_MISSING_INT;
01728 }
01729 if (status)
01730 *status = stat;
01731 return result;
01732 }
01733
01734 long long drms2longlong(DRMS_Type_t type, DRMS_Type_Value_t *value, int *status)
01735 {
01736 int stat;
01737 int ustat;
01738 volatile long long result;
01739 long long val;
01740 char *endptr;
01741
01742 result = DRMS_MISSING_LONGLONG;
01743 stat = DRMS_RANGE;
01744 switch(type)
01745 {
01746 case DRMS_TYPE_CHAR:
01747 if (value->char_val == DRMS_MISSING_CHAR)
01748 {
01749 stat = DRMS_SUCCESS;
01750 result = DRMS_MISSING_LONGLONG;
01751 }
01752 else
01753 {
01754 stat = DRMS_SUCCESS;
01755 result = (long long) value->char_val;
01756 }
01757 break;
01758 case DRMS_TYPE_SHORT:
01759 if (value->short_val == DRMS_MISSING_SHORT)
01760 {
01761 stat = DRMS_SUCCESS;
01762 result = DRMS_MISSING_LONGLONG;
01763 }
01764 else
01765 {
01766 stat = DRMS_SUCCESS;
01767 result = value->short_val;
01768 }
01769 break;
01770 case DRMS_TYPE_INT:
01771 if (value->int_val == DRMS_MISSING_INT)
01772 {
01773 stat = DRMS_SUCCESS;
01774 result = DRMS_MISSING_LONGLONG;
01775 }
01776 else
01777 {
01778 stat = DRMS_SUCCESS;
01779 result = (long long) value->int_val;
01780 }
01781 break;
01782 case DRMS_TYPE_LONGLONG:
01783 if (value->longlong_val == DRMS_MISSING_LONGLONG)
01784 {
01785 stat = DRMS_SUCCESS;
01786 result = DRMS_MISSING_LONGLONG;
01787 }
01788 else
01789 {
01790 stat = DRMS_SUCCESS;
01791 result = value->longlong_val;
01792 }
01793 break;
01794 case DRMS_TYPE_FLOAT:
01795 if (isnan(value->float_val))
01796 {
01797 stat = DRMS_SUCCESS;
01798 result = DRMS_MISSING_LONGLONG;
01799 }
01800 else if (!(value->float_val < LLONG_MIN ||
01801 value->float_val > LLONG_MAX))
01802 {
01803 result = FloatToLongLong(value->float_val, &ustat);
01804 stat = (ustat == kExact) ? DRMS_SUCCESS : DRMS_INEXACT;
01805 }
01806 break;
01807 case DRMS_TYPE_TIME:
01808 if (drms_ismissing_time(value->time_val))
01809 {
01810 stat = DRMS_SUCCESS;
01811 result = DRMS_MISSING_LONGLONG;
01812 }
01813 else if (!(value->double_val < LLONG_MIN ||
01814 value->double_val > LLONG_MAX))
01815 {
01816 result = DoubleToLongLong(value->double_val, &ustat);
01817 stat = (ustat == kExact) ? DRMS_SUCCESS : DRMS_INEXACT;
01818 }
01819 break;
01820 case DRMS_TYPE_DOUBLE:
01821 if (isnan(value->double_val))
01822 {
01823 stat = DRMS_SUCCESS;
01824 result = DRMS_MISSING_LONGLONG;
01825 }
01826 else if (!(value->double_val < LLONG_MIN ||
01827 value->double_val > LLONG_MAX))
01828 {
01829 result = DoubleToLongLong(value->double_val, &ustat);
01830 stat = (ustat == kExact) ? DRMS_SUCCESS : DRMS_INEXACT;
01831 }
01832 break;
01833 case DRMS_TYPE_STRING:
01834 val = strtoll(value->string_val, &endptr, 0);
01835 if (val==0 && endptr==value->string_val)
01836 {
01837 stat = DRMS_BADSTRING;
01838 result = DRMS_MISSING_LONGLONG;
01839 }
01840 else {
01841 stat = DRMS_SUCCESS;
01842 result = val;
01843 }
01844 break;
01845 default:
01846 stat = DRMS_RANGE;
01847 result = DRMS_MISSING_LONGLONG;
01848 }
01849 if (status)
01850 *status = stat;
01851 return result;
01852 }
01853
01854
01855 long long conv2longlong(DRMS_Type_t type, DRMS_Type_Value_t *value, int *status)
01856 {
01857 int stat;
01858 int ustat;
01859 volatile long long result;
01860 long long val;
01861 char *endptr;
01862
01863 result = DRMS_MISSING_LONGLONG;
01864 stat = DRMS_RANGE;
01865 switch(type)
01866 {
01867 case DRMS_TYPE_CHAR:
01868 stat = DRMS_SUCCESS;
01869 result = (long long) value->char_val;
01870
01871 break;
01872 case DRMS_TYPE_SHORT:
01873 stat = DRMS_SUCCESS;
01874 result = (long long)value->short_val;
01875 break;
01876 case DRMS_TYPE_INT:
01877 stat = DRMS_SUCCESS;
01878 result = (long long) value->int_val;
01879
01880 break;
01881 case DRMS_TYPE_LONGLONG:
01882 stat = DRMS_SUCCESS;
01883 result = value->longlong_val;
01884
01885 break;
01886 case DRMS_TYPE_FLOAT:
01887 if (isnan(value->float_val))
01888 {
01889 stat = DRMS_SUCCESS;
01890 result = DRMS_MISSING_LONGLONG;
01891 }
01892 else if (!(value->float_val < LLONG_MIN ||
01893 value->float_val > LLONG_MAX))
01894 {
01895 result = FloatToLongLong(value->float_val, &ustat);
01896 stat = (ustat == kExact) ? DRMS_SUCCESS : DRMS_INEXACT;
01897 }
01898 break;
01899 case DRMS_TYPE_TIME:
01900 case DRMS_TYPE_DOUBLE:
01901 if (isnan(value->double_val))
01902 {
01903 stat = DRMS_SUCCESS;
01904 result = DRMS_MISSING_LONGLONG;
01905 }
01906 else if (!(value->double_val < LLONG_MIN ||
01907 value->double_val > LLONG_MAX))
01908 {
01909 result = DoubleToLongLong(value->double_val, &ustat);
01910 stat = (ustat == kExact) ? DRMS_SUCCESS : DRMS_INEXACT;
01911 }
01912 break;
01913 case DRMS_TYPE_STRING:
01914 val = strtod(value->string_val,&endptr);
01915 if (val==0 && endptr==value->string_val )
01916 {
01917 stat = DRMS_BADSTRING;
01918 result = DRMS_MISSING_LONGLONG;
01919 }
01920 else {
01921 stat = DRMS_SUCCESS;
01922 result = val;
01923 }
01924 break;
01925 default:
01926 stat = DRMS_RANGE;
01927 result = DRMS_MISSING_LONGLONG;
01928 }
01929 if (status)
01930 *status = stat;
01931 return result;
01932 }
01933
01934 float drms2float(DRMS_Type_t type, DRMS_Type_Value_t *value, int *status)
01935 {
01936 int stat;
01937 volatile float result;
01938 float val;
01939 char *endptr;
01940
01941 result = DRMS_MISSING_FLOAT;
01942 stat = DRMS_RANGE;
01943 switch(type)
01944 {
01945 case DRMS_TYPE_CHAR:
01946 if (value->char_val == DRMS_MISSING_CHAR)
01947 {
01948 stat = DRMS_SUCCESS;
01949 result = DRMS_MISSING_FLOAT;
01950 }
01951 else
01952 {
01953 stat = DRMS_SUCCESS;
01954 result = (float) value->char_val;
01955 }
01956 break;
01957 case DRMS_TYPE_SHORT:
01958 if (value->short_val == DRMS_MISSING_SHORT)
01959 {
01960 stat = DRMS_SUCCESS;
01961 result = DRMS_MISSING_FLOAT;
01962 }
01963 else
01964 {
01965 stat = DRMS_SUCCESS;
01966 result = (float)value->short_val;
01967 }
01968 break;
01969 case DRMS_TYPE_INT:
01970 if (value->int_val == DRMS_MISSING_INT)
01971 {
01972 stat = DRMS_SUCCESS;
01973 result = DRMS_MISSING_FLOAT;
01974 }
01975 else
01976 {
01977 result = (float) value->int_val;
01978 if ((int) result == value->int_val)
01979 stat = DRMS_SUCCESS;
01980 else
01981 stat = DRMS_INEXACT;
01982 }
01983 break;
01984 case DRMS_TYPE_LONGLONG:
01985 if (value->longlong_val == DRMS_MISSING_LONGLONG)
01986 {
01987 stat = DRMS_SUCCESS;
01988 result = DRMS_MISSING_FLOAT;
01989 }
01990 else
01991 {
01992 result = (float) value->longlong_val;
01993 if ((long long) result == value->longlong_val)
01994 stat = DRMS_SUCCESS;
01995 else
01996 stat = DRMS_INEXACT;
01997 break;
01998 }
01999 case DRMS_TYPE_FLOAT:
02000 stat = DRMS_SUCCESS;
02001 result = value->float_val;
02002 break;
02003 case DRMS_TYPE_TIME:
02004 if (drms_ismissing_time(value->time_val))
02005 {
02006 stat = DRMS_SUCCESS;
02007 result = DRMS_MISSING_FLOAT;
02008 }
02009 else if (!(value->double_val < -FLT_MAX ||
02010 value->double_val > FLT_MAX))
02011 {
02012 result = (float) value->double_val;
02013 if ( (double)result == value->double_val )
02014 stat = DRMS_SUCCESS;
02015 else
02016 stat = DRMS_INEXACT;
02017 }
02018 break;
02019 case DRMS_TYPE_DOUBLE:
02020 if (isnan(value->double_val))
02021 {
02022 stat = DRMS_SUCCESS;
02023 result = DRMS_MISSING_FLOAT;
02024 }
02025 else if (!(value->double_val < -FLT_MAX ||
02026 value->double_val > FLT_MAX))
02027 {
02028 result = (float) value->double_val;
02029 if ( (double)result == value->double_val )
02030 stat = DRMS_SUCCESS;
02031 else
02032 stat = DRMS_INEXACT;
02033 }
02034 break;
02035 case DRMS_TYPE_STRING:
02036 val = strtof(value->string_val,&endptr);
02037 if (IsZeroF(val) && endptr==value->string_val )
02038 {
02039 stat = DRMS_BADSTRING;
02040 result = DRMS_MISSING_FLOAT;
02041 }
02042 else if ((IsPosHugeValF(val) || IsNegHugeValF(val)) && errno==ERANGE)
02043 {
02044 stat = DRMS_RANGE;
02045 result = DRMS_MISSING_FLOAT;
02046 }
02047 else {
02048 stat = DRMS_SUCCESS;
02049 result = (float) val;
02050 }
02051 break;
02052 default:
02053 stat = DRMS_RANGE;
02054 result = DRMS_MISSING_FLOAT;
02055 }
02056 if (status)
02057 *status = stat;
02058 return result;
02059 }
02060
02061
02062
02063 double drms2double(DRMS_Type_t type, DRMS_Type_Value_t *value, int *status)
02064 {
02065 int stat;
02066 volatile double result;
02067 double val;
02068 char *endptr;
02069
02070 result = DRMS_MISSING_DOUBLE;
02071 stat = DRMS_RANGE;
02072 switch(type)
02073 {
02074 case DRMS_TYPE_CHAR:
02075 if (value->char_val == DRMS_MISSING_CHAR)
02076 {
02077 stat = DRMS_SUCCESS;
02078 result = DRMS_MISSING_DOUBLE;
02079 }
02080 else
02081 {
02082 stat = DRMS_SUCCESS;
02083 result = (double) value->char_val;
02084 }
02085 break;
02086 case DRMS_TYPE_SHORT:
02087 if (value->short_val == DRMS_MISSING_SHORT)
02088 {
02089 stat = DRMS_SUCCESS;
02090 result = DRMS_MISSING_DOUBLE;
02091 }
02092 else
02093 {
02094 stat = DRMS_SUCCESS;
02095 result = (double)value->short_val;
02096 }
02097 break;
02098 case DRMS_TYPE_INT:
02099 if (value->int_val == DRMS_MISSING_INT)
02100 {
02101 stat = DRMS_SUCCESS;
02102 result = DRMS_MISSING_DOUBLE;
02103 }
02104 else
02105 {
02106 stat = DRMS_SUCCESS;
02107 result = (double) value->int_val;
02108 }
02109 break;
02110 case DRMS_TYPE_LONGLONG:
02111 if (value->longlong_val == DRMS_MISSING_LONGLONG)
02112 {
02113 stat = DRMS_SUCCESS;
02114 result = DRMS_MISSING_DOUBLE;
02115 }
02116 else
02117 {
02118 result = (double) value->longlong_val;
02119 if ((long long) result == value->longlong_val)
02120 stat = DRMS_SUCCESS;
02121 else
02122 stat = DRMS_INEXACT;
02123 }
02124 break;
02125 case DRMS_TYPE_FLOAT:
02126 if (isnan(value->float_val))
02127 {
02128 stat = DRMS_SUCCESS;
02129 result = DRMS_MISSING_DOUBLE;
02130 }
02131 else
02132 {
02133 stat = DRMS_SUCCESS;
02134 result = (double) value->float_val;
02135 }
02136 break;
02137 case DRMS_TYPE_TIME:
02138 {
02139 stat = DRMS_SUCCESS;
02140 if (drms_ismissing_time(value->time_val))
02141 {
02142 result = DRMS_MISSING_DOUBLE;
02143 }
02144 else
02145 {
02146 result = (double) value->time_val;
02147 }
02148 }
02149 break;
02150 case DRMS_TYPE_DOUBLE:
02151 stat = DRMS_SUCCESS;
02152 result = (double) value->double_val;
02153 break;
02154 case DRMS_TYPE_STRING:
02155 val = strtod(value->string_val,&endptr);
02156 if (IsZero(val) && endptr==value->string_val )
02157 {
02158 stat = DRMS_BADSTRING;
02159 result = DRMS_MISSING_DOUBLE;
02160 }
02161 else if ((IsPosHugeVal(val) || IsNegHugeVal(val)) && errno==ERANGE)
02162 {
02163 stat = DRMS_RANGE;
02164 result = DRMS_MISSING_DOUBLE;
02165 }
02166 else {
02167 stat = DRMS_SUCCESS;
02168 result = (double) val;
02169 }
02170 break;
02171 default:
02172 stat = DRMS_RANGE;
02173 result = DRMS_MISSING_DOUBLE;
02174 }
02175 if (status)
02176 *status = stat;
02177 return result;
02178 }
02179
02180
02181
02182 double drms2time(DRMS_Type_t type, DRMS_Type_Value_t *value, int *status)
02183 {
02184 int stat;
02185 volatile double result;
02186
02187 result = DRMS_MISSING_TIME;
02188 stat = DRMS_RANGE;
02189 switch(type)
02190 {
02191 case DRMS_TYPE_CHAR:
02192 if (value->char_val == DRMS_MISSING_CHAR)
02193 {
02194 stat = DRMS_SUCCESS;
02195 result = DRMS_MISSING_TIME;
02196 }
02197 else
02198 {
02199 stat = DRMS_SUCCESS;
02200 result = (double) value->char_val;
02201 }
02202 break;
02203 case DRMS_TYPE_SHORT:
02204 if (value->short_val == DRMS_MISSING_SHORT)
02205 {
02206 stat = DRMS_SUCCESS;
02207 result = DRMS_MISSING_TIME;
02208 }
02209 else
02210 {
02211 stat = DRMS_SUCCESS;
02212 result = (double)value->short_val;
02213 }
02214 break;
02215 case DRMS_TYPE_INT:
02216 if (value->int_val == DRMS_MISSING_INT)
02217 {
02218 stat = DRMS_SUCCESS;
02219 result = DRMS_MISSING_TIME;
02220 }
02221 else
02222 {
02223 stat = DRMS_SUCCESS;
02224 result = (double) value->int_val;
02225 }
02226 break;
02227 case DRMS_TYPE_LONGLONG:
02228 if (value->longlong_val == DRMS_MISSING_LONGLONG)
02229 {
02230 stat = DRMS_SUCCESS;
02231 result = DRMS_MISSING_TIME;
02232 }
02233 else
02234 {
02235 result = (double) value->longlong_val;
02236 if ((long long) result == value->longlong_val)
02237 stat = DRMS_SUCCESS;
02238 else
02239 stat = DRMS_INEXACT;
02240 }
02241 break;
02242 case DRMS_TYPE_FLOAT:
02243 if (isnan(value->float_val))
02244 {
02245 stat = DRMS_SUCCESS;
02246 result = DRMS_MISSING_TIME;
02247 }
02248 else
02249 {
02250 stat = DRMS_SUCCESS;
02251 result = (double) value->float_val;
02252 }
02253 break;
02254 case DRMS_TYPE_TIME:
02255 stat = DRMS_SUCCESS;
02256 result = value->time_val;
02257 break;
02258 case DRMS_TYPE_DOUBLE:
02259 if (isnan(value->double_val))
02260 {
02261 stat = DRMS_SUCCESS;
02262 result = DRMS_MISSING_TIME;
02263 }
02264 else
02265 {
02266 stat = DRMS_SUCCESS;
02267 result = (double) value->double_val;
02268 }
02269 break;
02270 case DRMS_TYPE_STRING:
02271 {
02272 TIME interval = 0;
02273
02274
02275 interval = atoinc2(value->string_val);
02276 if (interval >= 0)
02277 {
02278
02279 result = interval;
02280 }
02281 else
02282 {
02283
02284 result = sscan_time(value->string_val);
02285
02286 }
02287
02288 if (result < 0)
02289 {
02290 stat = DRMS_BADSTRING;
02291 result = DRMS_MISSING_TIME;
02292 }
02293 else
02294 stat = DRMS_SUCCESS;
02295 }
02296 break;
02297 default:
02298 stat = DRMS_RANGE;
02299 result = DRMS_MISSING_DOUBLE;
02300 }
02301 if (status)
02302 *status = stat;
02303 return result;
02304 }
02305
02306
02307 char *drms2string(DRMS_Type_t type, DRMS_Type_Value_t *value, int *status)
02308 {
02309 int stat;
02310 char *result;
02311
02312 result = NULL;
02313 stat = DRMS_SUCCESS;
02314 if (type == DRMS_TYPE_STRING)
02315 {
02316 if (value->string_val)
02317 {
02318 copy_string(&result, value->string_val);
02319 }
02320 }
02321 else
02322 {
02323 result = malloc(30);
02324 XASSERT(result);
02325 memset(result,0,30);
02326 switch(type)
02327 {
02328 case DRMS_TYPE_CHAR:
02329 CHECKSNPRINTF(snprintf(result, 30, "%hhd", value->char_val), 30);
02330 break;
02331 case DRMS_TYPE_SHORT:
02332 CHECKSNPRINTF(snprintf(result, 30, "%hd", value->short_val), 30);
02333 break;
02334 case DRMS_TYPE_INT:
02335 CHECKSNPRINTF(snprintf(result, 30, "%d", value->int_val), 30);
02336 break;
02337 case DRMS_TYPE_LONGLONG:
02338 CHECKSNPRINTF(snprintf(result, 30, "%lld", value->longlong_val), 30);
02339 break;
02340 case DRMS_TYPE_FLOAT:
02341 CHECKSNPRINTF(snprintf(result, 30, "%15.9g", value->float_val), 30);
02342 break;
02343 case DRMS_TYPE_DOUBLE:
02344 CHECKSNPRINTF(snprintf(result, 30, "%24.17lg", value->double_val), 30);
02345 break;
02346 case DRMS_TYPE_TIME:
02347 sprint_time(result, value->double_val, "TAI", 0);
02348 break;
02349 default:
02350 stat = DRMS_RANGE;
02351 result[0] = 0;
02352 }
02353 }
02354 if (status)
02355 *status = stat;
02356 return result;
02357 }
02358
02359
02360 void drms_byteswap(DRMS_Type_t type, int n, char *val)
02361 {
02362 if (type == DRMS_TYPE_STRING)
02363 return;
02364
02365 byteswap(drms_sizeof(type), n, val);
02366 }
02367
02368
02369
02370
02371
02372
02373 int drms_daxpy(DRMS_Type_t type, const double alpha, DRMS_Type_Value_t *x,
02374 DRMS_Type_Value_t *y )
02375 {
02376 switch(type)
02377 {
02378 case DRMS_TYPE_CHAR:
02379 if (x->char_val == DRMS_MISSING_CHAR)
02380 y->char_val = DRMS_MISSING_CHAR;
02381 else
02382 y->char_val = (char)(alpha*x->char_val + y->char_val);
02383 break;
02384 case DRMS_TYPE_SHORT:
02385 if (x->short_val == DRMS_MISSING_SHORT)
02386 y->short_val = DRMS_MISSING_SHORT;
02387 else
02388 y->short_val = (short)(alpha*x->short_val + y->short_val);
02389 break;
02390 case DRMS_TYPE_INT:
02391 if (x->int_val == DRMS_MISSING_INT)
02392 y->int_val = DRMS_MISSING_INT;
02393 else
02394 y->int_val = (int)(alpha*x->int_val + y->int_val);
02395 break;
02396 case DRMS_TYPE_LONGLONG:
02397 if (x->longlong_val == DRMS_MISSING_LONGLONG)
02398 y->longlong_val = DRMS_MISSING_LONGLONG;
02399 else
02400 y->longlong_val = (long long)(alpha*x->longlong_val + y->longlong_val);
02401 break;
02402 case DRMS_TYPE_FLOAT:
02403 if (isnan(x->float_val))
02404 y->float_val = DRMS_MISSING_FLOAT;
02405 else
02406 y->float_val = (float)(alpha*x->float_val + y->float_val);
02407 break;
02408 case DRMS_TYPE_DOUBLE:
02409 if (isnan(x->double_val))
02410 y->double_val = DRMS_MISSING_DOUBLE;
02411 else
02412 y->double_val = (double)(alpha*x->double_val + y->double_val);
02413 break;
02414 case DRMS_TYPE_TIME:
02415 if (drms_ismissing_time(x->time_val))
02416 y->time_val = DRMS_MISSING_TIME;
02417 else
02418 y->time_val = (double)(alpha*x->time_val + y->time_val);
02419 break;
02420 case DRMS_TYPE_STRING:
02421 fprintf(stderr, "DRMS_DAXPY: Operation undefined for strings.\n");
02422 XASSERT(0);
02423 return 1;
02424 break;
02425 default:
02426 fprintf(stderr, "ERROR: Unhandled DRMS type %d\n",(int)type);
02427 XASSERT(0);
02428 return 1;
02429 }
02430 return 0;
02431 }
02432
02433 const TIME *drms_time_getepoch(const char *str, DRMS_TimeEpoch_t *epochenum, int *status)
02434 {
02435 int stat = DRMS_SUCCESS;
02436 char buf[kTIMEIO_MaxTimeEpochStr];
02437 TIME *ret = NULL;
02438
02439
02440 if (epochenum && *epochenum > kTimeEpoch_Invalid && *epochenum < kTimeEpoch_END)
02441 {
02442 ret = &(gSEpochS[*epochenum].internalTime);
02443 }
02444 else
02445 {
02446 if (!gSlotEpochHC)
02447 {
02448 gSlotEpochHC = hcon_create(sizeof(TIME),
02449 kTIMEIO_MaxTimeEpochStr,
02450 NULL,
02451 NULL,
02452 NULL,
02453 NULL,
02454 0);
02455
02456 if (gSlotEpochHC)
02457 {
02458 int i = 0;
02459
02460 while (gSEpochS[i].type != -99)
02461 {
02462 snprintf(buf, sizeof(buf), "%s", gSEpochS[i].str);
02463 hcon_insert_lower(gSlotEpochHC, buf, &(gSEpochS[i].internalTime));
02464 i++;
02465 }
02466 }
02467 else
02468 {
02469 fprintf(stderr, "Error creating slot epoch string container.\n");
02470 stat = DRMS_ERROR_CANTCREATEHCON;
02471 }
02472 }
02473
02474 ret = (TIME *)hcon_lookup_lower(gSlotEpochHC, str);
02475 }
02476
02477 if (status)
02478 {
02479 *status = stat;
02480 }
02481
02482 return ret;
02483 }
02484
02485 void drms_time_term()
02486 {
02487 if (gSlotEpochHC)
02488 {
02489 hcon_destroy(&gSlotEpochHC);
02490 }
02491 }
02492