00001
00002
00003
00004
00005
00006
00007
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,
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;
00039 static const int ncBad_int = NC_FILL_INT;
00040 static const long ncBad_long = FILL_LONG;
00041 static const float ncBad_float = NC_FILL_FLOAT;
00042 static const double ncBad_double = NC_FILL_DOUBLE;
00043
00044
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
00049
00050
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
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
00241
00242
00243 virtual ncbyte as_ncbyte( long n ) const = 0;
00244 virtual char as_char( long n ) const = 0;
00245 virtual short as_short( long n ) const = 0;
00246 virtual int as_int( long n ) const = 0;
00247 virtual int as_nclong( long n ) const = 0;
00248 virtual long as_long( long n ) const = 0;
00249 virtual float as_float( long n ) const = 0;
00250 virtual double as_double( long n ) const = 0;
00251 virtual char* as_string( long n ) const = 0;
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