1 /*
2 * Copyright 1996, University Corporation for Atmospheric Research
3 * See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 */
5 /* $Id: v2i.c,v 1.52 2009/02/20 22:00:46 dmh Exp $ */
6
7 #ifndef NO_NETCDF_2
8
9 #include <config.h>
10 #include <stdlib.h>
11 #ifndef NO_SYS_TYPES_H
12 # include <sys/types.h> /* Keep before xxxnetcdf.h or Win64 gets confused. */
13 #endif /* NO_SYS_TYPES_H */
14 #include "nc.h" /* WARNING: nc.h must be included before xxxnetcdf.h or MSVC60 will die. */
15 #include "xxxnetcdf.h"
16
17 #if SIZEOF_LONG == SIZEOF_SIZE_T
18 /*
19 * We don't have to copy the arguments to switch from 'long'
20 * to 'size_t' or 'ptrdiff_t'. Use dummy macros.
21 */
22
23 # define NDIMS_DECL
24 # define A_DECL(name, type, ndims, rhs) \
25 const type *const name = ((const type *)(rhs))
26
27 # define A_FREE(name)
28
29 # define A_INIT(lhs, type, ndims, rhs)
30
31 #else
32 /*
33 * We do have to copy the arguments to switch from 'long'
34 * to 'size_t' or 'ptrdiff_t'. In my tests on an SGI,
35 * any additional cost was lost in measurement variation.
36 */
37
38 # include "onstack.h"
39
40 static size_t
nvdims(int ncid,int varid)41 nvdims(int ncid, int varid)
42 {
43 NC *ncp;
44 if(NC_check_id(ncid, &ncp) != NC_NOERR)
45 return 0;
46 {
47 const NC_var *const varp = NC_lookupvar(ncp, varid);
48 if(varp == NULL)
49 return 0;
50 return varp->ndims;
51 }
52 }
53
54 #define NDIMS_DECL const size_t ndims = nvdims(ncid, varid);
55
56 # define A_DECL(name, type, ndims, rhs) \
57 ALLOC_ONSTACK(name, type, ndims)
58
59 # define A_FREE(name) \
60 FREE_ONSTACK(name)
61
62 # define A_INIT(lhs, type, ndims, rhs) \
63 { \
64 const long *lp = rhs; \
65 type *tp = lhs; \
66 type *const end = lhs + ndims; \
67 while(tp < end) \
68 { \
69 *tp++ = (type) *lp++; \
70 } \
71 }
72
73
74 #endif
75
76 /*
77 * Computes number of record variables in an open netCDF file, and an array of
78 * the record variable ids, if the array parameter is non-null.
79 */
80 static int
numrecvars(int ncid,int * nrecvarsp,int * recvarids)81 numrecvars(int ncid, int *nrecvarsp, int *recvarids)
82 {
83 int status;
84 int nvars = 0;
85 int ndims = 0;
86 int nrecvars = 0;
87 int varid;
88 int recdimid;
89 int dimids[MAX_NC_DIMS];
90
91 status = nc_inq_nvars(ncid, &nvars);
92 if(status != NC_NOERR)
93 return status;
94
95 status = nc_inq_unlimdim(ncid, &recdimid);
96 if(status != NC_NOERR)
97 return status;
98
99 if (recdimid == -1) {
100 *nrecvarsp = 0;
101 return NC_NOERR;
102 }
103 nrecvars = 0;
104 for (varid = 0; varid < nvars; varid++) {
105 status = nc_inq_varndims(ncid, varid, &ndims);
106 if(status != NC_NOERR)
107 return status;
108 status = nc_inq_vardimid(ncid, varid, dimids);
109 if(status != NC_NOERR)
110 return status;
111 if (ndims > 0 && dimids[0] == recdimid) {
112 if (recvarids != NULL)
113 recvarids[nrecvars] = varid;
114 nrecvars++;
115 }
116 }
117 *nrecvarsp = nrecvars;
118 return NC_NOERR;
119 }
120
121
122 /*
123 * Computes record size (in bytes) of the record variable with a specified
124 * variable id. Returns size as 0 if not a record variable.
125 */
126 static int
ncrecsize(int ncid,int varid,size_t * recsizep)127 ncrecsize(int ncid, int varid, size_t *recsizep)
128 {
129 int status;
130 int recdimid;
131 nc_type type;
132 int ndims;
133 int dimids[MAX_NC_DIMS];
134 int id;
135 size_t size;
136
137 *recsizep = 0;
138 status = nc_inq_unlimdim(ncid, &recdimid);
139 if(status != NC_NOERR)
140 return status;
141 status = nc_inq_vartype(ncid, varid, &type);
142 if(status != NC_NOERR)
143 return status;
144 status = nc_inq_varndims(ncid, varid, &ndims);
145 if(status != NC_NOERR)
146 return status;
147 status = nc_inq_vardimid(ncid, varid, dimids);
148 if(status != NC_NOERR)
149 return status;
150 if (ndims == 0 || dimids[0] != recdimid) {
151 return NC_NOERR;
152 }
153 size = nctypelen(type);
154 for (id = 1; id < ndims; id++) {
155 size_t len;
156 status = nc_inq_dimlen(ncid, dimids[id], &len);
157 if(status != NC_NOERR)
158 return status;
159 size *= len;
160 }
161 *recsizep = size;
162 return NC_NOERR;
163 }
164
165
166 /*
167 * Retrieves the dimension sizes of a variable with a specified variable id in
168 * an open netCDF file. Returns -1 on error.
169 */
170 static int
dimsizes(int ncid,int varid,size_t * sizes)171 dimsizes(int ncid, int varid, size_t *sizes)
172 {
173 int status;
174 int ndims;
175 int id;
176 int dimids[MAX_NC_DIMS];
177
178 status = nc_inq_varndims(ncid, varid, &ndims);
179 if(status != NC_NOERR)
180 return status;
181 status = nc_inq_vardimid(ncid, varid, dimids);
182 if(status != NC_NOERR)
183 return status;
184 if (ndims == 0 || sizes == NULL)
185 return NC_NOERR;
186 for (id = 0; id < ndims; id++) {
187 size_t len;
188 status = nc_inq_dimlen(ncid, dimids[id], &len);
189 if(status != NC_NOERR)
190 return status;
191 sizes[id] = len;
192 }
193 return NC_NOERR;
194 }
195
196
197 /*
198 * Retrieves the number of record variables, the record variable ids, and the
199 * record size of each record variable. If any pointer to info to be returned
200 * is null, the associated information is not returned. Returns -1 on error.
201 */
202 int
nc_inq_rec(int ncid,size_t * nrecvarsp,int * recvarids,size_t * recsizes)203 nc_inq_rec(
204 int ncid,
205 size_t *nrecvarsp,
206 int *recvarids,
207 size_t *recsizes)
208 {
209 int status;
210 int nvars = 0;
211 int recdimid;
212 int varid;
213 int rvarids[MAX_NC_VARS];
214 int nrvars = 0;
215
216 status = nc_inq_nvars(ncid, &nvars);
217 if(status != NC_NOERR)
218 return status;
219
220 status = nc_inq_unlimdim(ncid, &recdimid);
221 if(status != NC_NOERR)
222 return status;
223
224 *nrecvarsp = 0;
225 if (recdimid == -1)
226 return NC_NOERR;
227
228 status = numrecvars(ncid, &nrvars, rvarids);
229 if(status != NC_NOERR)
230 return status;
231
232 if (nrecvarsp != NULL)
233 *nrecvarsp = nrvars;
234 if (recvarids != NULL)
235 for (varid = 0; varid < nrvars; varid++)
236 recvarids[varid] = rvarids[varid];
237
238 if (recsizes != NULL)
239 for (varid = 0; varid < nrvars; varid++) {
240 size_t rsize;
241 status = ncrecsize(ncid, rvarids[varid], &rsize);
242 if (status != NC_NOERR)
243 return status;
244 recsizes[varid] = rsize;
245 }
246 return NC_NOERR;
247 }
248
249
250 /*
251 * Write one record's worth of data, except don't write to variables for which
252 * the address of the data to be written is NULL. Return -1 on error. This is
253 * the same as the ncrecput() in the library, except that can handle errors
254 * better.
255 */
256 int
nc_put_rec(int ncid,size_t recnum,void * const * datap)257 nc_put_rec(
258 int ncid,
259 size_t recnum,
260 void* const* datap)
261 {
262 int status;
263 int varid;
264 int rvarids[MAX_NC_VARS];
265 int nrvars;
266 size_t start[MAX_NC_DIMS];
267 size_t edges[MAX_NC_DIMS];
268
269 status = numrecvars(ncid, &nrvars, rvarids);
270 if(status != NC_NOERR)
271 return status;
272
273 if (nrvars == 0)
274 return NC_NOERR;
275
276 start[0] = recnum;
277 for (varid = 1; varid < nrvars; varid++)
278 start[varid] = 0;
279
280 for (varid = 0; varid < nrvars; varid++) {
281 if (datap[varid] != NULL) {
282 status = dimsizes(ncid, rvarids[varid], edges);
283 if(status != NC_NOERR)
284 return status;
285
286 edges[0] = 1; /* only 1 record's worth */
287 status = nc_put_vara(ncid, rvarids[varid], start, edges, datap[varid]);
288 if(status != NC_NOERR)
289 return status;
290 }
291 }
292 return 0;
293 }
294
295
296 /*
297 * Read one record's worth of data, except don't read from variables for which
298 * the address of the data to be read is null. Return -1 on error. This is
299 * the same as the ncrecget() in the library, except that can handle errors
300 * better.
301 */
302 int
nc_get_rec(int ncid,size_t recnum,void ** datap)303 nc_get_rec(
304 int ncid,
305 size_t recnum,
306 void **datap)
307 {
308 int status;
309 int varid;
310 int rvarids[MAX_NC_VARS];
311 int nrvars;
312 size_t start[MAX_NC_DIMS];
313 size_t edges[MAX_NC_DIMS];
314
315 status = numrecvars(ncid, &nrvars, rvarids);
316 if(status != NC_NOERR)
317 return status;
318
319 if (nrvars == 0)
320 return NC_NOERR;
321
322 start[0] = recnum;
323 for (varid = 1; varid < nrvars; varid++)
324 start[varid] = 0;
325
326 for (varid = 0; varid < nrvars; varid++) {
327 if (datap[varid] != NULL) {
328 status = dimsizes(ncid, rvarids[varid], edges);
329 if(status != NC_NOERR)
330 return status;
331 edges[0] = 1; /* only 1 record's worth */
332 status = nc_get_vara(ncid, rvarids[varid], start, edges, datap[varid]);
333 if(status != NC_NOERR)
334 return status;
335 }
336 }
337 return 0;
338 }
339
340
341 /* Begin globals */
342
343 /*
344 * Error code
345 */
346 int ncerr = NC_NOERR ;
347
348
349 /*
350 * The subroutines in error.c emit no messages unless NC_VERBOSE bit is on.
351 * They call exit() when NC_FATAL bit is on.
352 */
353 int ncopts = (NC_FATAL | NC_VERBOSE) ;
354
355 /* End globals */
356
357 /* Begin error handling */
358
359 #include <stdio.h>
360 #include <stdlib.h>
361 #include <stdarg.h>
362
363 /*
364 */
365 void
nc_advise(const char * routine_name,int err,const char * fmt,...)366 nc_advise(const char *routine_name, int err, const char *fmt,...)
367 {
368 va_list args;
369
370 if(NC_ISSYSERR(err))
371 ncerr = NC_SYSERR;
372 else
373 ncerr = err;
374
375 if( ncopts & NC_VERBOSE )
376 {
377 (void) fprintf(stderr,"%s: ", routine_name);
378 va_start(args ,fmt);
379 (void) vfprintf(stderr,fmt,args);
380 va_end(args);
381 if(err != NC_NOERR)
382 {
383 (void) fprintf(stderr,": %s",
384 nc_strerror(err));
385 }
386 (void) fputc('\n',stderr);
387 (void) fflush(stderr); /* to ensure log files are current */
388 }
389
390 if( (ncopts & NC_FATAL) && err != NC_NOERR )
391 {
392 exit(ncopts);
393 }
394 }
395
396 /* End error handling */
397
398 int
nccreate(const char * path,int cmode)399 nccreate(const char* path, int cmode)
400 {
401 int ncid;
402 const int status = nc_create(path, cmode, &ncid);
403 if(status != NC_NOERR)
404 {
405 nc_advise("nccreate", status, "filename \"%s\"", path);
406 return -1;
407 }
408 return ncid;
409 }
410
411
412 int
ncopen(const char * path,int mode)413 ncopen(const char *path, int mode)
414 {
415 int ncid;
416 const int status = nc_open(path, mode, &ncid);
417 if(status != NC_NOERR)
418 {
419 nc_advise("ncopen", status, "filename \"%s\"", path);
420 return -1;
421 }
422 return ncid;
423 }
424
425
426 int
ncredef(int ncid)427 ncredef(int ncid)
428 {
429 const int status = nc_redef(ncid);
430 if(status != NC_NOERR)
431 {
432 nc_advise("ncredef", status, "ncid %d", ncid);
433 return -1;
434 }
435 return 0;
436 }
437
438
439 int
ncendef(int ncid)440 ncendef(int ncid)
441 {
442 const int status = nc_enddef(ncid);
443 if(status != NC_NOERR)
444 {
445 nc_advise("ncendef", status, "ncid %d", ncid);
446 return -1;
447 }
448 return 0;
449 }
450
451
452 int
ncclose(int ncid)453 ncclose(int ncid)
454 {
455 const int status = nc_close(ncid);
456 if(status != NC_NOERR)
457 {
458 nc_advise("ncclose", status, "ncid %d", ncid);
459 return -1;
460
461 }
462 return 0;
463 }
464
465
466 int
ncinquire(int ncid,int * ndims,int * nvars,int * natts,int * recdim)467 ncinquire(
468 int ncid,
469 int* ndims,
470 int* nvars,
471 int* natts,
472 int* recdim
473 )
474 {
475 int nd, nv, na;
476 const int status = nc_inq(ncid, &nd, &nv, &na, recdim);
477
478 if(status != NC_NOERR)
479 {
480 nc_advise("ncinquire", status, "ncid %d", ncid);
481 return -1;
482 }
483 /* else */
484
485 if(ndims != NULL)
486 *ndims = (int) nd;
487
488 if(nvars != NULL)
489 *nvars = (int) nv;
490
491 if(natts != NULL)
492 *natts = (int) na;
493
494 return ncid;
495 }
496
497
498 int
ncsync(int ncid)499 ncsync(int ncid)
500 {
501 const int status = nc_sync(ncid);
502 if(status != NC_NOERR)
503 {
504 nc_advise("ncsync", status, "ncid %d", ncid);
505 return -1;
506
507 }
508 return 0;
509 }
510
511
512 int
ncabort(int ncid)513 ncabort(int ncid)
514 {
515 const int status = nc_abort(ncid);
516 if(status != NC_NOERR)
517 {
518 nc_advise("ncabort", status, "ncid %d", ncid);
519 return -1;
520 }
521 return 0;
522 }
523
524
525 int
ncdimdef(int ncid,const char * name,long length)526 ncdimdef(
527 int ncid,
528 const char* name,
529 long length
530 )
531 {
532 int dimid;
533 int status;
534 if(length < 0) {
535 status = NC_EDIMSIZE;
536 nc_advise("ncdimdef", status, "ncid %d", ncid);
537 return -1;
538 }
539 status = nc_def_dim(ncid, name, (size_t)length, &dimid);
540 if(status != NC_NOERR)
541 {
542 nc_advise("ncdimdef", status, "ncid %d", ncid);
543 return -1;
544 }
545 return dimid;
546 }
547
548
549 int
ncdimid(int ncid,const char * name)550 ncdimid(int ncid, const char* name)
551 {
552 int dimid;
553 const int status = nc_inq_dimid(ncid, name, &dimid);
554 if(status != NC_NOERR)
555 {
556 nc_advise("ncdimid", status, "ncid %d", ncid);
557 return -1;
558 }
559 return dimid;
560 }
561
562
563 int
ncdiminq(int ncid,int dimid,char * name,long * length)564 ncdiminq(
565 int ncid,
566 int dimid,
567 char* name,
568 long* length
569 )
570 {
571 size_t ll;
572 const int status = nc_inq_dim(ncid, dimid, name, &ll);
573
574 if(status != NC_NOERR)
575 {
576 nc_advise("ncdiminq", status, "ncid %d", ncid);
577 return -1;
578 }
579 /* else */
580
581 if(length != NULL)
582 *length = (int) ll;
583
584 return dimid;
585 }
586
587
588 int
ncdimrename(int ncid,int dimid,const char * name)589 ncdimrename(
590 int ncid,
591 int dimid,
592 const char* name
593 )
594 {
595 const int status = nc_rename_dim(ncid, dimid, name);
596 if(status != NC_NOERR)
597 {
598 nc_advise("ncdimrename", status, "ncid %d", ncid);
599 return -1;
600 }
601 return dimid;
602 }
603
604
605 int
ncvardef(int ncid,const char * name,nc_type datatype,int ndims,const int * dim)606 ncvardef(
607 int ncid,
608 const char* name,
609 nc_type datatype,
610 int ndims,
611 const int* dim
612 )
613 {
614 int varid = -1;
615 const int status = nc_def_var(ncid, name, datatype, ndims, dim, &varid);
616 if(status != NC_NOERR)
617 {
618 nc_advise("ncvardef", status, "ncid %d", ncid);
619 return -1;
620 }
621 return varid;
622 }
623
624
625 int
ncvarid(int ncid,const char * name)626 ncvarid(
627 int ncid,
628 const char* name
629 )
630 {
631 int varid = -1;
632 const int status = nc_inq_varid(ncid, name, &varid);
633 if(status != NC_NOERR)
634 {
635 nc_advise("ncvarid", status, "ncid %d", ncid);
636 return -1;
637 }
638 return varid;
639 }
640
641
642 int
ncvarinq(int ncid,int varid,char * name,nc_type * datatype,int * ndims,int * dim,int * natts)643 ncvarinq(
644 int ncid,
645 int varid,
646 char* name,
647 nc_type* datatype,
648 int* ndims,
649 int* dim,
650 int* natts
651 )
652 {
653 int nd, na;
654 const int status = nc_inq_var(ncid, varid, name, datatype,
655 &nd, dim, &na);
656
657 if(status != NC_NOERR)
658 {
659 nc_advise("ncvarinq", status, "ncid %d", ncid);
660 return -1;
661 }
662 /* else */
663
664 if(ndims != NULL)
665 *ndims = (int) nd;
666
667 if(natts != NULL)
668 *natts = (int) na;
669
670 return varid;
671 }
672
673
674 int
ncvarput1(int ncid,int varid,const long * index,const void * value)675 ncvarput1(
676 int ncid,
677 int varid,
678 const long* index,
679 const void* value
680 )
681 {
682 NDIMS_DECL
683 A_DECL(coordp, size_t, ndims, index);
684 A_INIT(coordp, size_t, ndims, index);
685 {
686 const int status = nc_put_var1(ncid, varid, coordp, value);
687 A_FREE(coordp);
688 if(status != NC_NOERR)
689 {
690 nc_advise("ncvarput1", status, "ncid %d", ncid);
691 return -1;
692 }
693 }
694 return 0;
695 }
696
697
698 int
ncvarget1(int ncid,int varid,const long * index,void * value)699 ncvarget1(
700 int ncid,
701 int varid,
702 const long* index,
703 void* value
704 )
705 {
706 NDIMS_DECL
707 A_DECL(coordp, size_t, ndims, index);
708 A_INIT(coordp, size_t, ndims, index);
709 {
710 const int status = nc_get_var1(ncid, varid, coordp, value);
711 A_FREE(coordp);
712 if(status != NC_NOERR)
713 {
714 nc_advise("ncdimid", status, "ncid %d", ncid);
715 return -1;
716 }
717 }
718 return 0;
719 }
720
721
722 int
ncvarput(int ncid,int varid,const long * start,const long * count,const void * value)723 ncvarput(
724 int ncid,
725 int varid,
726 const long* start,
727 const long* count,
728 const void* value
729 )
730 {
731 NDIMS_DECL
732 A_DECL(stp, size_t, ndims, start);
733 A_DECL(cntp, size_t, ndims, count);
734 A_INIT(stp, size_t, ndims, start);
735 A_INIT(cntp, size_t, ndims, count);
736 {
737 const int status = nc_put_vara(ncid, varid, stp, cntp, value);
738 A_FREE(cntp);
739 A_FREE(stp);
740 if(status != NC_NOERR)
741 {
742 nc_advise("ncvarput", status, "ncid %d", ncid);
743 return -1;
744 }
745 }
746 return 0;
747 }
748
749
750 int
ncvarget(int ncid,int varid,const long * start,const long * count,void * value)751 ncvarget(
752 int ncid,
753 int varid,
754 const long* start,
755 const long* count,
756 void* value
757 )
758 {
759 NDIMS_DECL
760 A_DECL(stp, size_t, ndims, start);
761 A_DECL(cntp, size_t, ndims, count);
762 A_INIT(stp, size_t, ndims, start);
763 A_INIT(cntp, size_t, ndims, count);
764 {
765 const int status = nc_get_vara(ncid, varid, stp, cntp, value);
766 A_FREE(cntp);
767 A_FREE(stp);
768 if(status != NC_NOERR)
769 {
770 nc_advise("ncvarget", status, "ncid %d; varid %d", ncid, varid);
771 return -1;
772 }
773 }
774 return 0;
775 }
776
777
778 int
ncvarputs(int ncid,int varid,const long * start,const long * count,const long * stride,const void * value)779 ncvarputs(
780 int ncid,
781 int varid,
782 const long* start,
783 const long* count,
784 const long* stride,
785 const void* value
786 )
787 {
788 if(stride == NULL)
789 return ncvarput(ncid, varid, start, count, value);
790 /* else */
791 {
792 NDIMS_DECL
793 A_DECL(stp, size_t, ndims, start);
794 A_DECL(cntp, size_t, ndims, count);
795 A_DECL(strdp, ptrdiff_t, ndims, stride);
796 A_INIT(stp, size_t, ndims, start);
797 A_INIT(cntp, size_t, ndims, count);
798 A_INIT(strdp, ptrdiff_t, ndims, stride);
799 {
800 const int status = nc_put_vars(ncid, varid, stp, cntp, strdp, value);
801 A_FREE(strdp);
802 A_FREE(cntp);
803 A_FREE(stp);
804 if(status != NC_NOERR)
805 {
806 nc_advise("ncvarputs", status, "ncid %d", ncid);
807 return -1;
808 }
809 }
810 return 0;
811 }
812 }
813
814
815 int
ncvargets(int ncid,int varid,const long * start,const long * count,const long * stride,void * value)816 ncvargets(
817 int ncid,
818 int varid,
819 const long* start,
820 const long* count,
821 const long* stride,
822 void* value
823 )
824 {
825 if(stride == NULL)
826 return ncvarget(ncid, varid, start, count, value);
827 /* else */
828 {
829 NDIMS_DECL
830 A_DECL(stp, size_t, ndims, start);
831 A_DECL(cntp, size_t, ndims, count);
832 A_DECL(strdp, ptrdiff_t, ndims, stride);
833 A_INIT(stp, size_t, ndims, start);
834 A_INIT(cntp, size_t, ndims, count);
835 A_INIT(strdp, ptrdiff_t, ndims, stride);
836 {
837 const int status = nc_get_vars(ncid, varid, stp, cntp, strdp, value);
838 A_FREE(strdp);
839 A_FREE(cntp);
840 A_FREE(stp);
841 if(status != NC_NOERR)
842 {
843 nc_advise("ncvargets", status, "ncid %d", ncid);
844 return -1;
845 }
846 }
847 return 0;
848 }
849 }
850
851
852 int
ncvarputg(int ncid,int varid,const long * start,const long * count,const long * stride,const long * map,const void * value)853 ncvarputg(
854 int ncid,
855 int varid,
856 const long* start,
857 const long* count,
858 const long* stride,
859 const long* map,
860 const void* value
861 )
862 {
863 if(map == NULL)
864 return ncvarputs(ncid, varid, start, count, stride, value);
865 /* else */
866 {
867 NDIMS_DECL
868 A_DECL(stp, size_t, ndims, start);
869 A_DECL(cntp, size_t, ndims, count);
870 A_DECL(strdp, ptrdiff_t, ndims, stride);
871 A_DECL(imp, ptrdiff_t, ndims, map);
872 A_INIT(stp, size_t, ndims, start);
873 A_INIT(cntp, size_t, ndims, count);
874 A_INIT(strdp, ptrdiff_t, ndims, stride);
875 A_INIT(imp, ptrdiff_t, ndims, map);
876 {
877 const int status = nc_put_varm(ncid, varid,
878 stp, cntp, strdp, imp, value);
879 A_FREE(imp);
880 A_FREE(strdp);
881 A_FREE(cntp);
882 A_FREE(stp);
883 if(status != NC_NOERR)
884 {
885 nc_advise("ncvarputg", status, "ncid %d", ncid);
886 return -1;
887 }
888 }
889 return 0;
890 }
891 }
892
893
894 int
ncvargetg(int ncid,int varid,const long * start,const long * count,const long * stride,const long * map,void * value)895 ncvargetg(
896 int ncid,
897 int varid,
898 const long* start,
899 const long* count,
900 const long* stride,
901 const long* map,
902 void* value
903 )
904 {
905 if(map == NULL)
906 return ncvargets(ncid, varid, start, count, stride, value);
907 /* else */
908 {
909 NDIMS_DECL
910 A_DECL(stp, size_t, ndims, start);
911 A_DECL(cntp, size_t, ndims, count);
912 A_DECL(strdp, ptrdiff_t, ndims, stride);
913 A_DECL(imp, ptrdiff_t, ndims, map);
914 A_INIT(stp, size_t, ndims, start);
915 A_INIT(cntp, size_t, ndims, count);
916 A_INIT(strdp, ptrdiff_t, ndims, stride);
917 A_INIT(imp, ptrdiff_t, ndims, map);
918 {
919 const int status = nc_get_varm(ncid, varid,
920 stp, cntp, strdp, imp, value);
921 A_FREE(imp);
922 A_FREE(strdp);
923 A_FREE(cntp);
924 A_FREE(stp);
925 if(status != NC_NOERR)
926 {
927 nc_advise("ncvargetg", status, "ncid %d", ncid);
928 return -1;
929 }
930 }
931 return 0;
932 }
933 }
934
935
936 int
ncvarrename(int ncid,int varid,const char * name)937 ncvarrename(
938 int ncid,
939 int varid,
940 const char* name
941 )
942 {
943 const int status = nc_rename_var(ncid, varid, name);
944 if(status != NC_NOERR)
945 {
946 nc_advise("ncvarrename", status, "ncid %d", ncid);
947 return -1;
948 }
949 return varid;
950 }
951
952
953 int
ncattput(int ncid,int varid,const char * name,nc_type datatype,int len,const void * value)954 ncattput(
955 int ncid,
956 int varid,
957 const char* name,
958 nc_type datatype,
959 int len,
960 const void* value
961 )
962 {
963 const int status = nc_put_att(ncid, varid, name, datatype, len, value);
964 if(status != NC_NOERR)
965 {
966 nc_advise("ncattput", status, "ncid %d", ncid);
967 return -1;
968 }
969 return 0;
970 }
971
972
973 int
ncattinq(int ncid,int varid,const char * name,nc_type * datatype,int * len)974 ncattinq(
975 int ncid,
976 int varid,
977 const char* name,
978 nc_type* datatype,
979 int* len
980 )
981 {
982 size_t ll;
983 const int status = nc_inq_att(ncid, varid, name, datatype, &ll);
984 if(status != NC_NOERR)
985 {
986 nc_advise("ncattinq", status,
987 "ncid %d; varid %d; attname \"%s\"",
988 ncid, varid, name);
989 return -1;
990 }
991
992 if(len != NULL)
993 *len = (int) ll;
994
995 return 1;
996
997 }
998
999
1000 int
ncattget(int ncid,int varid,const char * name,void * value)1001 ncattget(
1002 int ncid,
1003 int varid,
1004 const char* name,
1005 void* value
1006 )
1007 {
1008 const int status = nc_get_att(ncid, varid, name, value);
1009 if(status != NC_NOERR)
1010 {
1011 nc_advise("ncattget", status, "ncid %d", ncid);
1012 return -1;
1013 }
1014 return 1;
1015 }
1016
1017
1018 int
ncattcopy(int ncid_in,int varid_in,const char * name,int ncid_out,int varid_out)1019 ncattcopy(
1020 int ncid_in,
1021 int varid_in,
1022 const char* name,
1023 int ncid_out,
1024 int varid_out
1025 )
1026 {
1027 const int status = nc_copy_att(ncid_in, varid_in, name, ncid_out, varid_out);
1028 if(status != NC_NOERR)
1029 {
1030 nc_advise("ncattcopy", status, "%s", name);
1031 return -1;
1032 }
1033 return 0;
1034 }
1035
1036
1037 int
ncattname(int ncid,int varid,int attnum,char * name)1038 ncattname(
1039 int ncid,
1040 int varid,
1041 int attnum,
1042 char* name
1043 )
1044 {
1045 const int status = nc_inq_attname(ncid, varid, attnum, name);
1046 if(status != NC_NOERR)
1047 {
1048 nc_advise("ncattname", status, "ncid %d", ncid);
1049 return -1;
1050 }
1051 return attnum;
1052 }
1053
1054
1055 int
ncattrename(int ncid,int varid,const char * name,const char * newname)1056 ncattrename(
1057 int ncid,
1058 int varid,
1059 const char* name,
1060 const char* newname
1061 )
1062 {
1063 const int status = nc_rename_att(ncid, varid, name, newname);
1064 if(status != NC_NOERR)
1065 {
1066 nc_advise("ncattrename", status, "ncid %d", ncid);
1067 return -1;
1068 }
1069 return 1;
1070 }
1071
1072
1073 int
ncattdel(int ncid,int varid,const char * name)1074 ncattdel(
1075 int ncid,
1076 int varid,
1077 const char* name
1078 )
1079 {
1080 const int status = nc_del_att(ncid, varid, name);
1081 if(status != NC_NOERR)
1082 {
1083 nc_advise("ncattdel", status, "ncid %d", ncid);
1084 return -1;
1085 }
1086 return 1;
1087 }
1088
1089 #endif /* NO_NETCDF_2 */
1090
1091 #ifndef NO_NETCDF_2
1092
1093 int
ncsetfill(int ncid,int fillmode)1094 ncsetfill(
1095 int ncid,
1096 int fillmode
1097 )
1098 {
1099 int oldmode = -1;
1100 const int status = nc_set_fill(ncid, fillmode, &oldmode);
1101 if(status != NC_NOERR)
1102 {
1103 nc_advise("ncsetfill", status, "ncid %d", ncid);
1104 return -1;
1105 }
1106 return oldmode;
1107 }
1108
1109
1110 int
ncrecinq(int ncid,int * nrecvars,int * recvarids,long * recsizes)1111 ncrecinq(
1112 int ncid,
1113 int* nrecvars,
1114 int* recvarids,
1115 long* recsizes
1116 )
1117 {
1118 size_t nrv = 0;
1119 size_t rs[NC_MAX_VARS]; /* TODO */
1120 const int status = nc_inq_rec(ncid, &nrv, recvarids, rs);
1121 if(status != NC_NOERR)
1122 {
1123 nc_advise("ncrecinq", status, "ncid %d", ncid);
1124 return -1;
1125 }
1126
1127 if(nrecvars != NULL)
1128 *nrecvars = (int) nrv;
1129
1130 if(recsizes != NULL)
1131 {
1132 size_t ii;
1133 for(ii = 0; ii < nrv; ii++)
1134 {
1135 recsizes[ii] = (long) rs[ii];
1136 }
1137 }
1138
1139 return (int) nrv;
1140 }
1141
1142
1143 int
ncrecget(int ncid,long recnum,void ** datap)1144 ncrecget(
1145 int ncid,
1146 long recnum,
1147 void** datap
1148 )
1149 {
1150 const int status = nc_get_rec(ncid, (size_t)recnum, datap);
1151 if(status != NC_NOERR)
1152 {
1153 nc_advise("ncrecget", status, "ncid %d", ncid);
1154 return -1;
1155 }
1156 return 0;
1157 }
1158
1159
1160 int
ncrecput(int ncid,long recnum,void * const * datap)1161 ncrecput(
1162 int ncid,
1163 long recnum,
1164 void* const* datap
1165 )
1166 {
1167 const int status = nc_put_rec(ncid, (size_t)recnum, datap);
1168 if(status != NC_NOERR)
1169 {
1170 nc_advise("ncrecput", status, "ncid %d", ncid);
1171 return -1;
1172 }
1173 return 0;
1174 }
1175
1176 #endif /* NO_NETCDF_2 */
1177