ncdf4a13/cxx/ncvalues.h

Go to the documentation of this file.
00001 /*********************************************************************
00002  *   Copyright 1992, University Corporation for Atmospheric Research
00003  *   See netcdf/README file for copying and redistribution conditions.
00004  *
00005  *   Purpose:   interface for classes of typed arrays for netCDF
00006  *
00007  *   $Header: /upc/share/CVS/netcdf-3/cxx/ncvalues.h,v 1.5 2004/11/17 20:13:30 russ Exp $
00008  *********************************************************************/
00009 
00010 #ifndef Ncvalues_def
00011 #define Ncvalues_def
00012 
00013 #include <iostream>
00014 #include <sstream>
00015 #include <limits.h>
00016 #include "netcdf.h"
00017 
00018 typedef unsigned char ncbyte;
00019 
00020 #define NC_UNSPECIFIED ((nc_type)0)
00021 
00022 enum NcType 
00023 {
00024   ncNoType = NC_UNSPECIFIED, 
00025   ncByte = NC_BYTE, 
00026   ncChar = NC_CHAR, 
00027   ncShort = NC_SHORT, 
00028   ncInt = NC_INT,
00029   ncLong = NC_LONG,             // deprecated, someday want to use for 64-bit ints
00030   ncFloat = NC_FLOAT, 
00031   ncDouble = NC_DOUBLE
00032 };
00033 
00034 #define ncBad_ncbyte ncBad_byte
00035 static const ncbyte ncBad_byte = NC_FILL_BYTE;
00036 static const char ncBad_char = NC_FILL_CHAR;
00037 static const short ncBad_short = NC_FILL_SHORT;
00038 static const nclong ncBad_nclong = FILL_LONG; // deprecated
00039 static const int ncBad_int = NC_FILL_INT;
00040 static const long ncBad_long = FILL_LONG; // deprecated
00041 static const float ncBad_float = NC_FILL_FLOAT;
00042 static const double ncBad_double = NC_FILL_DOUBLE;
00043 
00044 // macros to glue tokens together to form new names (used to be in generic.h)
00045 #define name2(a,b) a ## b
00046 #define declare(clas,t)        name2(clas,declare)(t)
00047 #define implement(clas,t)      name2(clas,implement)(t)
00048 // This is the same as the name2 macro, but we need to define our own
00049 // version since rescanning something generated with the name2 macro
00050 // won't necessarily cause name2 to be expanded again.
00051 #define makename2(z, y)         makename2_x(z, y)
00052 #define makename2_x(z, y)               z##y
00053 
00054 #define NcVal(TYPE) makename2(NcValues_,TYPE)
00055 
00056 #define NcValuesdeclare(TYPE)                                                 \
00057 class NcVal(TYPE) : public NcValues                                           \
00058 {                                                                             \
00059   public:                                                                     \
00060     NcVal(TYPE)( void );                                                      \
00061     NcVal(TYPE)(long num);                                                    \
00062     NcVal(TYPE)(long num, const TYPE* vals);                                  \
00063     NcVal(TYPE)(const NcVal(TYPE)&);                                          \
00064     virtual NcVal(TYPE)& operator=(const NcVal(TYPE)&);                       \
00065     virtual ~NcVal(TYPE)( void );                                             \
00066     virtual void* base( void ) const;                                         \
00067     virtual int bytes_for_one( void ) const;                                  \
00068     virtual ncbyte as_ncbyte( long n ) const;                                 \
00069     virtual char as_char( long n ) const;                                     \
00070     virtual short as_short( long n ) const;                                   \
00071     virtual int as_int( long n ) const;                               \
00072     virtual int as_nclong( long n ) const;                                    \
00073     virtual long as_long( long n ) const;                                     \
00074     virtual float as_float( long n ) const;                                   \
00075     virtual double as_double( long n ) const;                                 \
00076     virtual char* as_string( long n ) const;                                  \
00077     virtual int invalid( void ) const;                                        \
00078   private:                                                                    \
00079     TYPE* the_values;                                                         \
00080     std::ostream& print(std::ostream&) const;                                         \
00081 };
00082 
00083 #define NcTypeEnum(TYPE) makename2(_nc__,TYPE)
00084 #define _nc__ncbyte ncByte
00085 #define _nc__char ncChar
00086 #define _nc__short ncShort
00087 #define _nc__int ncInt
00088 #define _nc__nclong ncLong
00089 #define _nc__long ncLong
00090 #define _nc__float ncFloat
00091 #define _nc__double ncDouble
00092 #define NcValuesimplement(TYPE)                                               \
00093 NcVal(TYPE)::NcVal(TYPE)( void )                                              \
00094         : NcValues(NcTypeEnum(TYPE), 0), the_values(0)                        \
00095 {}                                                                            \
00096                                                                               \
00097 NcVal(TYPE)::NcVal(TYPE)(long num, const TYPE* vals)                          \
00098         : NcValues(NcTypeEnum(TYPE), num)                                     \
00099 {                                                                             \
00100     the_values = new TYPE[num];                                               \
00101     for(int i = 0; i < num; i++)                                              \
00102       the_values[i] = vals[i];                                                \
00103 }                                                                             \
00104                                                                               \
00105 NcVal(TYPE)::NcVal(TYPE)(long num)                                            \
00106         : NcValues(NcTypeEnum(TYPE), num), the_values(new TYPE[num])          \
00107 {}                                                                            \
00108                                                                               \
00109 NcVal(TYPE)::NcVal(TYPE)(const NcVal(TYPE)& v) :                              \
00110     NcValues(v)                                                               \
00111 {                                                                             \
00112     delete[] the_values;                                                      \
00113     the_values = new TYPE[v.the_number];                                      \
00114     for(int i = 0; i < v.the_number; i++)                                     \
00115       the_values[i] = v.the_values[i];                                        \
00116 }                                                                             \
00117                                                                               \
00118 NcVal(TYPE)& NcVal(TYPE)::operator=(const NcVal(TYPE)& v)                     \
00119 {                                                                             \
00120     if ( &v != this) {                                                        \
00121       NcValues::operator=(v);                                                   \
00122       delete[] the_values;                                                    \
00123       the_values = new TYPE[v.the_number];                                    \
00124       for(int i = 0; i < v.the_number; i++)                                   \
00125         the_values[i] = v.the_values[i];                                      \
00126     }                                                                         \
00127     return *this;                                                             \
00128 }                                                                             \
00129                                                                               \
00130 void* NcVal(TYPE)::base( void ) const                                         \
00131 {                                                                             \
00132     return the_values;                                                        \
00133 }                                                                             \
00134                                                                               \
00135 NcVal(TYPE)::~NcVal(TYPE)( void )                                             \
00136 {                                                                             \
00137     delete[] the_values;                                                      \
00138 }                                                                             \
00139                                                                               \
00140 int NcVal(TYPE)::invalid( void ) const                                        \
00141 {                                                                             \
00142     for(int i=0;i<the_number;i++)                                             \
00143         if (the_values[i] == makename2(ncBad_,TYPE)) return 1;                \
00144     return 0;                                                                 \
00145 }                                                                             \
00146 
00147 
00148 #define Ncbytes_for_one_implement(TYPE)                                       \
00149 int NcVal(TYPE)::bytes_for_one( void ) const                                  \
00150 {                                                                             \
00151     return nctypelen((nc_type) NcTypeEnum(TYPE));                             \
00152 }
00153 
00154 #define as_ncbyte_implement(TYPE)                                             \
00155 ncbyte NcVal(TYPE)::as_ncbyte( long n ) const                                 \
00156 {                                                                             \
00157     if (the_values[n] < 0 || the_values[n] > UCHAR_MAX)                       \
00158       return ncBad_byte;                                                      \
00159     return (ncbyte) the_values[n];                                            \
00160 }
00161 
00162 #define as_char_implement(TYPE)                                               \
00163 char NcVal(TYPE)::as_char( long n ) const                                     \
00164 {                                                                             \
00165     if (the_values[n] < CHAR_MIN || the_values[n] > CHAR_MAX)                 \
00166       return ncBad_char;                                                      \
00167     return (char) the_values[n];                                              \
00168 }
00169 
00170 #define as_short_implement(TYPE)                                              \
00171 short NcVal(TYPE)::as_short( long n ) const                                   \
00172 {                                                                             \
00173     if (the_values[n] < SHRT_MIN || the_values[n] > SHRT_MAX)                 \
00174       return ncBad_short;                                                     \
00175     return (short) the_values[n];                                             \
00176 }
00177 
00178 #define NCINT_MIN INT_MIN
00179 #define NCINT_MAX INT_MAX
00180 #define as_int_implement(TYPE)                                        \
00181 int NcVal(TYPE)::as_int( long n ) const                               \
00182 {                                                                             \
00183     if (the_values[n] < NCINT_MIN || the_values[n] > NCINT_MAX)       \
00184       return ncBad_int;                                               \
00185     return (int) the_values[n];                                       \
00186 }
00187 
00188 #define NCLONG_MIN INT_MIN
00189 #define NCLONG_MAX INT_MAX
00190 #define as_nclong_implement(TYPE)                                             \
00191 nclong NcVal(TYPE)::as_nclong( long n ) const                                 \
00192 {                                                                             \
00193     if (the_values[n] < NCLONG_MIN || the_values[n] > NCLONG_MAX)             \
00194       return ncBad_nclong;                                                    \
00195     return (nclong) the_values[n];                                            \
00196 }
00197 
00198 #define as_long_implement(TYPE)                                               \
00199 long NcVal(TYPE)::as_long( long n ) const                                     \
00200 {                                                                             \
00201     if (the_values[n] < LONG_MIN || the_values[n] > LONG_MAX)                 \
00202       return ncBad_long;                                                      \
00203     return (long) the_values[n];                                              \
00204 }
00205 
00206 #define as_float_implement(TYPE)                                              \
00207 inline float NcVal(TYPE)::as_float( long n ) const                            \
00208 {                                                                             \
00209     return (float) the_values[n];                                             \
00210 }
00211 
00212 #define as_double_implement(TYPE)                                             \
00213 inline double NcVal(TYPE)::as_double( long n ) const                          \
00214 {                                                                             \
00215     return (double) the_values[n];                                            \
00216 }
00217 
00218 #define as_string_implement(TYPE)                                             \
00219 char* NcVal(TYPE)::as_string( long n ) const                                  \
00220 {                                                                             \
00221     char* s = new char[32];                                                   \
00222     std::ostringstream ostr;                                                  \
00223     ostr << the_values[n];                                            \
00224     ostr.str().copy(s, std::string::npos);                                               \
00225     s[ostr.str().length()] = 0;                                                     \
00226     return s;                                                                 \
00227 }
00228 
00229 class NcValues                  // ABC for value blocks
00230 {
00231   public:
00232     NcValues( void );
00233     NcValues(NcType, long);
00234     virtual ~NcValues( void );
00235     virtual long num( void );
00236     virtual std::ostream& print(std::ostream&) const = 0;
00237     virtual void* base( void ) const = 0;
00238     virtual int bytes_for_one( void ) const = 0;
00239 
00240     // The following member functions provide conversions from the value
00241     // type to a desired basic type.  If the value is out of range, the
00242     // default "fill-value" for the appropriate type is returned.
00243     virtual ncbyte as_ncbyte( long n ) const = 0; // nth value as a byte
00244     virtual char as_char( long n ) const = 0;     // nth value as char
00245     virtual short as_short( long n ) const = 0;   // nth value as short
00246     virtual int    as_int( long n ) const = 0;    // nth value as int
00247     virtual int    as_nclong( long n ) const = 0; // nth value as nclong
00248     virtual long as_long( long n ) const = 0;     // nth value as long
00249     virtual float as_float( long n ) const = 0;   // nth value as floating-point
00250     virtual double as_double( long n ) const = 0; // nth value as double
00251     virtual char* as_string( long n ) const = 0;  // value as string
00252     
00253   protected:
00254     NcType the_type;
00255     long the_number;
00256     friend std::ostream& operator<< (std::ostream&, const NcValues&);
00257 };
00258 
00259 declare(NcValues,ncbyte)
00260 declare(NcValues,char)
00261 declare(NcValues,short)
00262 declare(NcValues,int)
00263 declare(NcValues,nclong)
00264 declare(NcValues,long)
00265 declare(NcValues,float)
00266 declare(NcValues,double)
00267 
00268 #endif

Generated on Thu Mar 16 18:10:07 2006 for nco by  doxygen 1.4.4