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


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed