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