00001
00002
00009 #ifndef DRMS_ARRAY_H
00010 #define DRMS_ARRAY_H
00011
00012 #include "drms_statuscodes.h"
00013 #include "drms_priv.h"
00014
00015 #define INLINE static inline
00016
00017 #define DRMS_ARRAY2STRING_LEN 30 // use in drms_array2string
00018
00019
00020
00021 typedef int axislen_t;
00022 typedef long long arraylen_t;
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #define DRMS_ARRAY_GETVAL(VAL, X, Y) \
00033 { \
00034 int gvErr = 0; \
00035 switch (X->type) \
00036 { \
00037 case DRMS_TYPE_CHAR: \
00038 VAL.value.char_val = *((char *)X->data + Y); \
00039 break; \
00040 case DRMS_TYPE_SHORT: \
00041 VAL.value.short_val = *((short *)X->data + Y); \
00042 break; \
00043 case DRMS_TYPE_INT: \
00044 VAL.value.int_val = *((int *)X->data + Y); \
00045 break; \
00046 case DRMS_TYPE_LONGLONG: \
00047 VAL.value.longlong_val = *((long long *)X->data + Y); \
00048 break; \
00049 case DRMS_TYPE_FLOAT: \
00050 VAL.value.float_val = *((float *)X->data + Y); \
00051 break; \
00052 case DRMS_TYPE_DOUBLE: \
00053 VAL.value.double_val = *((double *)X->data + Y); \
00054 break; \
00055 case DRMS_TYPE_TIME: \
00056 VAL.value.time_val = *((double *)X->data + Y); \
00057 break; \
00058 case DRMS_TYPE_STRING: \
00059 VAL.value.string_val = strdup((char *)X->data + Y); \
00060 break; \
00061 default: \
00062 fprintf(stderr, "Invalid drms type: %d\n", (int)X->type); \
00063 gvErr = 1; \
00064 } \
00065 if (!gvErr) \
00066 { \
00067 VAL.type = X->type; \
00068 } \
00069 }
00070
00071
00072
00073
00074
00075 #define DRMS_ARRAY_SETVAL(VAL, X, Y) \
00076 { \
00077 if (VAL.type == X->type) \
00078 { \
00079 switch (X->type) \
00080 { \
00081 case DRMS_TYPE_CHAR: \
00082 *((char *)X->data + Y) = VAL.value.char_val; \
00083 break; \
00084 case DRMS_TYPE_SHORT: \
00085 *((short *)X->data + Y) = VAL.value.short_val; \
00086 break; \
00087 case DRMS_TYPE_INT: \
00088 *((int *)X->data + Y) = VAL.value.int_val; \
00089 break; \
00090 case DRMS_TYPE_LONGLONG: \
00091 *((long long *)X->data + Y) = VAL.value.longlong_val; \
00092 break; \
00093 case DRMS_TYPE_FLOAT: \
00094 *((float *)X->data + Y) = VAL.value.float_val; \
00095 break; \
00096 case DRMS_TYPE_DOUBLE: \
00097 *((double *)X->data + Y) = VAL.value.double_val; \
00098 break; \
00099 case DRMS_TYPE_TIME: \
00100 *((double *)X->data + Y) = VAL.value.time_val; \
00101 break; \
00102 case DRMS_TYPE_STRING: \
00103 { \
00104 char **pStr = ((char **)X->data + Y); \
00105 *pStr = strdup(VAL.value.string_val); \
00106 break; \
00107 } \
00108 default: \
00109 fprintf(stderr, "Invalid drms type: %d\n", (int)X->type); \
00110 } \
00111 } \
00112 }
00113
00114
00115 INLINE void drms_array_setv(DRMS_Array_t *arr, ...)
00116 {
00117
00118 if (arr)
00119 {
00120
00121 }
00122 }
00123
00127
00128
00129
00141 INLINE arraylen_t drms_array_offset(DRMS_Array_t *arr, axislen_t *indexarr)
00142 {
00143 axislen_t i;
00144 arraylen_t idx;
00145
00146 for (i=0, idx=0; i<arr->naxis; i++)
00147 idx += indexarr[i]*arr->dope[i];
00148 return idx;
00149 }
00150
00164 void drms_array_print(DRMS_Array_t *arr, const char *colsep,
00165 const char *rowsep);
00180 void drms_array_fprint(FILE *arrfile, DRMS_Array_t *arr, const char *colsep,
00181 const char *rowsep);
00182
00183
00191 INLINE arraylen_t drms_array_count(DRMS_Array_t *arr)
00192 {
00193 int i;
00194 arraylen_t n;
00195
00196 n=1;
00197 for (i=0; i<arr->naxis; i++)
00198 n *= arr->axis[i];
00199 return n;
00200 }
00201
00210 INLINE long long drms_array_size(DRMS_Array_t *arr)
00211 {
00212 int size = drms_sizeof(arr->type);
00213 arraylen_t count = drms_array_count(arr);
00214 return size * count;
00215 }
00216
00217
00224 INLINE int drms_array_naxis(DRMS_Array_t *arr)
00225 {
00226 return arr->naxis;
00227 }
00228
00229
00230
00238 INLINE int drms_array_nth_axis(DRMS_Array_t *arr, int n)
00239 {
00240 if (n<arr->naxis)
00241 return arr->axis[n];
00242 else
00243 return DRMS_ERROR_INVALIDDIMS;
00244 }
00245
00246
00250
00262 INLINE int drms_array_setchar_ext(DRMS_Array_t *arr, long long index, char value)
00263 {
00264 if (arr->type == DRMS_TYPE_CHAR)
00265 {
00266 char *p = arr->data;
00267 p[index] = value;
00268 return DRMS_SUCCESS;
00269 }
00270
00271 return DRMS_ERROR_INVALIDDATA;
00272 }
00273
00274 INLINE int drms_array_setchar(DRMS_Array_t *arr, axislen_t *indexarr, char value)
00275 {
00276 if (arr->type == DRMS_TYPE_CHAR)
00277 {
00278 arraylen_t index = drms_array_offset(arr, indexarr);
00279 char *p = arr->data;
00280 p[index] = value;
00281 return DRMS_SUCCESS;
00282 }
00283
00284 return DRMS_ERROR_INVALIDDATA;
00285 }
00286
00287 INLINE int drms_array_setshort_ext(DRMS_Array_t *arr, arraylen_t index, short value)
00288 {
00289 if (arr->type == DRMS_TYPE_SHORT)
00290 {
00291 short *p = arr->data;
00292 p[index] = value;
00293 return DRMS_SUCCESS;
00294 }
00295
00296 return DRMS_ERROR_INVALIDDATA;
00297 }
00298
00299 INLINE int drms_array_setshort(DRMS_Array_t *arr, axislen_t *indexarr, short value)
00300 {
00301 if (arr->type == DRMS_TYPE_SHORT)
00302 {
00303 arraylen_t index = drms_array_offset(arr, indexarr);
00304 short *p = arr->data;
00305 p[index] = value;
00306 return DRMS_SUCCESS;
00307 }
00308
00309 return DRMS_ERROR_INVALIDDATA;
00310 }
00311
00312 INLINE int drms_array_setint_ext(DRMS_Array_t *arr, arraylen_t index, int value)
00313 {
00314 if (arr->type == DRMS_TYPE_INT)
00315 {
00316 int *p = arr->data;
00317 p[index] = value;
00318 return DRMS_SUCCESS;
00319 }
00320
00321 return DRMS_ERROR_INVALIDDATA;
00322 }
00323
00324 INLINE int drms_array_setint(DRMS_Array_t *arr, axislen_t *indexarr, int value)
00325 {
00326 if (arr->type == DRMS_TYPE_INT)
00327 {
00328 arraylen_t index = drms_array_offset(arr, indexarr);
00329 int *p = arr->data;
00330 p[index] = value;
00331 return DRMS_SUCCESS;
00332 }
00333
00334 return DRMS_ERROR_INVALIDDATA;
00335 }
00336
00337 INLINE int drms_array_setlonglong_ext(DRMS_Array_t *arr, arraylen_t index, long long value)
00338 {
00339 if (arr->type == DRMS_TYPE_LONGLONG)
00340 {
00341 long long *p = arr->data;
00342 p[index] = value;
00343 return DRMS_SUCCESS;
00344 }
00345
00346 return DRMS_ERROR_INVALIDDATA;
00347 }
00348
00349 INLINE int drms_array_setlonglong(DRMS_Array_t *arr, axislen_t *indexarr, long long value)
00350 {
00351 if (arr->type == DRMS_TYPE_LONGLONG)
00352 {
00353 arraylen_t index = drms_array_offset(arr, indexarr);
00354 long long *p = arr->data;
00355 p[index] = value;
00356 return DRMS_SUCCESS;
00357 }
00358
00359 return DRMS_ERROR_INVALIDDATA;
00360 }
00361
00362 INLINE int drms_array_setfloat_ext(DRMS_Array_t *arr, arraylen_t index, float value)
00363 {
00364 if (arr->type == DRMS_TYPE_FLOAT)
00365 {
00366 float *p = arr->data;
00367 p[index] = value;
00368 return DRMS_SUCCESS;
00369 }
00370
00371 return DRMS_ERROR_INVALIDDATA;
00372 }
00373
00374 INLINE int drms_array_setfloat(DRMS_Array_t *arr, axislen_t *indexarr, float value)
00375 {
00376 if (arr->type == DRMS_TYPE_FLOAT)
00377 {
00378 arraylen_t index = drms_array_offset(arr, indexarr);
00379 float *p = arr->data;
00380 p[index] = value;
00381 return DRMS_SUCCESS;
00382 }
00383
00384 return DRMS_ERROR_INVALIDDATA;
00385 }
00386
00387 INLINE int drms_array_setdouble_ext(DRMS_Array_t *arr, arraylen_t index, double value)
00388 {
00389 if (arr->type == DRMS_TYPE_DOUBLE)
00390 {
00391 double *p = arr->data;
00392 p[index] = value;
00393 return DRMS_SUCCESS;
00394 }
00395
00396 return DRMS_ERROR_INVALIDDATA;
00397 }
00398
00399 INLINE int drms_array_setdouble(DRMS_Array_t *arr, axislen_t *indexarr, double value)
00400 {
00401 if (arr->type == DRMS_TYPE_DOUBLE)
00402 {
00403 arraylen_t index = drms_array_offset(arr, indexarr);
00404 double *p = arr->data;
00405 p[index] = value;
00406 return DRMS_SUCCESS;
00407 }
00408
00409 return DRMS_ERROR_INVALIDDATA;
00410 }
00411
00422 INLINE int drms_array_settime_ext(DRMS_Array_t *arr, arraylen_t index, double value)
00423 {
00424 if (arr->type == DRMS_TYPE_TIME)
00425 {
00426 double *p = arr->data;
00427 p[index] = value;
00428 return DRMS_SUCCESS;
00429 }
00430
00431 return DRMS_ERROR_INVALIDDATA;
00432 }
00433
00444 INLINE int drms_array_settime(DRMS_Array_t *arr, axislen_t *indexarr, double value)
00445 {
00446 if (arr->type == DRMS_TYPE_TIME)
00447 {
00448 arraylen_t index = drms_array_offset(arr, indexarr);
00449 double *p = arr->data;
00450 p[index] = value;
00451 return DRMS_SUCCESS;
00452 }
00453
00454 return DRMS_ERROR_INVALIDDATA;
00455 }
00456
00470 INLINE int drms_array_setstring_ext(DRMS_Array_t *arr, arraylen_t index, char *value)
00471 {
00472 if (arr->type == DRMS_TYPE_STRING)
00473 {
00474 char **p = arr->data;
00475 p[index] = value;
00476 return DRMS_SUCCESS;
00477 }
00478
00479 return DRMS_ERROR_INVALIDDATA;
00480 }
00481
00495 INLINE int drms_array_setstring(DRMS_Array_t *arr, axislen_t *indexarr, char *value)
00496 {
00497 if (arr->type == DRMS_TYPE_STRING)
00498 {
00499 arraylen_t index = drms_array_offset(arr, indexarr);
00500 char **p = arr->data;
00501 p[index] = value;
00502 return DRMS_SUCCESS;
00503 }
00504
00505 return DRMS_ERROR_INVALIDDATA;
00506 }
00507
00508
00509
00521 INLINE int drms_array_setext(DRMS_Array_t *arr, arraylen_t index, DRMS_Value_t *src)
00522 {
00523 int status;
00524 DRMS_Type_t srctype = src->type;
00525
00526 switch(arr->type)
00527 {
00528 case DRMS_TYPE_CHAR:
00529 {
00530 char *p = arr->data;
00531 if (srctype != DRMS_TYPE_CHAR)
00532 {
00533 p[index] = drms2char(srctype, &(src->value), &status);
00534 }
00535 else
00536 {
00537 p[index] = (src->value).char_val;
00538 }
00539 }
00540 break;
00541 case DRMS_TYPE_SHORT:
00542 {
00543 short *p = arr->data;
00544 if (srctype != DRMS_TYPE_SHORT)
00545 {
00546 p[index] = drms2short(srctype, &(src->value), &status);
00547 }
00548 else
00549 {
00550 p[index] = (src->value).short_val;
00551 }
00552 }
00553 break;
00554 case DRMS_TYPE_INT:
00555 {
00556 int *p = arr->data;
00557 if (srctype != DRMS_TYPE_INT)
00558 {
00559 p[index] = drms2int(srctype, &(src->value), &status);
00560 }
00561 else
00562 {
00563 p[index] = (src->value).int_val;
00564 }
00565 }
00566 break;
00567 case DRMS_TYPE_LONGLONG:
00568 {
00569 long long *p = arr->data;
00570 if (srctype != DRMS_TYPE_LONGLONG)
00571 {
00572 p[index] = drms2longlong(srctype, &(src->value), &status);
00573 }
00574 else
00575 {
00576 p[index] = (src->value).longlong_val;
00577 }
00578 }
00579 break;
00580 case DRMS_TYPE_FLOAT:
00581 {
00582 float *p = arr->data;
00583 if (srctype != DRMS_TYPE_FLOAT)
00584 {
00585 p[index] = drms2float(srctype, &(src->value), &status);
00586 }
00587 else
00588 {
00589 p[index] = (src->value).float_val;
00590 }
00591 }
00592 break;
00593 case DRMS_TYPE_TIME:
00594 {
00595 double *p = arr->data;
00596 if (srctype != DRMS_TYPE_TIME)
00597 {
00598 p[index] = drms2time(srctype, &(src->value), &status);
00599 }
00600 else
00601 {
00602 p[index] = (src->value).time_val;
00603 }
00604 }
00605 break;
00606 case DRMS_TYPE_DOUBLE:
00607 {
00608 double *p = arr->data;
00609 if (srctype != DRMS_TYPE_DOUBLE)
00610 {
00611 p[index] = drms2double(srctype, &(src->value), &status);
00612 }
00613 else
00614 {
00615 p[index] = (src->value).double_val;
00616 }
00617 }
00618 break;
00619 case DRMS_TYPE_STRING:
00620 {
00621 char **p = ((char **) arr->data) + index;
00622 if (*p)
00623 free(*p);
00624 *p = drms2string(srctype, &(src->value), &status);
00625 }
00626 break;
00627 default:
00628 fprintf(stderr, "ERROR: Unhandled DRMS type %d\n",(int)arr->type);
00629 XASSERT(0);
00630 }
00631
00632 return status;
00633 }
00634
00635
00648 INLINE int drms_array_set(DRMS_Array_t *arr, axislen_t *indexarr, DRMS_Value_t *src)
00649 {
00650 arraylen_t i;
00651 i = drms_array_offset(arr,indexarr);
00652 return drms_array_setext(arr, i, src);
00653 }
00654
00667 void drms_array2missing(DRMS_Array_t *arr);
00668
00669
00673
00693 DRMS_Array_t *drms_array_create(DRMS_Type_t type, int naxis,
00694 axislen_t *axis, void *data, int *status);
00695
00705 void drms_free_array(DRMS_Array_t *src);
00706
00707
00708
00712
00728 DRMS_Array_t *drms_array_slice(axislen_t *start, axislen_t *end, DRMS_Array_t *src);
00742 DRMS_Array_t *drms_array_permute(DRMS_Array_t *src, int *perm, int *status);
00743
00744
00745
00749
00776 int drms_array2char(arraylen_t n, DRMS_Type_t src_type, double bzero, double bscale, void *src, char *dst);
00777 int drms_array2short(arraylen_t n, DRMS_Type_t src_type, double bzero, double bscale, void *src, short *dst);
00778 int drms_array2int(arraylen_t n, DRMS_Type_t src_type, double bzero, double bscale, void *src, int *dst);
00779 int drms_array2longlong(arraylen_t n, DRMS_Type_t src_type, double bzero, double bscale, void *src, long long *dst);
00780 int drms_array2float(arraylen_t n, DRMS_Type_t src_type, double bzero, double bscale, void *src, float *dst);
00781 int drms_array2double(arraylen_t n, DRMS_Type_t src_type, double bzero, double bscale, void *src, double *dst);
00782
00802 int drms_array2time(arraylen_t n, DRMS_Type_t src_type, double bzero, double bscale, void *src, double *dst);
00803
00828 int drms_array2string(arraylen_t n, DRMS_Type_t src_type, double bzero, double bscale, void *src, char **dst);
00829
00849 DRMS_Array_t *drms_array_convert(DRMS_Type_t dsttype, double bzero,
00850 double bscale, DRMS_Array_t *src);
00851
00865 void drms_array_convert_inplace(DRMS_Type_t newtype, double bzero,
00866 double bscale, DRMS_Array_t *src);
00867
00886 int drms_array_rawconvert(arraylen_t n, DRMS_Type_t dsttype, double bzero,
00887 double bscale, void *dst, DRMS_Type_t srctype,
00888 void *src);
00889
00890
00891 static inline void *drms_array_getdata(DRMS_Array_t *arr)
00892 {
00893 return arr->data;
00894 }
00895
00896 #endif