/* Do not edit this file. It is produced from the corresponding .m4 source */ /* * Copyright 1996, University Corporation for Atmospheric Research * See netcdf/COPYRIGHT file for copying and redistribution conditions. */ /* $Id: putget.c,v 1.3 2005/07/19 23:37:24 andy Exp $ */ #include "nc.h" #include #include #include #include "ncx.h" #include "fbits.h" #include "onstack.h" #undef MIN /* system may define MIN somewhere and complain */ #define MIN(mm,nn) (((mm) < (nn)) ? (mm) : (nn)) /* #define ODEBUG 1 */ #if ODEBUG #include /* * Print the values of an array of size_t */ void arrayp(const char *label, size_t count, const size_t *array) { (void) fprintf(stderr, "%s", label); (void) fputc('\t',stderr); for(; count > 0; count--, array++) (void) fprintf(stderr," %lu", (unsigned long)*array); (void) fputc('\n',stderr); } #endif /* ODEBUG */ /* Begin fill */ /* * This is tunable parameter. * It essentially controls the tradeoff between the number of times * memcpy() gets called to copy the external data to fill * a large buffer vs the number of times its called to * prepare the external data. */ #define NFILL 16 /* * Next 6 type specific functions * Fill a some memory with the default special value. * Formerly NC_arrayfill() */ static int NC_fill_schar( void **xpp, size_t nelems) /* how many */ { schar fillp[NFILL * sizeof(double)/X_SIZEOF_CHAR]; assert(nelems <= sizeof(fillp)/sizeof(fillp[0])); { schar *vp = fillp; /* lower bound of area to be filled */ const schar *const end = vp + nelems; while(vp < end) { *vp++ = NC_FILL_BYTE; } } return ncx_putn_schar_schar(xpp, nelems, fillp); } static int NC_fill_char( void **xpp, size_t nelems) /* how many */ { char fillp[NFILL * sizeof(double)/X_SIZEOF_CHAR]; assert(nelems <= sizeof(fillp)/sizeof(fillp[0])); { char *vp = fillp; /* lower bound of area to be filled */ const char *const end = vp + nelems; while(vp < end) { *vp++ = NC_FILL_CHAR; } } return ncx_putn_char_char(xpp, nelems, fillp); } static int NC_fill_short( void **xpp, size_t nelems) /* how many */ { short fillp[NFILL * sizeof(double)/X_SIZEOF_SHORT]; assert(nelems <= sizeof(fillp)/sizeof(fillp[0])); { short *vp = fillp; /* lower bound of area to be filled */ const short *const end = vp + nelems; while(vp < end) { *vp++ = NC_FILL_SHORT; } } return ncx_putn_short_short(xpp, nelems, fillp); } #if (SIZEOF_INT >= X_SIZEOF_INT) static int NC_fill_int( void **xpp, size_t nelems) /* how many */ { int fillp[NFILL * sizeof(double)/X_SIZEOF_INT]; assert(nelems <= sizeof(fillp)/sizeof(fillp[0])); { int *vp = fillp; /* lower bound of area to be filled */ const int *const end = vp + nelems; while(vp < end) { *vp++ = NC_FILL_INT; } } return ncx_putn_int_int(xpp, nelems, fillp); } #elif SIZEOF_LONG == X_SIZEOF_INT static int NC_fill_int( void **xpp, size_t nelems) /* how many */ { long fillp[NFILL * sizeof(double)/X_SIZEOF_INT]; assert(nelems <= sizeof(fillp)/sizeof(fillp[0])); { long *vp = fillp; /* lower bound of area to be filled */ const long *const end = vp + nelems; while(vp < end) { *vp++ = NC_FILL_INT; } } return ncx_putn_int_long(xpp, nelems, fillp); } #else #error "NC_fill_int implementation" #endif static int NC_fill_float( void **xpp, size_t nelems) /* how many */ { float fillp[NFILL * sizeof(double)/X_SIZEOF_FLOAT]; assert(nelems <= sizeof(fillp)/sizeof(fillp[0])); { float *vp = fillp; /* lower bound of area to be filled */ const float *const end = vp + nelems; while(vp < end) { *vp++ = NC_FILL_FLOAT; } } return ncx_putn_float_float(xpp, nelems, fillp); } static int NC_fill_double( void **xpp, size_t nelems) /* how many */ { double fillp[NFILL * sizeof(double)/X_SIZEOF_DOUBLE]; assert(nelems <= sizeof(fillp)/sizeof(fillp[0])); { double *vp = fillp; /* lower bound of area to be filled */ const double *const end = vp + nelems; while(vp < end) { *vp++ = NC_FILL_DOUBLE; } } return ncx_putn_double_double(xpp, nelems, fillp); } /* * Fill the external space for variable 'varp' values at 'recno' * with the appropriate value. If 'varp' is not a record * variable, fill the whole thing. * Formerly xdr_NC_fill() */ int fill_NC_var(NC *ncp, const NC_var *varp, size_t recno) { char xfillp[NFILL * X_SIZEOF_DOUBLE]; const size_t step = varp->xsz; const size_t nelems = sizeof(xfillp)/step; const size_t xsz = varp->xsz * nelems; NC_attr **attrpp = NULL; off_t offset; size_t remaining = varp->len; void *xp; int status = NC_NOERR; /* * Set up fill value */ attrpp = NC_findattr(&varp->attrs, _FillValue); if( attrpp != NULL ) { /* User defined fill value */ if( (*attrpp)->type != varp->type || (*attrpp)->nelems != 1 ) { return NC_EBADTYPE; } else { /* Use the user defined value */ char *cp = xfillp; const char *const end = &xfillp[sizeof(xfillp)]; assert(step <= (*attrpp)->xsz); for( /*NADA*/; cp < end; cp += step) { (void) memcpy(cp, (*attrpp)->xvalue, step); } } } else { /* use the default */ assert(xsz % X_ALIGN == 0); assert(xsz <= sizeof(xfillp)); xp = xfillp; switch(varp->type){ case NC_BYTE : status = NC_fill_schar(&xp, nelems); break; case NC_CHAR : status = NC_fill_char(&xp, nelems); break; case NC_SHORT : status = NC_fill_short(&xp, nelems); break; case NC_INT : status = NC_fill_int(&xp, nelems); break; case NC_FLOAT : status = NC_fill_float(&xp, nelems); break; case NC_DOUBLE : status = NC_fill_double(&xp, nelems); break; default : assert("fill_NC_var invalid type" == 0); status = NC_EBADTYPE; break; } if(status != NC_NOERR) return status; assert(xp == xfillp + xsz); } /* * copyout: * xfillp now contains 'nelems' elements of the fill value * in external representation. */ /* * Copy it out. */ offset = varp->begin; if(IS_RECVAR(varp)) { offset += (off_t)ncp->recsize * recno; } assert(remaining > 0); for(;;) { const size_t chunksz = MIN(remaining, ncp->chunk); size_t ii; assert(chunksz % X_ALIGN == 0); status = ncp->nciop->get(ncp->nciop, offset, chunksz, RGN_WRITE, &xp); if(status != NC_NOERR) { return status; } /* * fill the chunksz buffer in units of xsz */ for(ii = 0; ii < chunksz/xsz; ii++) { (void) memcpy(xp, xfillp, xsz); xp = (char *)xp + xsz; } /* * Deal with any remainder */ { const size_t rem = chunksz % xsz; if(rem != 0) { (void) memcpy(xp, xfillp, rem); /* xp = (char *)xp + xsz; */ } } status = ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); if(status != NC_NOERR) { break; } remaining -= chunksz; if(remaining == 0) break; /* normal loop exit */ offset += chunksz; } return status; } /* End fill */ /* * Add a record containing the fill values. */ static int NCfillrecord(NC *ncp, const NC_var *const *varpp, size_t recno) { size_t ii = 0; for(; ii < ncp->vars.nelems; ii++, varpp++) { if( !IS_RECVAR(*varpp) ) { continue; /* skip non-record variables */ } { const int status = fill_NC_var(ncp, *varpp, recno); if(status != NC_NOERR) return status; } } return NC_NOERR; } /* * It is advantageous to * #define TOUCH_LAST * when using memory mapped io. */ #if TOUCH_LAST /* * Grow the file to a size which can contain recno */ static int NCtouchlast(NC *ncp, const NC_var *const *varpp, size_t recno) { int status = NC_NOERR; const NC_var *varp = NULL; { size_t ii = 0; for(; ii < ncp->vars.nelems; ii++, varpp++) { if( !IS_RECVAR(*varpp) ) { continue; /* skip non-record variables */ } varp = *varpp; } } assert(varp != NULL); assert( IS_RECVAR(varp) ); { const off_t offset = varp->begin + (off_t)(recno-1) * (off_t)ncp->recsize + (off_t)(varp->len - varp->xsz); void *xp; status = ncp->nciop->get(ncp->nciop, offset, varp->xsz, RGN_WRITE, &xp); if(status != NC_NOERR) return status; (void)memset(xp, 0, varp->xsz); status = ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); } return status; } #endif /* TOUCH_LAST */ /* * Ensure that the netcdf file has 'numrecs' records, * add records and fill as neccessary. */ static int NCvnrecs(NC *ncp, size_t numrecs) { int status = NC_NOERR; if(numrecs > ncp->numrecs) { #if TOUCH_LAST status = NCtouchlast(ncp, (const NC_var *const*)ncp->vars.value, numrecs); if(status != NC_NOERR) return status; #endif /* TOUCH_LAST */ set_NC_ndirty(ncp); if(!NC_dofill(ncp)) { /* Go directly to jail, do not pass go */ ncp->numrecs = numrecs; } else { size_t unfilled = numrecs - ncp->numrecs; size_t ii; for(ii = 0; ii < unfilled; ii++, ncp->numrecs++) { status = NCfillrecord(ncp, (const NC_var *const*)ncp->vars.value, ncp->numrecs); if(status != NC_NOERR) { break; } } if(status != NC_NOERR) return status; } if(NC_doNsync(ncp)) { status = write_numrecs(ncp); } } return status; } /* * Check whether 'coord' values are valid for the variable. */ static int NCcoordck(NC *ncp, const NC_var *varp, const size_t *coord) { const size_t *ip; size_t *up; if(varp->ndims == 0) return NC_NOERR; /* 'scalar' variable */ if(IS_RECVAR(varp)) { if(*coord > X_INT_MAX) return NC_EINVALCOORDS; /* sanity check */ if(NC_readonly(ncp) && *coord >= ncp->numrecs) { if(!NC_doNsync(ncp)) return NC_EINVALCOORDS; /* else */ { /* Update from disk and check again */ const int status = read_numrecs(ncp); if(status != NC_NOERR) return status; if(*coord >= ncp->numrecs) return NC_EINVALCOORDS; } } ip = coord + 1; up = varp->shape + 1; } else { ip = coord; up = varp->shape; } #ifdef CDEBUG fprintf(stderr," NCcoordck: coord %ld, count %d, ip %ld\n", coord, varp->ndims, ip ); #endif /* CDEBUG */ for(; ip < coord + varp->ndims; ip++, up++) { #ifdef CDEBUG fprintf(stderr," NCcoordck: ip %p, *ip %ld, up %p, *up %lu\n", ip, *ip, up, *up ); #endif /* CDEBUG */ /* cast needed for braindead systems with signed size_t */ if((unsigned long) *ip >= (unsigned long) *up ) return NC_EINVALCOORDS; } return NC_NOERR; } /* * Check whether 'edges' are valid for the variable and 'start' */ /*ARGSUSED*/ static int NCedgeck(const NC *ncp, const NC_var *varp, const size_t *start, const size_t *edges) { const size_t *const end = start + varp->ndims; const size_t *shp = varp->shape; (void)ncp; if(varp->ndims == 0) return NC_NOERR; /* 'scalar' variable */ if(IS_RECVAR(varp)) { start++; edges++; shp++; } for(; start < end; start++, edges++, shp++) { /* cast needed for braindead systems with signed size_t */ if((unsigned long) *edges > *shp || (unsigned long) *start + (unsigned long) *edges > *shp) { return(NC_EEDGE); } } return NC_NOERR; } /* * Translate the (variable, coord) pair into a seek index */ static off_t NC_varoffset(const NC *ncp, const NC_var *varp, const size_t *coord) { if(varp->ndims == 0) /* 'scalar' variable */ return varp->begin; if(varp->ndims == 1) { if(IS_RECVAR(varp)) return varp->begin + (off_t)(*coord) * (off_t)ncp->recsize; /* else */ return varp->begin + (off_t)(*coord) * (off_t)varp->xsz; } /* else */ { off_t lcoord = (off_t)coord[varp->ndims -1]; size_t *up = varp->dsizes +1; const size_t *ip = coord; const size_t *const end = varp->dsizes + varp->ndims; if(IS_RECVAR(varp)) up++, ip++; for(; up < end; up++, ip++) lcoord += *up * *ip; lcoord *= varp->xsz; if(IS_RECVAR(varp)) lcoord += (off_t)(*coord) * ncp->recsize; lcoord += varp->begin; return lcoord; } } static int putNCvx_char_char(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const char *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_char_char(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_schar_schar(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const schar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_schar_schar(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_schar_uchar(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const uchar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_schar_uchar(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_schar_short(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const short *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_schar_short(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_schar_int(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const int *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_schar_int(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_schar_long(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const long *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_schar_long(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_schar_float(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const float *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_schar_float(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_schar_double(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const double *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_schar_double(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_short_schar(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const schar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_short_schar(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_short_uchar(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const uchar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_short_uchar(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_short_short(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const short *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_short_short(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_short_int(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const int *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_short_int(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_short_long(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const long *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_short_long(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_short_float(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const float *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_short_float(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_short_double(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const double *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_short_double(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_int_schar(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const schar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_int_schar(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_int_uchar(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const uchar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_int_uchar(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_int_short(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const short *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_int_short(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_int_int(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const int *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_int_int(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_int_long(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const long *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_int_long(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_int_float(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const float *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_int_float(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_int_double(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const double *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_int_double(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_float_schar(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const schar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_float_schar(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_float_uchar(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const uchar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_float_uchar(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_float_short(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const short *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_float_short(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_float_int(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const int *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_float_int(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_float_long(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const long *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_float_long(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_float_float(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const float *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_float_float(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_float_double(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const double *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_float_double(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_double_schar(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const schar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_double_schar(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_double_uchar(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const uchar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_double_uchar(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_double_short(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const short *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_double_short(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_double_int(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const int *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_double_int(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_double_long(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const long *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_double_long(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_double_float(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const float *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_double_float(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCvx_double_double(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const double *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nput = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, RGN_WRITE, &xp); if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_putn_double_double(&xp, nput, value); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ status = lstatus; } (void) ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nput; } return status; } static int putNCv_text(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const char *value) { if(varp->type != NC_CHAR) return NC_ECHAR; return putNCvx_char_char(ncp, varp, start, nelems, value); } static int putNCv_schar(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const schar *value) { switch(varp->type){ case NC_CHAR: return NC_ECHAR; case NC_BYTE: return putNCvx_schar_schar(ncp, varp, start, nelems, value); case NC_SHORT: return putNCvx_short_schar(ncp, varp, start, nelems, value); case NC_INT: return putNCvx_int_schar(ncp, varp, start, nelems, value); case NC_FLOAT: return putNCvx_float_schar(ncp, varp, start, nelems, value); case NC_DOUBLE: return putNCvx_double_schar(ncp, varp, start, nelems, value); } return NC_EBADTYPE; } static int putNCv_uchar(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const uchar *value) { switch(varp->type){ case NC_CHAR: return NC_ECHAR; case NC_BYTE: return putNCvx_schar_uchar(ncp, varp, start, nelems, value); case NC_SHORT: return putNCvx_short_uchar(ncp, varp, start, nelems, value); case NC_INT: return putNCvx_int_uchar(ncp, varp, start, nelems, value); case NC_FLOAT: return putNCvx_float_uchar(ncp, varp, start, nelems, value); case NC_DOUBLE: return putNCvx_double_uchar(ncp, varp, start, nelems, value); } return NC_EBADTYPE; } static int putNCv_short(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const short *value) { switch(varp->type){ case NC_CHAR: return NC_ECHAR; case NC_BYTE: return putNCvx_schar_short(ncp, varp, start, nelems, value); case NC_SHORT: return putNCvx_short_short(ncp, varp, start, nelems, value); case NC_INT: return putNCvx_int_short(ncp, varp, start, nelems, value); case NC_FLOAT: return putNCvx_float_short(ncp, varp, start, nelems, value); case NC_DOUBLE: return putNCvx_double_short(ncp, varp, start, nelems, value); } return NC_EBADTYPE; } static int putNCv_int(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const int *value) { switch(varp->type){ case NC_CHAR: return NC_ECHAR; case NC_BYTE: return putNCvx_schar_int(ncp, varp, start, nelems, value); case NC_SHORT: return putNCvx_short_int(ncp, varp, start, nelems, value); case NC_INT: return putNCvx_int_int(ncp, varp, start, nelems, value); case NC_FLOAT: return putNCvx_float_int(ncp, varp, start, nelems, value); case NC_DOUBLE: return putNCvx_double_int(ncp, varp, start, nelems, value); } return NC_EBADTYPE; } static int putNCv_long(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const long *value) { switch(varp->type){ case NC_CHAR: return NC_ECHAR; case NC_BYTE: return putNCvx_schar_long(ncp, varp, start, nelems, value); case NC_SHORT: return putNCvx_short_long(ncp, varp, start, nelems, value); case NC_INT: return putNCvx_int_long(ncp, varp, start, nelems, value); case NC_FLOAT: return putNCvx_float_long(ncp, varp, start, nelems, value); case NC_DOUBLE: return putNCvx_double_long(ncp, varp, start, nelems, value); } return NC_EBADTYPE; } static int putNCv_float(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const float *value) { switch(varp->type){ case NC_CHAR: return NC_ECHAR; case NC_BYTE: return putNCvx_schar_float(ncp, varp, start, nelems, value); case NC_SHORT: return putNCvx_short_float(ncp, varp, start, nelems, value); case NC_INT: return putNCvx_int_float(ncp, varp, start, nelems, value); case NC_FLOAT: return putNCvx_float_float(ncp, varp, start, nelems, value); case NC_DOUBLE: return putNCvx_double_float(ncp, varp, start, nelems, value); } return NC_EBADTYPE; } static int putNCv_double(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const double *value) { switch(varp->type){ case NC_CHAR: return NC_ECHAR; case NC_BYTE: return putNCvx_schar_double(ncp, varp, start, nelems, value); case NC_SHORT: return putNCvx_short_double(ncp, varp, start, nelems, value); case NC_INT: return putNCvx_int_double(ncp, varp, start, nelems, value); case NC_FLOAT: return putNCvx_float_double(ncp, varp, start, nelems, value); case NC_DOUBLE: return putNCvx_double_double(ncp, varp, start, nelems, value); } return NC_EBADTYPE; } static int getNCvx_char_char(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, char *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_char_char(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_schar_schar(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, schar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_schar_schar(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_schar_uchar(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, uchar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_schar_uchar(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_schar_short(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, short *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_schar_short(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_schar_int(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, int *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_schar_int(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_schar_long(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, long *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_schar_long(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_schar_float(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, float *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_schar_float(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_schar_double(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, double *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_schar_double(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_short_schar(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, schar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_short_schar(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_short_uchar(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, uchar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_short_uchar(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_short_short(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, short *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_short_short(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_short_int(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, int *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_short_int(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_short_long(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, long *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_short_long(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_short_float(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, float *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_short_float(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_short_double(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, double *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_short_double(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_int_schar(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, schar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_int_schar(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_int_uchar(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, uchar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_int_uchar(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_int_short(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, short *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_int_short(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_int_int(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, int *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_int_int(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_int_long(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, long *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_int_long(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_int_float(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, float *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_int_float(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_int_double(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, double *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_int_double(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_float_schar(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, schar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_float_schar(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_float_uchar(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, uchar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_float_uchar(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_float_short(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, short *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_float_short(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_float_int(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, int *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_float_int(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_float_long(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, long *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_float_long(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_float_float(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, float *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_float_float(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_float_double(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, double *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_float_double(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_double_schar(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, schar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_double_schar(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_double_uchar(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, uchar *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_double_uchar(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_double_short(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, short *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_double_short(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_double_int(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, int *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_double_int(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_double_long(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, long *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_double_long(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_double_float(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, float *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_double_float(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCvx_double_double(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, double *value) { off_t offset = NC_varoffset(ncp, varp, start); size_t remaining = varp->xsz * nelems; int status = NC_NOERR; const void *xp; if(nelems == 0) return NC_NOERR; assert(value != NULL); for(;;) { size_t extent = MIN(remaining, ncp->chunk); size_t nget = ncx_howmany(varp->type, extent); int lstatus = ncp->nciop->get(ncp->nciop, offset, extent, 0, (void **)&xp); /* cast away const */ if(lstatus != NC_NOERR) return lstatus; lstatus = ncx_getn_double_double(&xp, nget, value); if(lstatus != NC_NOERR && status == NC_NOERR) status = lstatus; (void) ncp->nciop->rel(ncp->nciop, offset, 0); remaining -= extent; if(remaining == 0) break; /* normal loop exit */ offset += extent; value += nget; } return status; } static int getNCv_schar(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, schar *value) { switch(varp->type){ case NC_CHAR: return NC_ECHAR; case NC_BYTE: return getNCvx_schar_schar(ncp, varp, start, nelems, value); case NC_SHORT: return getNCvx_short_schar(ncp, varp, start, nelems, value); case NC_INT: return getNCvx_int_schar(ncp, varp, start, nelems, value); case NC_FLOAT: return getNCvx_float_schar(ncp, varp, start, nelems, value); case NC_DOUBLE: return getNCvx_double_schar(ncp, varp, start, nelems, value); } return NC_EBADTYPE; } static int getNCv_uchar(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, uchar *value) { switch(varp->type){ case NC_CHAR: return NC_ECHAR; case NC_BYTE: return getNCvx_schar_uchar(ncp, varp, start, nelems, value); case NC_SHORT: return getNCvx_short_uchar(ncp, varp, start, nelems, value); case NC_INT: return getNCvx_int_uchar(ncp, varp, start, nelems, value); case NC_FLOAT: return getNCvx_float_uchar(ncp, varp, start, nelems, value); case NC_DOUBLE: return getNCvx_double_uchar(ncp, varp, start, nelems, value); } return NC_EBADTYPE; } static int getNCv_short(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, short *value) { switch(varp->type){ case NC_CHAR: return NC_ECHAR; case NC_BYTE: return getNCvx_schar_short(ncp, varp, start, nelems, value); case NC_SHORT: return getNCvx_short_short(ncp, varp, start, nelems, value); case NC_INT: return getNCvx_int_short(ncp, varp, start, nelems, value); case NC_FLOAT: return getNCvx_float_short(ncp, varp, start, nelems, value); case NC_DOUBLE: return getNCvx_double_short(ncp, varp, start, nelems, value); } return NC_EBADTYPE; } static int getNCv_int(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, int *value) { switch(varp->type){ case NC_CHAR: return NC_ECHAR; case NC_BYTE: return getNCvx_schar_int(ncp, varp, start, nelems, value); case NC_SHORT: return getNCvx_short_int(ncp, varp, start, nelems, value); case NC_INT: return getNCvx_int_int(ncp, varp, start, nelems, value); case NC_FLOAT: return getNCvx_float_int(ncp, varp, start, nelems, value); case NC_DOUBLE: return getNCvx_double_int(ncp, varp, start, nelems, value); } return NC_EBADTYPE; } static int getNCv_long(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, long *value) { switch(varp->type){ case NC_CHAR: return NC_ECHAR; case NC_BYTE: return getNCvx_schar_long(ncp, varp, start, nelems, value); case NC_SHORT: return getNCvx_short_long(ncp, varp, start, nelems, value); case NC_INT: return getNCvx_int_long(ncp, varp, start, nelems, value); case NC_FLOAT: return getNCvx_float_long(ncp, varp, start, nelems, value); case NC_DOUBLE: return getNCvx_double_long(ncp, varp, start, nelems, value); } return NC_EBADTYPE; } static int getNCv_float(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, float *value) { switch(varp->type){ case NC_CHAR: return NC_ECHAR; case NC_BYTE: return getNCvx_schar_float(ncp, varp, start, nelems, value); case NC_SHORT: return getNCvx_short_float(ncp, varp, start, nelems, value); case NC_INT: return getNCvx_int_float(ncp, varp, start, nelems, value); case NC_FLOAT: return getNCvx_float_float(ncp, varp, start, nelems, value); case NC_DOUBLE: return getNCvx_double_float(ncp, varp, start, nelems, value); } return NC_EBADTYPE; } static int getNCv_double(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, double *value) { switch(varp->type){ case NC_CHAR: return NC_ECHAR; case NC_BYTE: return getNCvx_schar_double(ncp, varp, start, nelems, value); case NC_SHORT: return getNCvx_short_double(ncp, varp, start, nelems, value); case NC_INT: return getNCvx_int_double(ncp, varp, start, nelems, value); case NC_FLOAT: return getNCvx_float_double(ncp, varp, start, nelems, value); case NC_DOUBLE: return getNCvx_double_double(ncp, varp, start, nelems, value); } return NC_EBADTYPE; } static int getNCv_text(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, char *value) { if(varp->type != NC_CHAR) return NC_ECHAR; return getNCvx_char_char(ncp, varp, start, nelems, value); } /* * Copy 'nbytes' contiguous external values * from ('inncp', invp', inncoord') * to ('outncp', 'outvp', 'outcoord') * 'inncp' shouldn't be the same as 'outncp'. * Used only by ncvarcopy() */ static int NCxvarcpy(NC *inncp, NC_var *invp, size_t *incoord, NC *outncp, NC_var *outvp, size_t *outcoord, size_t nbytes) { int status; off_t inoffset = NC_varoffset(inncp, invp, incoord); off_t outoffset = NC_varoffset(outncp, outvp, outcoord); void *inxp; void *outxp; const size_t chunk = MIN(inncp->chunk, outncp->chunk); do { const size_t extent = MIN(nbytes, chunk); status = inncp->nciop->get(inncp->nciop, inoffset, extent, 0, &inxp); if(status != NC_NOERR) return status; status = outncp->nciop->get(outncp->nciop, outoffset, extent, RGN_WRITE, &outxp); if(status != NC_NOERR) { (void) inncp->nciop->rel(inncp->nciop, inoffset, 0); break; } (void) memcpy(outxp, inxp, extent); status = outncp->nciop->rel(outncp->nciop, outoffset, RGN_MODIFIED); (void) inncp->nciop->rel(inncp->nciop, inoffset, 0); nbytes -= extent; if(nbytes == 0) break; /* normal loop exit */ inoffset += extent; outoffset += extent; } while (status == NC_NOERR); return status; } /* * For ncvar{put,get}, * find the largest contiguous block from within 'edges'. * returns the index to the left of this (which may be -1). * Compute the number of contiguous elements and return * that in *iocountp. * The presence of "record" variables makes this routine * overly subtle. */ static int NCiocount(const NC *const ncp, const NC_var *const varp, const size_t *const edges, size_t *const iocountp) { const size_t *edp0 = edges; const size_t *edp = edges + varp->ndims; const size_t *shp = varp->shape + varp->ndims; if(IS_RECVAR(varp)) { if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only 'record' variable */ *iocountp = *edges; return(0); } /* else */ edp0++; } assert(edges != NULL); /* find max contiguous */ while(edp > edp0) { shp--; edp--; if(*edp < *shp ) { const size_t *zedp = edp; while(zedp >= edp0) { if(*zedp == 0) { *iocountp = 0; goto done; } /* Tip of the hat to segmented architectures */ if(zedp == edp0) break; zedp--; } break; } assert(*edp == *shp); } /* * edp, shp reference rightmost index s.t. *(edp +1) == *(shp +1) * * Or there is only one dimension. * If there is only one dimension and it is 'non record' dimension, * edp is &edges[0] and we will return -1. * If there is only one dimension and and it is a "record dimension", * edp is &edges[1] (out of bounds) and we will return 0; */ assert(shp >= varp->shape + varp->ndims -1 || *(edp +1) == *(shp +1)); /* now accumulate max count for a single io operation */ for(*iocountp = 1, edp0 = edp; edp0 < edges + varp->ndims; edp0++) { *iocountp *= *edp0; } done: return((int)(edp - edges) - 1); } /* * Set the elements of the array 'upp' to * the sum of the corresponding elements of * 'stp' and 'edp'. 'end' should be &stp[nelems]. */ static void set_upper(size_t *upp, /* modified on return */ const size_t *stp, const size_t *edp, const size_t *const end) { while(upp < end) { *upp++ = *stp++ + *edp++; } } /* * The infamous and oft-discussed odometer code. * * 'start[]' is the starting coordinate. * 'upper[]' is the upper bound s.t. start[ii] < upper[ii]. * 'coord[]' is the register, the current coordinate value. * For some ii, * upp == &upper[ii] * cdp == &coord[ii] * * Running this routine increments *cdp. * * If after the increment, *cdp is equal to *upp * (and cdp is not the leftmost dimension), * *cdp is "zeroed" to the starting value and * we need to "carry", eg, increment one place to * the left. * * TODO: Some architectures hate recursion? * Reimplement non-recursively. */ static void odo1(const size_t *const start, const size_t *const upper, size_t *const coord, /* modified on return */ const size_t *upp, size_t *cdp) { assert(coord <= cdp && cdp <= coord + NC_MAX_DIMS); assert(upper <= upp && upp <= upper + NC_MAX_DIMS); assert(upp - upper == cdp - coord); assert(*cdp <= *upp); (*cdp)++; if(cdp != coord && *cdp >= *upp) { *cdp = start[cdp - coord]; odo1(start, upper, coord, upp -1, cdp -1); } } #ifdef _CRAYC #pragma _CRI noinline odo1 #endif /* Public */ int nc_put_var1_text(int ncid, int varid, const size_t *coord, const char *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type != NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, coord); if(status != NC_NOERR) return status; if(IS_RECVAR(varp)) { status = NCvnrecs(ncp, *coord +1); if(status != NC_NOERR) return status; } return putNCv_text(ncp, varp, coord, 1, value); } int nc_put_var1_uchar(int ncid, int varid, const size_t *coord, const uchar *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, coord); if(status != NC_NOERR) return status; if(IS_RECVAR(varp)) { status = NCvnrecs(ncp, *coord +1); if(status != NC_NOERR) return status; } return putNCv_uchar(ncp, varp, coord, 1, value); } int nc_put_var1_schar(int ncid, int varid, const size_t *coord, const schar *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, coord); if(status != NC_NOERR) return status; if(IS_RECVAR(varp)) { status = NCvnrecs(ncp, *coord +1); if(status != NC_NOERR) return status; } return putNCv_schar(ncp, varp, coord, 1, value); } int nc_put_var1_short(int ncid, int varid, const size_t *coord, const short *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, coord); if(status != NC_NOERR) return status; if(IS_RECVAR(varp)) { status = NCvnrecs(ncp, *coord +1); if(status != NC_NOERR) return status; } return putNCv_short(ncp, varp, coord, 1, value); } int nc_put_var1_int(int ncid, int varid, const size_t *coord, const int *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, coord); if(status != NC_NOERR) return status; if(IS_RECVAR(varp)) { status = NCvnrecs(ncp, *coord +1); if(status != NC_NOERR) return status; } return putNCv_int(ncp, varp, coord, 1, value); } int nc_put_var1_long(int ncid, int varid, const size_t *coord, const long *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, coord); if(status != NC_NOERR) return status; if(IS_RECVAR(varp)) { status = NCvnrecs(ncp, *coord +1); if(status != NC_NOERR) return status; } return putNCv_long(ncp, varp, coord, 1, value); } int nc_put_var1_float(int ncid, int varid, const size_t *coord, const float *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, coord); if(status != NC_NOERR) return status; if(IS_RECVAR(varp)) { status = NCvnrecs(ncp, *coord +1); if(status != NC_NOERR) return status; } return putNCv_float(ncp, varp, coord, 1, value); } int nc_put_var1_double(int ncid, int varid, const size_t *coord, const double *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, coord); if(status != NC_NOERR) return status; if(IS_RECVAR(varp)) { status = NCvnrecs(ncp, *coord +1); if(status != NC_NOERR) return status; } return putNCv_double(ncp, varp, coord, 1, value); } /* deprecated, used to support the 2.x interface */ int nc_put_var1(int ncid, int varid, const size_t *coord, const void *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; switch(varp->type){ case NC_CHAR: return nc_put_var1_text(ncid, varid, coord, (const char *) value); case NC_BYTE: return nc_put_var1_schar(ncid, varid, coord, (const schar *) value); case NC_SHORT: return nc_put_var1_short(ncid, varid, coord, (const short *) value); case NC_INT: return nc_put_var1_int(ncid, varid, coord, (const int *) value); case NC_FLOAT: return nc_put_var1_float(ncid, varid, coord, (const float *) value); case NC_DOUBLE: return nc_put_var1_double(ncid, varid, coord, (const double *) value); } return NC_EBADTYPE; } int nc_get_var1_text(int ncid, int varid, const size_t *coord, char *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type != NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, coord); if(status != NC_NOERR) return status; return getNCv_text(ncp, varp, coord, 1, value); } int nc_get_var1_uchar(int ncid, int varid, const size_t *coord, uchar *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, coord); if(status != NC_NOERR) return status; return getNCv_uchar(ncp, varp, coord, 1, value); } int nc_get_var1_schar(int ncid, int varid, const size_t *coord, schar *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, coord); if(status != NC_NOERR) return status; return getNCv_schar(ncp, varp, coord, 1, value); } int nc_get_var1_short(int ncid, int varid, const size_t *coord, short *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, coord); if(status != NC_NOERR) return status; return getNCv_short(ncp, varp, coord, 1, value); } int nc_get_var1_int(int ncid, int varid, const size_t *coord, int *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, coord); if(status != NC_NOERR) return status; return getNCv_int(ncp, varp, coord, 1, value); } int nc_get_var1_long(int ncid, int varid, const size_t *coord, long *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, coord); if(status != NC_NOERR) return status; return getNCv_long(ncp, varp, coord, 1, value); } int nc_get_var1_float(int ncid, int varid, const size_t *coord, float *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, coord); if(status != NC_NOERR) return status; return getNCv_float(ncp, varp, coord, 1, value); } int nc_get_var1_double(int ncid, int varid, const size_t *coord, double *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, coord); if(status != NC_NOERR) return status; return getNCv_double(ncp, varp, coord, 1, value); } /* deprecated, used to support the 2.x interface */ int nc_get_var1(int ncid, int varid, const size_t *coord, void *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; switch(varp->type){ case NC_CHAR: return nc_get_var1_text(ncid, varid, coord, (char *) value); case NC_BYTE: return nc_get_var1_schar(ncid, varid, coord, (schar *) value); case NC_SHORT: return nc_get_var1_short(ncid, varid, coord, (short *) value); case NC_INT: return nc_get_var1_int(ncid, varid, coord, (int *) value); case NC_FLOAT: return nc_get_var1_float(ncid, varid, coord, (float *) value); case NC_DOUBLE: return nc_get_var1_double(ncid, varid, coord, (double *) value); } return NC_EBADTYPE; } int nc_put_vara_text(int ncid, int varid, const size_t *start, const size_t *edges, const char *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; int ii; size_t iocount; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type != NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, start); if(status != NC_NOERR) return status; status = NCedgeck(ncp, varp, start, edges); if(status != NC_NOERR) return status; if(varp->ndims == 0) /* scalar variable */ { return( putNCv_text(ncp, varp, start, 1, value) ); } if(IS_RECVAR(varp)) { status = NCvnrecs(ncp, *start + *edges); if(status != NC_NOERR) return status; if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return( putNCv_text(ncp, varp, start, *edges, value) ); } } /* * find max contiguous * and accumulate max count for a single io operation */ ii = NCiocount(ncp, varp, edges, &iocount); if(ii == -1) { return( putNCv_text(ncp, varp, start, iocount, value) ); } assert(ii >= 0); { /* inline */ ALLOC_ONSTACK(coord, size_t, varp->ndims); ALLOC_ONSTACK(upper, size_t, varp->ndims); const size_t index = ii; /* copy in starting indices */ (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); /* set up in maximum indices */ set_upper(upper, start, edges, &upper[varp->ndims]); /* ripple counter */ while(*coord < *upper) { const int lstatus = putNCv_text(ncp, varp, coord, iocount, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += iocount; odo1(start, upper, coord, &upper[index], &coord[index]); } FREE_ONSTACK(upper); FREE_ONSTACK(coord); } /* end inline */ return status; } int nc_put_vara_uchar(int ncid, int varid, const size_t *start, const size_t *edges, const uchar *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; int ii; size_t iocount; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, start); if(status != NC_NOERR) return status; status = NCedgeck(ncp, varp, start, edges); if(status != NC_NOERR) return status; if(varp->ndims == 0) /* scalar variable */ { return( putNCv_uchar(ncp, varp, start, 1, value) ); } if(IS_RECVAR(varp)) { status = NCvnrecs(ncp, *start + *edges); if(status != NC_NOERR) return status; if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return( putNCv_uchar(ncp, varp, start, *edges, value) ); } } /* * find max contiguous * and accumulate max count for a single io operation */ ii = NCiocount(ncp, varp, edges, &iocount); if(ii == -1) { return( putNCv_uchar(ncp, varp, start, iocount, value) ); } assert(ii >= 0); { /* inline */ ALLOC_ONSTACK(coord, size_t, varp->ndims); ALLOC_ONSTACK(upper, size_t, varp->ndims); const size_t index = ii; /* copy in starting indices */ (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); /* set up in maximum indices */ set_upper(upper, start, edges, &upper[varp->ndims]); /* ripple counter */ while(*coord < *upper) { const int lstatus = putNCv_uchar(ncp, varp, coord, iocount, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += iocount; odo1(start, upper, coord, &upper[index], &coord[index]); } FREE_ONSTACK(upper); FREE_ONSTACK(coord); } /* end inline */ return status; } int nc_put_vara_schar(int ncid, int varid, const size_t *start, const size_t *edges, const schar *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; int ii; size_t iocount; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, start); if(status != NC_NOERR) return status; status = NCedgeck(ncp, varp, start, edges); if(status != NC_NOERR) return status; if(varp->ndims == 0) /* scalar variable */ { return( putNCv_schar(ncp, varp, start, 1, value) ); } if(IS_RECVAR(varp)) { status = NCvnrecs(ncp, *start + *edges); if(status != NC_NOERR) return status; if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return( putNCv_schar(ncp, varp, start, *edges, value) ); } } /* * find max contiguous * and accumulate max count for a single io operation */ ii = NCiocount(ncp, varp, edges, &iocount); if(ii == -1) { return( putNCv_schar(ncp, varp, start, iocount, value) ); } assert(ii >= 0); { /* inline */ ALLOC_ONSTACK(coord, size_t, varp->ndims); ALLOC_ONSTACK(upper, size_t, varp->ndims); const size_t index = ii; /* copy in starting indices */ (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); /* set up in maximum indices */ set_upper(upper, start, edges, &upper[varp->ndims]); /* ripple counter */ while(*coord < *upper) { const int lstatus = putNCv_schar(ncp, varp, coord, iocount, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += iocount; odo1(start, upper, coord, &upper[index], &coord[index]); } FREE_ONSTACK(upper); FREE_ONSTACK(coord); } /* end inline */ return status; } int nc_put_vara_short(int ncid, int varid, const size_t *start, const size_t *edges, const short *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; int ii; size_t iocount; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, start); if(status != NC_NOERR) return status; status = NCedgeck(ncp, varp, start, edges); if(status != NC_NOERR) return status; if(varp->ndims == 0) /* scalar variable */ { return( putNCv_short(ncp, varp, start, 1, value) ); } if(IS_RECVAR(varp)) { status = NCvnrecs(ncp, *start + *edges); if(status != NC_NOERR) return status; if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return( putNCv_short(ncp, varp, start, *edges, value) ); } } /* * find max contiguous * and accumulate max count for a single io operation */ ii = NCiocount(ncp, varp, edges, &iocount); if(ii == -1) { return( putNCv_short(ncp, varp, start, iocount, value) ); } assert(ii >= 0); { /* inline */ ALLOC_ONSTACK(coord, size_t, varp->ndims); ALLOC_ONSTACK(upper, size_t, varp->ndims); const size_t index = ii; /* copy in starting indices */ (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); /* set up in maximum indices */ set_upper(upper, start, edges, &upper[varp->ndims]); /* ripple counter */ while(*coord < *upper) { const int lstatus = putNCv_short(ncp, varp, coord, iocount, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += iocount; odo1(start, upper, coord, &upper[index], &coord[index]); } FREE_ONSTACK(upper); FREE_ONSTACK(coord); } /* end inline */ return status; } int nc_put_vara_int(int ncid, int varid, const size_t *start, const size_t *edges, const int *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; int ii; size_t iocount; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, start); if(status != NC_NOERR) return status; status = NCedgeck(ncp, varp, start, edges); if(status != NC_NOERR) return status; if(varp->ndims == 0) /* scalar variable */ { return( putNCv_int(ncp, varp, start, 1, value) ); } if(IS_RECVAR(varp)) { status = NCvnrecs(ncp, *start + *edges); if(status != NC_NOERR) return status; if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return( putNCv_int(ncp, varp, start, *edges, value) ); } } /* * find max contiguous * and accumulate max count for a single io operation */ ii = NCiocount(ncp, varp, edges, &iocount); if(ii == -1) { return( putNCv_int(ncp, varp, start, iocount, value) ); } assert(ii >= 0); { /* inline */ ALLOC_ONSTACK(coord, size_t, varp->ndims); ALLOC_ONSTACK(upper, size_t, varp->ndims); const size_t index = ii; /* copy in starting indices */ (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); /* set up in maximum indices */ set_upper(upper, start, edges, &upper[varp->ndims]); /* ripple counter */ while(*coord < *upper) { const int lstatus = putNCv_int(ncp, varp, coord, iocount, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += iocount; odo1(start, upper, coord, &upper[index], &coord[index]); } FREE_ONSTACK(upper); FREE_ONSTACK(coord); } /* end inline */ return status; } int nc_put_vara_long(int ncid, int varid, const size_t *start, const size_t *edges, const long *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; int ii; size_t iocount; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, start); if(status != NC_NOERR) return status; status = NCedgeck(ncp, varp, start, edges); if(status != NC_NOERR) return status; if(varp->ndims == 0) /* scalar variable */ { return( putNCv_long(ncp, varp, start, 1, value) ); } if(IS_RECVAR(varp)) { status = NCvnrecs(ncp, *start + *edges); if(status != NC_NOERR) return status; if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return( putNCv_long(ncp, varp, start, *edges, value) ); } } /* * find max contiguous * and accumulate max count for a single io operation */ ii = NCiocount(ncp, varp, edges, &iocount); if(ii == -1) { return( putNCv_long(ncp, varp, start, iocount, value) ); } assert(ii >= 0); { /* inline */ ALLOC_ONSTACK(coord, size_t, varp->ndims); ALLOC_ONSTACK(upper, size_t, varp->ndims); const size_t index = ii; /* copy in starting indices */ (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); /* set up in maximum indices */ set_upper(upper, start, edges, &upper[varp->ndims]); /* ripple counter */ while(*coord < *upper) { const int lstatus = putNCv_long(ncp, varp, coord, iocount, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += iocount; odo1(start, upper, coord, &upper[index], &coord[index]); } FREE_ONSTACK(upper); FREE_ONSTACK(coord); } /* end inline */ return status; } int nc_put_vara_float(int ncid, int varid, const size_t *start, const size_t *edges, const float *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; int ii; size_t iocount; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, start); if(status != NC_NOERR) return status; status = NCedgeck(ncp, varp, start, edges); if(status != NC_NOERR) return status; if(varp->ndims == 0) /* scalar variable */ { return( putNCv_float(ncp, varp, start, 1, value) ); } if(IS_RECVAR(varp)) { status = NCvnrecs(ncp, *start + *edges); if(status != NC_NOERR) return status; if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return( putNCv_float(ncp, varp, start, *edges, value) ); } } /* * find max contiguous * and accumulate max count for a single io operation */ ii = NCiocount(ncp, varp, edges, &iocount); if(ii == -1) { return( putNCv_float(ncp, varp, start, iocount, value) ); } assert(ii >= 0); { /* inline */ ALLOC_ONSTACK(coord, size_t, varp->ndims); ALLOC_ONSTACK(upper, size_t, varp->ndims); const size_t index = ii; /* copy in starting indices */ (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); /* set up in maximum indices */ set_upper(upper, start, edges, &upper[varp->ndims]); /* ripple counter */ while(*coord < *upper) { const int lstatus = putNCv_float(ncp, varp, coord, iocount, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += iocount; odo1(start, upper, coord, &upper[index], &coord[index]); } FREE_ONSTACK(upper); FREE_ONSTACK(coord); } /* end inline */ return status; } int nc_put_vara_double(int ncid, int varid, const size_t *start, const size_t *edges, const double *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; int ii; size_t iocount; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, start); if(status != NC_NOERR) return status; status = NCedgeck(ncp, varp, start, edges); if(status != NC_NOERR) return status; if(varp->ndims == 0) /* scalar variable */ { return( putNCv_double(ncp, varp, start, 1, value) ); } if(IS_RECVAR(varp)) { status = NCvnrecs(ncp, *start + *edges); if(status != NC_NOERR) return status; if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return( putNCv_double(ncp, varp, start, *edges, value) ); } } /* * find max contiguous * and accumulate max count for a single io operation */ ii = NCiocount(ncp, varp, edges, &iocount); if(ii == -1) { return( putNCv_double(ncp, varp, start, iocount, value) ); } assert(ii >= 0); { /* inline */ ALLOC_ONSTACK(coord, size_t, varp->ndims); ALLOC_ONSTACK(upper, size_t, varp->ndims); const size_t index = ii; /* copy in starting indices */ (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); /* set up in maximum indices */ set_upper(upper, start, edges, &upper[varp->ndims]); /* ripple counter */ while(*coord < *upper) { const int lstatus = putNCv_double(ncp, varp, coord, iocount, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += iocount; odo1(start, upper, coord, &upper[index], &coord[index]); } FREE_ONSTACK(upper); FREE_ONSTACK(coord); } /* end inline */ return status; } /* deprecated, used to support the 2.x interface */ int nc_put_vara(int ncid, int varid, const size_t *start, const size_t *edges, const void *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ switch(varp->type){ case NC_CHAR: return nc_put_vara_text(ncid, varid, start, edges, (const char *) value); case NC_BYTE: return nc_put_vara_schar(ncid, varid, start, edges, (const schar *) value); case NC_SHORT: return nc_put_vara_short(ncid, varid, start, edges, (const short *) value); case NC_INT: return nc_put_vara_int(ncid, varid, start, edges, (const int *) value); case NC_FLOAT: return nc_put_vara_float(ncid, varid, start, edges, (const float *) value); case NC_DOUBLE: return nc_put_vara_double(ncid, varid, start, edges, (const double *) value); } return NC_EBADTYPE; } int nc_get_vara_text(int ncid, int varid, const size_t *start, const size_t *edges, char *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; int ii; size_t iocount; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type != NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, start); if(status != NC_NOERR) return status; status = NCedgeck(ncp, varp, start, edges); if(status != NC_NOERR) return status; if(varp->ndims == 0) /* scalar variable */ { return( getNCv_text(ncp, varp, start, 1, value) ); } if(IS_RECVAR(varp)) { if(*start + *edges > ncp->numrecs) return NC_EEDGE; if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return( getNCv_text(ncp, varp, start, *edges, value) ); } } /* * find max contiguous * and accumulate max count for a single io operation */ ii = NCiocount(ncp, varp, edges, &iocount); if(ii == -1) { return( getNCv_text(ncp, varp, start, iocount, value) ); } assert(ii >= 0); { /* inline */ ALLOC_ONSTACK(coord, size_t, varp->ndims); ALLOC_ONSTACK(upper, size_t, varp->ndims); const size_t index = ii; /* copy in starting indices */ (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); /* set up in maximum indices */ set_upper(upper, start, edges, &upper[varp->ndims]); /* ripple counter */ while(*coord < *upper) { const int lstatus = getNCv_text(ncp, varp, coord, iocount, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += iocount; odo1(start, upper, coord, &upper[index], &coord[index]); } FREE_ONSTACK(upper); FREE_ONSTACK(coord); } /* end inline */ return status; } int nc_get_vara_uchar(int ncid, int varid, const size_t *start, const size_t *edges, uchar *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; int ii; size_t iocount; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, start); if(status != NC_NOERR) return status; status = NCedgeck(ncp, varp, start, edges); if(status != NC_NOERR) return status; if(varp->ndims == 0) /* scalar variable */ { return( getNCv_uchar(ncp, varp, start, 1, value) ); } if(IS_RECVAR(varp)) { if(*start + *edges > ncp->numrecs) return NC_EEDGE; if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return( getNCv_uchar(ncp, varp, start, *edges, value) ); } } /* * find max contiguous * and accumulate max count for a single io operation */ ii = NCiocount(ncp, varp, edges, &iocount); if(ii == -1) { return( getNCv_uchar(ncp, varp, start, iocount, value) ); } assert(ii >= 0); { /* inline */ ALLOC_ONSTACK(coord, size_t, varp->ndims); ALLOC_ONSTACK(upper, size_t, varp->ndims); const size_t index = ii; /* copy in starting indices */ (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); /* set up in maximum indices */ set_upper(upper, start, edges, &upper[varp->ndims]); /* ripple counter */ while(*coord < *upper) { const int lstatus = getNCv_uchar(ncp, varp, coord, iocount, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += iocount; odo1(start, upper, coord, &upper[index], &coord[index]); } FREE_ONSTACK(upper); FREE_ONSTACK(coord); } /* end inline */ return status; } int nc_get_vara_schar(int ncid, int varid, const size_t *start, const size_t *edges, schar *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; int ii; size_t iocount; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, start); if(status != NC_NOERR) return status; status = NCedgeck(ncp, varp, start, edges); if(status != NC_NOERR) return status; if(varp->ndims == 0) /* scalar variable */ { return( getNCv_schar(ncp, varp, start, 1, value) ); } if(IS_RECVAR(varp)) { if(*start + *edges > ncp->numrecs) return NC_EEDGE; if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return( getNCv_schar(ncp, varp, start, *edges, value) ); } } /* * find max contiguous * and accumulate max count for a single io operation */ ii = NCiocount(ncp, varp, edges, &iocount); if(ii == -1) { return( getNCv_schar(ncp, varp, start, iocount, value) ); } assert(ii >= 0); { /* inline */ ALLOC_ONSTACK(coord, size_t, varp->ndims); ALLOC_ONSTACK(upper, size_t, varp->ndims); const size_t index = ii; /* copy in starting indices */ (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); /* set up in maximum indices */ set_upper(upper, start, edges, &upper[varp->ndims]); /* ripple counter */ while(*coord < *upper) { const int lstatus = getNCv_schar(ncp, varp, coord, iocount, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += iocount; odo1(start, upper, coord, &upper[index], &coord[index]); } FREE_ONSTACK(upper); FREE_ONSTACK(coord); } /* end inline */ return status; } int nc_get_vara_short(int ncid, int varid, const size_t *start, const size_t *edges, short *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; int ii; size_t iocount; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, start); if(status != NC_NOERR) return status; status = NCedgeck(ncp, varp, start, edges); if(status != NC_NOERR) return status; if(varp->ndims == 0) /* scalar variable */ { return( getNCv_short(ncp, varp, start, 1, value) ); } if(IS_RECVAR(varp)) { if(*start + *edges > ncp->numrecs) return NC_EEDGE; if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return( getNCv_short(ncp, varp, start, *edges, value) ); } } /* * find max contiguous * and accumulate max count for a single io operation */ ii = NCiocount(ncp, varp, edges, &iocount); if(ii == -1) { return( getNCv_short(ncp, varp, start, iocount, value) ); } assert(ii >= 0); { /* inline */ ALLOC_ONSTACK(coord, size_t, varp->ndims); ALLOC_ONSTACK(upper, size_t, varp->ndims); const size_t index = ii; /* copy in starting indices */ (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); /* set up in maximum indices */ set_upper(upper, start, edges, &upper[varp->ndims]); /* ripple counter */ while(*coord < *upper) { const int lstatus = getNCv_short(ncp, varp, coord, iocount, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += iocount; odo1(start, upper, coord, &upper[index], &coord[index]); } FREE_ONSTACK(upper); FREE_ONSTACK(coord); } /* end inline */ return status; } int nc_get_vara_int(int ncid, int varid, const size_t *start, const size_t *edges, int *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; int ii; size_t iocount; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, start); if(status != NC_NOERR) return status; status = NCedgeck(ncp, varp, start, edges); if(status != NC_NOERR) return status; if(varp->ndims == 0) /* scalar variable */ { return( getNCv_int(ncp, varp, start, 1, value) ); } if(IS_RECVAR(varp)) { if(*start + *edges > ncp->numrecs) return NC_EEDGE; if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return( getNCv_int(ncp, varp, start, *edges, value) ); } } /* * find max contiguous * and accumulate max count for a single io operation */ ii = NCiocount(ncp, varp, edges, &iocount); if(ii == -1) { return( getNCv_int(ncp, varp, start, iocount, value) ); } assert(ii >= 0); { /* inline */ ALLOC_ONSTACK(coord, size_t, varp->ndims); ALLOC_ONSTACK(upper, size_t, varp->ndims); const size_t index = ii; /* copy in starting indices */ (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); /* set up in maximum indices */ set_upper(upper, start, edges, &upper[varp->ndims]); /* ripple counter */ while(*coord < *upper) { const int lstatus = getNCv_int(ncp, varp, coord, iocount, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += iocount; odo1(start, upper, coord, &upper[index], &coord[index]); } FREE_ONSTACK(upper); FREE_ONSTACK(coord); } /* end inline */ return status; } int nc_get_vara_long(int ncid, int varid, const size_t *start, const size_t *edges, long *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; int ii; size_t iocount; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, start); if(status != NC_NOERR) return status; status = NCedgeck(ncp, varp, start, edges); if(status != NC_NOERR) return status; if(varp->ndims == 0) /* scalar variable */ { return( getNCv_long(ncp, varp, start, 1, value) ); } if(IS_RECVAR(varp)) { if(*start + *edges > ncp->numrecs) return NC_EEDGE; if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return( getNCv_long(ncp, varp, start, *edges, value) ); } } /* * find max contiguous * and accumulate max count for a single io operation */ ii = NCiocount(ncp, varp, edges, &iocount); if(ii == -1) { return( getNCv_long(ncp, varp, start, iocount, value) ); } assert(ii >= 0); { /* inline */ ALLOC_ONSTACK(coord, size_t, varp->ndims); ALLOC_ONSTACK(upper, size_t, varp->ndims); const size_t index = ii; /* copy in starting indices */ (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); /* set up in maximum indices */ set_upper(upper, start, edges, &upper[varp->ndims]); /* ripple counter */ while(*coord < *upper) { const int lstatus = getNCv_long(ncp, varp, coord, iocount, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += iocount; odo1(start, upper, coord, &upper[index], &coord[index]); } FREE_ONSTACK(upper); FREE_ONSTACK(coord); } /* end inline */ return status; } int nc_get_vara_float(int ncid, int varid, const size_t *start, const size_t *edges, float *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; int ii; size_t iocount; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, start); if(status != NC_NOERR) return status; status = NCedgeck(ncp, varp, start, edges); if(status != NC_NOERR) return status; if(varp->ndims == 0) /* scalar variable */ { return( getNCv_float(ncp, varp, start, 1, value) ); } if(IS_RECVAR(varp)) { if(*start + *edges > ncp->numrecs) return NC_EEDGE; if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return( getNCv_float(ncp, varp, start, *edges, value) ); } } /* * find max contiguous * and accumulate max count for a single io operation */ ii = NCiocount(ncp, varp, edges, &iocount); if(ii == -1) { return( getNCv_float(ncp, varp, start, iocount, value) ); } assert(ii >= 0); { /* inline */ ALLOC_ONSTACK(coord, size_t, varp->ndims); ALLOC_ONSTACK(upper, size_t, varp->ndims); const size_t index = ii; /* copy in starting indices */ (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); /* set up in maximum indices */ set_upper(upper, start, edges, &upper[varp->ndims]); /* ripple counter */ while(*coord < *upper) { const int lstatus = getNCv_float(ncp, varp, coord, iocount, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += iocount; odo1(start, upper, coord, &upper[index], &coord[index]); } FREE_ONSTACK(upper); FREE_ONSTACK(coord); } /* end inline */ return status; } int nc_get_vara_double(int ncid, int varid, const size_t *start, const size_t *edges, double *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; int ii; size_t iocount; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; status = NCcoordck(ncp, varp, start); if(status != NC_NOERR) return status; status = NCedgeck(ncp, varp, start, edges); if(status != NC_NOERR) return status; if(varp->ndims == 0) /* scalar variable */ { return( getNCv_double(ncp, varp, start, 1, value) ); } if(IS_RECVAR(varp)) { if(*start + *edges > ncp->numrecs) return NC_EEDGE; if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return( getNCv_double(ncp, varp, start, *edges, value) ); } } /* * find max contiguous * and accumulate max count for a single io operation */ ii = NCiocount(ncp, varp, edges, &iocount); if(ii == -1) { return( getNCv_double(ncp, varp, start, iocount, value) ); } assert(ii >= 0); { /* inline */ ALLOC_ONSTACK(coord, size_t, varp->ndims); ALLOC_ONSTACK(upper, size_t, varp->ndims); const size_t index = ii; /* copy in starting indices */ (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); /* set up in maximum indices */ set_upper(upper, start, edges, &upper[varp->ndims]); /* ripple counter */ while(*coord < *upper) { const int lstatus = getNCv_double(ncp, varp, coord, iocount, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += iocount; odo1(start, upper, coord, &upper[index], &coord[index]); } FREE_ONSTACK(upper); FREE_ONSTACK(coord); } /* end inline */ return status; } /* deprecated, used to support the 2.x interface */ int nc_get_vara(int ncid, int varid, const size_t *start, const size_t *edges, void *value) { int status; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ switch(varp->type){ case NC_CHAR: return nc_get_vara_text(ncid, varid, start, edges, (char *) value); case NC_BYTE: return nc_get_vara_schar(ncid, varid, start, edges, (schar *) value); case NC_SHORT: return nc_get_vara_short(ncid, varid, start, edges, (short *) value); case NC_INT: #if (SIZEOF_INT >= X_SIZEOF_INT) return nc_get_vara_int(ncid, varid, start, edges, (int *) value); #elif SIZEOF_LONG == X_SIZEOF_INT return nc_get_vara_long(ncid, varid, start, edges, (long *) value); #else #error "nc_get_vara implementation" #endif case NC_FLOAT: return nc_get_vara_float(ncid, varid, start, edges, (float *) value); case NC_DOUBLE: return nc_get_vara_double(ncid, varid, start, edges, (double *) value); } return NC_EBADTYPE; } #if 1 /* defined(__cplusplus) */ /* C++ consts default to internal linkage and must be initialized */ static const size_t coord_zero[NC_MAX_VAR_DIMS] = {0}; #else static const size_t coord_zero[NC_MAX_VAR_DIMS]; #endif int nc_put_var_text(int ncid, int varid, const char *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type != NC_CHAR) return NC_ECHAR; if(varp->ndims == 0) /* scalar variable */ { const size_t zed = 0; return( putNCv_text(ncp, varp, &zed, 1, value) ); } if(!IS_RECVAR(varp)) { return(putNCv_text(ncp, varp, coord_zero, *varp->dsizes, value)); } /* else */ if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return(putNCv_text(ncp, varp, coord_zero, ncp->numrecs, value)); } /* else */ { ALLOC_ONSTACK(coord, size_t, varp->ndims); size_t elemsPerRec = 1; (void) memset(coord, 0, varp->ndims * sizeof(size_t)); /* TODO: fix dsizes to avoid this nonsense */ if(varp->ndims > 1) elemsPerRec = varp->dsizes[1]; while(*coord < ncp->numrecs) { const int lstatus = putNCv_text(ncp, varp, coord, elemsPerRec, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += elemsPerRec; (*coord)++; } FREE_ONSTACK(coord); } /* elemsPerRec */ return status; } int nc_put_var_uchar(int ncid, int varid, const uchar *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; if(varp->ndims == 0) /* scalar variable */ { const size_t zed = 0; return( putNCv_uchar(ncp, varp, &zed, 1, value) ); } if(!IS_RECVAR(varp)) { return(putNCv_uchar(ncp, varp, coord_zero, *varp->dsizes, value)); } /* else */ if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return(putNCv_uchar(ncp, varp, coord_zero, ncp->numrecs, value)); } /* else */ { ALLOC_ONSTACK(coord, size_t, varp->ndims); size_t elemsPerRec = 1; (void) memset(coord, 0, varp->ndims * sizeof(size_t)); /* TODO: fix dsizes to avoid this nonsense */ if(varp->ndims > 1) elemsPerRec = varp->dsizes[1]; while(*coord < ncp->numrecs) { const int lstatus = putNCv_uchar(ncp, varp, coord, elemsPerRec, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += elemsPerRec; (*coord)++; } FREE_ONSTACK(coord); } /* elemsPerRec */ return status; } int nc_put_var_schar(int ncid, int varid, const schar *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; if(varp->ndims == 0) /* scalar variable */ { const size_t zed = 0; return( putNCv_schar(ncp, varp, &zed, 1, value) ); } if(!IS_RECVAR(varp)) { return(putNCv_schar(ncp, varp, coord_zero, *varp->dsizes, value)); } /* else */ if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return(putNCv_schar(ncp, varp, coord_zero, ncp->numrecs, value)); } /* else */ { ALLOC_ONSTACK(coord, size_t, varp->ndims); size_t elemsPerRec = 1; (void) memset(coord, 0, varp->ndims * sizeof(size_t)); /* TODO: fix dsizes to avoid this nonsense */ if(varp->ndims > 1) elemsPerRec = varp->dsizes[1]; while(*coord < ncp->numrecs) { const int lstatus = putNCv_schar(ncp, varp, coord, elemsPerRec, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += elemsPerRec; (*coord)++; } FREE_ONSTACK(coord); } /* elemsPerRec */ return status; } int nc_put_var_short(int ncid, int varid, const short *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; if(varp->ndims == 0) /* scalar variable */ { const size_t zed = 0; return( putNCv_short(ncp, varp, &zed, 1, value) ); } if(!IS_RECVAR(varp)) { return(putNCv_short(ncp, varp, coord_zero, *varp->dsizes, value)); } /* else */ if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return(putNCv_short(ncp, varp, coord_zero, ncp->numrecs, value)); } /* else */ { ALLOC_ONSTACK(coord, size_t, varp->ndims); size_t elemsPerRec = 1; (void) memset(coord, 0, varp->ndims * sizeof(size_t)); /* TODO: fix dsizes to avoid this nonsense */ if(varp->ndims > 1) elemsPerRec = varp->dsizes[1]; while(*coord < ncp->numrecs) { const int lstatus = putNCv_short(ncp, varp, coord, elemsPerRec, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += elemsPerRec; (*coord)++; } FREE_ONSTACK(coord); } /* elemsPerRec */ return status; } int nc_put_var_int(int ncid, int varid, const int *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; if(varp->ndims == 0) /* scalar variable */ { const size_t zed = 0; return( putNCv_int(ncp, varp, &zed, 1, value) ); } if(!IS_RECVAR(varp)) { return(putNCv_int(ncp, varp, coord_zero, *varp->dsizes, value)); } /* else */ if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return(putNCv_int(ncp, varp, coord_zero, ncp->numrecs, value)); } /* else */ { ALLOC_ONSTACK(coord, size_t, varp->ndims); size_t elemsPerRec = 1; (void) memset(coord, 0, varp->ndims * sizeof(size_t)); /* TODO: fix dsizes to avoid this nonsense */ if(varp->ndims > 1) elemsPerRec = varp->dsizes[1]; while(*coord < ncp->numrecs) { const int lstatus = putNCv_int(ncp, varp, coord, elemsPerRec, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += elemsPerRec; (*coord)++; } FREE_ONSTACK(coord); } /* elemsPerRec */ return status; } int nc_put_var_long(int ncid, int varid, const long *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; if(varp->ndims == 0) /* scalar variable */ { const size_t zed = 0; return( putNCv_long(ncp, varp, &zed, 1, value) ); } if(!IS_RECVAR(varp)) { return(putNCv_long(ncp, varp, coord_zero, *varp->dsizes, value)); } /* else */ if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return(putNCv_long(ncp, varp, coord_zero, ncp->numrecs, value)); } /* else */ { ALLOC_ONSTACK(coord, size_t, varp->ndims); size_t elemsPerRec = 1; (void) memset(coord, 0, varp->ndims * sizeof(size_t)); /* TODO: fix dsizes to avoid this nonsense */ if(varp->ndims > 1) elemsPerRec = varp->dsizes[1]; while(*coord < ncp->numrecs) { const int lstatus = putNCv_long(ncp, varp, coord, elemsPerRec, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += elemsPerRec; (*coord)++; } FREE_ONSTACK(coord); } /* elemsPerRec */ return status; } int nc_put_var_float(int ncid, int varid, const float *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; if(varp->ndims == 0) /* scalar variable */ { const size_t zed = 0; return( putNCv_float(ncp, varp, &zed, 1, value) ); } if(!IS_RECVAR(varp)) { return(putNCv_float(ncp, varp, coord_zero, *varp->dsizes, value)); } /* else */ if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return(putNCv_float(ncp, varp, coord_zero, ncp->numrecs, value)); } /* else */ { ALLOC_ONSTACK(coord, size_t, varp->ndims); size_t elemsPerRec = 1; (void) memset(coord, 0, varp->ndims * sizeof(size_t)); /* TODO: fix dsizes to avoid this nonsense */ if(varp->ndims > 1) elemsPerRec = varp->dsizes[1]; while(*coord < ncp->numrecs) { const int lstatus = putNCv_float(ncp, varp, coord, elemsPerRec, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += elemsPerRec; (*coord)++; } FREE_ONSTACK(coord); } /* elemsPerRec */ return status; } int nc_put_var_double(int ncid, int varid, const double *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->type == NC_CHAR) return NC_ECHAR; if(varp->ndims == 0) /* scalar variable */ { const size_t zed = 0; return( putNCv_double(ncp, varp, &zed, 1, value) ); } if(!IS_RECVAR(varp)) { return(putNCv_double(ncp, varp, coord_zero, *varp->dsizes, value)); } /* else */ if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return(putNCv_double(ncp, varp, coord_zero, ncp->numrecs, value)); } /* else */ { ALLOC_ONSTACK(coord, size_t, varp->ndims); size_t elemsPerRec = 1; (void) memset(coord, 0, varp->ndims * sizeof(size_t)); /* TODO: fix dsizes to avoid this nonsense */ if(varp->ndims > 1) elemsPerRec = varp->dsizes[1]; while(*coord < ncp->numrecs) { const int lstatus = putNCv_double(ncp, varp, coord, elemsPerRec, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += elemsPerRec; (*coord)++; } FREE_ONSTACK(coord); } /* elemsPerRec */ return status; } int nc_get_var_text(int ncid, int varid, char *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->ndims == 0) /* scalar variable */ { const size_t zed = 0; return( getNCv_text(ncp, varp, &zed, 1, value) ); } if(varp->type != NC_CHAR) return NC_ECHAR; if(!IS_RECVAR(varp)) { return(getNCv_text(ncp, varp, coord_zero, *varp->dsizes, value)); } /* else */ if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return(getNCv_text(ncp, varp, coord_zero, ncp->numrecs, value)); } /* else */ { ALLOC_ONSTACK(coord, size_t, varp->ndims); size_t elemsPerRec = 1; (void) memset(coord, 0, varp->ndims * sizeof(size_t)); /* TODO: fix dsizes to avoid this nonsense */ if(varp->ndims > 1) elemsPerRec = varp->dsizes[1]; while(*coord < ncp->numrecs) { const int lstatus = getNCv_text(ncp, varp, coord, elemsPerRec, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += elemsPerRec; (*coord)++; } FREE_ONSTACK(coord); } /* elemsPerRec */ return status; } int nc_get_var_uchar(int ncid, int varid, uchar *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->ndims == 0) /* scalar variable */ { const size_t zed = 0; return( getNCv_uchar(ncp, varp, &zed, 1, value) ); } if(varp->type == NC_CHAR) return NC_ECHAR; if(!IS_RECVAR(varp)) { return(getNCv_uchar(ncp, varp, coord_zero, *varp->dsizes, value)); } /* else */ if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return(getNCv_uchar(ncp, varp, coord_zero, ncp->numrecs, value)); } /* else */ { ALLOC_ONSTACK(coord, size_t, varp->ndims); size_t elemsPerRec = 1; (void) memset(coord, 0, varp->ndims * sizeof(size_t)); /* TODO: fix dsizes to avoid this nonsense */ if(varp->ndims > 1) elemsPerRec = varp->dsizes[1]; while(*coord < ncp->numrecs) { const int lstatus = getNCv_uchar(ncp, varp, coord, elemsPerRec, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += elemsPerRec; (*coord)++; } FREE_ONSTACK(coord); } /* elemsPerRec */ return status; } int nc_get_var_schar(int ncid, int varid, schar *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->ndims == 0) /* scalar variable */ { const size_t zed = 0; return( getNCv_schar(ncp, varp, &zed, 1, value) ); } if(varp->type == NC_CHAR) return NC_ECHAR; if(!IS_RECVAR(varp)) { return(getNCv_schar(ncp, varp, coord_zero, *varp->dsizes, value)); } /* else */ if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return(getNCv_schar(ncp, varp, coord_zero, ncp->numrecs, value)); } /* else */ { ALLOC_ONSTACK(coord, size_t, varp->ndims); size_t elemsPerRec = 1; (void) memset(coord, 0, varp->ndims * sizeof(size_t)); /* TODO: fix dsizes to avoid this nonsense */ if(varp->ndims > 1) elemsPerRec = varp->dsizes[1]; while(*coord < ncp->numrecs) { const int lstatus = getNCv_schar(ncp, varp, coord, elemsPerRec, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += elemsPerRec; (*coord)++; } FREE_ONSTACK(coord); } /* elemsPerRec */ return status; } int nc_get_var_short(int ncid, int varid, short *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->ndims == 0) /* scalar variable */ { const size_t zed = 0; return( getNCv_short(ncp, varp, &zed, 1, value) ); } if(varp->type == NC_CHAR) return NC_ECHAR; if(!IS_RECVAR(varp)) { return(getNCv_short(ncp, varp, coord_zero, *varp->dsizes, value)); } /* else */ if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return(getNCv_short(ncp, varp, coord_zero, ncp->numrecs, value)); } /* else */ { ALLOC_ONSTACK(coord, size_t, varp->ndims); size_t elemsPerRec = 1; (void) memset(coord, 0, varp->ndims * sizeof(size_t)); /* TODO: fix dsizes to avoid this nonsense */ if(varp->ndims > 1) elemsPerRec = varp->dsizes[1]; while(*coord < ncp->numrecs) { const int lstatus = getNCv_short(ncp, varp, coord, elemsPerRec, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += elemsPerRec; (*coord)++; } FREE_ONSTACK(coord); } /* elemsPerRec */ return status; } int nc_get_var_int(int ncid, int varid, int *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->ndims == 0) /* scalar variable */ { const size_t zed = 0; return( getNCv_int(ncp, varp, &zed, 1, value) ); } if(varp->type == NC_CHAR) return NC_ECHAR; if(!IS_RECVAR(varp)) { return(getNCv_int(ncp, varp, coord_zero, *varp->dsizes, value)); } /* else */ if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return(getNCv_int(ncp, varp, coord_zero, ncp->numrecs, value)); } /* else */ { ALLOC_ONSTACK(coord, size_t, varp->ndims); size_t elemsPerRec = 1; (void) memset(coord, 0, varp->ndims * sizeof(size_t)); /* TODO: fix dsizes to avoid this nonsense */ if(varp->ndims > 1) elemsPerRec = varp->dsizes[1]; while(*coord < ncp->numrecs) { const int lstatus = getNCv_int(ncp, varp, coord, elemsPerRec, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += elemsPerRec; (*coord)++; } FREE_ONSTACK(coord); } /* elemsPerRec */ return status; } int nc_get_var_long(int ncid, int varid, long *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->ndims == 0) /* scalar variable */ { const size_t zed = 0; return( getNCv_long(ncp, varp, &zed, 1, value) ); } if(varp->type == NC_CHAR) return NC_ECHAR; if(!IS_RECVAR(varp)) { return(getNCv_long(ncp, varp, coord_zero, *varp->dsizes, value)); } /* else */ if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return(getNCv_long(ncp, varp, coord_zero, ncp->numrecs, value)); } /* else */ { ALLOC_ONSTACK(coord, size_t, varp->ndims); size_t elemsPerRec = 1; (void) memset(coord, 0, varp->ndims * sizeof(size_t)); /* TODO: fix dsizes to avoid this nonsense */ if(varp->ndims > 1) elemsPerRec = varp->dsizes[1]; while(*coord < ncp->numrecs) { const int lstatus = getNCv_long(ncp, varp, coord, elemsPerRec, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += elemsPerRec; (*coord)++; } FREE_ONSTACK(coord); } /* elemsPerRec */ return status; } int nc_get_var_float(int ncid, int varid, float *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->ndims == 0) /* scalar variable */ { const size_t zed = 0; return( getNCv_float(ncp, varp, &zed, 1, value) ); } if(varp->type == NC_CHAR) return NC_ECHAR; if(!IS_RECVAR(varp)) { return(getNCv_float(ncp, varp, coord_zero, *varp->dsizes, value)); } /* else */ if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return(getNCv_float(ncp, varp, coord_zero, ncp->numrecs, value)); } /* else */ { ALLOC_ONSTACK(coord, size_t, varp->ndims); size_t elemsPerRec = 1; (void) memset(coord, 0, varp->ndims * sizeof(size_t)); /* TODO: fix dsizes to avoid this nonsense */ if(varp->ndims > 1) elemsPerRec = varp->dsizes[1]; while(*coord < ncp->numrecs) { const int lstatus = getNCv_float(ncp, varp, coord, elemsPerRec, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += elemsPerRec; (*coord)++; } FREE_ONSTACK(coord); } /* elemsPerRec */ return status; } int nc_get_var_double(int ncid, int varid, double *value) { int status = NC_NOERR; NC *ncp; const NC_var *varp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ if(varp->ndims == 0) /* scalar variable */ { const size_t zed = 0; return( getNCv_double(ncp, varp, &zed, 1, value) ); } if(varp->type == NC_CHAR) return NC_ECHAR; if(!IS_RECVAR(varp)) { return(getNCv_double(ncp, varp, coord_zero, *varp->dsizes, value)); } /* else */ if(varp->ndims == 1 && ncp->recsize <= varp->len) { /* one dimensional && the only record variable */ return(getNCv_double(ncp, varp, coord_zero, ncp->numrecs, value)); } /* else */ { ALLOC_ONSTACK(coord, size_t, varp->ndims); size_t elemsPerRec = 1; (void) memset(coord, 0, varp->ndims * sizeof(size_t)); /* TODO: fix dsizes to avoid this nonsense */ if(varp->ndims > 1) elemsPerRec = varp->dsizes[1]; while(*coord < ncp->numrecs) { const int lstatus = getNCv_double(ncp, varp, coord, elemsPerRec, value); if(lstatus != NC_NOERR) { if(lstatus != NC_ERANGE) { status = lstatus; /* fatal for the loop */ break; } /* else NC_ERANGE, not fatal for the loop */ if(status == NC_NOERR) status = lstatus; } value += elemsPerRec; (*coord)++; } FREE_ONSTACK(coord); } /* elemsPerRec */ return status; } /* Begin putgetg.c */ int nc_get_vars_text ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, char *value) { return nc_get_varm_text (ncid, varid, start, edges, stride, 0, value); } int nc_get_vars_uchar ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, uchar *value) { return nc_get_varm_uchar (ncid, varid, start, edges, stride, 0, value); } int nc_get_vars_schar ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, schar *value) { return nc_get_varm_schar (ncid, varid, start, edges, stride, 0, value); } int nc_get_vars_short ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, short *value) { return nc_get_varm_short (ncid, varid, start, edges, stride, 0, value); } int nc_get_vars_int ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, int *value) { return nc_get_varm_int (ncid, varid, start, edges, stride, 0, value); } int nc_get_vars_long ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, long *value) { return nc_get_varm_long (ncid, varid, start, edges, stride, 0, value); } int nc_get_vars_float ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, float *value) { return nc_get_varm_float (ncid, varid, start, edges, stride, 0, value); } int nc_get_vars_double ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, double *value) { return nc_get_varm_double (ncid, varid, start, edges, stride, 0, value); } int nc_get_vars ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, void *value) { return nc_get_varm (ncid, varid, start, edges, stride, 0, value); } int nc_put_vars_text ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, const char *value) { return nc_put_varm_text (ncid, varid, start, edges, stride, 0, value); } int nc_put_vars_uchar ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, const uchar *value) { return nc_put_varm_uchar (ncid, varid, start, edges, stride, 0, value); } int nc_put_vars_schar ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, const schar *value) { return nc_put_varm_schar (ncid, varid, start, edges, stride, 0, value); } int nc_put_vars_short ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, const short *value) { return nc_put_varm_short (ncid, varid, start, edges, stride, 0, value); } int nc_put_vars_int ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, const int *value) { return nc_put_varm_int (ncid, varid, start, edges, stride, 0, value); } int nc_put_vars_long ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, const long *value) { return nc_put_varm_long (ncid, varid, start, edges, stride, 0, value); } int nc_put_vars_float ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, const float *value) { return nc_put_varm_float (ncid, varid, start, edges, stride, 0, value); } int nc_put_vars_double ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, const double *value) { return nc_put_varm_double (ncid, varid, start, edges, stride, 0, value); } int nc_put_vars ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, const void *value) { return nc_put_varm (ncid, varid, start, edges, stride, 0, value); } /* * Generalized hyperslab input. */ int nc_get_varm_text(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *map, char *value) { int status = ENOERR; NC *ncp; NC_var *varp; int maxidim; /* maximum dimensional index */ status = NC_check_id (ncid, &ncp); if (status != NC_NOERR) return status; if (NC_indef (ncp)) { return NC_EINDEFINE; } varp = NC_lookupvar (ncp, varid); if (varp == NULL) return NC_ENOTVAR; if(varp->type != NC_CHAR) return NC_ECHAR; maxidim = (int) varp->ndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ return getNCv_text (ncp, varp, start, 1, value); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; /* * Verify stride argument. */ for (idim = 0; idim <= maxidim; ++idim) { if (stride != NULL && (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || (unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varp->ndims; iocount = myedges + varp->ndims; stop = iocount + varp->ndims; length = stop + varp->ndims; mystride = (ptrdiff_t *)(length + varp->ndims); mymap = mystride + varp->ndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && IS_RECVAR (varp) ? ncp->numrecs - mystart[idim] : varp->shape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; mymap[idim] = map != NULL ? map[idim] : idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; iocount[idim] = 1; length[idim] = mymap[idim] * myedges[idim]; stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; } /* * Check start, edges */ for (idim = maxidim; idim >= 0; --idim) { size_t dimlen = idim == 0 && IS_RECVAR (varp) ? ncp->numrecs : varp->shape[idim]; if (mystart[idim] >= dimlen) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > dimlen) { status = NC_EEDGE; goto done; } } /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvarnc_get_vara_text() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = nc_get_vara_text (ncid, varid, mystart, iocount, value); if (lstatus != NC_NOERR && (status == NC_NOERR || lstatus != NC_ERANGE)) status = lstatus; /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += mymap[idim]; mystart[idim] += mystride[idim]; if (mystart[idim] == stop[idim]) { mystart[idim] = start[idim]; value -= length[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; } int nc_get_varm_uchar(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *map, uchar *value) { int status = ENOERR; NC *ncp; NC_var *varp; int maxidim; /* maximum dimensional index */ status = NC_check_id (ncid, &ncp); if (status != NC_NOERR) return status; if (NC_indef (ncp)) { return NC_EINDEFINE; } varp = NC_lookupvar (ncp, varid); if (varp == NULL) return NC_ENOTVAR; if(varp->type == NC_CHAR) return NC_ECHAR; maxidim = (int) varp->ndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ return getNCv_uchar (ncp, varp, start, 1, value); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; /* * Verify stride argument. */ for (idim = 0; idim <= maxidim; ++idim) { if (stride != NULL && (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || (unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varp->ndims; iocount = myedges + varp->ndims; stop = iocount + varp->ndims; length = stop + varp->ndims; mystride = (ptrdiff_t *)(length + varp->ndims); mymap = mystride + varp->ndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && IS_RECVAR (varp) ? ncp->numrecs - mystart[idim] : varp->shape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; mymap[idim] = map != NULL ? map[idim] : idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; iocount[idim] = 1; length[idim] = mymap[idim] * myedges[idim]; stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; } /* * Check start, edges */ for (idim = maxidim; idim >= 0; --idim) { size_t dimlen = idim == 0 && IS_RECVAR (varp) ? ncp->numrecs : varp->shape[idim]; if (mystart[idim] >= dimlen) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > dimlen) { status = NC_EEDGE; goto done; } } /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvarnc_get_vara_uchar() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = nc_get_vara_uchar (ncid, varid, mystart, iocount, value); if (lstatus != NC_NOERR && (status == NC_NOERR || lstatus != NC_ERANGE)) status = lstatus; /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += mymap[idim]; mystart[idim] += mystride[idim]; if (mystart[idim] == stop[idim]) { mystart[idim] = start[idim]; value -= length[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; } int nc_get_varm_schar(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *map, schar *value) { int status = ENOERR; NC *ncp; NC_var *varp; int maxidim; /* maximum dimensional index */ status = NC_check_id (ncid, &ncp); if (status != NC_NOERR) return status; if (NC_indef (ncp)) { return NC_EINDEFINE; } varp = NC_lookupvar (ncp, varid); if (varp == NULL) return NC_ENOTVAR; if(varp->type == NC_CHAR) return NC_ECHAR; maxidim = (int) varp->ndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ return getNCv_schar (ncp, varp, start, 1, value); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; /* * Verify stride argument. */ for (idim = 0; idim <= maxidim; ++idim) { if (stride != NULL && (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || (unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varp->ndims; iocount = myedges + varp->ndims; stop = iocount + varp->ndims; length = stop + varp->ndims; mystride = (ptrdiff_t *)(length + varp->ndims); mymap = mystride + varp->ndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && IS_RECVAR (varp) ? ncp->numrecs - mystart[idim] : varp->shape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; mymap[idim] = map != NULL ? map[idim] : idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; iocount[idim] = 1; length[idim] = mymap[idim] * myedges[idim]; stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; } /* * Check start, edges */ for (idim = maxidim; idim >= 0; --idim) { size_t dimlen = idim == 0 && IS_RECVAR (varp) ? ncp->numrecs : varp->shape[idim]; if (mystart[idim] >= dimlen) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > dimlen) { status = NC_EEDGE; goto done; } } /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvarnc_get_vara_schar() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = nc_get_vara_schar (ncid, varid, mystart, iocount, value); if (lstatus != NC_NOERR && (status == NC_NOERR || lstatus != NC_ERANGE)) status = lstatus; /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += mymap[idim]; mystart[idim] += mystride[idim]; if (mystart[idim] == stop[idim]) { mystart[idim] = start[idim]; value -= length[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; } int nc_get_varm_short(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *map, short *value) { int status = ENOERR; NC *ncp; NC_var *varp; int maxidim; /* maximum dimensional index */ status = NC_check_id (ncid, &ncp); if (status != NC_NOERR) return status; if (NC_indef (ncp)) { return NC_EINDEFINE; } varp = NC_lookupvar (ncp, varid); if (varp == NULL) return NC_ENOTVAR; if(varp->type == NC_CHAR) return NC_ECHAR; maxidim = (int) varp->ndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ return getNCv_short (ncp, varp, start, 1, value); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; /* * Verify stride argument. */ for (idim = 0; idim <= maxidim; ++idim) { if (stride != NULL && (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || (unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varp->ndims; iocount = myedges + varp->ndims; stop = iocount + varp->ndims; length = stop + varp->ndims; mystride = (ptrdiff_t *)(length + varp->ndims); mymap = mystride + varp->ndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && IS_RECVAR (varp) ? ncp->numrecs - mystart[idim] : varp->shape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; mymap[idim] = map != NULL ? map[idim] : idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; iocount[idim] = 1; length[idim] = mymap[idim] * myedges[idim]; stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; } /* * Check start, edges */ for (idim = maxidim; idim >= 0; --idim) { size_t dimlen = idim == 0 && IS_RECVAR (varp) ? ncp->numrecs : varp->shape[idim]; if (mystart[idim] >= dimlen) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > dimlen) { status = NC_EEDGE; goto done; } } /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvarnc_get_vara_short() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = nc_get_vara_short (ncid, varid, mystart, iocount, value); if (lstatus != NC_NOERR && (status == NC_NOERR || lstatus != NC_ERANGE)) status = lstatus; /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += mymap[idim]; mystart[idim] += mystride[idim]; if (mystart[idim] == stop[idim]) { mystart[idim] = start[idim]; value -= length[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; } int nc_get_varm_int(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *map, int *value) { int status = ENOERR; NC *ncp; NC_var *varp; int maxidim; /* maximum dimensional index */ status = NC_check_id (ncid, &ncp); if (status != NC_NOERR) return status; if (NC_indef (ncp)) { return NC_EINDEFINE; } varp = NC_lookupvar (ncp, varid); if (varp == NULL) return NC_ENOTVAR; if(varp->type == NC_CHAR) return NC_ECHAR; maxidim = (int) varp->ndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ return getNCv_int (ncp, varp, start, 1, value); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; /* * Verify stride argument. */ for (idim = 0; idim <= maxidim; ++idim) { if (stride != NULL && (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || (unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varp->ndims; iocount = myedges + varp->ndims; stop = iocount + varp->ndims; length = stop + varp->ndims; mystride = (ptrdiff_t *)(length + varp->ndims); mymap = mystride + varp->ndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && IS_RECVAR (varp) ? ncp->numrecs - mystart[idim] : varp->shape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; mymap[idim] = map != NULL ? map[idim] : idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; iocount[idim] = 1; length[idim] = mymap[idim] * myedges[idim]; stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; } /* * Check start, edges */ for (idim = maxidim; idim >= 0; --idim) { size_t dimlen = idim == 0 && IS_RECVAR (varp) ? ncp->numrecs : varp->shape[idim]; if (mystart[idim] >= dimlen) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > dimlen) { status = NC_EEDGE; goto done; } } /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvarnc_get_vara_int() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = nc_get_vara_int (ncid, varid, mystart, iocount, value); if (lstatus != NC_NOERR && (status == NC_NOERR || lstatus != NC_ERANGE)) status = lstatus; /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += mymap[idim]; mystart[idim] += mystride[idim]; if (mystart[idim] == stop[idim]) { mystart[idim] = start[idim]; value -= length[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; } int nc_get_varm_long(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *map, long *value) { int status = ENOERR; NC *ncp; NC_var *varp; int maxidim; /* maximum dimensional index */ status = NC_check_id (ncid, &ncp); if (status != NC_NOERR) return status; if (NC_indef (ncp)) { return NC_EINDEFINE; } varp = NC_lookupvar (ncp, varid); if (varp == NULL) return NC_ENOTVAR; if(varp->type == NC_CHAR) return NC_ECHAR; maxidim = (int) varp->ndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ return getNCv_long (ncp, varp, start, 1, value); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; /* * Verify stride argument. */ for (idim = 0; idim <= maxidim; ++idim) { if (stride != NULL && (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || (unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varp->ndims; iocount = myedges + varp->ndims; stop = iocount + varp->ndims; length = stop + varp->ndims; mystride = (ptrdiff_t *)(length + varp->ndims); mymap = mystride + varp->ndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && IS_RECVAR (varp) ? ncp->numrecs - mystart[idim] : varp->shape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; mymap[idim] = map != NULL ? map[idim] : idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; iocount[idim] = 1; length[idim] = mymap[idim] * myedges[idim]; stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; } /* * Check start, edges */ for (idim = maxidim; idim >= 0; --idim) { size_t dimlen = idim == 0 && IS_RECVAR (varp) ? ncp->numrecs : varp->shape[idim]; if (mystart[idim] >= dimlen) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > dimlen) { status = NC_EEDGE; goto done; } } /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvarnc_get_vara_long() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = nc_get_vara_long (ncid, varid, mystart, iocount, value); if (lstatus != NC_NOERR && (status == NC_NOERR || lstatus != NC_ERANGE)) status = lstatus; /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += mymap[idim]; mystart[idim] += mystride[idim]; if (mystart[idim] == stop[idim]) { mystart[idim] = start[idim]; value -= length[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; } int nc_get_varm_float(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *map, float *value) { int status = ENOERR; NC *ncp; NC_var *varp; int maxidim; /* maximum dimensional index */ status = NC_check_id (ncid, &ncp); if (status != NC_NOERR) return status; if (NC_indef (ncp)) { return NC_EINDEFINE; } varp = NC_lookupvar (ncp, varid); if (varp == NULL) return NC_ENOTVAR; if(varp->type == NC_CHAR) return NC_ECHAR; maxidim = (int) varp->ndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ return getNCv_float (ncp, varp, start, 1, value); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; /* * Verify stride argument. */ for (idim = 0; idim <= maxidim; ++idim) { if (stride != NULL && (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || (unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varp->ndims; iocount = myedges + varp->ndims; stop = iocount + varp->ndims; length = stop + varp->ndims; mystride = (ptrdiff_t *)(length + varp->ndims); mymap = mystride + varp->ndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && IS_RECVAR (varp) ? ncp->numrecs - mystart[idim] : varp->shape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; mymap[idim] = map != NULL ? map[idim] : idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; iocount[idim] = 1; length[idim] = mymap[idim] * myedges[idim]; stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; } /* * Check start, edges */ for (idim = maxidim; idim >= 0; --idim) { size_t dimlen = idim == 0 && IS_RECVAR (varp) ? ncp->numrecs : varp->shape[idim]; if (mystart[idim] >= dimlen) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > dimlen) { status = NC_EEDGE; goto done; } } /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvarnc_get_vara_float() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = nc_get_vara_float (ncid, varid, mystart, iocount, value); if (lstatus != NC_NOERR && (status == NC_NOERR || lstatus != NC_ERANGE)) status = lstatus; /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += mymap[idim]; mystart[idim] += mystride[idim]; if (mystart[idim] == stop[idim]) { mystart[idim] = start[idim]; value -= length[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; } int nc_get_varm_double(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *map, double *value) { int status = ENOERR; NC *ncp; NC_var *varp; int maxidim; /* maximum dimensional index */ status = NC_check_id (ncid, &ncp); if (status != NC_NOERR) return status; if (NC_indef (ncp)) { return NC_EINDEFINE; } varp = NC_lookupvar (ncp, varid); if (varp == NULL) return NC_ENOTVAR; if(varp->type == NC_CHAR) return NC_ECHAR; maxidim = (int) varp->ndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ return getNCv_double (ncp, varp, start, 1, value); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; /* * Verify stride argument. */ for (idim = 0; idim <= maxidim; ++idim) { if (stride != NULL && (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || (unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varp->ndims; iocount = myedges + varp->ndims; stop = iocount + varp->ndims; length = stop + varp->ndims; mystride = (ptrdiff_t *)(length + varp->ndims); mymap = mystride + varp->ndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && IS_RECVAR (varp) ? ncp->numrecs - mystart[idim] : varp->shape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; mymap[idim] = map != NULL ? map[idim] : idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; iocount[idim] = 1; length[idim] = mymap[idim] * myedges[idim]; stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; } /* * Check start, edges */ for (idim = maxidim; idim >= 0; --idim) { size_t dimlen = idim == 0 && IS_RECVAR (varp) ? ncp->numrecs : varp->shape[idim]; if (mystart[idim] >= dimlen) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > dimlen) { status = NC_EEDGE; goto done; } } /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvarnc_get_vara_double() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = nc_get_vara_double (ncid, varid, mystart, iocount, value); if (lstatus != NC_NOERR && (status == NC_NOERR || lstatus != NC_ERANGE)) status = lstatus; /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += mymap[idim]; mystart[idim] += mystride[idim]; if (mystart[idim] == stop[idim]) { mystart[idim] = start[idim]; value -= length[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; } /* deprecated, used to support the 2.x interface */ int nc_get_varm ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, const ptrdiff_t * map, void *value) { int status; NC *ncp; const NC_var *varp; ptrdiff_t *cvtmap = NULL; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; if(map != NULL && varp->ndims != 0) { /* * convert map units from bytes to units of sizeof(type) */ size_t ii; const ptrdiff_t szof = (ptrdiff_t) nctypelen(varp->type); cvtmap = (ptrdiff_t *)calloc(varp->ndims, sizeof(ptrdiff_t)); if(cvtmap == NULL) return NC_ENOMEM; for(ii = 0; ii < varp->ndims; ii++) { if(map[ii] % szof != 0) { free(cvtmap); return NC_EINVAL; } cvtmap[ii] = map[ii] / szof; } map = cvtmap; } switch(varp->type){ case NC_CHAR: status = nc_get_varm_text(ncid, varid, start, edges, stride, map, (char *) value); break; case NC_BYTE: status = nc_get_varm_schar(ncid, varid, start, edges, stride, map, (schar *) value); break; case NC_SHORT: status = nc_get_varm_short(ncid, varid, start, edges, stride, map, (short *) value); break; case NC_INT: #if (SIZEOF_INT >= X_SIZEOF_INT) status = nc_get_varm_int(ncid, varid, start, edges, stride, map, (int *) value); #elif SIZEOF_LONG == X_SIZEOF_INT status = nc_get_varm_long(ncid, varid, start, edges, stride, map, (long *) value); #else #error "nc_get_varm implementation" #endif break; case NC_FLOAT: status = nc_get_varm_float(ncid, varid, start, edges, stride, map, (float *) value); break; case NC_DOUBLE: status = nc_get_varm_double(ncid, varid, start, edges, stride, map, (double *) value); break; default: status = NC_EBADTYPE; break; } if(cvtmap != NULL) { free(cvtmap); } return status; } /* * Generalized hyperslab output. */ int nc_put_varm_text(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *map, const char *value) { int status = ENOERR; NC *ncp; NC_var *varp; int maxidim; /* maximum dimensional index */ status = NC_check_id (ncid, &ncp); if (status != NC_NOERR) return status; if (NC_indef (ncp)) { return NC_EINDEFINE; } if (NC_readonly (ncp)) return NC_EPERM; varp = NC_lookupvar (ncp, varid); if (varp == NULL) return NC_ENOTVAR; if(varp->type != NC_CHAR) return NC_ECHAR; maxidim = (int) varp->ndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ return putNCv_text (ncp, varp, start, 1, value); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; /* * Verify stride argument. */ for (idim = 0; idim <= maxidim; ++idim) { if (stride != NULL && (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || (unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varp->ndims; iocount = myedges + varp->ndims; stop = iocount + varp->ndims; length = stop + varp->ndims; mystride = (ptrdiff_t *)(length + varp->ndims); mymap = mystride + varp->ndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && IS_RECVAR (varp) ? ncp->numrecs - mystart[idim] : varp->shape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; mymap[idim] = map != NULL ? map[idim] : idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; iocount[idim] = 1; length[idim] = mymap[idim] * myedges[idim]; stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; } /* * Check start, edges */ for (idim = IS_RECVAR (varp); idim < maxidim; ++idim) { if (mystart[idim] >= varp->shape[idim]) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > varp->shape[idim]) { status = NC_EEDGE; goto done; } } /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvarnc_put_vara_text() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = nc_put_vara_text (ncid, varid, mystart, iocount, value); if (lstatus != NC_NOERR && (status == NC_NOERR || lstatus != NC_ERANGE)) status = lstatus; /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += mymap[idim]; mystart[idim] += mystride[idim]; if (mystart[idim] == stop[idim]) { mystart[idim] = start[idim]; value -= length[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; } int nc_put_varm_uchar(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *map, const uchar *value) { int status = ENOERR; NC *ncp; NC_var *varp; int maxidim; /* maximum dimensional index */ status = NC_check_id (ncid, &ncp); if (status != NC_NOERR) return status; if (NC_indef (ncp)) { return NC_EINDEFINE; } if (NC_readonly (ncp)) return NC_EPERM; varp = NC_lookupvar (ncp, varid); if (varp == NULL) return NC_ENOTVAR; if(varp->type == NC_CHAR) return NC_ECHAR; maxidim = (int) varp->ndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ return putNCv_uchar (ncp, varp, start, 1, value); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; /* * Verify stride argument. */ for (idim = 0; idim <= maxidim; ++idim) { if (stride != NULL && (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || (unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varp->ndims; iocount = myedges + varp->ndims; stop = iocount + varp->ndims; length = stop + varp->ndims; mystride = (ptrdiff_t *)(length + varp->ndims); mymap = mystride + varp->ndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && IS_RECVAR (varp) ? ncp->numrecs - mystart[idim] : varp->shape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; mymap[idim] = map != NULL ? map[idim] : idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; iocount[idim] = 1; length[idim] = mymap[idim] * myedges[idim]; stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; } /* * Check start, edges */ for (idim = IS_RECVAR (varp); idim < maxidim; ++idim) { if (mystart[idim] >= varp->shape[idim]) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > varp->shape[idim]) { status = NC_EEDGE; goto done; } } /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvarnc_put_vara_uchar() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = nc_put_vara_uchar (ncid, varid, mystart, iocount, value); if (lstatus != NC_NOERR && (status == NC_NOERR || lstatus != NC_ERANGE)) status = lstatus; /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += mymap[idim]; mystart[idim] += mystride[idim]; if (mystart[idim] == stop[idim]) { mystart[idim] = start[idim]; value -= length[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; } int nc_put_varm_schar(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *map, const schar *value) { int status = ENOERR; NC *ncp; NC_var *varp; int maxidim; /* maximum dimensional index */ status = NC_check_id (ncid, &ncp); if (status != NC_NOERR) return status; if (NC_indef (ncp)) { return NC_EINDEFINE; } if (NC_readonly (ncp)) return NC_EPERM; varp = NC_lookupvar (ncp, varid); if (varp == NULL) return NC_ENOTVAR; if(varp->type == NC_CHAR) return NC_ECHAR; maxidim = (int) varp->ndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ return putNCv_schar (ncp, varp, start, 1, value); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; /* * Verify stride argument. */ for (idim = 0; idim <= maxidim; ++idim) { if (stride != NULL && (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || (unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varp->ndims; iocount = myedges + varp->ndims; stop = iocount + varp->ndims; length = stop + varp->ndims; mystride = (ptrdiff_t *)(length + varp->ndims); mymap = mystride + varp->ndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && IS_RECVAR (varp) ? ncp->numrecs - mystart[idim] : varp->shape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; mymap[idim] = map != NULL ? map[idim] : idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; iocount[idim] = 1; length[idim] = mymap[idim] * myedges[idim]; stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; } /* * Check start, edges */ for (idim = IS_RECVAR (varp); idim < maxidim; ++idim) { if (mystart[idim] >= varp->shape[idim]) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > varp->shape[idim]) { status = NC_EEDGE; goto done; } } /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvarnc_put_vara_schar() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = nc_put_vara_schar (ncid, varid, mystart, iocount, value); if (lstatus != NC_NOERR && (status == NC_NOERR || lstatus != NC_ERANGE)) status = lstatus; /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += mymap[idim]; mystart[idim] += mystride[idim]; if (mystart[idim] == stop[idim]) { mystart[idim] = start[idim]; value -= length[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; } int nc_put_varm_short(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *map, const short *value) { int status = ENOERR; NC *ncp; NC_var *varp; int maxidim; /* maximum dimensional index */ status = NC_check_id (ncid, &ncp); if (status != NC_NOERR) return status; if (NC_indef (ncp)) { return NC_EINDEFINE; } if (NC_readonly (ncp)) return NC_EPERM; varp = NC_lookupvar (ncp, varid); if (varp == NULL) return NC_ENOTVAR; if(varp->type == NC_CHAR) return NC_ECHAR; maxidim = (int) varp->ndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ return putNCv_short (ncp, varp, start, 1, value); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; /* * Verify stride argument. */ for (idim = 0; idim <= maxidim; ++idim) { if (stride != NULL && (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || (unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varp->ndims; iocount = myedges + varp->ndims; stop = iocount + varp->ndims; length = stop + varp->ndims; mystride = (ptrdiff_t *)(length + varp->ndims); mymap = mystride + varp->ndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && IS_RECVAR (varp) ? ncp->numrecs - mystart[idim] : varp->shape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; mymap[idim] = map != NULL ? map[idim] : idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; iocount[idim] = 1; length[idim] = mymap[idim] * myedges[idim]; stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; } /* * Check start, edges */ for (idim = IS_RECVAR (varp); idim < maxidim; ++idim) { if (mystart[idim] >= varp->shape[idim]) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > varp->shape[idim]) { status = NC_EEDGE; goto done; } } /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvarnc_put_vara_short() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = nc_put_vara_short (ncid, varid, mystart, iocount, value); if (lstatus != NC_NOERR && (status == NC_NOERR || lstatus != NC_ERANGE)) status = lstatus; /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += mymap[idim]; mystart[idim] += mystride[idim]; if (mystart[idim] == stop[idim]) { mystart[idim] = start[idim]; value -= length[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; } int nc_put_varm_int(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *map, const int *value) { int status = ENOERR; NC *ncp; NC_var *varp; int maxidim; /* maximum dimensional index */ status = NC_check_id (ncid, &ncp); if (status != NC_NOERR) return status; if (NC_indef (ncp)) { return NC_EINDEFINE; } if (NC_readonly (ncp)) return NC_EPERM; varp = NC_lookupvar (ncp, varid); if (varp == NULL) return NC_ENOTVAR; if(varp->type == NC_CHAR) return NC_ECHAR; maxidim = (int) varp->ndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ return putNCv_int (ncp, varp, start, 1, value); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; /* * Verify stride argument. */ for (idim = 0; idim <= maxidim; ++idim) { if (stride != NULL && (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || (unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varp->ndims; iocount = myedges + varp->ndims; stop = iocount + varp->ndims; length = stop + varp->ndims; mystride = (ptrdiff_t *)(length + varp->ndims); mymap = mystride + varp->ndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && IS_RECVAR (varp) ? ncp->numrecs - mystart[idim] : varp->shape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; mymap[idim] = map != NULL ? map[idim] : idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; iocount[idim] = 1; length[idim] = mymap[idim] * myedges[idim]; stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; } /* * Check start, edges */ for (idim = IS_RECVAR (varp); idim < maxidim; ++idim) { if (mystart[idim] >= varp->shape[idim]) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > varp->shape[idim]) { status = NC_EEDGE; goto done; } } /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvarnc_put_vara_int() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = nc_put_vara_int (ncid, varid, mystart, iocount, value); if (lstatus != NC_NOERR && (status == NC_NOERR || lstatus != NC_ERANGE)) status = lstatus; /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += mymap[idim]; mystart[idim] += mystride[idim]; if (mystart[idim] == stop[idim]) { mystart[idim] = start[idim]; value -= length[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; } int nc_put_varm_long(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *map, const long *value) { int status = ENOERR; NC *ncp; NC_var *varp; int maxidim; /* maximum dimensional index */ status = NC_check_id (ncid, &ncp); if (status != NC_NOERR) return status; if (NC_indef (ncp)) { return NC_EINDEFINE; } if (NC_readonly (ncp)) return NC_EPERM; varp = NC_lookupvar (ncp, varid); if (varp == NULL) return NC_ENOTVAR; if(varp->type == NC_CHAR) return NC_ECHAR; maxidim = (int) varp->ndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ return putNCv_long (ncp, varp, start, 1, value); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; /* * Verify stride argument. */ for (idim = 0; idim <= maxidim; ++idim) { if (stride != NULL && (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || (unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varp->ndims; iocount = myedges + varp->ndims; stop = iocount + varp->ndims; length = stop + varp->ndims; mystride = (ptrdiff_t *)(length + varp->ndims); mymap = mystride + varp->ndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && IS_RECVAR (varp) ? ncp->numrecs - mystart[idim] : varp->shape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; mymap[idim] = map != NULL ? map[idim] : idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; iocount[idim] = 1; length[idim] = mymap[idim] * myedges[idim]; stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; } /* * Check start, edges */ for (idim = IS_RECVAR (varp); idim < maxidim; ++idim) { if (mystart[idim] >= varp->shape[idim]) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > varp->shape[idim]) { status = NC_EEDGE; goto done; } } /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvarnc_put_vara_long() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = nc_put_vara_long (ncid, varid, mystart, iocount, value); if (lstatus != NC_NOERR && (status == NC_NOERR || lstatus != NC_ERANGE)) status = lstatus; /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += mymap[idim]; mystart[idim] += mystride[idim]; if (mystart[idim] == stop[idim]) { mystart[idim] = start[idim]; value -= length[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; } int nc_put_varm_float(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *map, const float *value) { int status = ENOERR; NC *ncp; NC_var *varp; int maxidim; /* maximum dimensional index */ status = NC_check_id (ncid, &ncp); if (status != NC_NOERR) return status; if (NC_indef (ncp)) { return NC_EINDEFINE; } if (NC_readonly (ncp)) return NC_EPERM; varp = NC_lookupvar (ncp, varid); if (varp == NULL) return NC_ENOTVAR; if(varp->type == NC_CHAR) return NC_ECHAR; maxidim = (int) varp->ndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ return putNCv_float (ncp, varp, start, 1, value); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; /* * Verify stride argument. */ for (idim = 0; idim <= maxidim; ++idim) { if (stride != NULL && (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || (unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varp->ndims; iocount = myedges + varp->ndims; stop = iocount + varp->ndims; length = stop + varp->ndims; mystride = (ptrdiff_t *)(length + varp->ndims); mymap = mystride + varp->ndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && IS_RECVAR (varp) ? ncp->numrecs - mystart[idim] : varp->shape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; mymap[idim] = map != NULL ? map[idim] : idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; iocount[idim] = 1; length[idim] = mymap[idim] * myedges[idim]; stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; } /* * Check start, edges */ for (idim = IS_RECVAR (varp); idim < maxidim; ++idim) { if (mystart[idim] >= varp->shape[idim]) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > varp->shape[idim]) { status = NC_EEDGE; goto done; } } /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvarnc_put_vara_float() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = nc_put_vara_float (ncid, varid, mystart, iocount, value); if (lstatus != NC_NOERR && (status == NC_NOERR || lstatus != NC_ERANGE)) status = lstatus; /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += mymap[idim]; mystart[idim] += mystride[idim]; if (mystart[idim] == stop[idim]) { mystart[idim] = start[idim]; value -= length[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; } int nc_put_varm_double(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *map, const double *value) { int status = ENOERR; NC *ncp; NC_var *varp; int maxidim; /* maximum dimensional index */ status = NC_check_id (ncid, &ncp); if (status != NC_NOERR) return status; if (NC_indef (ncp)) { return NC_EINDEFINE; } if (NC_readonly (ncp)) return NC_EPERM; varp = NC_lookupvar (ncp, varid); if (varp == NULL) return NC_ENOTVAR; if(varp->type == NC_CHAR) return NC_ECHAR; maxidim = (int) varp->ndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ return putNCv_double (ncp, varp, start, 1, value); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; /* * Verify stride argument. */ for (idim = 0; idim <= maxidim; ++idim) { if (stride != NULL && (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || (unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varp->ndims; iocount = myedges + varp->ndims; stop = iocount + varp->ndims; length = stop + varp->ndims; mystride = (ptrdiff_t *)(length + varp->ndims); mymap = mystride + varp->ndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && IS_RECVAR (varp) ? ncp->numrecs - mystart[idim] : varp->shape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; mymap[idim] = map != NULL ? map[idim] : idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; iocount[idim] = 1; length[idim] = mymap[idim] * myedges[idim]; stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; } /* * Check start, edges */ for (idim = IS_RECVAR (varp); idim < maxidim; ++idim) { if (mystart[idim] >= varp->shape[idim]) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > varp->shape[idim]) { status = NC_EEDGE; goto done; } } /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvarnc_put_vara_double() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = nc_put_vara_double (ncid, varid, mystart, iocount, value); if (lstatus != NC_NOERR && (status == NC_NOERR || lstatus != NC_ERANGE)) status = lstatus; /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += mymap[idim]; mystart[idim] += mystride[idim]; if (mystart[idim] == stop[idim]) { mystart[idim] = start[idim]; value -= length[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; } /* deprecated, used to support the 2.x interface */ int nc_put_varm ( int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, const ptrdiff_t * map, const void *value) { int status; NC *ncp; const NC_var *varp; ptrdiff_t *cvtmap = NULL; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; varp = NC_lookupvar(ncp, varid); if(varp == NULL) return NC_ENOTVAR; if(map != NULL && varp->ndims != 0) { /* * convert map units from bytes to units of sizeof(type) */ size_t ii; const ptrdiff_t szof = (ptrdiff_t) nctypelen(varp->type); cvtmap = (ptrdiff_t *)calloc(varp->ndims, sizeof(ptrdiff_t)); if(cvtmap == NULL) return NC_ENOMEM; for(ii = 0; ii < varp->ndims; ii++) { if(map[ii] % szof != 0) { free(cvtmap); return NC_EINVAL; } cvtmap[ii] = map[ii] / szof; } map = cvtmap; } switch(varp->type){ case NC_CHAR: status = nc_put_varm_text(ncid, varid, start, edges, stride, map, (const char *) value); break; case NC_BYTE: status = nc_put_varm_schar(ncid, varid, start, edges, stride, map, (const schar *) value); break; case NC_SHORT: status = nc_put_varm_short(ncid, varid, start, edges, stride, map, (const short *) value); break; case NC_INT: #if (SIZEOF_INT >= X_SIZEOF_INT) status = nc_put_varm_int(ncid, varid, start, edges, stride, map, (const int *) value); #elif SIZEOF_LONG == X_SIZEOF_INT status = nc_put_varm_long(ncid, varid, start, edges, stride, map, (const long *) value); #else #error "nc_put_varm implementation" #endif break; case NC_FLOAT: status = nc_put_varm_float(ncid, varid, start, edges, stride, map, (const float *) value); break; case NC_DOUBLE: status = nc_put_varm_double(ncid, varid, start, edges, stride, map, (const double *) value); break; default: status = NC_EBADTYPE; break; } if(cvtmap != NULL) { free(cvtmap); } return status; } /* Begin recio, deprecated */ /* * input 'nelems' items of contiguous data of 'varp' at 'start' * N.B. this function deprecated. */ static int getNCvdata(const NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, void *value) { switch(varp->type){ case NC_CHAR: return getNCvx_char_char(ncp, varp, start, nelems, (char *) value); case NC_BYTE: return getNCvx_schar_schar(ncp, varp, start, nelems, (schar *) value); case NC_SHORT: return getNCvx_short_short(ncp, varp, start, nelems, (short *) value); case NC_INT: #if (SIZEOF_INT >= X_SIZEOF_INT) return getNCvx_int_int(ncp, varp, start, nelems, (int *) value); #elif SIZEOF_LONG == X_SIZEOF_INT return getNCvx_int_long(ncp, varp, start, nelems, (long *) value); #else #error "getNCvdata implementation" #endif case NC_FLOAT: return getNCvx_float_float(ncp, varp, start, nelems, (float *) value); case NC_DOUBLE: return getNCvx_double_double(ncp, varp, start, nelems, (double *) value); } return NC_EBADTYPE; } /* * output 'nelems' items of contiguous data of 'varp' at 'start' * N.B. this function deprecated. */ static int putNCvdata(NC *ncp, const NC_var *varp, const size_t *start, size_t nelems, const void *value) { switch(varp->type){ case NC_CHAR: return putNCvx_char_char(ncp, varp, start, nelems, (const char *) value); case NC_BYTE: return putNCvx_schar_schar(ncp, varp, start, nelems, (const schar *) value); case NC_SHORT: return putNCvx_short_short(ncp, varp, start, nelems, (const short *) value); case NC_INT: #if (SIZEOF_INT >= X_SIZEOF_INT) return putNCvx_int_int(ncp, varp, start, nelems, (const int *) value); #elif SIZEOF_LONG == X_SIZEOF_INT return putNCvx_long_int(ncp, varp, start, nelems, (const long *) value); #else #error "putNCvdata implementation" #endif case NC_FLOAT: return putNCvx_float_float(ncp, varp, start, nelems, (const float *) value); case NC_DOUBLE: return putNCvx_double_double(ncp, varp, start, nelems, (const double *) value); } return NC_EBADTYPE; } static size_t NCelemsPerRec( const NC_var *varp) { size_t nelems = 1; size_t jj; for(jj = 1; jj < varp->ndims; jj++) nelems *= varp->shape[jj]; return nelems; } /* * 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. */ int nc_inq_rec( int ncid, size_t *nrecvars, int *recvarids, size_t *recsizes) { NC *ncp; { const int status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; } { size_t nrvars = 0; size_t ii = 0; for(; ii < ncp->vars.nelems; ii++) { const NC_var *const varp = ncp->vars.value[ii]; if(!IS_RECVAR(varp)) continue; if(recvarids != NULL) recvarids[nrvars] = (int) ii; if(recsizes != NULL) { *recsizes++ = nctypelen(varp->type) * NCelemsPerRec(varp); } nrvars++; } if(nrecvars != NULL) *nrecvars = nrvars; } return NC_NOERR; } static int NCrecput( NC *ncp, size_t recnum, void *const *datap) { int status = NC_NOERR; size_t nrvars = 0; NC_var *varp; size_t ii; size_t iocount; ALLOC_ONSTACK(coord, size_t, ncp->dims.nelems); assert(ncp->dims.nelems != 0); (void) memset(coord, 0, ncp->dims.nelems * sizeof(size_t)); coord[0] = recnum; for(ii = 0; ii < ncp->vars.nelems; ii++) { varp = ncp->vars.value[ii]; if(!IS_RECVAR(varp)) continue; /* else */ nrvars++; if(*datap == NULL) { datap++; continue; } /* else */ iocount = NCelemsPerRec(varp); status = putNCvdata(ncp, varp, coord, iocount, *datap++); if(status != NC_NOERR) break; } if(nrvars == 0 && status == NC_NOERR) { status = NC_ENORECVARS; } FREE_ONSTACK(coord); return status; } static int NCrecget( NC *ncp, size_t recnum, void **datap) { int status = NC_NOERR; size_t nrvars = 0; NC_var *varp; size_t ii; size_t iocount; ALLOC_ONSTACK(coord, size_t, ncp->dims.nelems); assert(ncp->dims.nelems != 0); (void) memset(coord, 0, ncp->dims.nelems * sizeof(size_t)); coord[0] = recnum; for(ii = 0; ii < ncp->vars.nelems; ii++) { varp = ncp->vars.value[ii]; if(!IS_RECVAR(varp)) continue; /* else */ nrvars++; if(*datap == NULL) { datap++; continue; } /* else */ iocount = NCelemsPerRec(varp); status = getNCvdata(ncp, varp, coord, iocount, *datap++); if(status != NC_NOERR) break; } if(nrvars == 0 && status == NC_NOERR) { status = NC_ENORECVARS; } FREE_ONSTACK(coord); return status; } /* * 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. */ int nc_put_rec( int ncid, size_t recnum, void * const *datap) { int status; NC *ncp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) { return NC_EPERM; } if(NC_indef(ncp)) { return NC_EINDEFINE; } status = NCvnrecs(ncp, recnum +1); if(status != NC_NOERR) return status; return( NCrecput(ncp, recnum, datap) ); } /* * 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; */ int nc_get_rec( int ncid, size_t recnum, void **datap) { int status; NC *ncp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) { return NC_EINDEFINE; } if(recnum >= ncp->numrecs) { return NC_EINVALCOORDS; } return( NCrecget(ncp, recnum, datap) ); } /* * Copy the values of a variable from an input netCDF to an output netCDF. * Input and output var assummed to have the same shape. * return -1 on error. */ int nc_copy_var(int ncid_in, int varid, int ncid_out) { int status = NC_NOERR; NC *inncp, *outncp; NC_var *invp, *outvp; status = NC_check_id(ncid_in, &inncp); if(status != NC_NOERR) return status; if(NC_indef(inncp)) { return NC_EINDEFINE; } status = NC_check_id(ncid_out, &outncp); if(status != NC_NOERR) return status; if(NC_readonly(outncp)) { /* output file isn't writable */ return NC_EPERM; } if(NC_indef(outncp)) { return NC_EINDEFINE; } /* find the variable in the input cdf */ invp = NC_lookupvar(inncp, varid); if(invp == NULL) { return NC_ENOTVAR; } /* find the variable in the output cdf */ if(NC_findvar(&outncp->vars, invp->name->cp, &outvp) == -1) { return NC_ENOTVAR; } /* can we even attempt to copy without conversion? */ if(outvp->type != invp->type) { return NC_EINVAL; } if( (invp->ndims == 0 && outvp->ndims != 0) || (invp->ndims != 0 && outvp->ndims == 0) || (IS_RECVAR(invp) && !IS_RECVAR(outvp)) || (!IS_RECVAR(invp) && IS_RECVAR(outvp)) || (invp->len != outvp->len) ) { return NC_EINVAL; } /* * Check coordinates */ { ALLOC_ONSTACK(coord, size_t, invp->ndims); (void) memcpy(coord, invp->shape, invp->ndims * sizeof(size_t)); if(IS_RECVAR(invp)) *coord = inncp->numrecs; { size_t ii = 0; for(; ii < invp->ndims; ii++) coord[ii] --; } /* at this point, coord is the largest valid coord of invp */ if(NCcoordck(outncp, outvp, coord) != NC_NOERR) { return NC_EINVAL; } /* else */ (void) memset(coord, 0, invp->ndims * sizeof(size_t)); if(!IS_RECVAR(invp)) { status = NCxvarcpy(inncp, invp, coord, outncp, outvp, coord, invp->len); goto done; } /* else */ status = NCvnrecs(outncp, inncp->numrecs); if(status != NC_NOERR) goto done; for( /*NADA*/; *coord < inncp->numrecs; (*coord)++) { status = NCxvarcpy(inncp, invp, coord, outncp, outvp, coord, invp->len); if(status != NC_NOERR) break; } done: FREE_ONSTACK(coord); } return status; }