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