📄 v2i.c
字号:
/* * Copyright 1996, University Corporation for Atmospheric Research * See netcdf/COPYRIGHT file for copying and redistribution conditions. *//* $Id: v2i.c 2501 2007-11-20 02:33:29Z benkirk $ */#include <config.h>#include <stdlib.h>#include <netcdf.h>#ifndef NO_NETCDF_2#if SIZEOF_LONG == SIZEOF_SIZE_T/* * We don't have to copy the arguments to switch from 'long' * to 'size_t' or 'ptrdiff_t'. Use dummy macros. */# define NDIMS_DECL# define A_DECL(name, type, ndims, rhs) \ const type *const name = ((const type *)(rhs))# define A_FREE(name)# define A_INIT(lhs, type, ndims, rhs) #else /* * We do have to copy the arguments to switch from 'long' * to 'size_t' or 'ptrdiff_t'. In my tests on an SGI, * any additional cost was lost in measurement variation. */# include "onstack.h"static size_tnvdims(int ncid, int varid){ NC *ncp; if(NC_check_id(ncid, &ncp) != NC_NOERR) return 0; { const NC_var *const varp = NC_lookupvar(ncp, varid); if(varp == NULL) return 0; return varp->ndims; }}#define NDIMS_DECL const size_t ndims = nvdims(ncid, varid);# define A_DECL(name, type, ndims, rhs) \ ALLOC_ONSTACK(name, type, ndims)# define A_FREE(name) \ FREE_ONSTACK(name)# define A_INIT(lhs, type, ndims, rhs) \ { \ const long *lp = rhs; \ type *tp = lhs; \ type *const end = lhs + ndims; \ while(tp < end) \ { \ *tp++ = (type) *lp++; \ } \ }#endiftypedef signed char schar;/* * Computes number of record variables in an open netCDF file, and an array of * the record variable ids, if the array parameter is non-null. */static intnumrecvars(int ncid, int *nrecvarsp, int *recvarids){ int status; int nvars = 0; int ndims = 0; int nrecvars = 0; int varid; int recdimid; int dimids[MAX_NC_DIMS]; status = nc_inq_nvars(ncid, &nvars); if(status != NC_NOERR) return status; status = nc_inq_unlimdim(ncid, &recdimid); if(status != NC_NOERR) return status; if (recdimid == -1) { *nrecvarsp = 0; return NC_NOERR; } nrecvars = 0; for (varid = 0; varid < nvars; varid++) { status = nc_inq_varndims(ncid, varid, &ndims); if(status != NC_NOERR) return status; status = nc_inq_vardimid(ncid, varid, dimids); if(status != NC_NOERR) return status; if (ndims > 0 && dimids[0] == recdimid) { if (recvarids != NULL) recvarids[nrecvars] = varid; nrecvars++; } } *nrecvarsp = nrecvars; return NC_NOERR;}/* * Computes record size (in bytes) of the record variable with a specified * variable id. Returns size as 0 if not a record variable. */static intncrecsize(int ncid, int varid, size_t *recsizep){ int status; int recdimid; nc_type type; int ndims; int dimids[MAX_NC_DIMS]; int id; size_t size; *recsizep = 0; status = nc_inq_unlimdim(ncid, &recdimid); if(status != NC_NOERR) return status; status = nc_inq_vartype(ncid, varid, &type); if(status != NC_NOERR) return status; status = nc_inq_varndims(ncid, varid, &ndims); if(status != NC_NOERR) return status; status = nc_inq_vardimid(ncid, varid, dimids); if(status != NC_NOERR) return status; if (ndims == 0 || dimids[0] != recdimid) { return NC_NOERR; } size = nctypelen(type); for (id = 1; id < ndims; id++) { size_t len; status = nc_inq_dimlen(ncid, dimids[id], &len); if(status != NC_NOERR) return status; size *= len; } *recsizep = size; return NC_NOERR;}/* * Retrieves the dimension sizes of a variable with a specified variable id in * an open netCDF file. Returns -1 on error. */static intdimsizes(int ncid, int varid, size_t *sizes){ int status; int ndims; int id; int dimids[MAX_NC_DIMS]; status = nc_inq_varndims(ncid, varid, &ndims); if(status != NC_NOERR) return status; status = nc_inq_vardimid(ncid, varid, dimids); if(status != NC_NOERR) return status; if (ndims == 0 || sizes == NULL) return NC_NOERR; for (id = 0; id < ndims; id++) { size_t len; status = nc_inq_dimlen(ncid, dimids[id], &len); if(status != NC_NOERR) return status; sizes[id] = len; } return NC_NOERR;}/* * Retrieves the number of record variables, the record variable ids, and the * record size of each record variable. If any pointer to info to be returned * is null, the associated information is not returned. Returns -1 on error. */intnc_inq_rec( int ncid, size_t *nrecvarsp, int *recvarids, size_t *recsizes){ int status; int nvars = 0; int recdimid; int varid; int rvarids[MAX_NC_VARS]; int nrvars = 0; status = nc_inq_nvars(ncid, &nvars); if(status != NC_NOERR) return status; status = nc_inq_unlimdim(ncid, &recdimid); if(status != NC_NOERR) return status; *nrecvarsp = 0; if (recdimid == -1) return NC_NOERR; status = numrecvars(ncid, &nrvars, rvarids); if(status != NC_NOERR) return status; if (nrecvarsp != NULL) *nrecvarsp = nrvars; if (recvarids != NULL) for (varid = 0; varid < nrvars; varid++) recvarids[varid] = rvarids[varid]; if (recsizes != NULL) for (varid = 0; varid < nrvars; varid++) { size_t rsize; status = ncrecsize(ncid, rvarids[varid], &rsize); if (status != NC_NOERR) return status; recsizes[varid] = rsize; } return NC_NOERR;}/* * Write one record's worth of data, except don't write to variables for which * the address of the data to be written is NULL. Return -1 on error. This is * the same as the ncrecput() in the library, except that can handle errors * better. */intnc_put_rec( int ncid, size_t recnum, void* const* datap){ int status; int varid; int rvarids[MAX_NC_VARS]; int nrvars; size_t start[MAX_NC_DIMS]; size_t edges[MAX_NC_DIMS]; status = numrecvars(ncid, &nrvars, rvarids); if(status != NC_NOERR) return status; if (nrvars == 0) return NC_NOERR; start[0] = recnum; for (varid = 1; varid < nrvars; varid++) start[varid] = 0; for (varid = 0; varid < nrvars; varid++) { if (datap[varid] != NULL) { status = dimsizes(ncid, rvarids[varid], edges); if(status != NC_NOERR) return status; edges[0] = 1; /* only 1 record's worth */ status = nc_put_vara(ncid, rvarids[varid], start, edges, datap[varid]); if(status != NC_NOERR) return status; } } return 0;}/* * Read one record's worth of data, except don't read from variables for which * the address of the data to be read is null. Return -1 on error. This is * the same as the ncrecget() in the library, except that can handle errors * better. */intnc_get_rec( int ncid, size_t recnum, void **datap){ int status; int varid; int rvarids[MAX_NC_VARS]; int nrvars; size_t start[MAX_NC_DIMS]; size_t edges[MAX_NC_DIMS]; status = numrecvars(ncid, &nrvars, rvarids); if(status != NC_NOERR) return status; if (nrvars == 0) return NC_NOERR; start[0] = recnum; for (varid = 1; varid < nrvars; varid++) start[varid] = 0; for (varid = 0; varid < nrvars; varid++) { if (datap[varid] != NULL) { status = dimsizes(ncid, rvarids[varid], edges); if(status != NC_NOERR) return status; edges[0] = 1; /* only 1 record's worth */ status = nc_get_vara(ncid, rvarids[varid], start, edges, datap[varid]); if(status != NC_NOERR) return status; } } return 0;}/* Begin globals *//* * Error code */#if !DLL_NETCDF /* define when library is not a DLL */int ncerr = NC_NOERR ;/* * The subroutines in error.c emit no messages unless NC_VERBOSE bit is on. * They call exit() when NC_FATAL bit is on. */int ncopts = (NC_FATAL | NC_VERBOSE) ;#endif/* End globals *//* Begin error handling */#include <stdio.h>#include <stdlib.h>#include <stdarg.h>/* */voidnc_advise(const char *routine_name, int err, const char *fmt,...){ va_list args; if(NC_ISSYSERR(err)) ncerr = NC_SYSERR; else ncerr = err; if( ncopts & NC_VERBOSE ) { (void) fprintf(stderr,"%s: ", routine_name); va_start(args ,fmt); (void) vfprintf(stderr,fmt,args); va_end(args); if(err != NC_NOERR) { (void) fprintf(stderr,": %s", nc_strerror(err)); } (void) fputc('\n',stderr); (void) fflush(stderr); /* to ensure log files are current */ } if( (ncopts & NC_FATAL) && err != NC_NOERR ) { exit(ncopts); }}/* End error handling */intnccreate(const char* path, int cmode){ int ncid; const int status = nc_create(path, cmode, &ncid); if(status != NC_NOERR) { nc_advise("nccreate", status, "filename \"%s\"", path); return -1; } return ncid;}intncopen(const char *path, int mode){ int ncid; const int status = nc_open(path, mode, &ncid); if(status != NC_NOERR) { nc_advise("ncopen", status, "filename \"%s\"", path); return -1; } return ncid;}intncredef(int ncid){ const int status = nc_redef(ncid); if(status != NC_NOERR) { nc_advise("ncredef", status, "ncid %d", ncid); return -1; } return 0;}intncendef(int ncid){ const int status = nc_enddef(ncid); if(status != NC_NOERR) { nc_advise("ncendef", status, "ncid %d", ncid); return -1; } return 0;}intncclose(int ncid){ const int status = nc_close(ncid); if(status != NC_NOERR) { nc_advise("ncclose", status, "ncid %d", ncid); return -1; } return 0;}intncinquire( int ncid, int* ndims, int* nvars, int* natts, int* recdim){ int nd, nv, na; const int status = nc_inq(ncid, &nd, &nv, &na, recdim); if(status != NC_NOERR) { nc_advise("ncinquire", status, "ncid %d", ncid); return -1; } /* else */ if(ndims != NULL) *ndims = (int) nd; if(nvars != NULL) *nvars = (int) nv; if(natts != NULL) *natts = (int) na; return ncid;}intncsync(int ncid){ const int status = nc_sync(ncid); if(status != NC_NOERR) { nc_advise("ncsync", status, "ncid %d", ncid); return -1; } return 0;}intncabort(int ncid){ const int status = nc_abort(ncid); if(status != NC_NOERR) { nc_advise("ncabort", status, "ncid %d", ncid); return -1; } return 0;}intncdimdef( int ncid, const char* name, long length){ int dimid; int status; if(length < 0) { status = NC_EDIMSIZE; nc_advise("ncdimdef", status, "ncid %d", ncid); return -1; } status = nc_def_dim(ncid, name, (size_t)length, &dimid); if(status != NC_NOERR) { nc_advise("ncdimdef", status, "ncid %d", ncid); return -1; } return dimid;}intncdimid(int ncid, const char* name){ int dimid; const int status = nc_inq_dimid(ncid, name, &dimid); if(status != NC_NOERR) { nc_advise("ncdimid", status, "ncid %d", ncid); return -1; } return dimid;}intncdiminq( int ncid, int dimid, char* name, long* length){ size_t ll; const int status = nc_inq_dim(ncid, dimid, name, &ll); if(status != NC_NOERR) { nc_advise("ncdiminq", status, "ncid %d", ncid); return -1; } /* else */ if(length != NULL) *length = (int) ll; return dimid;}intncdimrename(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -