00001
00002
00003 #include "fitsexport.h"
00004 #include "util.h"
00005 #include "tasrw.h"
00006
00007 #define kFERecnum "RECNUM"
00008 #define kFERecnumFormat "%lld"
00009
00010
00011
00012 #undef A
00013 #undef B
00014 #define A(X,Y,Z) #X,
00015 #define B(X,Y)
00016 char *kFITSRESERVED[] =
00017 {
00018 #include "reserved.h"
00019 ""
00020 };
00021 #undef A
00022 #undef B
00023
00024 #define A(X,Y,Z) Y,
00025 #define B(X,Y)
00026 enum FE_ReservedKeys_enum
00027 {
00028 #include "reserved.h"
00029 kRKW_NUMKEYWORDS
00030 };
00031 #undef A
00032 #undef B
00033
00034 typedef enum FE_ReservedKeys_enum FE_ReservedKeys_t;
00035 typedef int (*pFn_ExportHandler)(void *key, void **fitskeys, void *nameout);
00036
00037 int drms_segment_mapexport_tofile2(DRMS_Segment_t *seg, const char *cparms, const char *clname, const char *mapfile, const char *fileout, export_callback_func_t callback);
00038 static int ExportFITS(DRMS_Env_t *env, DRMS_Array_t *arrout, const char *fileout, const char *cparms, CFITSIO_KEYWORD *fitskeys);
00039 static int ExportFITS2(DRMS_Env_t *env, DRMS_Array_t *arrout, const char *fileout, const char *cparms, CFITSIO_KEYWORD *fitskeys, export_callback_func_t callback);
00040
00041
00042
00043 int DateHndlr(void *keyin, void **fitskeys, void *nameout);
00044 int CommHndlr(void *keyin, void **fitskeys, void *nameout);
00045
00046
00047 #define A(X,Y,Z) Z,
00048 #define B(X,Y)
00049 pFn_ExportHandler ExportHandlers[] =
00050 {
00051 #include "reserved.h"
00052 NULL
00053 };
00054 #undef A
00055 #undef B
00056
00057
00058 #define A(X,Y,Z)
00059 #define B(X,Y) #X,
00060 char *kDRMSFORBIDDEN[] =
00061 {
00062 #include "reserved.h"
00063 ""
00064 };
00065 #undef A
00066 #undef B
00067
00068 #define A(X,Y,Z)
00069 #define B(X,Y) Y,
00070 enum FE_ForbiddenKeys_enum
00071 {
00072 #include "reserved.h"
00073 kFKW_NUMKEYWORDS
00074 };
00075 #undef A
00076 #undef B
00077
00078 HContainer_t *gReservedFits = NULL;
00079 HContainer_t *gForbiddenDrms = NULL;
00080
00081 char *FE_Keyword_ExtType_Strings[] =
00082 {
00083 "NONE",
00084 "INTEGER",
00085 "FLOAT",
00086 "STRING",
00087 "LOGICAL"
00088 };
00089
00090 #define ISUPPER(X) (X >= 0x41 && X <= 0x5A)
00091 #define ISLOWER(X) (X >= 0x61 && X <= 0x7A)
00092 #define ISDIGIT(X) (X >= 0x30 && X <= 0x39)
00093
00094 typedef enum
00095 {
00096 kFeKwCharFirst = 0,
00097 kFeKwCharNew,
00098 kFeKwCharError
00099 } FeKwCharState_t;
00100
00101
00102 int DateHndlr(void *keyin, void **fitskeys, void *nameout)
00103 {
00104 DRMS_Keyword_t *key = (DRMS_Keyword_t *)keyin;
00105 int err = 0;
00106
00107
00108 const DRMS_Type_Value_t *val = drms_keyword_getvalue(key);
00109 if (val && drms_keyword_gettype(key) == DRMS_TYPE_TIME)
00110 {
00111
00112 char unitbuf[DRMS_MAXUNITLEN];
00113 int fitsrwRet = 0;
00114
00115 snprintf(unitbuf, sizeof(unitbuf), "%s", key->info->unit);
00116 strtoupper(unitbuf);
00117
00118
00119 if (strcmp(kFITSRESERVED[kRKW_date], key->info->name) != 0 || !drms_ismissing_time(val->time_val))
00120 {
00121 if (strcmp(unitbuf, "ISO") == 0)
00122 {
00123 char tbuf[1024];
00124 drms_keyword_snprintfval(key, tbuf, sizeof(tbuf));
00125
00126
00127
00128 if (tbuf[strlen(tbuf) - 1] == 'Z')
00129 {
00130 tbuf[strlen(tbuf) - 1] = '\0';
00131 }
00132
00133 if (CFITSIO_SUCCESS != (fitsrwRet = cfitsio_append_key((CFITSIO_KEYWORD**)fitskeys,
00134 (char *)nameout,
00135 kFITSRW_Type_String,
00136 NULL,
00137 (void *)tbuf,
00138 NULL)))
00139 {
00140 fprintf(stderr, "FITSRW returned '%d'.\n", fitsrwRet);
00141 err = 2;
00142 }
00143 }
00144 else
00145 {
00146
00147 fprintf(stderr, "Invalid time format for keyword '%s' - must be ISO.\n", key->info->name);
00148 err = 1;
00149 }
00150 }
00151 }
00152 else
00153 {
00154 fprintf(stderr, "Invalid data type for keyword '%s'.\n", key->info->name);
00155 err = 1;
00156 }
00157
00158 return err;
00159 }
00160
00161
00162
00163
00164 int CommHndlr(void *keyin, void **fitskeys, void *nameout)
00165 {
00166 int err = 0;
00167 char *sbuf = NULL;
00168 int rangeout = 0;
00169 DRMS_Keyword_t *key = (DRMS_Keyword_t *)keyin;
00170 const DRMS_Type_Value_t *val = drms_keyword_getvalue(key);
00171
00172 if (val && drms_keyword_gettype(key) == DRMS_TYPE_STRING)
00173 {
00174 char *tmp = strdup(val->string_val);
00175
00176 if (tmp)
00177 {
00178 char *pc = tmp;
00179 char *pout = NULL;
00180 int nelem = 0;
00181 int fitsrwRet = 0;
00182
00183 sbuf = malloc(sizeof(char) * strlen(tmp) + 1);
00184 pout = sbuf;
00185
00186 while (*pc)
00187 {
00188 if (*pc == '\n')
00189 {
00190
00191 *pout = '\0';
00192
00193 if (*sbuf)
00194 {
00195 if (CFITSIO_SUCCESS != (fitsrwRet = cfitsio_append_key((CFITSIO_KEYWORD**)fitskeys,
00196 (char *)nameout,
00197 kFITSRW_Type_String,
00198 NULL,
00199 (void *)sbuf,
00200 NULL)))
00201 {
00202 fprintf(stderr, "FITSRW returned '%d'.\n", fitsrwRet);
00203 err = 2;
00204 }
00205 }
00206
00207 nelem = 0;
00208 pout = sbuf;
00209 }
00210 else if (*pc >= 0x20 && *pc <= 0x7E || *pc >= 0xA0 && *pc <= 0xFF)
00211 {
00212 *pout = *pc;
00213 pout++;
00214 nelem++;
00215 }
00216 else
00217 {
00218 fprintf(stderr, "Bad char '%x' at offset %d in comment '%s'.\n", *pc, (int)(pc - tmp), tmp);
00219 rangeout = 1;
00220 }
00221
00222 pc++;
00223 }
00224
00225
00226 if (nelem > 0)
00227 {
00228 *pout = '\0';
00229 if (*sbuf)
00230 {
00231 if (CFITSIO_SUCCESS != (fitsrwRet = cfitsio_append_key((CFITSIO_KEYWORD**)fitskeys,
00232 (char *)nameout,
00233 kFITSRW_Type_String,
00234 NULL,
00235 (void *)sbuf,
00236 NULL)))
00237 {
00238 fprintf(stderr, "FITSRW returned '%d'.\n", fitsrwRet);
00239 err = 2;
00240 }
00241 }
00242
00243 nelem = 0;
00244 }
00245
00246 if (sbuf)
00247 {
00248 free(sbuf);
00249 sbuf = NULL;
00250 }
00251
00252 free(tmp);
00253 }
00254 else
00255 {
00256 err = 1;
00257 }
00258 }
00259
00260 if (rangeout)
00261 {
00262 fprintf(stderr, "At least one character encoding in DRMS keyword '%s' not a member of Latin-1.\n", key->info->name);
00263 }
00264
00265 return err;
00266 }
00267
00268 static void FreeReservedFits(void *data)
00269 {
00270 if (gReservedFits != (HContainer_t *)data)
00271 {
00272 fprintf(stderr, "Unexpected argument to FreeReservedFits(); bailing.\n");
00273 return;
00274 }
00275
00276 hcon_destroy(&gReservedFits);
00277 }
00278
00279 static void FreeForbiddenDrms(void *data)
00280 {
00281 if (gForbiddenDrms != (HContainer_t *)data)
00282 {
00283 fprintf(stderr, "Unexpected argument to FreeForbiddenDrms(); bailing.\n");
00284 return;
00285 }
00286
00287 hcon_destroy(&gForbiddenDrms);
00288 }
00289
00290
00291
00292
00293
00294
00295
00296 static int FitsKeyNameValidationStatus(const char *fitsName)
00297 {
00298 int error = 0;
00299 FeKwCharState_t state = kFeKwCharNew;
00300 char *nameC = strdup(fitsName);
00301 char *pc = nameC;
00302
00303 if (strlen(fitsName) > 8)
00304 {
00305
00306 error = 1;
00307 }
00308 else
00309 {
00310
00311 if (!gReservedFits)
00312 {
00313 int i = 0;
00314
00315 gReservedFits = hcon_create(sizeof(int), 128, NULL, NULL, NULL, NULL, 0);
00316 while (*(kFITSRESERVED[i]) != '\0')
00317 {
00318
00319 hcon_insert_lower(gReservedFits, kFITSRESERVED[i], &i);
00320 i++;
00321 }
00322
00323
00324 BASE_Cleanup_t cu;
00325 cu.item = gReservedFits;
00326 cu.free = FreeReservedFits;
00327 base_cleanup_register("reservedfitskws", &cu);
00328 }
00329
00330 if (gReservedFits)
00331 {
00332 char *tmp = strdup(fitsName);
00333 char *pch = NULL;
00334 char *endptr = NULL;
00335 char *naxis = "NAXIS";
00336 int len = strlen(naxis);
00337 int theint;
00338
00339 strtoupper(tmp);
00340
00341
00342 if (strncmp(tmp, naxis, len) == 0)
00343 {
00344 pch = tmp + len;
00345
00346 if (*pch)
00347 {
00348 theint = (int)strtol(pch, &endptr, 10);
00349 if (endptr == pch + strlen(pch))
00350 {
00351
00352 if (theint > 0 && theint <= 999)
00353 {
00354
00355 error = 2;
00356 }
00357 }
00358 }
00359 }
00360
00361 if (hcon_lookup_lower(gReservedFits, tmp))
00362 {
00363 error = 2;
00364 }
00365
00366 free(tmp);
00367 }
00368
00369
00370 if (!error)
00371 {
00372
00373 if (strcasecmp(fitsName, kFERecnum) == 0)
00374 {
00375 error = 3;
00376 }
00377 }
00378
00379 if (!error)
00380 {
00381 while (*pc != 0 && !error)
00382 {
00383 switch (state)
00384 {
00385 case kFeKwCharError:
00386 error = 1;
00387 break;
00388 case kFeKwCharNew:
00389 if (*pc == '-' ||
00390 *pc == '_' ||
00391 ISUPPER(*pc) ||
00392 ISDIGIT(*pc))
00393 {
00394 state = kFeKwCharNew;
00395 pc++;
00396 }
00397 else
00398 {
00399 state = kFeKwCharError;
00400 }
00401 break;
00402 default:
00403 state = kFeKwCharError;
00404 }
00405 }
00406 }
00407 }
00408
00409 if (nameC)
00410 {
00411 free(nameC);
00412 }
00413
00414 return error;
00415 }
00416
00417
00418
00419 int GenerateFitsKeyName(const char *drmsName, char *fitsName, int size)
00420 {
00421 const char *pC = drmsName;
00422 int nch = 0;
00423
00424 memset(fitsName, 0, size);
00425
00426 if (size >= 9)
00427 {
00428 while (*pC && nch < 8)
00429 {
00430 if (*pC >= 65 && *pC <= 90)
00431 {
00432 fitsName[nch] = *pC;
00433 nch++;
00434 }
00435 else if (*pC >= 97 && *pC <= 122)
00436 {
00437 fitsName[nch] = (char)toupper(*pC);
00438 nch++;
00439 }
00440
00441 pC++;
00442 }
00443
00444
00445 if (FitsKeyNameValidationStatus(fitsName) == 2)
00446 {
00447
00448 char *tmp = strdup(fitsName);
00449 char *pch = NULL;
00450
00451 if (tmp && (pch = strchr(tmp, '_')) != NULL && hcon_lookup_lower(gReservedFits, pch))
00452 {
00453 *pch = '\0';
00454 snprintf(fitsName, 9, "_%s", tmp);
00455 }
00456 else
00457 {
00458 snprintf(fitsName, 9, "_%s", tmp);
00459 }
00460
00461 if (tmp)
00462 {
00463 free(tmp);
00464 }
00465 }
00466
00467 }
00468 else
00469 {
00470 return 0;
00471 }
00472
00473 return 1;
00474 }
00475
00476
00477 int ExportFITS(DRMS_Env_t *env,
00478 DRMS_Array_t *arrout,
00479 const char *fileout,
00480 const char *cparms,
00481 CFITSIO_KEYWORD *fitskeys)
00482 {
00483 return ExportFITS2(env, arrout, fileout, cparms, fitskeys, (export_callback_func_t) NULL);
00484 }
00485
00486
00487 static int ExportFITS2(DRMS_Env_t *env,
00488 DRMS_Array_t *arrout,
00489 const char *fileout,
00490 const char *cparms,
00491 CFITSIO_KEYWORD *fitskeys,
00492 export_callback_func_t callback)
00493 {
00494 int stat = DRMS_SUCCESS;
00495
00496 if (arrout)
00497 {
00498
00499
00500 CFITSIO_IMAGE_INFO imginfo;
00501 int compType;
00502 int isRiceCompressed = 0;
00503 int fiostat;
00504
00505
00506
00507 if (arrout->type == DRMS_TYPE_CHAR)
00508 {
00509 drms_array_convert_inplace(DRMS_TYPE_SHORT, 0, 1, arrout);
00510 fprintf(stderr, "FITS doesn't support signed char, converting to signed short.\n");
00511 }
00512
00513 if (strcmp(fileout, "-") == 0)
00514 {
00515 fiostat = 0;
00516 fits_get_compression_type((fitsfile *)callback, &compType, &fiostat);
00517 if (fiostat)
00518 {
00519 fits_report_error(stderr, fiostat);
00520 stat = CFITSIO_ERROR_LIBRARY;
00521 }
00522 else
00523 {
00524 isRiceCompressed = (compType == RICE_1);
00525 }
00526 }
00527 else
00528 {
00529 isRiceCompressed = fitsrw_iscompressed(cparms);
00530 }
00531
00532
00533 if (isRiceCompressed && (arrout->type == DRMS_TYPE_FLOAT || arrout->type == DRMS_TYPE_DOUBLE))
00534 {
00535 fprintf(stderr, "Cannot export Rice-compressed floating-point images.\n");
00536 stat = DRMS_ERROR_CANTCOMPRESSFLOAT;
00537 }
00538 else
00539 {
00540 if (!drms_fitsrw_SetImageInfo(arrout, &imginfo))
00541 {
00542
00543
00544 if (arrout->type == DRMS_TYPE_STRING)
00545 {
00546 fprintf(stderr, "Can't save string data into a fits file.\n");
00547 stat = DRMS_ERROR_EXPORT;
00548 }
00549 else
00550 {
00551
00552 if (strcmp(fileout, "-") != 0 && callback != NULL)
00553 {
00554 (*callback)("setarrout", arrout);
00555 }
00556
00557 if (fitsrw_write2(env->verbose, fileout, &imginfo, arrout->data, cparms, fitskeys, callback))
00558 {
00559 fprintf(stderr, "Can't write fits file '%s'.\n", fileout);
00560 stat = DRMS_ERROR_EXPORT;
00561 }
00562 }
00563 }
00564 else
00565 {
00566 fprintf(stderr, "Data array being exported is invalid.\n");
00567 stat = DRMS_ERROR_EXPORT;
00568 }
00569 }
00570 }
00571 else
00572 {
00573 stat = DRMS_ERROR_INVALIDDATA;
00574 }
00575
00576 return stat;
00577 }
00578
00579 static int DRMSKeyValToFITSKeyVal(DRMS_Keyword_t *key,
00580 char *fitstype,
00581 char **format,
00582 void **fitsval)
00583 {
00584 int err = 0;
00585 DRMS_Type_Value_t *valin = &key->value;
00586 void *res = NULL;
00587 int status = DRMS_SUCCESS;
00588 FE_Keyword_ExtType_t casttype = fitsexport_keyword_getcast(key);
00589
00590 if (valin && fitstype && format)
00591 {
00592 *format = strdup(key->info->format);
00593
00594
00595
00596 if (casttype != kFE_Keyword_ExtType_None)
00597 {
00598
00599 if (key->info->type != DRMS_TYPE_RAW)
00600 {
00601 switch (casttype)
00602 {
00603 case kFE_Keyword_ExtType_Integer:
00604 res = malloc(sizeof(long long));
00605 *(long long *)res = drms2int(key->info->type, valin, &status);
00606 *fitstype = kFITSRW_Type_Integer;
00607 break;
00608 case kFE_Keyword_ExtType_Float:
00609 res = malloc(sizeof(double));
00610 *(double *)res = drms2double(key->info->type, valin, &status);
00611 *fitstype = kFITSRW_Type_Float;
00612 break;
00613 case kFE_Keyword_ExtType_String:
00614 {
00615 char tbuf[1024];
00616 drms_keyword_snprintfval(key, tbuf, sizeof(tbuf));
00617 res = (void *)strdup(tbuf);
00618 *fitstype = kFITSRW_Type_String;
00619 }
00620 break;
00621 case kFE_Keyword_ExtType_Logical:
00622 res = malloc(sizeof(long long));
00623
00624 if (drms2longlong(key->info->type, valin, &status))
00625 {
00626 *(long long *)res = 0;
00627 }
00628 else
00629 {
00630 *(long long *)res = 1;
00631 }
00632 *fitstype = kFITSRW_Type_Logical;
00633 break;
00634 default:
00635 fprintf(stderr, "Unsupported FITS type '%d'.\n", (int)casttype);
00636 err = 1;
00637 break;
00638 }
00639 }
00640 else
00641 {
00642
00643 fprintf(stderr, "DRMS_TYPE_RAW is not supported.\n");
00644 err = 1;
00645 }
00646 }
00647 else
00648 {
00649
00650 switch (key->info->type)
00651 {
00652 case DRMS_TYPE_CHAR:
00653 res = malloc(sizeof(long long));
00654 *(long long *)res = (long long)(valin->char_val);
00655 *fitstype = 'I';
00656 break;
00657 case DRMS_TYPE_SHORT:
00658 res = malloc(sizeof(long long));
00659 *(long long *)res = (long long)(valin->short_val);
00660 *fitstype = 'I';
00661 break;
00662 case DRMS_TYPE_INT:
00663 res = malloc(sizeof(long long));
00664 *(long long *)res = (long long)(valin->int_val);
00665 *fitstype = 'I';
00666 break;
00667 case DRMS_TYPE_LONGLONG:
00668 res = malloc(sizeof(long long));
00669 *(long long *)res = valin->longlong_val;
00670 *fitstype = 'I';
00671 break;
00672 case DRMS_TYPE_FLOAT:
00673 res = malloc(sizeof(double));
00674 *(double *)res = (double)(valin->float_val);
00675 *fitstype = 'F';
00676 break;
00677 case DRMS_TYPE_DOUBLE:
00678 res = malloc(sizeof(double));
00679 *(double *)res = valin->double_val;
00680 *fitstype = 'F';
00681 break;
00682 case DRMS_TYPE_TIME:
00683 {
00684 char tbuf[1024];
00685 drms_keyword_snprintfval(key, tbuf, sizeof(tbuf));
00686 res = (void *)strdup(tbuf);
00687 *fitstype = 'C';
00688 }
00689 break;
00690 case DRMS_TYPE_STRING:
00691 res = (void *)strdup(valin->string_val);
00692 *fitstype = 'C';
00693 break;
00694 default:
00695 fprintf(stderr, "Unsupported DRMS type '%d'.\n", (int)key->info->type);
00696 err = 1;
00697 break;
00698 }
00699 }
00700 }
00701 else
00702 {
00703 fprintf(stderr, "DRMSKeyValToFITSKeyVal() - Invalid argument.\n");
00704 err = 1;
00705 }
00706
00707 if (!err)
00708 {
00709 *fitsval = res;
00710 }
00711
00712 return err;
00713 }
00714
00715
00716 int fitsexport_export_tofile(DRMS_Segment_t *seg, const char *cparms, const char *fileout, char **actualfname, unsigned long long *expsize)
00717 {
00718 return fitsexport_mapexport_tofile(seg, cparms, NULL, NULL, fileout, actualfname, expsize);
00719 }
00720
00721
00722 int fitsexport_mapexport_tofile(DRMS_Segment_t *seg,
00723 const char *cparms,
00724 const char *clname,
00725 const char *mapfile,
00726 const char *fileout,
00727 char **actualfname,
00728 unsigned long long *expsize)
00729 {
00730 return fitsexport_mapexport_tofile2(seg, cparms, clname, mapfile, fileout, actualfname, expsize, (export_callback_func_t) NULL);
00731 }
00732
00733 int fitsexport_mapexport_tofile2(DRMS_Segment_t *seg,
00734 const char *cparms,
00735 const char *clname,
00736 const char *mapfile,
00737 const char *fileout,
00738 char **actualfname,
00739 unsigned long long *expsize,
00740 export_callback_func_t callback)
00741 {
00742 int status = DRMS_SUCCESS;
00743
00744 CFITSIO_KEYWORD *fitskeys = NULL;
00745 char filename[DRMS_MAXPATHLEN];
00746 struct stat stbuf;
00747 DRMS_Segment_t *tgtseg = NULL;
00748 char realfileout[DRMS_MAXPATHLEN];
00749 struct stat filestat;
00750
00751 if (seg->info->islink)
00752 {
00753 if ((tgtseg = drms_segment_lookup(seg->record, seg->info->name)) == NULL)
00754 {
00755 fprintf(stderr, "Unable to locate target segment %s.\n", seg->info->name);
00756 status = DRMS_ERROR_INVALIDFILE;
00757 }
00758 else
00759 {
00760 drms_segment_filename(tgtseg, filename);
00761 }
00762 }
00763 else
00764 {
00765 drms_segment_filename(seg, filename);
00766 }
00767
00768 if (status == DRMS_SUCCESS)
00769 {
00770 if (*filename == '\0' || stat(filename, &stbuf))
00771 {
00772
00773 snprintf(seg->filename, sizeof(seg->filename), "%s", filename);
00774 status = DRMS_ERROR_INVALIDFILE;
00775 }
00776 else
00777 {
00778 int swval;
00779
00780
00781 fitskeys = fitsexport_mapkeys(seg, clname, mapfile, &status);
00782
00783 if (tgtseg)
00784 {
00785 swval = tgtseg->info->protocol;
00786 }
00787 else
00788 {
00789 swval = seg->info->protocol;
00790 }
00791
00792 if (strcmp(fileout, "-") == 0)
00793 {
00794
00795 snprintf(realfileout, sizeof(realfileout), "-");
00796 }
00797 else
00798 {
00799 snprintf(realfileout, sizeof(realfileout), "%s", fileout);
00800 }
00801
00802 switch (swval)
00803 {
00804 case DRMS_TAS:
00805 {
00806 if (strcmp(fileout, "-") != 0)
00807 {
00808
00809
00810
00811
00812 size_t len = strlen(realfileout) + 64;
00813 size_t lenstr;
00814 char *dup = malloc(len);
00815 snprintf(dup, len, "%s", realfileout);
00816
00817 if (dup)
00818 {
00819 lenstr = strlen(dup);
00820 if (lenstr > 0 &&
00821 (dup[lenstr - 1] == 's' || dup[lenstr - 1] == 'S') &&
00822 (dup[lenstr - 2] == 'a' || dup[lenstr - 2] == 'A') &&
00823 (dup[lenstr - 3] == 't' || dup[lenstr - 3] == 'T') &&
00824 dup[lenstr - 4] == '.')
00825 {
00826 *(dup + lenstr - 3) = '\0';
00827 snprintf(realfileout, sizeof(realfileout), "%sfits", dup);
00828 }
00829 else
00830 {
00831 fprintf(stderr, "Unexpected export file name '%s'.\n", dup);
00832 free(dup);
00833 status = DRMS_ERROR_EXPORT;
00834 break;
00835 }
00836
00837 free(dup);
00838 }
00839 else
00840 {
00841 status = DRMS_ERROR_OUTOFMEMORY;
00842 }
00843 }
00844 }
00845
00846
00847 case DRMS_BINARY:
00848
00849 case DRMS_BINZIP:
00850
00851 case DRMS_FITZ:
00852
00853 case DRMS_FITS:
00854
00855 case DRMS_DSDS:
00856
00857 case DRMS_LOCAL:
00858 {
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876 DRMS_Array_t *arrout = NULL;
00877
00878 if (seg->info->islink)
00879 {
00880 arrout = drms_segment_read(tgtseg, DRMS_TYPE_RAW, &status);
00881 }
00882 else
00883 {
00884 arrout = drms_segment_read(seg, DRMS_TYPE_RAW, &status);
00885 }
00886
00887 if (arrout)
00888 {
00889 const char *cparmsArg = NULL;
00890
00891 if (strcmp(fileout, "-") == 0)
00892 {
00893
00894 }
00895 else
00896 {
00897 cparmsArg = cparms ? cparms : (seg->info->islink ? tgtseg->cparms : seg->cparms);
00898 }
00899
00900 if (strcmp(fileout, "-") == 0)
00901 {
00902
00903 snprintf(realfileout, sizeof(realfileout), "-");
00904 }
00905
00906 status = ExportFITS2(seg->record->env, arrout, realfileout, cparmsArg, fitskeys, callback);
00907 drms_free_array(arrout);
00908 }
00909 }
00910 break;
00911 case DRMS_GENERIC:
00912 {
00913 int ioerr;
00914
00915
00916
00917
00918
00919
00920
00921 if (CopyFile(filename, realfileout, &ioerr) != stbuf.st_size)
00922 {
00923 if (!S_ISDIR(stbuf.st_mode))
00924 {
00925
00926
00927
00928 fprintf(stderr, "Unable to export file '%s' to '%s'.\n", filename, realfileout);
00929 status = DRMS_ERROR_FILECOPY;
00930 }
00931 }
00932 }
00933 break;
00934 default:
00935 fprintf(stderr,
00936 "Data export does not support data segment protocol '%s'.\n",
00937 drms_prot2str(seg->info->protocol));
00938 }
00939
00940
00941
00942
00943
00944
00945 if (callback == NULL)
00946 {
00947
00948 if (stat(realfileout, &filestat))
00949 {
00950 status = DRMS_ERROR_EXPORT;
00951 }
00952 else if (expsize)
00953 {
00954 *actualfname = strdup(basename(realfileout));
00955 *expsize = filestat.st_size;
00956 }
00957 }
00958
00959 cfitsio_free_keys(&fitskeys);
00960 }
00961 }
00962
00963 return status;
00964 }
00965
00966 int fitsexport_mapexport_tostdout(fitsfile *fitsPtr, DRMS_Segment_t *seg, const char *clname, const char *mapfile)
00967 {
00968
00969
00970
00971 return fitsexport_mapexport_tofile2(seg, NULL, clname, mapfile, "-", NULL, NULL, (export_callback_func_t)fitsPtr);
00972 }
00973
00974
00975
00976
00977
00978
00979 CFITSIO_KEYWORD *fitsexport_mapkeys(DRMS_Segment_t *seg,
00980 const char *clname,
00981 const char *mapfile,
00982 int *status)
00983 {
00984 CFITSIO_KEYWORD *fitskeys = NULL;
00985 HIterator_t *last = NULL;
00986 int statint = DRMS_SUCCESS;
00987 DRMS_Keyword_t *key = NULL;
00988 const char *keyname = NULL;
00989 char segnum[4];
00990 DRMS_Record_t *recin = seg->record;
00991 Exputl_KeyMap_t *map = NULL;
00992 FILE *fptr = NULL;
00993 int fitsrwRet = 0;
00994
00995 while ((key = drms_record_nextkey(recin, &last, 0)) != NULL)
00996 {
00997 keyname = drms_keyword_getname(key);
00998
00999 if (!drms_keyword_getimplicit(key))
01000 {
01001 if (drms_keyword_getperseg(key))
01002 {
01003 snprintf(segnum, sizeof(segnum), "%03d", seg->info->segnum);
01004
01005
01006 if (!strstr(keyname, segnum))
01007 {
01008 continue;
01009 }
01010 }
01011
01012 if (mapfile && !map)
01013 {
01014 map = exputl_keymap_create();
01015
01016
01017 fptr = fopen(mapfile, "r");
01018 if (fptr)
01019 {
01020 if (!exputl_keymap_parsefile(map, fptr))
01021 {
01022 exputl_keymap_destroy(&map);
01023 }
01024
01025 fclose(fptr);
01026 }
01027 else if (!exputl_keymap_parsetable(map, mapfile))
01028 {
01029
01030 fprintf(stderr, "drms_keyword_mapexport() - warning, keyword map file or string '%s' is invalid.\n", mapfile);
01031 exputl_keymap_destroy(&map);
01032 mapfile = NULL;
01033 }
01034 }
01035
01036 if (fitsexport_mapexportkey(key, clname, map, &fitskeys))
01037 {
01038 fprintf(stderr, "Couldn't export keyword '%s'.\n", keyname);
01039 statint = DRMS_ERROR_EXPORT;
01040 }
01041 }
01042 }
01043
01044
01045 long long recnum = seg->record->recnum;
01046 if (CFITSIO_SUCCESS != (fitsrwRet = cfitsio_append_key(&fitskeys,
01047 kFERecnum,
01048 kFITSRW_Type_Integer,
01049 NULL,
01050 (void *)&recnum,
01051 kFERecnumFormat)))
01052 {
01053 fprintf(stderr, "FITSRW returned '%d'.\n", fitsrwRet);
01054 statint = DRMS_ERROR_FITSRW;
01055 }
01056
01057 if (map)
01058 {
01059 exputl_keymap_destroy(&map);
01060 }
01061
01062 if (last)
01063 {
01064 hiter_destroy(&last);
01065 }
01066
01067 if (status)
01068 {
01069 *status = statint;
01070 }
01071
01072 return fitskeys;
01073 }
01074
01075
01076 int fitsexport_exportkey(DRMS_Keyword_t *key, CFITSIO_KEYWORD **fitskeys)
01077 {
01078 return fitsexport_mapexportkey(key, NULL, NULL, fitskeys);
01079 }
01080
01081
01082 int fitsexport_mapexportkey(DRMS_Keyword_t *key,
01083 const char *clname,
01084 Exputl_KeyMap_t *map,
01085 CFITSIO_KEYWORD **fitskeys)
01086 {
01087 int stat = DRMS_SUCCESS;
01088
01089 if (key && fitskeys)
01090 {
01091 char nameout[16];
01092
01093 if (fitsexport_getmappedextkeyname(key, clname, map, nameout, sizeof(nameout)))
01094 {
01095 int fitsrwRet = 0;
01096 char fitskwtype = '\0';
01097 void *fitskwval = NULL;
01098 char *format = NULL;
01099 DRMS_Keyword_t *keywval = NULL;
01100 int rv = 0;
01101
01102
01103 keywval = drms_keyword_lookup(key->record, key->info->name, 1);
01104
01105
01106
01107 if (keywval)
01108 {
01109 FE_ReservedKeys_t *ikey = NULL;
01110
01111 if (gReservedFits &&
01112 (ikey = (FE_ReservedKeys_t *)hcon_lookup_lower(gReservedFits, keywval->info->name)))
01113 {
01114 if (ExportHandlers[*ikey])
01115 {
01116
01117 rv = (*(ExportHandlers[*ikey]))(keywval, (void **)fitskeys, (void *)nameout);
01118 if (rv == 2)
01119 {
01120 stat = DRMS_ERROR_FITSRW;
01121 }
01122 else if (rv == 1)
01123 {
01124 stat = DRMS_ERROR_INVALIDDATA;
01125 }
01126 }
01127 else
01128 {
01129
01130 fprintf(stderr, "Cannot export reserved keyword '%s'.\n", keywval->info->name);
01131 }
01132 }
01133 else
01134 {
01135 if ((rv = DRMSKeyValToFITSKeyVal(keywval, &fitskwtype, &format, &fitskwval)) == 0)
01136 {
01137 if (CFITSIO_SUCCESS != (fitsrwRet = cfitsio_append_key(fitskeys,
01138 nameout,
01139 fitskwtype,
01140 NULL,
01141 fitskwval,
01142 format)))
01143 {
01144 fprintf(stderr, "FITSRW returned '%d'.\n", fitsrwRet);
01145 stat = DRMS_ERROR_FITSRW;
01146 }
01147 }
01148 else
01149 {
01150 fprintf(stderr,
01151 "Could not convert DRMS keyword '%s' to FITS keyword.\n",
01152 key->info->name);
01153 stat = DRMS_ERROR_INVALIDDATA;
01154 }
01155 }
01156 }
01157 else
01158 {
01159
01160 fprintf(stderr, "Broken link - unable to locate target for linked keyword '%s'.\n", key->info->name);
01161 stat = DRMS_ERROR_BADLINK;
01162 }
01163
01164 if (fitskwval)
01165 {
01166 free(fitskwval);
01167 }
01168
01169 if (format)
01170 {
01171 free(format);
01172 }
01173 }
01174 else
01175 {
01176 fprintf(stderr,
01177 "Could not determine external FITS keyword name for DRMS name '%s'.\n",
01178 key->info->name);
01179 stat = DRMS_ERROR_INVALIDDATA;
01180 }
01181 }
01182
01183 return stat;
01184 }
01185
01186 int fitsexport_getextkeyname(DRMS_Keyword_t *key, char *nameOut, int size)
01187 {
01188 return fitsexport_getmappedextkeyname(key, NULL, NULL, nameOut, size);
01189 }
01190
01191
01192 int fitsexport_getmappedextkeyname(DRMS_Keyword_t *key,
01193 const char *class,
01194 Exputl_KeyMap_t *map,
01195 char *nameOut,
01196 int size)
01197 {
01198 int success = 0;
01199 const char *potential = NULL;
01200 int vstat = 0;
01201
01202
01203 if (map != NULL)
01204 {
01205 potential = exputl_keymap_extname(map, key->info->name);
01206 if (potential)
01207 {
01208 vstat = fitsexport_fitskeycheck(potential);
01209
01210 if (vstat != 1)
01211 {
01212 snprintf(nameOut, size, "%s", potential);
01213 success = 1;
01214 }
01215 }
01216 }
01217
01218
01219 if (!success && class != NULL)
01220 {
01221 potential = exputl_keymap_classextname(class, key->info->name);
01222 if (potential)
01223 {
01224 vstat = fitsexport_fitskeycheck(potential);
01225
01226 if (vstat != 1)
01227 {
01228 snprintf(nameOut, size, "%s", potential);
01229 success = 1;
01230 }
01231 }
01232 }
01233
01234 if (!success)
01235 {
01236
01237 char *pot = NULL;
01238 char *psep = NULL;
01239 char *desc = strdup(key->info->description);
01240 char *pFitsName = NULL;
01241 *nameOut = '\0';
01242
01243
01244 if (desc)
01245 {
01246 pFitsName = strtok(desc, " ");
01247 if (pFitsName)
01248 {
01249 int len = strlen(pFitsName);
01250
01251 if (len > 2 &&
01252 pFitsName[0] == '[' &&
01253 pFitsName[len - 1] == ']')
01254 {
01255 if (len - 2 < size)
01256 {
01257 pot = (char *)malloc(sizeof(char) * size);
01258 if (pot)
01259 {
01260 memcpy(pot, pFitsName + 1, len - 2);
01261 pot[len - 2] = '\0';
01262
01263
01264
01265
01266 if (fitsexport_keyword_getcast(key) != kFE_Keyword_ExtType_None)
01267 {
01268 psep = strchr(pot, ':');
01269 *psep = '\0';
01270 }
01271
01272 vstat = fitsexport_fitskeycheck(pot);
01273
01274 if (vstat != 1)
01275 {
01276 snprintf(nameOut, size, "%s", pot);
01277 success = 1;
01278 }
01279
01280 free(pot);
01281 }
01282 }
01283 }
01284 }
01285
01286 free(desc);
01287 }
01288
01289
01290 if (!success)
01291 {
01292 char nbuf[DRMS_MAXKEYNAMELEN];
01293
01294 snprintf(nbuf, sizeof(nbuf), "%s", key->info->name);
01295 strtoupper(nbuf);
01296
01297 vstat = fitsexport_fitskeycheck(nbuf);
01298
01299 if (vstat != 1)
01300 {
01301 snprintf(nameOut, size, "%s", nbuf);
01302 success = 1;
01303 }
01304 }
01305
01306
01307 if (!success)
01308 {
01309 pot = (char *)malloc(sizeof(char) * size);
01310 if (pot)
01311 {
01312 if (GenerateFitsKeyName(key->info->name, pot, size))
01313 {
01314 vstat = fitsexport_fitskeycheck(pot);
01315
01316 if (vstat != 1)
01317 {
01318 snprintf(nameOut, size, "%s", pot);
01319 success = 1;
01320 }
01321 }
01322
01323 free(pot);
01324 }
01325 }
01326 }
01327
01328 if (success && vstat == 2)
01329 {
01330
01331
01332
01333
01334 }
01335
01336 return success;
01337 }
01338
01339 int fitsexport_fitskeycheck(const char *fitsName)
01340 {
01341 return FitsKeyNameValidationStatus(fitsName);
01342 }
01343
01344 static int FITSKeyValToDRMSKeyVal(CFITSIO_KEYWORD *fitskey,
01345 DRMS_Type_t *type,
01346 DRMS_Type_Value_t *value,
01347 FE_Keyword_ExtType_t *casttype,
01348 char **format)
01349 {
01350 int err = 0;
01351
01352 if (fitskey && type &&value &&casttype)
01353 {
01354 if (*(fitskey->key_format) != '\0')
01355 {
01356 *format = strdup(fitskey->key_format);
01357 }
01358
01359 switch (fitskey->key_type)
01360 {
01361 case kFITSRW_Type_String:
01362 {
01363
01364
01365
01366 char *strval = strdup((fitskey->key_value).vs);
01367 char *pb = strval;
01368 char *pe = pb + strlen(pb) - 1;
01369
01370 if (*pb == '\'' && *pe == '\'')
01371 {
01372 *pe = '\0';
01373 pe--;
01374 pb++;
01375 }
01376
01377 while (*pb == ' ')
01378 {
01379 pb++;
01380 }
01381
01382 while (*pe == ' ')
01383 {
01384 *pe = '\0';
01385 pe--;
01386 }
01387
01388 value->string_val = strdup(pb);
01389
01390 if (strval)
01391 {
01392 free(strval);
01393 }
01394
01395 *type = DRMS_TYPE_STRING;
01396 *casttype = kFE_Keyword_ExtType_String;
01397 }
01398 break;
01399 case kFITSRW_Type_Logical:
01400
01401 if ((fitskey->key_value).vl == 1)
01402 {
01403 value->char_val = 1;
01404 }
01405 else
01406 {
01407 value->char_val = 0;
01408 }
01409 *type = DRMS_TYPE_CHAR;
01410 *casttype = kFE_Keyword_ExtType_Logical;
01411 break;
01412 case kFITSRW_Type_Integer:
01413 {
01414 long long intval = (fitskey->key_value).vi;
01415
01416 if (intval <= (long long)SCHAR_MAX &&
01417 intval >= (long long)SCHAR_MIN)
01418 {
01419 value->char_val = (char)intval;
01420 *type = DRMS_TYPE_CHAR;
01421 }
01422 else if (intval <= (long long)SHRT_MAX &&
01423 intval >= (long long)SHRT_MIN)
01424 {
01425 value->short_val = (short)intval;
01426 *type = DRMS_TYPE_SHORT;
01427 }
01428 else if (intval <= (long long)INT_MAX &&
01429 intval >= (long long)INT_MIN)
01430 {
01431 value->int_val = (int)intval;
01432 *type = DRMS_TYPE_INT;
01433 }
01434 else
01435 {
01436 value->longlong_val = intval;
01437 *type = DRMS_TYPE_LONGLONG;
01438 }
01439
01440 *casttype = kFE_Keyword_ExtType_Integer;
01441 }
01442 break;
01443 case kFITSRW_Type_Float:
01444 {
01445 double floatval = (fitskey->key_value).vf;
01446
01447 if (floatval <= (double)FLT_MAX &&
01448 floatval >= (double)-FLT_MAX)
01449 {
01450 value->float_val = (float)floatval;
01451 *type = DRMS_TYPE_FLOAT;
01452 }
01453 else
01454 {
01455 value->double_val = floatval;
01456 *type = DRMS_TYPE_DOUBLE;
01457 }
01458
01459 *casttype = kFE_Keyword_ExtType_Float;
01460 }
01461 break;
01462 default:
01463 fprintf(stderr, "Unsupported FITS type '%c'.\n", fitskey->key_type);
01464 break;
01465 }
01466 }
01467 else
01468 {
01469 fprintf(stderr, "FITSKeyValToDRMSKeyVal() - Invalid argument.\n");
01470 err = 1;
01471 }
01472
01473 return err;
01474 }
01475
01476 int fitsexport_getintkeyname(const char *keyname, char *nameOut, int size)
01477 {
01478 int success = 0;
01479 char *potential = NULL;
01480
01481 *nameOut = '\0';
01482
01483
01484 if (base_drmskeycheck(keyname) == 0)
01485 {
01486 strcpy(nameOut, keyname);
01487 success = 1;
01488 }
01489
01490
01491 if (!success)
01492 {
01493 potential = (char *)malloc(sizeof(char) * size);
01494 if (potential)
01495 {
01496 if (GenerateDRMSKeyName(keyname, potential, size))
01497 {
01498 strcpy(nameOut, potential);
01499 success = 1;
01500 }
01501
01502 free(potential);
01503 }
01504 }
01505
01506 return success;
01507 }
01508
01509 int fitsexport_getmappedintkeyname(const char *keyname,
01510 const char *class,
01511 Exputl_KeyMap_t *map,
01512 char *nameOut,
01513 int size)
01514 {
01515 int success = 0;
01516 const char *potential = NULL;
01517 *nameOut = '\0';
01518
01519
01520 if (map != NULL)
01521 {
01522 potential = exputl_keymap_intname(map, keyname);
01523 if (potential)
01524 {
01525 snprintf(nameOut, size, "%s", potential);
01526 success = 1;
01527 }
01528 }
01529
01530
01531 if (!success && class != NULL)
01532 {
01533 potential = exputl_keymap_classintname(class, keyname);
01534 if (potential)
01535 {
01536 snprintf(nameOut, size, "%s", potential);
01537 success = 1;
01538 }
01539 }
01540
01541 if (!success)
01542 {
01543
01544 char buf[DRMS_MAXKEYNAMELEN];
01545 success = fitsexport_getintkeyname(keyname, buf, sizeof(buf));
01546 if (success)
01547 {
01548 strncpy(nameOut, buf, size);
01549 }
01550 }
01551
01552 return success;
01553 }
01554
01555 static int IsForbidden(const char *fitskey)
01556 {
01557 int disp = 0;
01558
01559 if (!gForbiddenDrms)
01560 {
01561 int i = 0;
01562
01563 gForbiddenDrms = hcon_create(sizeof(int), 128, NULL, NULL, NULL, NULL, 0);
01564 while (*(kDRMSFORBIDDEN[i]) != '\0')
01565 {
01566
01567 hcon_insert_lower(gForbiddenDrms, kDRMSFORBIDDEN[i], &i);
01568 i++;
01569 }
01570
01571
01572 BASE_Cleanup_t cu;
01573 cu.item = gForbiddenDrms;
01574 cu.free = FreeForbiddenDrms;
01575 base_cleanup_register("forbiddendrmskws", &cu);
01576 }
01577
01578 if (gForbiddenDrms)
01579 {
01580 char *tmp = strdup(fitskey);
01581 char *pch = NULL;
01582 char *endptr = NULL;
01583 char *naxis = "naxis";
01584 int len = strlen(naxis);
01585 int theint;
01586
01587 strtolower(tmp);
01588
01589
01590 if (strncmp(tmp, naxis, len) == 0)
01591 {
01592 pch = tmp + len;
01593
01594 if (*pch)
01595 {
01596 theint = (int)strtol(pch, &endptr, 10);
01597 if (endptr == pch + strlen(pch))
01598 {
01599
01600 if (theint > 0 && theint <= 999)
01601 {
01602
01603 disp = 1;
01604 }
01605 }
01606 }
01607 }
01608
01609 if (hcon_lookup_lower(gForbiddenDrms, tmp))
01610 {
01611 disp = 1;
01612 }
01613
01614 free(tmp);
01615 }
01616
01617 return disp;
01618 }
01619
01620 int fitsexport_importkey(CFITSIO_KEYWORD *fitskey, HContainer_t *keys, int verbose)
01621 {
01622 return fitsexport_mapimportkey(fitskey, NULL, NULL, keys, verbose);
01623 }
01624
01625
01626 int fitsexport_mapimportkey(CFITSIO_KEYWORD *fitskey,
01627 const char *clname,
01628 const char *mapfile,
01629 HContainer_t *keys,
01630 int verbose)
01631 {
01632 int stat = DRMS_SUCCESS;
01633
01634 if (fitskey && keys)
01635 {
01636 char nameout[DRMS_MAXKEYNAMELEN];
01637 char *namelower = NULL;
01638 Exputl_KeyMap_t *map = NULL;
01639 FILE *fptr = NULL;
01640
01641
01642
01643
01644
01645 if (!IsForbidden(fitskey->key_name))
01646 {
01647 if (mapfile)
01648 {
01649 fptr = fopen(mapfile, "r");
01650 if (fptr)
01651 {
01652 map = exputl_keymap_create();
01653
01654 if (!exputl_keymap_parsefile(map, fptr))
01655 {
01656 exputl_keymap_destroy(&map);
01657 }
01658
01659 fclose(fptr);
01660 }
01661 }
01662
01663 if (fitsexport_getmappedintkeyname(fitskey->key_name, clname, map, nameout, sizeof(nameout)))
01664 {
01665 DRMS_Type_t drmskwtype;
01666 DRMS_Type_Value_t drmskwval;
01667 FE_Keyword_ExtType_t cast;
01668 DRMS_Keyword_t *newkey = NULL;
01669 char *format = NULL;
01670
01671
01672
01673
01674 if (!FITSKeyValToDRMSKeyVal(fitskey, &drmskwtype, &drmskwval, &cast, &format))
01675 {
01676 namelower = strdup(nameout);
01677 strtolower(namelower);
01678
01679 if ((newkey = hcon_lookup(keys, namelower)) != NULL)
01680 {
01681
01682
01683
01684 if (strcmp(namelower, "comment") == 0 || strcmp(namelower, "history") == 0 )
01685 {
01686
01687
01688
01689 size_t size = strlen(newkey->value.string_val) + 1;
01690 newkey->value.string_val = base_strcatalloc(newkey->value.string_val, "\n", &size);
01691 newkey->value.string_val = base_strcatalloc(newkey->value.string_val,
01692 drmskwval.string_val,
01693 &size);
01694 }
01695 else if (newkey->record &&
01696 newkey->info &&
01697 newkey->info->type == drmskwtype)
01698 {
01699
01700
01701 memcpy(&(newkey->value), &drmskwval, sizeof(DRMS_Type_Value_t));
01702 if (format && *format != '\0')
01703 {
01704 snprintf(newkey->info->format, sizeof(newkey->info->format), "%s", format);
01705 }
01706 }
01707 else if (verbose)
01708 {
01709 fprintf(stderr, "WARNING: Keyword '%s' already exists; the DRMS value is the value of the first instance .\n", nameout);
01710 }
01711 }
01712 else if ((newkey = (DRMS_Keyword_t *)hcon_allocslot(keys, namelower)) != NULL)
01713 {
01714 memset(newkey, 0, sizeof(DRMS_Keyword_t));
01715 newkey->info = calloc(1, sizeof(DRMS_KeywordInfo_t));
01716 memcpy(&(newkey->value), &drmskwval, sizeof(DRMS_Type_Value_t));
01717
01718 snprintf(newkey->info->name, DRMS_MAXKEYNAMELEN, "%s", nameout);
01719 newkey->info->islink = 0;
01720 newkey->info->type = drmskwtype;
01721
01722
01723
01724
01725
01726 if (cast == kFE_Keyword_ExtType_Logical || strcmp(nameout, fitskey->key_name) != 0)
01727 {
01728 snprintf(newkey->info->description,
01729 DRMS_MAXCOMMENTLEN,
01730 "[%s:%s]",
01731 fitskey->key_name,
01732 FE_Keyword_ExtType_Strings[cast]);
01733 }
01734
01735 if (format && *format != '\0')
01736 {
01737 snprintf(newkey->info->format, sizeof(newkey->info->format), "%s", format);
01738 }
01739 else
01740 {
01741
01742
01743 switch (drmskwtype)
01744 {
01745 case DRMS_TYPE_CHAR:
01746 snprintf(newkey->info->format, DRMS_MAXFORMATLEN, "%%hhd");
01747 break;
01748 case DRMS_TYPE_SHORT:
01749 snprintf(newkey->info->format, DRMS_MAXFORMATLEN, "%%hd");
01750 break;
01751 case DRMS_TYPE_INT:
01752 snprintf(newkey->info->format, DRMS_MAXFORMATLEN, "%%d");
01753 break;
01754 case DRMS_TYPE_LONGLONG:
01755 snprintf(newkey->info->format, DRMS_MAXFORMATLEN, "%%lld");
01756 break;
01757 case DRMS_TYPE_FLOAT:
01758 snprintf(newkey->info->format, DRMS_MAXFORMATLEN, "%%f");
01759 break;
01760 case DRMS_TYPE_DOUBLE:
01761 snprintf(newkey->info->format, DRMS_MAXFORMATLEN, "%%lf");
01762 break;
01763 case DRMS_TYPE_STRING:
01764 snprintf(newkey->info->format, DRMS_MAXFORMATLEN, "%%s");
01765 break;
01766 default:
01767 fprintf(stderr, "Unsupported keyword data type '%d'", (int)drmskwtype);
01768 stat = DRMS_ERROR_INVALIDDATA;
01769 break;
01770 }
01771 }
01772 }
01773 else
01774 {
01775 fprintf(stderr, "Failed to alloc a new slot in keys container.\n");
01776 stat = DRMS_ERROR_OUTOFMEMORY;
01777 }
01778
01779 if (namelower)
01780 {
01781 free(namelower);
01782 }
01783
01784 if (format)
01785 {
01786 free(format);
01787 }
01788 }
01789 else
01790 {
01791 fprintf(stderr,
01792 "Could not convert FITS keyword '%s' to DRMS keyword.\n",
01793 fitskey->key_name);
01794 stat = DRMS_ERROR_INVALIDDATA;
01795 }
01796 }
01797 else
01798 {
01799 fprintf(stderr,
01800 "Could not determine internal DRMS keyword name for FITS name '%s'.\n",
01801 fitskey->key_name);
01802 stat = DRMS_ERROR_INVALIDDATA;
01803 }
01804
01805 if (map)
01806 {
01807 exputl_keymap_destroy(&map);
01808 }
01809 }
01810 }
01811
01812 return stat;
01813 }
01814
01815 FE_Keyword_ExtType_t fitsexport_keyword_getcast(DRMS_Keyword_t *key)
01816 {
01817 FE_Keyword_ExtType_t type = kFE_Keyword_ExtType_None;
01818 char *pcast = NULL;
01819 int icast;
01820
01821 if (key && key->info->description)
01822 {
01823 pcast = strchr(key->info->description, ':');
01824 if (pcast)
01825 {
01826 pcast++;
01827
01828 for (icast = 0; icast < (int)kFE_Keyword_ExtType_End; icast++)
01829 {
01830 if (strcasecmp(pcast, FE_Keyword_ExtType_Strings[icast]) == 0)
01831 {
01832 break;
01833 }
01834 }
01835
01836 if (icast != kFE_Keyword_ExtType_End)
01837 {
01838 type = (FE_Keyword_ExtType_t)icast;
01839 }
01840 }
01841 }
01842
01843 return type;
01844 }
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857 int fitsexport_getextname(const char *strin, char **extname, char **cast)
01858 {
01859 int rv;
01860 const char *pch = NULL;
01861 int state;
01862 char buf[16];
01863 char bufcast[16];
01864 char *pbuf = NULL;
01865 char *pbufcast = NULL;
01866
01867 pch = strin;
01868 pbuf = buf;
01869 pbufcast = bufcast;
01870 rv = 0;
01871 state = 0;
01872
01873 if (extname || cast)
01874 {
01875 while (*pch && state != -1 && state != 3)
01876 {
01877 switch(state)
01878 {
01879 case 0:
01880 if (*pch == ' ')
01881 {
01882 pch++;
01883 }
01884 else if (*pch == '[')
01885 {
01886 state = 1;
01887 pch++;
01888 }
01889 else
01890 {
01891
01892 state = 3;
01893 break;
01894 }
01895 break;
01896 case 1:
01897 if (*pch == ':')
01898 {
01899 state = 2;
01900 pch++;
01901 }
01902 else if (*pch == ']')
01903 {
01904 state = 3;
01905 break;
01906 }
01907 else
01908 {
01909 *pbuf = *pch;
01910 pch++;
01911 pbuf++;
01912 }
01913 break;
01914 case 2:
01915 if (*pch == ']')
01916 {
01917 state = 3;
01918 break;
01919 }
01920 else
01921 {
01922 *pbufcast = *pch;
01923 pch++;
01924 pbufcast++;
01925 }
01926 break;
01927 default:
01928
01929 state = -1;
01930 break;
01931 }
01932 }
01933
01934 if (state == 0)
01935 {
01936
01937 state = 3;
01938 }
01939
01940 if (state != 3)
01941 {
01942 rv = 1;
01943 }
01944 else
01945 {
01946 *pbuf = '\0';
01947 if (extname)
01948 {
01949 *extname = strdup(buf);
01950 }
01951 *pbufcast = '\0';
01952 if (cast)
01953 {
01954 *cast = strdup(bufcast);
01955 }
01956 }
01957 }
01958
01959 return rv;
01960 }
01961
01962
01963
01964
01965
01966 int fitsexport_getmappedextkeyvalue(DRMS_Keyword_t *key, char **fitsKwString)
01967 {
01968 DRMS_Keyword_t *keyWithVal = NULL;
01969 char fitsioCard[FLEN_CARD];
01970 CFITSIO_KEYWORD *cfitsioKey = NULL;
01971 char fitsKwType = '\0';
01972 char *fitsKwFormat = NULL;
01973 void *fitsKwVal = NULL;
01974 char dummy[] = "EXTVAL25";
01975
01976 int err = 0;
01977
01978
01979 keyWithVal = drms_keyword_lookup(key->record, key->info->name, 1);
01980
01981 if ((DRMSKeyValToFITSKeyVal(keyWithVal, &fitsKwType, &fitsKwFormat, &fitsKwVal)) == 0)
01982 {
01983 if (cfitsio_create_key(dummy, fitsKwType, NULL, fitsKwVal, fitsKwFormat, &cfitsioKey) == 0)
01984 {
01985 if (cfitsio_key_to_card(cfitsioKey, fitsioCard) == 0)
01986 {
01987
01988 if (*fitsioCard != '\0')
01989 {
01990 char stripped[128];
01991 char *end = NULL;
01992
01993 snprintf(stripped, sizeof(stripped), "%s", &(fitsioCard[10]));
01994 end = stripped + strlen(stripped) - 1;
01995 while (end > stripped && isspace((unsigned char)*end))
01996 {
01997 end--;
01998 }
01999
02000 end++;
02001 *end = '\0';
02002
02003 *fitsKwString = strdup(stripped);
02004 }
02005 else
02006 {
02007
02008 err = 1;
02009 fprintf(stderr, "Invalid FITS keyword card.\n");
02010 }
02011 }
02012 else
02013 {
02014
02015 err = 1;
02016 fprintf(stderr, "Unable to print FITS keyword.\n");
02017 }
02018
02019
02020 if (cfitsioKey)
02021 {
02022 if (cfitsioKey->key_type == kFITSRW_Type_String && cfitsioKey->key_value.vs)
02023 {
02024 free(cfitsioKey->key_value.vs);
02025 cfitsioKey->key_value.vs = NULL;
02026 }
02027
02028 free(cfitsioKey);
02029 cfitsioKey = NULL;
02030 }
02031 }
02032 else
02033 {
02034
02035 err = 1;
02036 fprintf(stderr, "Unable to create FITS keyword.\n");
02037 }
02038
02039 if (fitsKwFormat)
02040 {
02041 free(fitsKwFormat);
02042 fitsKwFormat = NULL;
02043 }
02044
02045 if (fitsKwVal)
02046 {
02047 free(fitsKwVal);
02048 fitsKwVal = NULL;
02049 }
02050 }
02051 else
02052 {
02053
02054 err = 1;
02055 fprintf(stderr, "Unable to convert DRMS keyword %s to FITS keyword.\n", key->info->name);
02056 }
02057
02058 return err;
02059 }