/[escript]/trunk/escript/src/netcdf.cpp
ViewVC logotype

Contents of /trunk/escript/src/netcdf.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1128 - (show annotations)
Tue May 8 04:22:53 2007 UTC (12 years, 3 months ago) by gross
File size: 42378 byte(s)


1 /*********************************************************************
2 * Copyright 1992, University Corporation for Atmospheric Research
3 * See netcdf/README file for copying and redistribution conditions.
4 *
5 * Purpose: Implements class interface for netCDF over C interface
6 *
7 * $Header: /upc/share/CVS/netcdf-3/cxx/netcdf.cpp,v 1.15 2006/12/29 16:38:46 ed Exp $
8 *********************************************************************/
9
10 // #include <config.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include <iostream>
14 #include "netcdfcpp.h"
15
16 #ifndef TRUE
17 #define TRUE 1
18 #define FALSE 0
19 #endif
20
21 static const int ncGlobal = NC_GLOBAL; // psuedo-variable for global attributes
22
23 static const int ncBad = -1; // failure return for netCDF C interface
24
25 NcFile::~NcFile( void )
26 {
27 (void) close();
28 }
29
30 NcBool NcFile::is_valid( void ) const
31 {
32 return the_id != ncBad;
33 }
34
35 int NcFile::num_dims( void ) const
36 {
37 int num = 0;
38 if (is_valid())
39 NcError::set_err(
40 nc_inq_ndims(the_id, &num)
41 );
42 return num;
43 }
44
45 int NcFile::num_vars( void ) const
46 {
47 int num = 0;
48 if (is_valid())
49 NcError::set_err(
50 nc_inq_nvars(the_id, &num)
51 );
52 return num;
53 }
54
55 int NcFile::num_atts( void ) const
56 {
57 int num = 0;
58 if (is_valid())
59 NcError::set_err(
60 nc_inq_natts(the_id, &num)
61 );
62 return num;
63 }
64
65 NcDim* NcFile::get_dim( NcToken name ) const
66 {
67 int dimid;
68 if(NcError::set_err(
69 nc_inq_dimid(the_id, name, &dimid)
70 ) != NC_NOERR)
71 return 0;
72 return get_dim(dimid);
73 }
74
75 NcVar* NcFile::get_var( NcToken name ) const
76 {
77 int varid;
78 if(NcError::set_err(
79 nc_inq_varid(the_id, name, &varid)
80 ) != NC_NOERR)
81 return 0;
82 return get_var(varid);
83 }
84
85 NcAtt* NcFile::get_att( NcToken aname ) const
86 {
87 return is_valid() ? globalv->get_att(aname) : 0;
88 }
89
90 NcDim* NcFile::get_dim( int i ) const
91 {
92 if (! is_valid() || i < 0 || i >= num_dims())
93 return 0;
94 return dimensions[i];
95 }
96
97 NcVar* NcFile::get_var( int i ) const
98 {
99 if (! is_valid() || i < 0 || i >= num_vars())
100 return 0;
101 return variables[i];
102 }
103
104 NcAtt* NcFile::get_att( int n ) const
105 {
106 return is_valid() ? globalv->get_att(n) : 0;
107 }
108
109 NcDim* NcFile::rec_dim( ) const
110 {
111 if (! is_valid())
112 return 0;
113 int recdim;
114 if(NcError::set_err(
115 nc_inq_unlimdim(the_id, &recdim)
116 ) != NC_NOERR)
117 return 0;
118 return get_dim(recdim);
119 }
120
121 NcDim* NcFile::add_dim(NcToken name, long size)
122 {
123 if (!is_valid() || !define_mode())
124 return 0;
125 int n = num_dims();
126 NcDim* dimp = new NcDim(this, name, size);
127 dimensions[n] = dimp; // for garbage collection on close()
128 return dimp;
129 }
130
131 NcDim* NcFile::add_dim(NcToken name)
132 {
133 return add_dim(name, NC_UNLIMITED);
134 }
135
136 // To create scalar, 1-dimensional, ..., 5-dimensional variables, just supply
137 // as many dimension arguments as necessary
138
139 NcVar* NcFile::add_var(NcToken name, NcType type, // scalar to 5D var
140 const NcDim* dim0,
141 const NcDim* dim1,
142 const NcDim* dim2,
143 const NcDim* dim3,
144 const NcDim* dim4)
145 {
146 if (!is_valid() || !define_mode())
147 return 0;
148 int dims[5];
149 int ndims = 0;
150 if (dim0) {
151 ndims++;
152 dims[0] = dim0->id();
153 if (dim1) {
154 ndims++;
155 dims[1] = dim1->id();
156 if (dim2) {
157 ndims++;
158 dims[2] = dim2->id();
159 if (dim3) {
160 ndims++;
161 dims[3] = dim3->id();
162 if (dim4) {
163 ndims++;
164 dims[4] = dim4->id();
165 }
166 }
167 }
168 }
169 }
170 int n = num_vars();
171 int varid;
172 if(NcError::set_err(
173 nc_def_var(the_id, name, (nc_type) type, ndims, dims, &varid)
174 ) != NC_NOERR)
175 return 0;
176 NcVar* varp =
177 new NcVar(this, varid);
178 variables[n] = varp;
179 return varp;
180 }
181
182 // For variables with more than 5 dimensions, use n-dimensional interface
183 // with vector of dimensions.
184
185 NcVar* NcFile::add_var(NcToken name, NcType type, int ndims, const NcDim** dims)
186 {
187 if (!is_valid() || !define_mode())
188 return 0;
189 int* dimids = new int[ndims];
190 for (int i=0; i < ndims; i++)
191 dimids[i] = dims[i]->id();
192 int n = num_vars();
193 int varid;
194 if(NcError::set_err(
195 nc_def_var(the_id, name, (nc_type) type, ndims, dimids, &varid)
196 ) != NC_NOERR)
197 return 0;
198 NcVar* varp =
199 new NcVar(this, varid);
200 variables[n] = varp;
201 delete [] dimids;
202 return varp;
203 }
204
205 #define NcFile_add_scalar_att(TYPE) \
206 NcBool NcFile::add_att(NcToken aname, TYPE val) \
207 { \
208 return globalv->add_att(aname, val); \
209 }
210
211 NcFile_add_scalar_att(char)
212 NcFile_add_scalar_att(ncbyte)
213 NcFile_add_scalar_att(short)
214 NcFile_add_scalar_att(int)
215 NcFile_add_scalar_att(long)
216 NcFile_add_scalar_att(float)
217 NcFile_add_scalar_att(double)
218 NcFile_add_scalar_att(const char*)
219
220 #define NcFile_add_vector_att(TYPE) \
221 NcBool NcFile::add_att(NcToken aname, int n, const TYPE* val) \
222 { \
223 return globalv->add_att(aname, n, val); \
224 }
225
226 NcFile_add_vector_att(char)
227 NcFile_add_vector_att(ncbyte)
228 NcFile_add_vector_att(short)
229 NcFile_add_vector_att(int)
230 NcFile_add_vector_att(long)
231 NcFile_add_vector_att(float)
232 NcFile_add_vector_att(double)
233
234 NcBool NcFile::set_fill( FillMode a_mode )
235 {
236 int prev_mode;
237 if (NcError::set_err(
238 nc_set_fill(the_id, a_mode, &prev_mode)
239 ) == NC_NOERR) {
240 the_fill_mode = a_mode;
241 return TRUE;
242 }
243 return FALSE;
244 }
245
246 NcFile::FillMode NcFile::get_fill( void ) const
247 {
248 return the_fill_mode;
249 }
250
251 NcFile::FileFormat NcFile::get_format( void ) const
252 {
253 int the_format;
254 NcError::set_err(
255 nc_inq_format(the_id, &the_format)
256 );
257 switch (the_format) {
258 case NC_FORMAT_CLASSIC:
259 return Classic;
260 case NC_FORMAT_64BIT:
261 return Offset64Bits;
262 case NC_FORMAT_NETCDF4:
263 return Netcdf4;
264 case NC_FORMAT_NETCDF4_CLASSIC:
265 return Netcdf4Classic;
266 default:
267 return BadFormat;
268 }
269 }
270
271 NcBool NcFile::sync( void )
272 {
273 if (!data_mode())
274 return 0;
275 if (NcError::set_err(
276 nc_sync(the_id)
277 ) != NC_NOERR)
278 return 0;
279 int i;
280 for (i = 0; i < num_dims(); i++) {
281 if (dimensions[i]->is_valid()) {
282 dimensions[i]->sync();
283 } else { // someone else added a new dimension
284 dimensions[i] = new NcDim(this,i);
285 }
286 }
287 for (i = 0; i < num_vars(); i++) {
288 if (variables[i]->is_valid()) {
289 variables[i]->sync();
290 } else { // someone else added a new variable
291 variables[i] = new NcVar(this,i);
292 }
293 }
294 return 1;
295 }
296
297 NcBool NcFile::close( void )
298 {
299 int i;
300
301 if (the_id == ncBad)
302 return 0;
303 for (i = 0; i < num_dims(); i++)
304 delete dimensions[i];
305 for (i = 0; i < num_vars(); i++)
306 delete variables[i];
307 delete [] dimensions;
308 delete [] variables;
309 delete globalv;
310 int old_id = the_id;
311 the_id = ncBad;
312 return NcError::set_err(
313 nc_close(old_id)
314 ) == NC_NOERR;
315 }
316
317 NcBool NcFile::abort( void )
318 {
319 return NcError::set_err(
320 nc_abort(the_id)
321 ) == NC_NOERR;
322 }
323
324 NcBool NcFile::define_mode( void )
325 {
326 if (! is_valid())
327 return FALSE;
328 if (in_define_mode)
329 return TRUE;
330 if (NcError::set_err(
331 nc_redef(the_id)
332 ) != NC_NOERR)
333 return FALSE;
334 in_define_mode = 1;
335 return TRUE;
336 }
337
338 NcBool NcFile::data_mode( void )
339 {
340 if (! is_valid())
341 return FALSE;
342 if (! in_define_mode)
343 return TRUE;
344 if (NcError::set_err(
345 nc_enddef(the_id)
346 ) != NC_NOERR)
347 return FALSE;
348 in_define_mode = 0;
349 return TRUE;
350 }
351
352 int NcFile::id( void ) const
353 {
354 return the_id;
355 }
356
357 NcFile::NcFile( const char* path, FileMode fmode,
358 size_t* chunksizeptr, size_t initialsize, FileFormat fformat )
359 {
360 NcError err(NcError::silent_nonfatal); // constructor must not fail
361
362 int mode = NC_NOWRITE;
363 the_fill_mode = Fill;
364 int status;
365
366 // If the user wants a 64-bit offset format, set that flag.
367 if (fformat == Offset64Bits)
368 mode |= NC_64BIT_OFFSET;
369 #ifdef USE_NETCDF4
370 else if (fformat == Netcdf4)
371 mode |= NC_NETCDF4;
372 else if (fformat == Netcdf4Classic)
373 mode |= NC_NETCDF4|NC_CLASSIC_MODEL;
374 #endif
375
376 switch (fmode) {
377 case Write:
378 mode = NC_WRITE;
379 /*FALLTHRU*/
380 case ReadOnly:
381 // use netcdf-3 interface to permit specifying tuning parameter
382 status = NcError::set_err(
383 nc__open(path, mode, chunksizeptr, &the_id)
384 );
385 if(status != NC_NOERR)
386 {
387 NcError::set_err(status);
388 the_id = -1;
389 }
390 in_define_mode = 0;
391 break;
392 case New:
393 mode = NC_NOCLOBBER;
394 /*FALLTHRU*/
395 case Replace:
396 // use netcdf-3 interface to permit specifying tuning parameters
397 status = NcError::set_err(
398 nc__create(path, mode, initialsize,
399 chunksizeptr, &the_id)
400 );
401 if(status != NC_NOERR)
402 {
403 NcError::set_err(status);
404 the_id = -1;
405 }
406 in_define_mode = 1;
407 break;
408 default:
409 the_id = ncBad;
410 in_define_mode = 0;
411 break;
412 }
413 if (is_valid()) {
414 dimensions = new NcDim*[NC_MAX_DIMS];
415 variables = new NcVar*[NC_MAX_VARS];
416 int i;
417 for (i = 0; i < num_dims(); i++)
418 dimensions[i] = new NcDim(this, i);
419 for (i = 0; i < num_vars(); i++)
420 variables[i] = new NcVar(this, i);
421 globalv = new NcVar(this, ncGlobal);
422 } else {
423 dimensions = 0;
424 variables = 0;
425 globalv = 0;
426 }
427 }
428
429 NcToken NcDim::name( void ) const
430 {
431 return the_name;
432 }
433
434 long NcDim::size( void ) const
435 {
436 size_t sz = 0;
437 if (the_file)
438 NcError::set_err(
439 nc_inq_dimlen(the_file->id(), the_id, &sz)
440 );
441 return sz;
442 }
443
444 NcBool NcDim::is_valid( void ) const
445 {
446 return the_file->is_valid() && the_id != ncBad;
447 }
448
449 NcBool NcDim::is_unlimited( void ) const
450 {
451 if (!the_file)
452 return FALSE;
453 int recdim;
454 NcError::set_err(
455 nc_inq_unlimdim(the_file->id(), &recdim)
456 );
457 return the_id == recdim;
458 }
459
460 NcBool NcDim::rename(NcToken newname)
461 {
462 if (strlen(newname) > strlen(the_name)) {
463 if (! the_file->define_mode())
464 return FALSE;
465 }
466 NcBool ret = NcError::set_err(
467 nc_rename_dim(the_file->id(), the_id, newname)
468 ) == NC_NOERR;
469 if (ret) {
470 delete [] the_name;
471 the_name = new char[1 + strlen(newname)];
472 strcpy(the_name, newname);
473 }
474 return ret;
475 }
476
477 int NcDim::id( void ) const
478 {
479 return the_id;
480 }
481
482 NcBool NcDim::sync(void)
483 {
484 char nam[NC_MAX_NAME];
485 if (the_name) {
486 delete [] the_name;
487 }
488 if (the_file && NcError::set_err(
489 nc_inq_dimname(the_file->id(), the_id, nam)
490 ) == NC_NOERR) {
491 the_name = new char[strlen(nam) + 1];
492 strcpy(the_name, nam);
493 return TRUE;
494 }
495 the_name = 0;
496 return FALSE;
497 }
498
499 NcDim::NcDim(NcFile* nc, int id)
500 : the_file(nc), the_id(id)
501 {
502 char nam[NC_MAX_NAME];
503 if (the_file && NcError::set_err(
504 nc_inq_dimname(the_file->id(), the_id, nam)
505 ) == NC_NOERR) {
506 the_name = new char[strlen(nam) + 1];
507 strcpy(the_name, nam);
508 } else {
509 the_name = 0;
510 }
511 }
512
513 NcDim::NcDim(NcFile* nc, NcToken name, long sz)
514 : the_file(nc)
515 {
516 size_t dimlen = sz;
517 if(NcError::set_err(
518 nc_def_dim(the_file->id(), name, dimlen, &the_id)
519 ) == NC_NOERR) {
520 the_name = new char[strlen(name) + 1];
521 strcpy(the_name, name);
522 } else {
523 the_name = 0;
524 }
525 }
526
527 NcDim::~NcDim( void )
528 {
529 delete [] the_name;
530 }
531
532 #define Nc_as(TYPE) name2(as_,TYPE)
533 #define NcTypedComponent_as(TYPE) \
534 TYPE NcTypedComponent::Nc_as(TYPE)( long n ) const \
535 { \
536 NcValues* tmp = values(); \
537 TYPE rval = tmp->Nc_as(TYPE)(n); \
538 delete tmp; \
539 return rval; \
540 }
541 NcTypedComponent_as(ncbyte)
542 NcTypedComponent_as(char)
543 NcTypedComponent_as(short)
544 NcTypedComponent_as(int)
545 NcTypedComponent_as(nclong)
546 NcTypedComponent_as(long)
547 NcTypedComponent_as(float)
548 NcTypedComponent_as(double)
549
550 char* NcTypedComponent::as_string( long n ) const
551 {
552 NcValues* tmp = values();
553 char* rval = tmp->as_string(n);
554 delete tmp;
555 return rval;
556 }
557
558 NcTypedComponent::NcTypedComponent ( NcFile* nc )
559 : the_file(nc)
560 {}
561
562 NcValues* NcTypedComponent::get_space( long numVals ) const
563 {
564 NcValues* valp;
565 if (numVals < 1)
566 numVals = num_vals();
567 switch (type()) {
568 case ncFloat:
569 valp = new NcValues_float(numVals);
570 break;
571 case ncDouble:
572 valp = new NcValues_double(numVals);
573 break;
574 case ncInt:
575 valp = new NcValues_int(numVals);
576 break;
577 case ncShort:
578 valp = new NcValues_short(numVals);
579 break;
580 case ncByte:
581 case ncChar:
582 valp = new NcValues_char(numVals);
583 break;
584 case ncNoType:
585 default:
586 valp = 0;
587 }
588 return valp;
589 }
590
591 NcVar::~NcVar( void )
592 {
593 delete[] the_cur;
594 delete[] cur_rec;
595 delete[] the_name;
596 }
597
598 NcToken NcVar::name( void ) const
599 {
600 return the_name;
601 }
602
603 NcType NcVar::type( void ) const
604 {
605 nc_type typ;
606 NcError::set_err(
607 nc_inq_vartype(the_file->id(), the_id, &typ)
608 );
609 return (NcType) typ;
610 }
611
612 NcBool NcVar::is_valid( void ) const
613 {
614 return the_file->is_valid() && the_id != ncBad;
615 }
616
617 int NcVar::num_dims( void ) const
618 {
619 int ndim;
620 NcError::set_err(
621 nc_inq_varndims(the_file->id(), the_id, &ndim)
622 );
623 return ndim;
624 }
625
626 // The i-th dimension for this variable
627 NcDim* NcVar::get_dim( int i ) const
628 {
629 int ndim;
630 int dims[NC_MAX_DIMS];
631 if(NcError::set_err(
632 nc_inq_var(the_file->id(), the_id, 0, 0, &ndim, dims, 0)
633 ) != NC_NOERR ||
634 i < 0 || i >= ndim)
635 return 0;
636 return the_file->get_dim(dims[i]);
637 }
638
639 long* NcVar::edges( void ) const // edge lengths (dimension sizes)
640 {
641 long* evec = new long[num_dims()];
642 for(int i=0; i < num_dims(); i++)
643 evec[i] = get_dim(i)->size();
644 return evec;
645 }
646
647 int NcVar::num_atts( void ) const // handles variable and global atts
648 {
649 int natt = 0;
650 if (the_file->is_valid())
651 if (the_id == ncGlobal)
652 natt = the_file->num_atts();
653 else
654 NcError::set_err(
655 nc_inq_varnatts(the_file->id(), the_id, &natt)
656 );
657 return natt;
658 }
659
660 NcAtt* NcVar::get_att( NcToken aname ) const
661 {
662 NcAtt* att = new NcAtt(the_file, this, aname);
663 if (! att->is_valid()) {
664 delete att;
665 return 0;
666 }
667 return att;
668 }
669
670 NcAtt* NcVar::get_att( int n ) const
671 {
672 if (n < 0 || n >= num_atts())
673 return 0;
674 NcToken aname = attname(n);
675 NcAtt* ap = get_att(aname);
676 delete [] (char*)aname;
677 return ap;
678 }
679
680 long NcVar::num_vals( void ) const
681 {
682 long prod = 1;
683 for (int d = 0; d < num_dims(); d++)
684 prod *= get_dim(d)->size();
685 return prod;
686 }
687
688 NcValues* NcVar::values( void ) const
689 {
690 int ndims = num_dims();
691 size_t crnr[NC_MAX_DIMS];
692 size_t edgs[NC_MAX_DIMS];
693 for (int i = 0; i < ndims; i++) {
694 crnr[i] = 0;
695 edgs[i] = get_dim(i)->size();
696 }
697 NcValues* valp = get_space();
698 int status;
699 switch (type()) {
700 case ncFloat:
701 status = NcError::set_err(
702 nc_get_vara_float(the_file->id(), the_id, crnr, edgs,
703 (float *)valp->base())
704 );
705 break;
706 case ncDouble:
707 status = NcError::set_err(
708 nc_get_vara_double(the_file->id(), the_id, crnr, edgs,
709 (double *)valp->base())
710 );
711 break;
712 case ncInt:
713 status = NcError::set_err(
714 nc_get_vara_int(the_file->id(), the_id, crnr, edgs,
715 (int *)valp->base())
716 );
717 break;
718 case ncShort:
719 status = NcError::set_err(
720 nc_get_vara_short(the_file->id(), the_id, crnr, edgs,
721 (short *)valp->base())
722 );
723 break;
724 case ncByte:
725 status = NcError::set_err(
726 nc_get_vara_schar(the_file->id(), the_id, crnr, edgs,
727 (signed char *)valp->base())
728 );
729 break;
730 case ncChar:
731 status = NcError::set_err(
732 nc_get_vara_text(the_file->id(), the_id, crnr, edgs,
733 (char *)valp->base())
734 );
735 break;
736 case ncNoType:
737 default:
738 return 0;
739 }
740 if (status != NC_NOERR)
741 return 0;
742 return valp;
743 }
744
745 int NcVar::dim_to_index(NcDim *rdim)
746 {
747 for (int i=0; i < num_dims() ; i++) {
748 if (strcmp(get_dim(i)->name(),rdim->name()) == 0) {
749 return i;
750 }
751 }
752 // we should fail and gripe about it here....
753 return -1;
754 }
755
756 void NcVar::set_rec(NcDim *rdim, long slice)
757 {
758 int i = dim_to_index(rdim);
759 // we should fail and gripe about it here....
760 if (slice >= get_dim(i)->size() && ! get_dim(i)->is_unlimited())
761 return;
762 cur_rec[i] = slice;
763 return;
764 }
765
766 void NcVar::set_rec(long rec)
767 {
768 // Since we can't ask for the record dimension here
769 // just assume [0] is it.....
770 set_rec(get_dim(0),rec);
771 return;
772 }
773
774 NcValues* NcVar::get_rec(void)
775 {
776 return get_rec(get_dim(0), cur_rec[0]);
777 }
778
779 NcValues* NcVar::get_rec(long rec)
780 {
781 return get_rec(get_dim(0), rec);
782 }
783
784 NcValues* NcVar::get_rec(NcDim* rdim, long slice)
785 {
786 int idx = dim_to_index(rdim);
787 long size = num_dims();
788 size_t* start = new size_t[size];
789 long* startl = new long[size];
790 for (int i=1; i < size ; i++) {
791 start[i] = 0;
792 startl[i] = 0;
793 }
794 start[idx] = slice;
795 startl[idx] = slice;
796 NcBool result = set_cur(startl);
797 if (! result ) {
798 delete [] start;
799 delete [] startl;
800 return 0;
801 }
802
803 long* edgel = edges();
804 size_t* edge = new size_t[size];
805 for (int i=1; i < size ; i++) {
806 edge[i] = edgel[i];
807 }
808 edge[idx] = 1;
809 edgel[idx] = 1;
810 NcValues* valp = get_space(rec_size(rdim));
811 int status;
812 switch (type()) {
813 case ncFloat:
814 status = NcError::set_err(
815 nc_get_vara_float(the_file->id(), the_id, start, edge,
816 (float *)valp->base())
817 );
818 break;
819 case ncDouble:
820 status = NcError::set_err(
821 nc_get_vara_double(the_file->id(), the_id, start, edge,
822 (double *)valp->base())
823 );
824 break;
825 case ncInt:
826 status = NcError::set_err(
827 nc_get_vara_int(the_file->id(), the_id, start, edge,
828 (int *)valp->base())
829 );
830 break;
831 case ncShort:
832 status = NcError::set_err(
833 nc_get_vara_short(the_file->id(), the_id, start, edge,
834 (short *)valp->base())
835 );
836 break;
837 case ncByte:
838 status = NcError::set_err(
839 nc_get_vara_schar(the_file->id(), the_id, start, edge,
840 (signed char *)valp->base())
841 );
842 break;
843 case ncChar:
844 status = NcError::set_err(
845 nc_get_vara_text(the_file->id(), the_id, start, edge,
846 (char *)valp->base())
847 );
848 break;
849 case ncNoType:
850 default:
851 return 0;
852 }
853 delete [] start;
854 delete [] startl;
855 delete [] edge;
856 delete [] edgel;
857 if (status != NC_NOERR) {
858 delete valp;
859 return 0;
860 }
861 return valp;
862 }
863
864
865 #define NcVar_put_rec(TYPE) \
866 NcBool NcVar::put_rec( const TYPE* vals) \
867 { \
868 return put_rec(get_dim(0), vals, cur_rec[0]); \
869 } \
870 \
871 NcBool NcVar::put_rec( NcDim *rdim, const TYPE* vals) \
872 { \
873 int idx = dim_to_index(rdim); \
874 return put_rec(rdim, vals, cur_rec[idx]); \
875 } \
876 \
877 NcBool NcVar::put_rec( const TYPE* vals, \
878 long rec) \
879 { \
880 return put_rec(get_dim(0), vals, rec); \
881 } \
882 \
883 NcBool NcVar::put_rec( NcDim* rdim, const TYPE* vals, \
884 long slice) \
885 { \
886 int idx = dim_to_index(rdim); \
887 long size = num_dims(); \
888 long* start = new long[size]; \
889 for (int i=1; i < size ; i++) start[i] = 0; \
890 start[idx] = slice; \
891 NcBool result = set_cur(start); \
892 delete [] start; \
893 if (! result ) \
894 return FALSE; \
895 \
896 long* edge = edges(); \
897 edge[idx] = 1; \
898 result = put(vals, edge); \
899 delete [] edge; \
900 return result; \
901 }
902
903 NcVar_put_rec(ncbyte)
904 NcVar_put_rec(char)
905 NcVar_put_rec(short)
906 NcVar_put_rec(int)
907 NcVar_put_rec(long)
908 NcVar_put_rec(float)
909 NcVar_put_rec(double)
910
911 long NcVar::rec_size(void) {
912 return rec_size(get_dim(0));
913 }
914
915 long NcVar::rec_size(NcDim *rdim) {
916 int idx = dim_to_index(rdim);
917 long size = 1;
918 long* edge = edges();
919 for( int i = 0 ; i<num_dims() ; i++) {
920 if (i != idx) {
921 size *= edge[i];
922 }
923 }
924 delete [] edge;
925 return size;
926 }
927
928 #define NcVar_get_index(TYPE) \
929 long NcVar::get_index(const TYPE* key) \
930 { \
931 return get_index(get_dim(0), key); \
932 } \
933 \
934 long NcVar::get_index(NcDim *rdim, const TYPE* key) \
935 { \
936 if (type() != NcTypeEnum(TYPE)) \
937 return -1; \
938 if (! the_file->data_mode()) \
939 return -1; \
940 int idx = dim_to_index(rdim); \
941 long maxrec = get_dim(idx)->size(); \
942 long maxvals = rec_size(rdim); \
943 NcValues* val; \
944 int validx; \
945 for (long j=0; j<maxrec; j++) { \
946 val = get_rec(rdim,j); \
947 if (val == NULL) return -1; \
948 for (validx = 0; validx < maxvals; validx++) { \
949 if (key[validx] != val->as_ ## TYPE(validx)) break; \
950 } \
951 delete val; \
952 if (validx == maxvals) return j; \
953 } \
954 return -1; \
955 }
956
957
958 NcVar_get_index(ncbyte)
959 NcVar_get_index(char)
960 NcVar_get_index(short)
961 NcVar_get_index(nclong)
962 NcVar_get_index(long)
963 NcVar_get_index(float)
964 NcVar_get_index(double)
965
966 // Macros below work for short, nclong, long, float, and double, but for ncbyte
967 // and char, we must use corresponding schar, uchar, or text C functions, so in
968 // these cases macros are expanded manually.
969 #define NcVar_put_array(TYPE) \
970 NcBool NcVar::put( const TYPE* vals, \
971 long edge0, \
972 long edge1, \
973 long edge2, \
974 long edge3, \
975 long edge4) \
976 { \
977 /* no need to check type() vs. TYPE, invoked C function will do that */ \
978 if (! the_file->data_mode()) \
979 return FALSE; \
980 size_t count[5]; \
981 count[0] = edge0; \
982 count[1] = edge1; \
983 count[2] = edge2; \
984 count[3] = edge3; \
985 count[4] = edge4; \
986 for (int i = 0; i < 5; i++) { \
987 if (count[i]) { \
988 if (num_dims() < i) \
989 return FALSE; \
990 } else \
991 break; \
992 } \
993 size_t start[5]; \
994 for (int j = 0; j < 5; j++) { \
995 start[j] = the_cur[j]; \
996 } \
997 return NcError::set_err( \
998 makename2(nc_put_vara_,TYPE) (the_file->id(), the_id, start, count, vals) \
999 ) == NC_NOERR; \
1000 }
1001
1002 NcBool NcVar::put( const ncbyte* vals,
1003 long edge0,
1004 long edge1,
1005 long edge2,
1006 long edge3,
1007 long edge4)
1008 {
1009 /* no need to check type() vs. TYPE, invoked C function will do that */
1010 if (! the_file->data_mode())
1011 return FALSE;
1012 size_t count[5];
1013 count[0] = edge0;
1014 count[1] = edge1;
1015 count[2] = edge2;
1016 count[3] = edge3;
1017 count[4] = edge4;
1018 for (int i = 0; i < 5; i++) {
1019 if (count[i]) {
1020 if (num_dims() < i)
1021 return FALSE;
1022 } else
1023 break;
1024 }
1025 size_t start[5];
1026 for (int j = 0; j < 5; j++) {
1027 start[j] = the_cur[j];
1028 }
1029 return NcError::set_err(
1030 nc_put_vara_schar (the_file->id(), the_id, start, count, vals)
1031 ) == NC_NOERR;
1032 }
1033
1034 NcBool NcVar::put( const char* vals,
1035 long edge0,
1036 long edge1,
1037 long edge2,
1038 long edge3,
1039 long edge4)
1040 {
1041 /* no need to check type() vs. TYPE, invoked C function will do that */
1042 if (! the_file->data_mode())
1043 return FALSE;
1044 size_t count[5];
1045 count[0] = edge0;
1046 count[1] = edge1;
1047 count[2] = edge2;
1048 count[3] = edge3;
1049 count[4] = edge4;
1050 for (int i = 0; i < 5; i++) {
1051 if (count[i]) {
1052 if (num_dims() < i)
1053 return FALSE;
1054 } else
1055 break;
1056 }
1057 size_t start[5];
1058 for (int j = 0; j < 5; j++) {
1059 start[j] = the_cur[j];
1060 }
1061 return NcError::set_err(
1062 nc_put_vara_text (the_file->id(), the_id, start, count, vals)
1063 ) == NC_NOERR;
1064 }
1065
1066 NcVar_put_array(short)
1067 NcVar_put_array(int)
1068 NcVar_put_array(long)
1069 NcVar_put_array(float)
1070 NcVar_put_array(double)
1071
1072 #define NcVar_put_nd_array(TYPE) \
1073 NcBool NcVar::put( const TYPE* vals, const long* count ) \
1074 { \
1075 /* no need to check type() vs. TYPE, invoked C function will do that */ \
1076 if (! the_file->data_mode()) \
1077 return FALSE; \
1078 size_t start[NC_MAX_DIMS]; \
1079 for (int i = 0; i < num_dims(); i++) \
1080 start[i] = the_cur[i]; \
1081 return NcError::set_err( \
1082 makename2(nc_put_vara_,TYPE) (the_file->id(), the_id, start, (const size_t *) count, vals) \
1083 ) == NC_NOERR; \
1084 }
1085
1086 NcBool NcVar::put( const ncbyte* vals, const long* count )
1087 {
1088 /* no need to check type() vs. TYPE, invoked C function will do that */
1089 if (! the_file->data_mode())
1090 return FALSE;
1091 size_t start[NC_MAX_DIMS];
1092 for (int i = 0; i < num_dims(); i++)
1093 start[i] = the_cur[i];
1094 return NcError::set_err(
1095 nc_put_vara_schar (the_file->id(), the_id, start, (const size_t *)count, vals)
1096 ) == NC_NOERR;
1097 }
1098
1099 NcBool NcVar::put( const char* vals, const long* count )
1100 {
1101 /* no need to check type() vs. TYPE, invoked C function will do that */
1102 if (! the_file->data_mode())
1103 return FALSE;
1104 size_t start[NC_MAX_DIMS];
1105 for (int i = 0; i < num_dims(); i++)
1106 start[i] = the_cur[i];
1107 return NcError::set_err(
1108 nc_put_vara_text (the_file->id(), the_id, start, (const size_t *)count, vals)
1109 ) == NC_NOERR;
1110 }
1111
1112 NcVar_put_nd_array(short)
1113 NcVar_put_nd_array(int)
1114 NcVar_put_nd_array(long)
1115 NcVar_put_nd_array(float)
1116 NcVar_put_nd_array(double)
1117
1118 #define NcVar_get_array(TYPE) \
1119 NcBool NcVar::get( TYPE* vals, \
1120 long edge0, \
1121 long edge1, \
1122 long edge2, \
1123 long edge3, \
1124 long edge4) const \
1125 { \
1126 if (! the_file->data_mode()) \
1127 return FALSE; \
1128 size_t count[5]; \
1129 count[0] = edge0; \
1130 count[1] = edge1; \
1131 count[2] = edge2; \
1132 count[3] = edge3; \
1133 count[4] = edge4; \
1134 for (int i = 0; i < 5; i++) { \
1135 if (count[i]) { \
1136 if (num_dims() < i) \
1137 return FALSE; \
1138 } else \
1139 break; \
1140 } \
1141 size_t start[5]; \
1142 for (int j = 0; j < 5; j++) { \
1143 start[j] = the_cur[j]; \
1144 } \
1145 return NcError::set_err( \
1146 makename2(nc_get_vara_,TYPE) (the_file->id(), the_id, start, count, vals) \
1147 ) == NC_NOERR; \
1148 }
1149
1150 NcBool NcVar::get( ncbyte* vals,
1151 long edge0,
1152 long edge1,
1153 long edge2,
1154 long edge3,
1155 long edge4) const
1156 {
1157 if (! the_file->data_mode())
1158 return FALSE;
1159 size_t count[5];
1160 count[0] = edge0;
1161 count[1] = edge1;
1162 count[2] = edge2;
1163 count[3] = edge3;
1164 count[4] = edge4;
1165 for (int i = 0; i < 5; i++) {
1166 if (count[i]) {
1167 if (num_dims() < i)
1168 return FALSE;
1169 } else
1170 break;
1171 }
1172 size_t start[5];
1173 for (int j = 0; j < 5; j++) {
1174 start[j] = the_cur[j];
1175 }
1176 return NcError::set_err(
1177 nc_get_vara_schar (the_file->id(), the_id, start, count, vals)
1178 ) == NC_NOERR;
1179 }
1180
1181 NcBool NcVar::get( char* vals,
1182 long edge0,
1183 long edge1,
1184 long edge2,
1185 long edge3,
1186 long edge4) const
1187 {
1188 if (! the_file->data_mode())
1189 return FALSE;
1190 size_t count[5];
1191 count[0] = edge0;
1192 count[1] = edge1;
1193 count[2] = edge2;
1194 count[3] = edge3;
1195 count[4] = edge4;
1196 for (int i = 0; i < 5; i++) {
1197 if (count[i]) {
1198 if (num_dims() < i)
1199 return FALSE;
1200 } else
1201 break;
1202 }
1203 size_t start[5];
1204 for (int j = 0; j < 5; j++) {
1205 start[j] = the_cur[j];
1206 }
1207 return NcError::set_err(
1208 nc_get_vara_text (the_file->id(), the_id, start, count, vals)
1209 ) == NC_NOERR;
1210 }
1211
1212 NcVar_get_array(short)
1213 NcVar_get_array(int)
1214 NcVar_get_array(long)
1215 NcVar_get_array(float)
1216 NcVar_get_array(double)
1217
1218 #define NcVar_get_nd_array(TYPE) \
1219 NcBool NcVar::get( TYPE* vals, const long* count ) const \
1220 { \
1221 if (! the_file->data_mode()) \
1222 return FALSE; \
1223 size_t start[NC_MAX_DIMS]; \
1224 for (int i = 0; i < num_dims(); i++) \
1225 start[i] = the_cur[i]; \
1226 return NcError::set_err( \
1227 makename2(nc_get_vara_,TYPE) (the_file->id(), the_id, start, (const size_t *) count, vals) \
1228 ) == NC_NOERR; \
1229 }
1230
1231 NcBool NcVar::get( ncbyte* vals, const long* count ) const
1232 {
1233 if (! the_file->data_mode())
1234 return FALSE;
1235 size_t start[NC_MAX_DIMS];
1236 for (int i = 0; i < num_dims(); i++)
1237 start[i] = the_cur[i];
1238 return nc_get_vara_schar (the_file->id(), the_id, start, (const size_t *) count, vals) == NC_NOERR;
1239 }
1240
1241 NcBool NcVar::get( char* vals, const long* count ) const
1242 {
1243 if (! the_file->data_mode())
1244 return FALSE;
1245 size_t start[NC_MAX_DIMS];
1246 for (int i = 0; i < num_dims(); i++)
1247 start[i] = the_cur[i];
1248 return nc_get_vara_text (the_file->id(), the_id, start, (const size_t*) count, vals) == NC_NOERR;
1249 }
1250
1251 NcVar_get_nd_array(short)
1252 NcVar_get_nd_array(int)
1253 NcVar_get_nd_array(long)
1254 NcVar_get_nd_array(float)
1255 NcVar_get_nd_array(double)
1256
1257 // If no args, set cursor to all zeros. Else set initial elements of cursor
1258 // to args provided, rest to zeros.
1259 NcBool NcVar::set_cur(long c0, long c1, long c2, long c3, long c4)
1260 {
1261 size_t t[6];
1262 t[0] = c0;
1263 t[1] = c1;
1264 t[2] = c2;
1265 t[3] = c3;
1266 t[4] = c4;
1267 t[5] = -1;
1268 for(int j = 0; j < 6; j++) { // find how many parameters were used
1269 int i;
1270 if (t[j] == -1) {
1271 if (num_dims() < j)
1272 return FALSE; // too many for variable's dimensionality
1273 for (i = 0; i < j; i++) {
1274 if (t[i] >= get_dim(i)->size() && ! get_dim(i)->is_unlimited())
1275 return FALSE; // too big for dimension
1276 the_cur[i] = t[i];
1277 }
1278 for(i = j; i < num_dims(); i++)
1279 the_cur[i] = 0;
1280 return TRUE;
1281 }
1282 }
1283 return TRUE;
1284 }
1285
1286 NcBool NcVar::set_cur(long* cur)
1287 {
1288 for(int i = 0; i < num_dims(); i++) {
1289 if (cur[i] >= get_dim(i)->size() && ! get_dim(i)->is_unlimited())
1290 return FALSE;
1291 the_cur[i] = cur[i];
1292 }
1293 return TRUE;
1294 }
1295
1296 #define NcVar_add_scalar_att(TYPE) \
1297 NcBool NcVar::add_att(NcToken aname, TYPE val) \
1298 { \
1299 if (! the_file->define_mode()) \
1300 return FALSE; \
1301 if (NcError::set_err( \
1302 makename2(nc_put_att_,TYPE) (the_file->id(), the_id, aname, (nc_type) NcTypeEnum(TYPE), \
1303 1, &val) \
1304 ) != NC_NOERR) \
1305 return FALSE; \
1306 return TRUE; \
1307 }
1308
1309 NcBool NcVar::add_att(NcToken aname, ncbyte val)
1310 {
1311 if (! the_file->define_mode())
1312 return FALSE;
1313 if (nc_put_att_schar (the_file->id(), the_id, aname, (nc_type) NcTypeEnum(ncbyte),
1314 1, &val) != NC_NOERR)
1315 return FALSE;
1316 return TRUE;
1317 }
1318
1319 NcBool NcVar::add_att(NcToken aname, char val)
1320 {
1321 if (! the_file->define_mode())
1322 return FALSE;
1323 if (nc_put_att_text (the_file->id(), the_id, aname,
1324 1, &val) != NC_NOERR)
1325 return FALSE;
1326 return TRUE;
1327 }
1328
1329 NcVar_add_scalar_att(short)
1330 NcVar_add_scalar_att(int)
1331 NcVar_add_scalar_att(long)
1332 NcVar_add_scalar_att(double)
1333
1334 NcBool NcVar::add_att(NcToken aname, float val)
1335 {
1336 if (! the_file->define_mode())
1337 return FALSE;
1338 float fval = (float) val; // workaround for bug, val passed as double??
1339 if (nc_put_att_float(the_file->id(), the_id, aname, (nc_type) ncFloat,
1340 1, &fval) != NC_NOERR)
1341 return FALSE;
1342 return TRUE;
1343 }
1344
1345 NcBool NcVar::add_att(NcToken aname, const char* val)
1346 {
1347 if (! the_file->define_mode())
1348 return FALSE;
1349 if (nc_put_att_text(the_file->id(), the_id, aname,
1350 strlen(val), val) != NC_NOERR)
1351 return FALSE;
1352 return TRUE;
1353 }
1354
1355 #define NcVar_add_vector_att(TYPE) \
1356 NcBool NcVar::add_att(NcToken aname, int len, const TYPE* vals) \
1357 { \
1358 if (! the_file->define_mode()) \
1359 return FALSE; \
1360 if (NcError::set_err( \
1361 makename2(nc_put_att_,TYPE) (the_file->id(), the_id, aname, (nc_type) NcTypeEnum(TYPE), \
1362 len, vals) \
1363 ) != NC_NOERR) \
1364 return FALSE; \
1365 return TRUE; \
1366 }
1367
1368 NcBool NcVar::add_att(NcToken aname, int len, const ncbyte* vals)
1369 {
1370 if (! the_file->define_mode())
1371 return FALSE;
1372 if (NcError::set_err(
1373 nc_put_att_schar (the_file->id(), the_id, aname, (nc_type) NcTypeEnum(ncbyte),
1374 len, vals)
1375 ) != NC_NOERR)
1376 return FALSE;
1377 return TRUE;
1378 }
1379
1380 NcBool NcVar::add_att(NcToken aname, int len, const char* vals)
1381 {
1382 if (! the_file->define_mode())
1383 return FALSE;
1384 if (NcError::set_err(
1385 nc_put_att_text (the_file->id(), the_id, aname,
1386 len, vals)
1387 ) != NC_NOERR)
1388 return FALSE;
1389 return TRUE;
1390 }
1391
1392 NcVar_add_vector_att(short)
1393 NcVar_add_vector_att(int)
1394 NcVar_add_vector_att(long)
1395 NcVar_add_vector_att(float)
1396 NcVar_add_vector_att(double)
1397
1398 NcBool NcVar::rename(NcToken newname)
1399 {
1400 if (strlen(newname) > strlen(the_name)) {
1401 if (! the_file->define_mode())
1402 return FALSE;
1403 }
1404 NcBool ret = NcError::set_err(
1405 nc_rename_var(the_file->id(), the_id, newname)
1406 ) == NC_NOERR;
1407 if (ret) {
1408 delete [] the_name;
1409 the_name = new char [1 + strlen(newname)];
1410 strcpy(the_name, newname);
1411 }
1412 return ret;
1413 }
1414
1415 int NcVar::id( void ) const
1416 {
1417 return the_id;
1418 }
1419
1420 NcBool NcVar::sync(void)
1421 {
1422 if (the_name) {
1423 delete [] the_name;
1424 }
1425 if (the_cur) {
1426 delete [] the_cur;
1427 }
1428 if (cur_rec) {
1429 delete [] cur_rec;
1430 }
1431 char nam[NC_MAX_NAME];
1432 if (the_file
1433 && NcError::set_err(
1434 nc_inq_varname(the_file->id(), the_id, nam)
1435 ) == NC_NOERR) {
1436 the_name = new char[1 + strlen(nam)];
1437 strcpy(the_name, nam);
1438 } else {
1439 the_name = 0;
1440 return FALSE;
1441 }
1442 init_cur();
1443 return TRUE;
1444 }
1445
1446
1447 NcVar::NcVar(NcFile* nc, int id)
1448 : NcTypedComponent(nc), the_id(id)
1449 {
1450 char nam[NC_MAX_NAME];
1451 if (the_file
1452 && NcError::set_err(
1453 nc_inq_varname(the_file->id(), the_id, nam)
1454 ) == NC_NOERR) {
1455 the_name = new char[1 + strlen(nam)];
1456 strcpy(the_name, nam);
1457 } else {
1458 the_name = 0;
1459 }
1460 init_cur();
1461 }
1462
1463 int NcVar::attnum( NcToken attrname ) const
1464 {
1465 int num;
1466 for(num=0; num < num_atts(); num++) {
1467 char aname[NC_MAX_NAME];
1468 NcError::set_err(
1469 nc_inq_attname(the_file->id(), the_id, num, aname)
1470 );
1471 if (strcmp(aname, attrname) == 0)
1472 break;
1473 }
1474 return num; // num_atts() if no such attribute
1475 }
1476
1477 NcToken NcVar::attname( int attnum ) const // caller must delete[]
1478 {
1479 if (attnum < 0 || attnum >= num_atts())
1480 return 0;
1481 char aname[NC_MAX_NAME];
1482 if (NcError::set_err(
1483 nc_inq_attname(the_file->id(), the_id, attnum, aname)
1484 ) != NC_NOERR)
1485 return 0;
1486 char* rname = new char[1 + strlen(aname)];
1487 strcpy(rname, aname);
1488 return rname;
1489 }
1490
1491 void NcVar::init_cur( void )
1492 {
1493 the_cur = new long[NC_MAX_DIMS]; // *** don't know num_dims() yet?
1494 cur_rec = new long[NC_MAX_DIMS]; // *** don't know num_dims() yet?
1495 for(int i = 0; i < NC_MAX_DIMS; i++) {
1496 the_cur[i] = 0; cur_rec[i] = 0; }
1497 }
1498
1499 NcAtt::NcAtt(NcFile* nc, const NcVar* var, NcToken name)
1500 : NcTypedComponent(nc), the_variable(var)
1501 {
1502 the_name = new char[1 + strlen(name)];
1503 strcpy(the_name, name);
1504 }
1505
1506 NcAtt::NcAtt(NcFile* nc, NcToken name)
1507 : NcTypedComponent(nc), the_variable(NULL)
1508 {
1509 the_name = new char[1 + strlen(name)];
1510 strcpy(the_name, name);
1511 }
1512
1513 NcAtt::~NcAtt( void )
1514 {
1515 delete [] the_name;
1516 }
1517
1518 NcToken NcAtt::name( void ) const
1519 {
1520 return the_name;
1521 }
1522
1523 NcType NcAtt::type( void ) const
1524 {
1525 nc_type typ;
1526 NcError::set_err(
1527 nc_inq_atttype(the_file->id(), the_variable->id(), the_name, &typ)
1528 );
1529 return (NcType) typ;
1530 }
1531
1532 long NcAtt::num_vals( void ) const
1533 {
1534 size_t len;
1535 NcError::set_err(
1536 nc_inq_attlen(the_file->id(), the_variable->id(), the_name, &len)
1537 );
1538 return len;
1539 }
1540
1541 NcBool NcAtt::is_valid( void ) const
1542 {
1543 int num;
1544 return the_file->is_valid() &&
1545 (the_variable->id() == NC_GLOBAL || the_variable->is_valid()) &&
1546 NcError::set_err(
1547 nc_inq_attid(the_file->id(), the_variable->id(), the_name, &num)
1548 ) == NC_NOERR;
1549 }
1550
1551 NcValues* NcAtt::values( void ) const
1552 {
1553 NcValues* valp = get_space();
1554 int status;
1555 switch (type()) {
1556 case ncFloat:
1557 status = NcError::set_err(
1558 nc_get_att_float(the_file->id(), the_variable->id(), the_name,
1559 (float *)valp->base())
1560 );
1561 break;
1562 case ncDouble:
1563 status = NcError::set_err(
1564 nc_get_att_double(the_file->id(), the_variable->id(), the_name,
1565 (double *)valp->base())
1566 );
1567 break;
1568 case ncInt:
1569 status = NcError::set_err(
1570 nc_get_att_int(the_file->id(), the_variable->id(), the_name,
1571 (int *)valp->base())
1572 );
1573 break;
1574 case ncShort:
1575 status = NcError::set_err(
1576 nc_get_att_short(the_file->id(), the_variable->id(), the_name,
1577 (short *)valp->base())
1578 );
1579 break;
1580 case ncByte:
1581 status = NcError::set_err(
1582 nc_get_att_schar(the_file->id(), the_variable->id(), the_name,
1583 (signed char *)valp->base())
1584 );
1585 break;
1586 case ncChar:
1587 status = NcError::set_err(
1588 nc_get_att_text(the_file->id(), the_variable->id(), the_name,
1589 (char *)valp->base())
1590 );
1591 break;
1592 case ncNoType:
1593 default:
1594 return 0;
1595 }
1596 if (status != NC_NOERR) {
1597 delete valp;
1598 return 0;
1599 }
1600 return valp;
1601 }
1602
1603 NcBool NcAtt::rename(NcToken newname)
1604 {
1605 if (strlen(newname) > strlen(the_name)) {
1606 if (! the_file->define_mode())
1607 return FALSE;
1608 }
1609 return NcError::set_err(
1610 nc_rename_att(the_file->id(), the_variable->id(),
1611 the_name, newname)
1612 ) == NC_NOERR;
1613 }
1614
1615 NcBool NcAtt::remove( void )
1616 {
1617 if (! the_file->define_mode())
1618 return FALSE;
1619 return NcError::set_err(
1620 nc_del_att(the_file->id(), the_variable->id(), the_name)
1621 ) == NC_NOERR;
1622 }
1623
1624 NcError::NcError( Behavior b )
1625 {
1626 the_old_state = ncopts; // global variable in version 2 C interface
1627 the_old_err = ncerr; // global variable in version 2 C interface
1628 ncopts = (int) b;
1629 }
1630
1631 NcError::~NcError( void )
1632 {
1633 ncopts = the_old_state;
1634 ncerr = the_old_err;
1635 }
1636
1637 int NcError::get_err( void ) // returns most recent error
1638 {
1639 return ncerr;
1640 }
1641
1642 int NcError::set_err (int err)
1643 {
1644 ncerr = err;
1645 // Check ncopts and handle appropriately
1646 if(err != NC_NOERR) {
1647 if(ncopts == verbose_nonfatal || ncopts == verbose_fatal) {
1648 std::cout << nc_strerror(err) << std::endl;
1649 }
1650 if(ncopts == silent_fatal || ncopts == verbose_fatal) {
1651 exit(ncopts);
1652 }
1653 }
1654 return err;
1655 }
1656
1657 int NcError::ncerr = NC_NOERR;
1658 int NcError::ncopts = NcError::verbose_fatal ; // for backward compatibility

  ViewVC Help
Powered by ViewVC 1.1.26