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