00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 # if !defined(AIPS_FITS)
00029 # define AIPS_FITS
00030
00031
00032 # include <casacore/casa/aips.h>
00033 # include <stdlib.h>
00034 # include <ctype.h>
00035 # include <casacore/casa/iostream.h>
00036 # include <casacore/casa/BasicSL/Complex.h>
00037 # include <casacore/casa/BasicSL/IComplex.h>
00038 # include <casacore/fits/FITS/FITSError.h>
00039
00040 namespace casacore {
00041
00042
00043
00044
00045 # if (defined(__alpha) || defined(__sgi) || defined(__x86_64__))
00046 typedef Int FitsLong;
00047 # else
00048 typedef Long FitsLong;
00049 # endif
00050
00051
00052
00053 class ReservedFitsKeywordCollection;
00054 class FitsNameResult;
00055 class FitsValueResult;
00056 class FitsKeyword;
00057 class FitsParse;
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 template <class TYPE>
00068 class NoConvert {
00069 public:
00070 NoConvert() { }
00071 void operator = (int) {; }
00072 };
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 class FitsLogical {
00096 friend ostream & operator << (ostream &o, const FitsLogical &);
00097 public:
00098 FitsLogical() : v('\0') { }
00099 FitsLogical(Bool x) { v = (x == True ? 'T' : 'F'); }
00100 FitsLogical(const FitsLogical &x) : v(x.v) { }
00101 FitsLogical & operator = (const FitsLogical &x) {
00102 v = x.v; return *this; }
00103 FitsLogical & operator = (Bool x) {
00104 v = (x == True ? 'T' : 'F'); return *this; }
00105 Bool isdefined() const { return v == '\0' ? True : False; }
00106 void undefine() { v = '\0'; }
00107 operator Bool() { return (v == 'T' ? True : False); }
00108 protected:
00109 char v;
00110 };
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 class FitsBit {
00123 public:
00124 FitsBit() : bit_array(0) { }
00125 FitsBit(unsigned char x) : bit_array(x) { }
00126 FitsBit(const FitsBit &x) : bit_array(x.bit_array) { }
00127 FitsBit & operator = (const FitsBit &x) {
00128 bit_array = x.bit_array; return *this; }
00129 FitsBit & operator = (unsigned char x) { bit_array = x; return *this; }
00130 operator unsigned char() { return bit_array; }
00131 protected:
00132 unsigned char bit_array;
00133 };
00134
00135
00136
00137
00138
00139 class FitsVADesc {
00140 friend ostream & operator << (ostream &o, const FitsVADesc &);
00141 public:
00142 FitsVADesc() : no_elements(0), rel_offset(0) { }
00143 FitsVADesc(const FitsVADesc &x) :
00144 no_elements(x.no_elements), rel_offset(x.rel_offset) { }
00145 FitsVADesc & operator = (const FitsVADesc &x) {
00146 no_elements= x.no_elements;
00147 rel_offset = x.rel_offset; return *this; }
00148 FitsVADesc(int n, int o) : no_elements(n), rel_offset(o) { }
00149 void set(int n, int o) { no_elements = n; rel_offset = o; }
00150 int num() const { return no_elements; }
00151 int offset() const { return rel_offset; }
00152 protected:
00153 int no_elements;
00154 int rel_offset;
00155 };
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 class FITS {
00171 public:
00172
00173
00174
00175
00176 enum ValueType {
00177 NOVALUE = 0, LOGICAL = 1, BIT = 2, CHAR = 3, BYTE = 4,
00178 SHORT = 5, LONG = 6, FLOAT = 7, DOUBLE = 8, COMPLEX = 9,
00179 ICOMPLEX = 10, DCOMPLEX = 11, VADESC = 12,
00180 STRING, FSTRING, REAL
00181 };
00182
00183
00184 static FITS::ValueType getfitstype(NoConvert<FitsLogical> x) {
00185 x=0; return FITS::LOGICAL; }
00186 static FITS::ValueType getfitstype(NoConvert<FitsBit> x) {
00187 x=0; return FITS::BIT; }
00188 static FITS::ValueType getfitstype(NoConvert<char> x) {
00189 x=0; return FITS::CHAR; }
00190 static FITS::ValueType getfitstype(NoConvert<unsigned char> x) {
00191 x=0; return FITS::BYTE; }
00192 static FITS::ValueType getfitstype(NoConvert<short> x) {
00193 x=0; return FITS::SHORT; }
00194 static FITS::ValueType getfitstype(NoConvert<Int> x) {
00195 x=0; return FITS::LONG; }
00196 static FITS::ValueType getfitstype(NoConvert<long> x) {
00197 x=0; return FITS::LONG; }
00198 static FITS::ValueType getfitstype(NoConvert<float> x) {
00199 x=0; return FITS::FLOAT; }
00200 static FITS::ValueType getfitstype(NoConvert<double> x) {
00201 x=0; return FITS::DOUBLE; }
00202 static FITS::ValueType getfitstype(NoConvert<Complex> x) {
00203 x=0; return FITS::COMPLEX; }
00204 static FITS::ValueType getfitstype(NoConvert<IComplex> x) {
00205 x=0; return FITS::ICOMPLEX; }
00206 static FITS::ValueType getfitstype(NoConvert<DComplex> x) {
00207 x=0; return FITS::DCOMPLEX; }
00208 static FITS::ValueType getfitstype(NoConvert<FitsVADesc> x) {
00209 x=0; return FITS::VADESC; }
00210
00211 static int fitssize(FITS::ValueType t);
00212 static int localsize(FITS::ValueType t);
00213
00214
00215 static void f2l(FitsLogical *,void *,int);
00216 static void l2f(void *,FitsLogical *,int);
00217 static void f2l(FitsBit *,void *,int);
00218 static void l2f(void *,FitsBit *,int);
00219 static void f2l(char *,void *,int);
00220 static void l2f(void *,char *,int);
00221 static void f2l(unsigned char *,void *,int);
00222 static void l2f(void *,unsigned char *,int);
00223 static void f2l(short *,void *,int);
00224 static void l2f(void *,short *,int);
00225 static void f2l(Int *,void *,int);
00226 static void l2f(void *,Int *,int);
00227 static void f2l(long *,void *,int);
00228 static void l2f(void *,long *,int);
00229 static void f2l(float *,void *,int);
00230 static void l2f(void *,float *,int);
00231 static void f2l(double *,void *,int);
00232 static void l2f(void *,double *,int);
00233 static void f2l(Complex *,void *,int);
00234 static void l2f(void *,Complex *,int);
00235 static void f2l(IComplex *,void *,int);
00236 static void l2f(void *,IComplex *,int);
00237 static void f2l(DComplex *,void *,int);
00238 static void l2f(void *,DComplex *,int);
00239 static void f2l(FitsVADesc *,void *,int);
00240 static void l2f(void *,FitsVADesc *,int);
00241 static void swap2(void *, void *, int);
00242 static void swap4(void *, void *, int);
00243 static void swap8(void *, void *, int);
00244
00245
00246
00247 enum ReservedName {
00248 USER_DEF, AUTHOR, BITPIX, BLANK, BLOCKED, BSCALE,
00249 BUNIT, BZERO, CDELT, COMMENT, CROTA, CRPIX,
00250 CRVAL, CTYPE, DATAMAX, DATAMIN, DATE, DATE_OBS,
00251 END, EPOCH, EQUINOX, EXTEND, EXTLEVEL, EXTNAME,
00252 EXTVER, GCOUNT, GROUPS, HISTORY, INSTRUME, NAXIS,
00253 OBJECT, OBSERVER, ORIGIN, PCOUNT, PSCAL, PTYPE,
00254 PZERO_FITS, REFERENC, SIMPLE, SPACES, TBCOL, TDIM,
00255 TDISP, TELESCOP, TFIELDS, TFORM, THEAP, TNULL,
00256 TSCAL, TTYPE, TUNIT, TZERO, XTENSION, ERRWORD,
00257 ALTRPIX, DATE_MAP
00258 };
00259
00260
00261 enum FitsRecType {
00262 InitialState, BadBeginningRecord, HDURecord,
00263 UnrecognizableRecord, SpecialRecord, EndOfFile
00264 };
00265
00266
00267 enum FitsDevice {
00268 Disk, Std, Tape9
00269 };
00270
00271
00272 enum HDUType {
00273 NotAHDU, PrimaryArrayHDU, PrimaryGroupHDU, AsciiTableHDU,
00274 BinaryTableHDU, ImageExtensionHDU, UnknownExtensionHDU,
00275 PrimaryTableHDU
00276 };
00277
00278
00279 enum FitsArrayOption { NoOpt = 0, CtoF = 1, FtoC = 2};
00280
00281 static ReservedFitsKeywordCollection &ResWord;
00282 static void valstr(ostream &o, const ValueType &ty, const void *val);
00283 static Bool isa_digit(char c);
00284 static int digit2bin(char c);
00285 static Bool isa_text(char c);
00286 static Bool isa_letter(char);
00287 static int letter2bin(char);
00288 static void fstr2str(char *, const char *, int);
00289 static int str2fstr(char *, const char *, int);
00290 static void get_name(const char *s, int len, FitsNameResult &result);
00291 static int get_value_id(const char *s, int l, int &pos);
00292 static void get_value(const char *s, int len, FitsValueResult &result);
00293 static int trim_comment(const char *s, int len);
00294 static int chk_comment(const char *s, int len);
00295 static int get_comment(const char *s, int len, int &begpos);
00296 static void get_numeric(const char *s, int len, FitsValueResult &result);
00297
00298
00299
00300
00301
00302
00303
00304 static void parse_vatform(const char *s, FITS::ValueType &valType,
00305 int &maxelem);
00306 static const Int minInt;
00307 static const Int maxInt;
00308 static const float minfloat;
00309 static const float maxfloat;
00310 static const double mindouble;
00311 static const double maxdouble;
00312
00313 private:
00314 FITS();
00315 static double tenpowerD[309];
00316 static float tenpowerF[39];
00317 static const int minfltexp;
00318 static const int maxfltexp;
00319 static const int mindblexp;
00320 static const int maxdblexp;
00321 static const int maxsigdigits;
00322 static const int maxdigl;
00323 static const int maxexpdig;
00324 static double tenD(Int, int);
00325 static float tenF(Int, int);
00326 static int ckaccum(double &, Int, int);
00327 static int ckaccum(float &, Int, int);
00328 };
00329
00330 inline FITS::FITS() { }
00331 inline Bool FITS::isa_digit(char c) { return isdigit(c) ? True : False; }
00332 inline int FITS::digit2bin(char c) { return c - '0'; }
00333 inline Bool FITS::isa_text(char c) { return isprint(c) ? True : False; }
00334 inline Bool FITS::isa_letter(char c) { return isupper(c) ? True : False; }
00335 inline int FITS::letter2bin(char c) { return c - 'A'; }
00336
00337 ostream & operator << (ostream &, const FITS::ValueType &);
00338
00339 inline double FITS::tenD(Int numb, int pow) {
00340 return (pow > 0) ? (((double)numb) * tenpowerD[pow]) :
00341 ((pow < 0) ? (((double)numb) / tenpowerD[-pow]) : ((double)numb));
00342 }
00343 inline float FITS::tenF(Int numb, int pow) {
00344 return (pow > 0) ? (((float)numb) * tenpowerF[pow]) :
00345 ((pow < 0) ? (((float)numb) / tenpowerF[-pow]) : ((float)numb));
00346 }
00347
00348
00349
00350
00351
00352 class ReservedFitsKeyword {
00353 public:
00354 const char *aname() const;
00355 FITS::ReservedName name() const;
00356 int namesize() const;
00357 FITS::ValueType type() const;
00358 Bool isindexed() const;
00359 Bool isessential() const;
00360 # if defined(TURBOCPP)
00361
00362
00363
00364
00365 private:
00366 # endif
00367 FITS::ReservedName name_;
00368 const char *aname_;
00369 int namesize_;
00370 FITS::ValueType type_;
00371 Bool isindexed_;
00372 Bool isessential_;
00373 };
00374
00375 inline const char *ReservedFitsKeyword::aname() const { return aname_; }
00376 inline int ReservedFitsKeyword::namesize() const { return namesize_; }
00377 inline FITS::ValueType ReservedFitsKeyword::type() const { return type_; }
00378 inline Bool ReservedFitsKeyword::isindexed() const { return isindexed_; }
00379 inline Bool ReservedFitsKeyword::isessential() const {
00380 return isessential_; }
00381
00382
00383
00384
00385
00386 class ReservedFitsKeywordCollection {
00387 public:
00388 const ReservedFitsKeyword & operator [] (int i) const;
00389 int no() const;
00390 const ReservedFitsKeyword &get(FITS::ReservedName, Bool, FITS::ValueType,
00391 const void *, int, const char *&) const;
00392 const ReservedFitsKeyword &get(const char *, int, Bool, FITS::ValueType,
00393 const void *, int, const char *&) const;
00394 const char *aname(FITS::ReservedName) const;
00395 int essential_name(const char *, int) const;
00396 const ReservedFitsKeyword &get_essential(int, Bool, FITS::ValueType,
00397 const void *, int, const char *&) const;
00398 int isreserved(const char *, int) const;
00399 Bool isunique(int) const;
00400 Bool requires_value(int) const;
00401 const ReservedFitsKeyword &userdef_item() const;
00402 const ReservedFitsKeyword &err_item() const;
00403 const ReservedFitsKeyword &end_item() const;
00404 const ReservedFitsKeyword &spaces() const;
00405 const ReservedFitsKeyword &comment() const;
00406 const ReservedFitsKeyword &history() const;
00407 int rules(const ReservedFitsKeyword &, const char *, int, Bool,
00408 FITS::ValueType, const void *, int, const char *&) const;
00409 private:
00410 static const int no_items;
00411 static const ReservedFitsKeyword &user_def_item;
00412 static const ReservedFitsKeyword &error_item;
00413 static const ReservedFitsKeyword &end__item;
00414 static const ReservedFitsKeyword &spaces_item;
00415 static const ReservedFitsKeyword &comment_item;
00416 static const ReservedFitsKeyword &history_item;
00417 static const ReservedFitsKeyword resword[];
00418 static const int resalpha[26];
00419 const ReservedFitsKeyword &match(int, const char *, int, Bool,
00420 FITS::ValueType, const void *, int, const char *&) const;
00421
00422 };
00423
00424 inline const ReservedFitsKeyword & ReservedFitsKeywordCollection::
00425 operator [] (int i) const { return resword[i]; }
00426 inline int ReservedFitsKeywordCollection::no() const { return no_items; }
00427 inline Bool ReservedFitsKeywordCollection::isunique(int i) const {
00428 return (Bool)(resword[i + 1].name() != resword[i].name()); }
00429 inline const ReservedFitsKeyword &ReservedFitsKeywordCollection::userdef_item()
00430 const { return user_def_item; }
00431 inline const ReservedFitsKeyword &ReservedFitsKeywordCollection::err_item()
00432 const { return error_item; }
00433 inline const ReservedFitsKeyword &ReservedFitsKeywordCollection::end_item()
00434 const { return end__item; }
00435 inline const ReservedFitsKeyword &ReservedFitsKeywordCollection::spaces()
00436 const { return spaces_item; }
00437 inline const ReservedFitsKeyword &ReservedFitsKeywordCollection::comment()
00438 const { return comment_item; }
00439 inline const ReservedFitsKeyword &ReservedFitsKeywordCollection::history()
00440 const { return history_item; }
00441
00442
00443
00444
00445
00446
00447
00448
00449 class FitsNameResult {
00450 public:
00451 Bool isaname;
00452 int begpos;
00453 int endpos;
00454 Bool isaindex;
00455 int index;
00456 int len;
00457 enum ErrMsg { OK = 0, NO_0_NDX };
00458 ErrMsg err;
00459 };
00460
00461
00462
00463
00464
00465
00466
00467
00468 class FitsValueResult {
00469 public:
00470 FITS::ValueType type;
00471 union {
00472 Bool b;
00473 int s[2];
00474 Int l;
00475 float f;
00476 double d;
00477 };
00478 Complex c;
00479 IComplex lc;
00480 DComplex dc;
00481 int begpos;
00482 int endpos;
00483 Bool isa_point;
00484 int pointpos;
00485 int no_sig;
00486 const char *errmsg;
00487 };
00488
00489
00490
00491
00492
00493
00494
00495
00496 class FitsParse {
00497 friend class FitsKeywordList;
00498 public:
00499 FitsKeyword &parse(const char *, int);
00500 int no_errs() const;
00501 const char *err(int) const;
00502 private:
00503 FitsParse(int = 10);
00504 ~FitsParse();
00505 int no_errs_;
00506 const int max_errs;
00507 const char **err_;
00508 int seterr(const char *);
00509 FitsKeyword &mkerr(const char *s, int len);
00510 };
00511
00512 inline FitsParse::~FitsParse() { delete [] err_; }
00513 inline int FitsParse::no_errs() const { return no_errs_; }
00514 inline const char *FitsParse::err(int i) const { return err_[i]; }
00515 inline int FitsParse::seterr(const char *s) {
00516 return no_errs_ < max_errs ? ( err_[no_errs_++] = s, 0) : -1; }
00517
00518
00519
00520
00521
00522
00523
00524 class FitsKeyword {
00525 friend class FitsKeywordList;
00526 friend class FitsParse;
00527
00528
00529
00530
00531 public:
00532
00533 FitsKeyword(const FitsKeyword &);
00534 FitsKeyword & operator = (const FitsKeyword &);
00535 ~FitsKeyword();
00536
00537
00538
00539 const char *name() const;
00540 int namelen() const;
00541 Bool isreserved() const;
00542 Bool isindexed() const;
00543 const ReservedFitsKeyword &kw() const;
00544 int index() const;
00545
00546
00547
00548
00549 const char *comm() const;
00550 int commlen() const;
00551
00552
00553
00554 int err() const;
00555
00556
00557 FITS::ValueType type() const;
00558
00559
00560
00561 Bool asBool() const;
00562 const char *asString() const;
00563 int valStrlen() const;
00564 Int asInt() const;
00565 float asFloat() const;
00566 double asDouble() const;
00567 IComplex asIComplex() const;
00568 Complex asComplex() const;
00569 DComplex asDComplex() const;
00570 const void *value() const;
00571
00572
00573
00574
00575 FitsKeyword & operator = (Bool);
00576 FitsKeyword & operator = (const char *);
00577 FitsKeyword & operator = (Int);
00578 FitsKeyword & operator = (float);
00579 FitsKeyword & operator = (double);
00580 FitsKeyword & operator = (IComplex);
00581 FitsKeyword & operator = (Complex);
00582 FitsKeyword & operator = (DComplex);
00583
00584
00585
00586 void comm(const char *);
00587
00588
00589 void name(const char *);
00590
00591 private:
00592 FitsKeyword *next_;
00593 FitsKeyword *prev_;
00594
00595
00596
00597
00598
00599 char *name_;
00600 const ReservedFitsKeyword *kw_;
00601 int ndx;
00602 short namelen_;
00603
00604
00605
00606
00607
00608 char *comm_;
00609 short commlen_;
00610
00611
00612
00613
00614
00615 FITS::ValueType type_;
00616 union {
00617 Bool bval;
00618 Int ival;
00619 float fval;
00620 double dval;
00621 };
00622 void *val;
00623 short vallen;
00624 void del_val();
00625
00626
00627 void init(const FitsKeyword &);
00628 void setval(const FITS::ValueType &, const void *, int);
00629 void setcomm(const char *, int);
00630 static void err(const char *, const FITS::ValueType &, const void *,
00631 const char *);
00632 static void memchk(void *);
00633
00634
00635
00636
00637
00638
00639 FitsKeyword(const char *, int ,
00640 FITS::ValueType, const void *, int, const char *, int);
00641
00642
00643 FitsKeyword(const ReservedFitsKeyword *, int,
00644 FITS::ValueType, const void *, int, const char *, int);
00645
00646
00647
00648 };
00649
00650 ostream & operator << (ostream &, const FitsKeyword &);
00651
00652 inline FitsKeyword::FitsKeyword(const FitsKeyword &k) : next_(0), prev_(0),
00653 name_(0), kw_(0), comm_(0), val(0) { init(k); }
00654 inline FitsKeyword & FitsKeyword::operator = (const FitsKeyword &k) {
00655 delete [] name_; delete [] comm_; del_val(); init(k); return *this; }
00656 inline FitsKeyword::~FitsKeyword() {
00657 delete [] name_;
00658 delete [] comm_;
00659 del_val();
00660 }
00661
00662 inline const ReservedFitsKeyword &FitsKeyword::kw() const { return *kw_; }
00663 inline Bool FitsKeyword::isreserved() const { return
00664 (kw().name() != FITS::ERRWORD && kw().name() != FITS::USER_DEF)
00665 ? True : False; }
00666 inline const char *FitsKeyword::name() const {
00667 return isreserved() ? kw().aname() : (namelen_ ? name_ : ""); }
00668 inline int FitsKeyword::namelen() const { return namelen_; }
00669 inline Bool FitsKeyword::isindexed() const {return ndx > 0 ? True : False;}
00670 inline int FitsKeyword::index() const { return ndx; }
00671
00672 inline const char *FitsKeyword::comm() const {
00673 return comm_ ? comm_ : ""; }
00674 inline int FitsKeyword::commlen() const { return commlen_; }
00675 inline int FitsKeyword::err() const { return (kw().name() == FITS::ERRWORD); }
00676 inline FITS::ValueType FitsKeyword::type() const { return type_; }
00677
00678 inline Bool FitsKeyword::asBool() const { return bval; }
00679 inline const char *FitsKeyword::asString() const {
00680 return vallen ? (const char *)val : ""; }
00681 inline int FitsKeyword::valStrlen() const { return vallen; }
00682 inline Int FitsKeyword::asInt() const {
00683 if( type() != FITS::LONG ) {
00684 cerr << "Unexpected keyword type in FitsKeyword::asInt()\n";
00685 exit(1);
00686 }
00687 return ival;
00688 }
00689 inline float FitsKeyword::asFloat() const {
00690 switch( type() ) {
00691 case FITS::BYTE:
00692 case FITS::SHORT:
00693 case FITS::LONG: return (float)ival;
00694 case FITS::FLOAT: return fval;
00695 case FITS::DOUBLE: return (float)dval;
00696 default:
00697 cerr << "Unexpected keyword type in asFloat()\n";
00698 exit(1);
00699 }
00700 return 0.0;
00701 }
00702 inline double FitsKeyword::asDouble() const {
00703 switch( type() ) {
00704 case FITS::BYTE:
00705 case FITS::SHORT:
00706 case FITS::LONG: return (double)ival;
00707 case FITS::FLOAT: return (double)fval;
00708 case FITS::DOUBLE: return dval;
00709 default:
00710 cerr << "Unexpected keyword type in asDouble()\n";
00711 exit(1);
00712 }
00713 return 0.0;
00714 }
00715 inline IComplex FitsKeyword::asIComplex() const {
00716 return *((IComplex *)val); }
00717 inline Complex FitsKeyword::asComplex() const {
00718 return *((Complex *)val); }
00719 inline DComplex FitsKeyword::asDComplex() const {
00720 return *((DComplex *)val); }
00721
00722 inline FitsKeyword & FitsKeyword::operator = (Bool x) {
00723 bval = x; type_ = FITS::LOGICAL; return *this; }
00724 inline FitsKeyword & FitsKeyword::operator = (Int x) {
00725 ival = x; type_ = FITS::LONG; return *this; }
00726 inline FitsKeyword & FitsKeyword::operator = (float x) {
00727 fval = x; type_ = FITS::FLOAT; return *this; }
00728 inline FitsKeyword & FitsKeyword::operator = (double x) {
00729 dval = x; type_ = FITS::DOUBLE; return *this; }
00730 inline FitsKeyword & FitsKeyword::operator = (IComplex x) {
00731 *((IComplex *)val) = x; type_ = FITS::ICOMPLEX; return *this; }
00732 inline FitsKeyword & FitsKeyword::operator = (Complex x) {
00733 *((Complex *)val) = x; type_ = FITS::COMPLEX; return *this; }
00734 inline FitsKeyword & FitsKeyword::operator = (DComplex x) {
00735 *((DComplex *)val) = x; type_ = FITS::DCOMPLEX; return *this; }
00736
00737 class ConstFitsKeywordList;
00738
00739
00740
00741
00742
00743
00744
00745
00746 class FitsKeywordList {
00747 public:
00748 FitsKeywordList();
00749 ~FitsKeywordList();
00750 FitsKeywordList(const FitsKeywordList &);
00751 FitsKeywordList(ConstFitsKeywordList &);
00752 FitsKeywordList & operator = (const FitsKeywordList &);
00753
00754
00755 std::string toString() const;
00756
00757
00758 void del();
00759
00760
00761
00762
00763
00764
00765 void mk(FITS::ReservedName k, Bool v, const char *c = 0);
00766 void mk(FITS::ReservedName k, const char *v = 0, const char *c = 0);
00767 void mk(FITS::ReservedName k, Int v, const char *c = 0);
00768 void mk(FITS::ReservedName k, long v, const char *c = 0);
00769 void mk(FITS::ReservedName k, double v, const char *c = 0);
00770
00771
00772
00773
00774
00775
00776
00777 void mk(int n, FITS::ReservedName k, Bool v, const char *c = 0);
00778 void mk(int n, FITS::ReservedName k, const char *v, const char *c = 0);
00779 void mk(int n, FITS::ReservedName k, Int v, const char *c = 0);
00780 void mk(int n, FITS::ReservedName k, long v, const char *c = 0);
00781 void mk(int n, FITS::ReservedName k, double v, const char *c = 0);
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791 void mk(const char *n, Bool v, const char *c = 0);
00792 void mk(const char *n, const char *v = 0, const char *c = 0);
00793 void mk(const char *n, Int v, const char *c = 0);
00794 void mk(const char *n, long v, const char *c = 0);
00795 void mk(const char *n, float v, const char *c = 0);
00796 void mk(const char *n, double v, const char *c = 0);
00797 void mk(const char *n, Int r, Int i, const char *c = 0);
00798 void mk(const char *n, float r, float i, const char *c = 0);
00799 void mk(const char *n, double r, double i, const char *c = 0);
00800
00801
00802
00803 void spaces(const char *n = 0, const char *c = 0);
00804
00805
00806 void comment(const char *n = 0, const char *c = 0);
00807
00808
00809 void history(const char *c = 0);
00810
00811
00812 void end();
00813
00814
00815
00816
00817 FitsKeyword * operator () (int);
00818
00819 FitsKeyword * operator () (const FITS::ReservedName &);
00820 FitsKeyword * next(const FITS::ReservedName &);
00821
00822 FitsKeyword * operator () (const FITS::ReservedName &, int);
00823 FitsKeyword * next(const FITS::ReservedName &, int);
00824
00825 FitsKeyword * operator () (const char *);
00826 FitsKeyword * next(const char *);
00827
00828
00829
00830 Bool isempty() const;
00831 void first();
00832 void last();
00833 FitsKeyword *next();
00834 FitsKeyword *prev();
00835 FitsKeyword *curr();
00836
00837
00838
00839 void delete_all();
00840 int rules(FitsKeyword &,
00841 FITSErrorHandler errhandler = FITSError::defaultHandler);
00842 int rules(FITSErrorHandler errhandler = FITSError::defaultHandler);
00843 Bool basic_rules();
00844
00845
00846
00847
00848 void parse(const char *, int);
00849 int no_parse_errs() const;
00850 const char *parse_err(int) const;
00851
00852
00853 void insert(FitsKeyword &);
00854 private:
00855 FitsKeyword *beg_;
00856 FitsKeyword *end_;
00857 FitsKeyword *pos;
00858 int total;
00859 int cursor;
00860 FitsKeyword &make(const char *nm,
00861 FITS::ValueType t, const void *v, const char *c);
00862 FitsKeyword &make(FITS::ReservedName nm,
00863 FITS::ValueType t, const void *v, const char *c);
00864 FitsKeyword &make(int ind, FITS::ReservedName nm,
00865 FITS::ValueType t, const void *v, const char *c);
00866
00867
00868
00869
00870
00871
00872 FitsKeyword &makeErrKeyword(const char *name, FITS::ValueType type,
00873 const void *val, const char *errmsg);
00874 FitsParse card;
00875 };
00876
00877 ostream & operator << (ostream &o, FitsKeywordList &);
00878
00879 inline FitsKeywordList::FitsKeywordList() : beg_(0), end_(0), pos(0),
00880 total(0), cursor(0) { }
00881 inline FitsKeywordList::~FitsKeywordList() { delete_all(); }
00882 inline Bool FitsKeywordList::isempty() const { return total == 0 ? True : False; }
00883 inline void FitsKeywordList::first() { cursor = 0; pos = beg_; }
00884 inline void FitsKeywordList::last() { cursor = total; pos = end_; }
00885 inline FitsKeyword *FitsKeywordList::curr() { return pos; }
00886 inline FitsKeyword *FitsKeywordList::operator () (const FITS::ReservedName &n) {
00887 first(); return next(n); }
00888 inline FitsKeyword *FitsKeywordList::operator () (const FITS::ReservedName &n,
00889 int ndx) { first(); return next(n,ndx); }
00890 inline FitsKeyword *FitsKeywordList::operator () (const char *w) {
00891 first(); return next(w); }
00892 inline void FitsKeywordList::parse(const char *s, int l) {
00893 insert(card.parse(s,l)); }
00894 inline int FitsKeywordList::no_parse_errs() const { return card.no_errs();}
00895 inline const char *FitsKeywordList::parse_err(int n) const {
00896 return card.err(n); }
00897
00898
00899 inline void FitsKeywordList::mk(FITS::ReservedName k, Bool v, const char *c) {
00900 insert(make(k,FITS::LOGICAL,&v,c)); }
00901 inline void FitsKeywordList::mk(FITS::ReservedName k, const char *v,
00902 const char *c) { insert(make(k,FITS::STRING,v,c)); }
00903 inline void FitsKeywordList::mk(FITS::ReservedName k, Int v, const char *c) {
00904 insert(make(k,FITS::LONG,&v,c)); }
00905 inline void FitsKeywordList::mk(FITS::ReservedName k, long v, const char *c) {
00906 insert(make(k,FITS::LONG,&v,c)); }
00907 inline void FitsKeywordList::mk(FITS::ReservedName k, double v, const char *c) {
00908 insert(make(k,FITS::DOUBLE,&v,c)); }
00909
00910 inline void FitsKeywordList::mk(int n, FITS::ReservedName k, Bool v,
00911 const char *c) {
00912 Bool tmp; tmp = v; insert(make(n,k,FITS::LOGICAL,&tmp,c)); }
00913 inline void FitsKeywordList::mk(int n, FITS::ReservedName k, const char *v,
00914 const char *c) { insert(make(n,k,FITS::STRING,v,c)); }
00915 inline void FitsKeywordList::mk(int n, FITS::ReservedName k, Int v,
00916 const char *c) { insert(make(n,k,FITS::LONG,&v,c)); }
00917 inline void FitsKeywordList::mk(int n, FITS::ReservedName k, long v,
00918 const char *c) { insert(make(n,k,FITS::LONG,&v,c)); }
00919 inline void FitsKeywordList::mk(int n, FITS::ReservedName k, double v,
00920 const char *c) { insert(make(n,k,FITS::DOUBLE,&v,c)); }
00921
00922 inline void FitsKeywordList::mk(const char *n, Bool v, const char *c) {
00923 Bool tmp; tmp = v; insert(make(n,FITS::LOGICAL,&tmp,c)); }
00924 inline void FitsKeywordList::mk(const char *n, const char *v, const char *c) {
00925 insert(make(n,FITS::STRING,v,c)); }
00926 inline void FitsKeywordList::mk(const char *n, Int v, const char *c) {
00927 insert(make(n,FITS::LONG,&v,c)); }
00928 inline void FitsKeywordList::mk(const char *n, long v, const char *c) {
00929 insert(make(n,FITS::LONG,&v,c)); }
00930 inline void FitsKeywordList::mk(const char *n, float v, const char *c) {
00931 insert(make(n,FITS::FLOAT,&v,c)); }
00932 inline void FitsKeywordList::mk(const char *n, double v, const char *c) {
00933 insert(make(n,FITS::DOUBLE,&v,c)); }
00934 inline void FitsKeywordList::mk(const char *n, Int r, Int i, const char *c) {
00935 IComplex v(r,i);
00936 insert(make(n,FITS::ICOMPLEX,&v,c)); }
00937 inline void FitsKeywordList::mk(const char *n, float r, float i, const char *c)
00938 { Complex v(r,i); insert(make(n,FITS::COMPLEX,&v,c)); }
00939 inline void FitsKeywordList::mk(const char *n, double r, double i,
00940 const char *c) { DComplex v(r,i);
00941 insert(make(n,FITS::DCOMPLEX,&v,c)); }
00942
00943 inline void FitsKeywordList::spaces(const char *n, const char *c) {
00944 insert((n == 0 ? make(FITS::SPACES,FITS::NOVALUE,0,c) :
00945 (c == 0 ? make(FITS::SPACES,FITS::NOVALUE,0,n) :
00946 make(n,FITS::NOVALUE,0,c)))); }
00947 inline void FitsKeywordList::comment(const char *n, const char *c) {
00948 insert((n == 0 ? make(FITS::COMMENT,FITS::NOVALUE,0,c) :
00949 (c == 0 ? make(FITS::COMMENT,FITS::NOVALUE,0,n) :
00950 make(n,FITS::NOVALUE,0,c)))); }
00951 inline void FitsKeywordList::history(const char *c) {
00952 insert(make(FITS::HISTORY,FITS::NOVALUE,0,c)); }
00953 inline void FitsKeywordList::end() {
00954 insert(make(FITS::END,FITS::NOVALUE,0,0)); }
00955
00956
00957
00958
00959
00960 class ConstFitsKeywordList {
00961 public:
00962 ConstFitsKeywordList(FitsKeywordList &x) : kw(x) { }
00963
00964 const FitsKeyword * operator () (int n) { return kw(n); }
00965 const FitsKeyword * operator () (const FITS::ReservedName &x) {
00966 return kw(x); }
00967 const FitsKeyword * next(const FITS::ReservedName &x) {
00968 return kw.next(x); }
00969 const FitsKeyword * operator () (const FITS::ReservedName &x, int n) {
00970 return kw(x,n); }
00971 const FitsKeyword * next(const FITS::ReservedName &x, int n) {
00972 return kw.next(x,n); }
00973 const FitsKeyword * operator () (const char *x) { return kw(x); }
00974 const FitsKeyword * next(const char *x) { return kw.next(x); }
00975
00976 Bool isempty() const { return kw.isempty(); }
00977 void first() { kw.first(); }
00978 void last() { kw.last(); }
00979 const FitsKeyword *next() { return kw.next(); }
00980 const FitsKeyword *prev() { return kw.prev(); }
00981 const FitsKeyword *curr() { return kw.curr(); }
00982
00983 private:
00984 FitsKeywordList &kw;
00985 };
00986
00987
00988
00989
00990
00991
00992
00993
00994 class FitsKeyCardTranslator {
00995 public:
00996 FitsKeyCardTranslator(int = 100);
00997 ~FitsKeyCardTranslator();
00998 FitsKeywordList & parse(const char *,
00999 FitsKeywordList &, int, FITSErrorHandler, Bool);
01000 int build(char *, FitsKeywordList &);
01001 int no_errs() const;
01002 const char *err(int) const;
01003 int err_cardno(int) const;
01004 static void fmtcard(char *, const FitsKeyword &);
01005 private:
01006 int cardno;
01007 const int FitsCardSize;
01008 const int FitsMaxCard;
01009 const int FitsRecSize;
01010 int max_errs;
01011 int no_errs_;
01012 const char **err_;
01013 int *err_cardno_;
01014 char *blanks;
01015 };
01016
01017 inline FitsKeyCardTranslator::~FitsKeyCardTranslator() {
01018 delete [] err_; delete [] err_cardno_; delete [] blanks; }
01019 inline int FitsKeyCardTranslator::no_errs() const { return no_errs_; }
01020 inline const char *FitsKeyCardTranslator::err(int i) const { return err_[i]; }
01021 inline int FitsKeyCardTranslator::err_cardno(int i) const {
01022 return err_cardno_[i]; }
01023
01024
01025
01026
01027 class FitsFPUtil
01028 {
01029 public:
01030
01031
01032
01033
01034 static Bool isFP(const float *);
01035 static Bool isFP(const double *);
01036 static Bool isFP(const void *);
01037
01038
01039
01040
01041
01042 static void setNaN(double &val);
01043 static void setNaN(float &val);
01044
01045 };
01046
01047
01048 }
01049
01050 # endif