1 /********************************************************************* 2 * Copyright 1992, University Corporation for Atmospheric Research 3 * See netcdf/README file for copying and redistribution conditions. 4 * 5 * Purpose: C++ class interface for netCDF 6 * 7 * $Header: /upc/share/CVS/netcdf-3/cxx/netcdfcpp.h,v 1.15 2009/03/10 15:20:54 russ Exp $ 8 *********************************************************************/ 9 10 #ifndef NETCDF_HH 11 #define NETCDF_HH 12 13 #include "ncvalues.h" // arrays that know their element type 14 15 typedef const char* NcToken; // names for netCDF objects 16 typedef unsigned int NcBool; // many members return 0 on failure 17 18 class MSCPP_EXTRA NcDim; // dimensions 19 class MSCPP_EXTRA NcVar; // variables 20 class MSCPP_EXTRA NcAtt; // attributes 21 class MSCPP_EXTRA NcError; 22 23 /* 24 * *********************************************************************** 25 * A netCDF file. 26 * *********************************************************************** 27 */ 28 class MSCPP_EXTRA NcFile 29 { 30 public: 31 32 virtual ~NcFile( void ); 33 34 enum FileMode { 35 ReadOnly, // file exists, open read-only 36 Write, // file exists, open for writing 37 Replace, // create new file, even if already exists 38 New // create new file, fail if already exists 39 }; 40 41 enum FileFormat { 42 Classic, // netCDF classic format (i.e. version 1 format) 43 Offset64Bits, // netCDF 64-bit offset format 44 Netcdf4, // netCDF-4 using HDF5 format 45 Netcdf4Classic, // netCDF-4 using HDF5 format using only netCDF-3 calls 46 BadFormat 47 }; 48 49 NcFile( const char * path, FileMode = ReadOnly , 50 size_t *bufrsizeptr = NULL, // optional tuning parameters 51 size_t initialsize = 0, 52 FileFormat = Classic ); 53 54 NcBool is_valid( void ) const; // opened OK in ctr, still valid 55 56 int num_dims( void ) const; // number of dimensions 57 int num_vars( void ) const; // number of variables 58 int num_atts( void ) const; // number of (global) attributes 59 60 NcDim* get_dim( NcToken ) const; // dimension by name 61 NcVar* get_var( NcToken ) const; // variable by name 62 NcAtt* get_att( NcToken ) const; // global attribute by name 63 64 NcDim* get_dim( int ) const; // n-th dimension 65 NcVar* get_var( int ) const; // n-th variable 66 NcAtt* get_att( int ) const; // n-th global attribute 67 NcDim* rec_dim( void ) const; // unlimited dimension, if any 68 69 // Add new dimensions, variables, global attributes. 70 // These put the file in "define" mode, so could be expensive. 71 virtual NcDim* add_dim( NcToken dimname, long dimsize ); 72 virtual NcDim* add_dim( NcToken dimname ); // unlimited 73 74 virtual NcVar* add_var( NcToken varname, NcType type, // scalar 75 const NcDim* dim0=0, // 1-dim 76 const NcDim* dim1=0, // 2-dim 77 const NcDim* dim2=0, // 3-dim 78 const NcDim* dim3=0, // 4-dim 79 const NcDim* dim4=0 ); // 5-dim 80 virtual NcVar* add_var( NcToken varname, NcType type, // n-dim 81 int ndims, const NcDim** dims ); 82 83 NcBool add_att( NcToken attname, char ); // scalar attributes 84 NcBool add_att( NcToken attname, ncbyte ); 85 NcBool add_att( NcToken attname, short ); 86 NcBool add_att( NcToken attname, long ); 87 NcBool add_att( NcToken attname, int ); 88 NcBool add_att( NcToken attname, float ); 89 NcBool add_att( NcToken attname, double ); 90 NcBool add_att( NcToken attname, const char*); // string attribute 91 NcBool add_att( NcToken attname, int, const char* ); // vector attributes 92 NcBool add_att( NcToken attname, int, const ncbyte* ); 93 NcBool add_att( NcToken attname, int, const short* ); 94 NcBool add_att( NcToken attname, int, const long* ); 95 NcBool add_att( NcToken attname, int, const int* ); 96 NcBool add_att( NcToken attname, int, const float* ); 97 NcBool add_att( NcToken attname, int, const double* ); 98 99 enum FillMode { 100 Fill = NC_FILL, // prefill (default) 101 NoFill = NC_NOFILL, // don't prefill 102 Bad 103 }; 104 105 NcBool set_fill( FillMode = Fill ); // set fill-mode 106 FillMode get_fill( void ) const; // get fill-mode 107 FileFormat get_format( void ) const; // get format version 108 109 NcBool sync( void ); // synchronize to disk 110 NcBool close( void ); // to close earlier than dtr 111 NcBool abort( void ); // back out of bad defines 112 113 // Needed by other Nc classes, but users will not need them 114 NcBool define_mode( void ); // leaves in define mode, if possible 115 NcBool data_mode( void ); // leaves in data mode, if possible 116 int id( void ) const; // id used by C interface 117 118 protected: 119 int the_id; 120 int in_define_mode; 121 FillMode the_fill_mode; 122 NcDim** dimensions; 123 NcVar** variables; 124 NcVar* globalv; // "variable" for global attributes 125 }; 126 127 /* 128 * For backward compatibility. We used to derive NcOldFile and NcNewFile 129 * from NcFile, but that was over-zealous inheritance. 130 */ 131 #define NcOldFile NcFile 132 #define NcNewFile NcFile 133 #define Clobber Replace 134 #define NoClobber New 135 136 /* 137 * ********************************************************************** 138 * A netCDF dimension, with a name and a size. These are only created 139 * by NcFile member functions, because they cannot exist independently 140 * of an open netCDF file. 141 * ********************************************************************** 142 */ 143 class MSCPP_EXTRA NcDim 144 { 145 public: 146 NcToken name( void ) const; 147 long size( void ) const; 148 NcBool is_valid( void ) const; 149 NcBool is_unlimited( void ) const; 150 NcBool rename( NcToken newname ); 151 int id( void ) const; 152 NcBool sync( void ); 153 154 private: 155 NcFile *the_file; // not const because of rename 156 int the_id; 157 char *the_name; 158 159 NcDim(NcFile*, int num); // existing dimension 160 NcDim(NcFile*, NcToken name, long sz); // defines a new dim 161 virtual ~NcDim( void ); 162 163 // to construct dimensions, since constructor is private 164 friend class NcFile; 165 }; 166 167 168 /* 169 * ********************************************************************** 170 * Abstract base class for a netCDF variable or attribute, both of which 171 * have a name, a type, and associated values. These only exist as 172 * components of an open netCDF file. 173 * ********************************************************************** 174 */ 175 class MSCPP_EXTRA NcTypedComponent 176 { 177 public: ~NcTypedComponent(void)178 virtual ~NcTypedComponent( void ) {} 179 virtual NcToken name( void ) const = 0; 180 virtual NcType type( void ) const = 0; 181 virtual NcBool is_valid( void ) const = 0; 182 virtual long num_vals( void ) const = 0; 183 virtual NcBool rename( NcToken newname ) = 0; 184 virtual NcValues* values( void ) const = 0; // block of all values 185 186 // The following member functions provide conversions from the value 187 // type to a desired basic type. If the value is out of range, 188 // the default "fill-value" for the appropriate type is returned. 189 190 virtual ncbyte as_ncbyte( long n ) const; // nth value as an unsgnd char 191 virtual char as_char( long n ) const; // nth value as char 192 virtual short as_short( long n ) const; // nth value as short 193 virtual int as_int( long n ) const; // nth value as int 194 virtual int as_nclong( long n ) const; // nth value as nclong (deprecated) 195 virtual long as_long( long n ) const; // nth value as long 196 virtual float as_float( long n ) const; // nth value as floating-point 197 virtual double as_double( long n ) const; // nth value as double 198 virtual char* as_string( long n ) const; // nth value as string 199 200 protected: 201 NcFile *the_file; 202 NcTypedComponent( NcFile* ); 203 virtual NcValues* get_space( long numVals = 0 ) const; // to hold values 204 }; 205 206 207 /* 208 * ********************************************************************** 209 * netCDF variables. In addition to a name and a type, these also have 210 * a shape, given by a list of dimensions 211 * ********************************************************************** 212 */ 213 class MSCPP_EXTRA NcVar : public NcTypedComponent 214 { 215 public: 216 virtual ~NcVar( void ); 217 NcToken name( void ) const; 218 NcType type( void ) const; 219 NcBool is_valid( void ) const; 220 int num_dims( void ) const; // dimensionality of variable 221 NcDim* get_dim( int ) const; // n-th dimension 222 size_t* edges( void ) const; // dimension sizes 223 int num_atts( void ) const; // number of attributes 224 NcAtt* get_att( NcToken ) const; // attribute by name 225 NcAtt* get_att( int ) const; // n-th attribute 226 long num_vals( void ) const; // product of dimension sizes 227 NcValues* values( void ) const; // all values 228 229 // Put scalar or 1, ..., 5 dimensional arrays by providing enough 230 // arguments. Arguments are edge lengths, and their number must not 231 // exceed variable's dimensionality. Start corner is [0,0,..., 0] by 232 // default, but may be reset using the set_cur() member. FALSE is 233 // returned if type of values does not match type for variable. 234 NcBool put( const ncbyte* vals, 235 long c0=0, long c1=0, long c2=0, long c3=0, long c4=0 ); 236 NcBool put( const char* vals, 237 long c0=0, long c1=0, long c2=0, long c3=0, long c4=0 ); 238 NcBool put( const short* vals, 239 long c0=0, long c1=0, long c2=0, long c3=0, long c4=0 ); 240 NcBool put( const int* vals, 241 long c0=0, long c1=0, long c2=0, long c3=0, long c4=0 ); 242 NcBool put( const long* vals, 243 long c0=0, long c1=0, long c2=0, long c3=0, long c4=0 ); 244 NcBool put( const float* vals, 245 long c0=0, long c1=0, long c2=0, long c3=0, long c4=0 ); 246 NcBool put( const double* vals, 247 long c0=0, long c1=0, long c2=0, long c3=0, long c4=0 ); 248 249 // Put n-dimensional arrays, starting at [0, 0, ..., 0] by default, 250 // may be reset with set_cur(). 251 NcBool put( const ncbyte* vals, const size_t* counts ); 252 NcBool put( const char* vals, const size_t* counts ); 253 NcBool put( const short* vals, const size_t* counts ); 254 NcBool put( const int* vals, const size_t* counts ); 255 NcBool put( const long* vals, const size_t* counts ); 256 NcBool put( const float* vals, const size_t* counts ); 257 NcBool put( const double* vals, const size_t* counts ); 258 259 // Get scalar or 1, ..., 5 dimensional arrays by providing enough 260 // arguments. Arguments are edge lengths, and their number must not 261 // exceed variable's dimensionality. Start corner is [0,0,..., 0] by 262 // default, but may be reset using the set_cur() member. 263 NcBool get( ncbyte* vals, long c0=0, long c1=0, 264 long c2=0, long c3=0, long c4=0 ) const; 265 NcBool get( char* vals, long c0=0, long c1=0, 266 long c2=0, long c3=0, long c4=0 ) const; 267 NcBool get( short* vals, long c0=0, long c1=0, 268 long c2=0, long c3=0, long c4=0 ) const; 269 NcBool get( int* vals, long c0=0, long c1=0, 270 long c2=0, long c3=0, long c4=0 ) const; 271 NcBool get( long* vals, long c0=0, long c1=0, 272 long c2=0, long c3=0, long c4=0 ) const; 273 NcBool get( float* vals, long c0=0, long c1=0, 274 long c2=0, long c3=0, long c4=0 ) const; 275 NcBool get( double* vals, long c0=0, long c1=0, 276 long c2=0, long c3=0, long c4=0 ) const; 277 278 // Get n-dimensional arrays, starting at [0, 0, ..., 0] by default, 279 // may be reset with set_cur(). 280 NcBool get( ncbyte* vals, const size_t* counts ) const; 281 NcBool get( char* vals, const size_t* counts ) const; 282 NcBool get( short* vals, const size_t* counts ) const; 283 NcBool get( int* vals, const size_t* counts ) const; 284 NcBool get( long* vals, const size_t* counts ) const; 285 NcBool get( float* vals, const size_t* counts ) const; 286 NcBool get( double* vals, const size_t* counts ) const; 287 288 NcBool set_cur(long c0=-1, long c1=-1, long c2=-1, 289 long c3=-1, long c4=-1); 290 NcBool set_cur(long* cur); 291 292 // these put file in define mode, so could be expensive 293 NcBool add_att( NcToken, char ); // add scalar attributes 294 NcBool add_att( NcToken, ncbyte ); 295 NcBool add_att( NcToken, short ); 296 NcBool add_att( NcToken, int ); 297 NcBool add_att( NcToken, long ); 298 NcBool add_att( NcToken, float ); 299 NcBool add_att( NcToken, double ); 300 NcBool add_att( NcToken, const char* ); // string attribute 301 NcBool add_att( NcToken, int, const char* ); // vector attributes 302 NcBool add_att( NcToken, int, const ncbyte* ); 303 NcBool add_att( NcToken, int, const short* ); 304 NcBool add_att( NcToken, int, const int* ); 305 NcBool add_att( NcToken, int, const long* ); 306 NcBool add_att( NcToken, int, const float* ); 307 NcBool add_att( NcToken, int, const double* ); 308 309 NcBool rename( NcToken newname ); 310 311 long rec_size ( void ); // number of values per record 312 long rec_size ( NcDim* ); // number of values per dimension slice 313 314 // Though following are intended for record variables, they also work 315 // for other variables, using first dimension as record dimension. 316 317 // Get a record's worth of data 318 NcValues *get_rec(void); // get current record 319 NcValues *get_rec(long rec); // get specified record 320 NcValues *get_rec(NcDim* d); // get current dimension slice 321 NcValues *get_rec(NcDim* d, long slice); // get specified dimension slice 322 323 // Put a record's worth of data in current record 324 NcBool put_rec( const ncbyte* vals ); 325 NcBool put_rec( const char* vals ); 326 NcBool put_rec( const short* vals ); 327 NcBool put_rec( const int* vals ); 328 NcBool put_rec( const long* vals ); 329 NcBool put_rec( const float* vals ); 330 NcBool put_rec( const double* vals ); 331 332 // Put a dimension slice worth of data in current dimension slice 333 NcBool put_rec( NcDim* d, const ncbyte* vals ); 334 NcBool put_rec( NcDim* d, const char* vals ); 335 NcBool put_rec( NcDim* d, const short* vals ); 336 NcBool put_rec( NcDim* d, const int* vals ); 337 NcBool put_rec( NcDim* d, const long* vals ); 338 NcBool put_rec( NcDim* d, const float* vals ); 339 NcBool put_rec( NcDim* d, const double* vals ); 340 341 // Put a record's worth of data in specified record 342 NcBool put_rec( const ncbyte* vals, long rec ); 343 NcBool put_rec( const char* vals, long rec ); 344 NcBool put_rec( const short* vals, long rec ); 345 NcBool put_rec( const int* vals, long rec ); 346 NcBool put_rec( const long* vals, long rec ); 347 NcBool put_rec( const float* vals, long rec ); 348 NcBool put_rec( const double* vals, long rec ); 349 350 // Put a dimension slice worth of data in specified dimension slice 351 NcBool put_rec( NcDim* d, const ncbyte* vals, long slice ); 352 NcBool put_rec( NcDim* d, const char* vals, long slice ); 353 NcBool put_rec( NcDim* d, const short* vals, long slice ); 354 NcBool put_rec( NcDim* d, const int* vals, long slice ); 355 NcBool put_rec( NcDim* d, const long* vals, long slice ); 356 NcBool put_rec( NcDim* d, const float* vals, long slice ); 357 NcBool put_rec( NcDim* d, const double* vals, long slice ); 358 359 // Get first record index corresponding to specified key value(s) 360 long get_index( const ncbyte* vals ); 361 long get_index( const char* vals ); 362 long get_index( const short* vals ); 363 long get_index( const int* vals ); 364 long get_index( const long* vals ); 365 long get_index( const float* vals ); 366 long get_index( const double* vals ); 367 368 // Get first index of specified dimension corresponding to key values 369 long get_index( NcDim* d, const ncbyte* vals ); 370 long get_index( NcDim* d, const char* vals ); 371 long get_index( NcDim* d, const short* vals ); 372 long get_index( NcDim* d, const int* vals ); 373 long get_index( NcDim* d, const long* vals ); 374 long get_index( NcDim* d, const float* vals ); 375 long get_index( NcDim* d, const double* vals ); 376 377 // Set current record 378 void set_rec ( long rec ); 379 // Set current dimension slice 380 void set_rec ( NcDim* d, long slice ); 381 382 int id( void ) const; // rarely needed, C interface id 383 NcBool sync( void ); 384 385 private: 386 int dim_to_index(NcDim* rdim); 387 int the_id; 388 long* the_cur; 389 char* the_name; 390 long* cur_rec; 391 392 // private constructors because only an NcFile creates these 393 NcVar( void ); 394 NcVar(NcFile*, int); 395 396 int attnum( NcToken attname ) const; 397 NcToken attname( int attnum ) const; 398 void init_cur( void ); 399 400 // to make variables, since constructor is private 401 friend class NcFile; 402 }; 403 404 405 /* 406 * ********************************************************************** 407 * netCDF attributes. In addition to a name and a type, these are each 408 * associated with a specific variable, or are global to the file. 409 * ********************************************************************** 410 */ 411 class MSCPP_EXTRA NcAtt : public NcTypedComponent 412 { 413 public: 414 virtual ~NcAtt( void ); 415 NcToken name( void ) const; 416 NcType type( void ) const; 417 NcBool is_valid( void ) const; 418 long num_vals( void ) const; 419 NcValues* values( void ) const; 420 NcBool rename( NcToken newname ); 421 NcBool remove( void ); 422 423 private: 424 const NcVar* the_variable; 425 char* the_name; 426 // protected constructors because only NcVars and NcFiles create 427 // attributes 428 NcAtt( NcFile*, const NcVar*, NcToken); 429 NcAtt( NcFile*, NcToken); // global attribute 430 431 // To make attributes, since constructor is private 432 friend class NcFile; 433 friend NcAtt* NcVar::get_att( NcToken ) const; 434 }; 435 436 437 /* 438 * ********************************************************************** 439 * To control error handling. Declaring an NcError object temporarily 440 * changes the error-handling behavior until the object is destroyed, at 441 * which time the previous error-handling behavior is restored. 442 * ********************************************************************** 443 */ 444 class MSCPP_EXTRA NcError { 445 public: 446 enum Behavior { 447 silent_nonfatal = 0, 448 silent_fatal = 1, 449 verbose_nonfatal = 2, 450 verbose_fatal = 3 451 }; 452 453 // constructor saves previous error state, sets new state 454 NcError( Behavior b = verbose_fatal ); 455 456 // destructor restores previous error state 457 virtual ~NcError( void ); 458 459 int get_err( void ); // returns most recent error number get_errmsg(void)460 const char* get_errmsg( void ) {return nc_strerror(get_err());} 461 static int set_err( int err ); 462 463 private: 464 int the_old_state; 465 int the_old_err; 466 static int ncopts; 467 static int ncerr; 468 }; 469 470 #endif /* NETCDF_HH */ 471