/* * Read just the numrecs member. * (A relatively expensive way to do things.) */ int read_numrecs(NC *ncp) { int status = NC_NOERR; const void *xp = NULL; size_t nrecs = NC_get_numrecs(ncp); assert(!NC_indef(ncp)); #define NC_NUMRECS_OFFSET 4 #define NC_NUMRECS_EXTENT 4 status = ncp->nciop->get(ncp->nciop, NC_NUMRECS_OFFSET, NC_NUMRECS_EXTENT, 0, (void **)&xp); /* cast away const */ if(status != NC_NOERR) return status; status = ncx_get_size_t(&xp, &nrecs); (void) ncp->nciop->rel(ncp->nciop, NC_NUMRECS_OFFSET, 0); if(status == NC_NOERR) { NC_set_numrecs(ncp, nrecs); fClr(ncp->flags, NC_NDIRTY); } return status; }
/* * Write out just the numrecs member. * (A relatively expensive way to do things.) */ int write_numrecs(NC *ncp) { int status = NC_NOERR; void *xp = NULL; assert(!NC_readonly(ncp)); assert(!NC_indef(ncp)); status = ncp->nciop->get(ncp->nciop, NC_NUMRECS_OFFSET, NC_NUMRECS_EXTENT, RGN_WRITE, &xp); if(status != NC_NOERR) return status; { const size_t nrecs = NC_get_numrecs(ncp); status = ncx_put_size_t(&xp, &nrecs); } (void) ncp->nciop->rel(ncp->nciop, NC_NUMRECS_OFFSET, RGN_MODIFIED); if(status == NC_NOERR) fClr(ncp->flags, NC_NDIRTY); return status; }
/*----< ncmpi_bput_var1() >--------------------------------------------------*/ int ncmpi_bput_var1(int ncid, int varid, const MPI_Offset *start, const void *buf, MPI_Offset bufcount, MPI_Datatype buftype, int *reqid) { int status; NC *ncp; NC_var *varp; MPI_Offset *count; *reqid = NC_REQ_NULL; CHECK_NCID if (ncp->abuf == NULL) return NC_ENULLABUF; CHECK_WRITE_PERMISSION if (NC_indef(ncp)) return NC_EINDEFINE; CHECK_VARID(varid, varp) GET_ONE_COUNT status = NCcoordck(ncp, varp, start); if (status != NC_NOERR) return status; status = ncmpii_igetput_varm(ncp, varp, start, count, NULL, NULL, (void*)buf, bufcount, buftype, reqid, WRITE_REQ, 1); if (varp->ndims > 0) NCI_Free(count); return status; }
int nc_sync(int ncid) { int status; NC *ncp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) return NC_EINDEFINE; if(NC_readonly(ncp)) { return read_NC(ncp); } /* else, read/write */ status = NC_sync(ncp); if(status != NC_NOERR) return status; return ncp->nciop->sync(ncp->nciop); }
int NC3_del_att(int ncid, int varid, const char *uname) { int status; NC *ncp; NC_attrarray *ncap; NC_attr **attrpp; NC_attr *old = NULL; int attrid; size_t slen; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(!NC_indef(ncp)) return NC_ENOTINDEFINE; ncap = NC_attrarray0(ncp, varid); if(ncap == NULL) return NC_ENOTVAR; { char *name = (char *)utf8proc_NFC((const unsigned char *)uname); if(name == NULL) return NC_ENOMEM; /* sortof inline NC_findattr() */ slen = strlen(name); attrpp = (NC_attr **) ncap->value; for(attrid = 0; (size_t) attrid < ncap->nelems; attrid++, attrpp++) { if( slen == (*attrpp)->name->nchars && strncmp(name, (*attrpp)->name->cp, slen) == 0) { old = *attrpp; break; } } free(name); } if( (size_t) attrid == ncap->nelems ) return NC_ENOTATT; /* end inline NC_findattr() */ /* shuffle down */ for(attrid++; (size_t) attrid < ncap->nelems; attrid++) { *attrpp = *(attrpp + 1); attrpp++; } *attrpp = NULL; /* decrement count */ ncap->nelems--; free_NC_attr(old); return NC_NOERR; }
int NC3_def_dim(int ncid, const char *name, size_t size, int *dimidp) { int status; NC *nc; NC3_INFO* ncp; int dimid; NC_dim *dimp; status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); if(!NC_indef(ncp)) return NC_ENOTINDEFINE; status = NC_check_name(name); if(status != NC_NOERR) return status; if(ncp->flags & NC_64BIT_DATA) {/*CDF-5*/ if((sizeof(size_t) > 4) && (size > X_UINT64_MAX - 3)) /* "- 3" handles rounded-up size */ return NC_EDIMSIZE; } else if(ncp->flags & NC_64BIT_OFFSET) {/* CDF2 format and LFS */ if((sizeof(size_t) > 4) && (size > X_UINT_MAX - 3)) /* "- 3" handles rounded-up size */ return NC_EDIMSIZE; } else {/*CDF-1*/ if(size > X_INT_MAX - 3) return NC_EDIMSIZE; } if(size == NC_UNLIMITED) { dimid = find_NC_Udim(&ncp->dims, &dimp); if(dimid != -1) { assert(dimid != -1); return NC_EUNLIMIT; } } dimid = NC_finddim(&ncp->dims, name, &dimp); if(dimid != -1) return NC_ENAMEINUSE; dimp = new_NC_dim(name, size); if(dimp == NULL) return NC_ENOMEM; status = incr_NC_dimarray(&ncp->dims, dimp); if(status != NC_NOERR) { free_NC_dim(dimp); return status; } if(dimidp != NULL) *dimidp = (int)ncp->dims.nelems -1; return NC_NOERR; }
int nc_redef(int ncid) { 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; if(fIsSet(ncp->nciop->ioflags, NC_SHARE)) { /* read in from disk */ status = read_NC(ncp); if(status != NC_NOERR) return status; } ncp->old = dup_NC(ncp); if(ncp->old == NULL) return NC_ENOMEM; fSet(ncp->flags, NC_INDEF); return NC_NOERR; }
int ncmpi_rename_var(int ncid, int varid, const char *newname) { int file_ver, status, other; NC *ncp; NC_var *varp; NC_string *old, *newStr; status = ncmpii_NC_check_id(ncid, &ncp); if (status != NC_NOERR) return status; if (NC_readonly(ncp)) return NC_EPERM; file_ver = 1; if (fIsSet(ncp->flags, NC_64BIT_OFFSET)) file_ver = 2; else if (fIsSet(ncp->flags, NC_64BIT_DATA)) file_ver = 5; status = ncmpii_NC_check_name(newname, file_ver); if (status != NC_NOERR) return status; /* check for name in use */ other = ncmpii_NC_findvar(&ncp->vars, newname, &varp); if (other != -1) return NC_ENAMEINUSE; varp = ncmpii_NC_lookupvar(ncp, varid); if (varp == NULL) /* invalid varid */ return NC_ENOTVAR; /* TODO: is this the right error code? */ old = varp->name; if (NC_indef(ncp)) { newStr = ncmpii_new_NC_string(strlen(newname),newname); if (newStr == NULL) return(-1); varp->name = newStr; ncmpii_free_NC_string(old); return NC_NOERR; } /* else, not in define mode */ status = ncmpii_set_NC_string(varp->name, newname); if (status != NC_NOERR) return status; set_NC_hdirty(ncp); if (NC_doHsync(ncp)) { status = ncmpii_NC_sync(ncp, 1); if (status != NC_NOERR) return status; } return NC_NOERR; }
int ncmpi_rename_dim( int ncid, int dimid, const char *newname) { int file_ver, status, existid; NC *ncp; NC_dim *dimp; status = ncmpii_NC_check_id(ncid, &ncp); if (status != NC_NOERR) return status; if (NC_readonly(ncp)) return NC_EPERM; file_ver = 1; if (fIsSet(ncp->flags, NC_64BIT_OFFSET)) file_ver = 2; else if (fIsSet(ncp->flags, NC_64BIT_DATA)) file_ver = 5; status = ncmpii_NC_check_name(newname, file_ver); if (status != NC_NOERR) return status; existid = NC_finddim(&ncp->dims, newname, &dimp); if (existid != -1) return NC_ENAMEINUSE; dimp = ncmpii_elem_NC_dimarray(&ncp->dims, (size_t) dimid); if (dimp == NULL) return NC_EBADDIM; if (NC_indef(ncp)) { NC_string *old = dimp->name; NC_string *newStr = ncmpii_new_NC_string(strlen(newname), newname); if (newStr == NULL) return NC_ENOMEM; dimp->name = newStr; ncmpii_free_NC_string(old); return NC_NOERR; } /* else, not in define mode */ status = ncmpii_set_NC_string(dimp->name, newname); if (status != NC_NOERR) return status; set_NC_hdirty(ncp); if (NC_doHsync(ncp)) { status = ncmpii_NC_sync(ncp, 1); if (status != NC_NOERR) return status; } return NC_NOERR; }
int nc_close(int ncid) { int status = NC_NOERR; NC *ncp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) { status = NC_endef(ncp, 0, 1, 0, 1); /* TODO: defaults */ if(status != NC_NOERR ) { (void) nc_abort(ncid); return status; } } else if(!NC_readonly(ncp)) { status = NC_sync(ncp); /* flush buffers before any filesize comparisons */ (void) ncp->nciop->sync(ncp->nciop); } /* * If file opened for writing and filesize is less than * what it should be (due to previous use of NOFILL mode), * pad it to correct size, as reported by NC_calcsize(). */ if (status == ENOERR) { off_t filesize; /* current size of open file */ off_t calcsize; /* calculated file size, from header */ status = ncio_filesize(ncp->nciop, &filesize); if(status != ENOERR) return status; status = NC_calcsize(ncp, &calcsize); if(status != NC_NOERR) return status; if(filesize < calcsize && !NC_readonly(ncp)) { status = ncio_pad_length(ncp->nciop, calcsize); if(status != ENOERR) return status; } } (void) ncio_close(ncp->nciop, 0); ncp->nciop = NULL; del_from_NCList(ncp); free_NC(ncp); return status; }
int NC3_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value) { int status; NC *nc; NC3_INFO* ncp; NC_var *varp; status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); if(NC_readonly(ncp)) { return NC_EPERM; } if(!NC_indef(ncp)) { return NC_ENOTINDEFINE; } varp = elem_NC_vararray(&ncp->vars, (size_t)varid); if(varp == NULL) return NC_ENOTVAR; if (no_fill) varp->no_fill = 1; else varp->no_fill = 0; /* Are we setting a fill value? */ if (fill_value != NULL && !varp->no_fill) { /* If there's a _FillValue attribute, delete it. */ status = NC3_del_att(ncid, varid, _FillValue); if (status != NC_NOERR && status != NC_ENOTATT) return status; /* Create/overwrite attribute _FillValue */ status = NC3_put_att(ncid, varid, _FillValue, varp->type, 1, fill_value, varp->type); if (status != NC_NOERR) return status; } return NC_NOERR; }
int nc_enddef(int ncid) { int status; NC *ncp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(!NC_indef(ncp)) return(NC_ENOTINDEFINE); /* return(NC_endef(ncp, 0, 4096, 0, 4096)); */ return (NC_endef(ncp, 0, 1, 0, 1)); }
int nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, size_t r_align) { int status; NC *ncp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(!NC_indef(ncp)) return(NC_ENOTINDEFINE); return (NC_endef(ncp, h_minfree, v_align, v_minfree, r_align)); }
int nc_rename_att( int ncid, int varid, const char *name, const char *newname) { int status; NC *ncp; NC_attrarray *ncap; NC_attr **tmp; NC_attr *attrp; NC_string *newStr, *old; /* sortof inline clone of NC_lookupattr() */ status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; ncap = NC_attrarray0(ncp, varid); if(ncap == NULL) return NC_ENOTVAR; status = NC_check_name(newname); if(status != NC_NOERR) return status; tmp = NC_findattr(ncap, name); if(tmp == NULL) return NC_ENOTATT; attrp = *tmp; /* end inline clone NC_lookupattr() */ if(NC_findattr(ncap, newname) != NULL) { /* name in use */ return NC_ENAMEINUSE; } old = attrp->name; if(NC_indef(ncp)) { newStr = new_NC_string(strlen(newname), newname); if( newStr == NULL) return NC_ENOMEM; attrp->name = newStr; free_NC_string(old); return NC_NOERR; } /* else */ status = set_NC_string(old, newname); if( status != NC_NOERR) return status; set_NC_hdirty(ncp); if(NC_doHsync(ncp)) { status = NC_sync(ncp); if(status != NC_NOERR) return status; } return NC_NOERR; }
int nc_put_att_double(int ncid, int varid, const char *name, nc_type type, size_t nelems, const double *value) { int status; NC *ncp; NC_attrarray *ncap; NC_attr **attrpp; NC_attr *old = NULL; NC_attr *attrp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; ncap = NC_attrarray0(ncp, varid); if(ncap == NULL) return NC_ENOTVAR; status = nc_cktype(type); if(status != NC_NOERR) return status; if(type == NC_CHAR) return NC_ECHAR; /* cast needed for braindead systems with signed size_t */ if((unsigned long) nelems > X_INT_MAX) /* backward compat */ return NC_EINVAL; /* Invalid nelems */ if(nelems != 0 && value == NULL) return NC_EINVAL; /* Null arg */ attrpp = NC_findattr(ncap, name); if(attrpp != NULL) /* name in use */ { if(!NC_indef(ncp) ) { const size_t xsz = ncx_len_NC_attrV(type, nelems); attrp = *attrpp; /* convenience */ if(xsz > attrp->xsz) return NC_ENOTINDEFINE; /* else, we can reuse existing without redef */ attrp->xsz = xsz; attrp->type = type; attrp->nelems = nelems; if(nelems != 0) { void *xp = attrp->xvalue; status = ncx_pad_putn_Idouble(&xp, nelems, value, type); } set_NC_hdirty(ncp); if(NC_doHsync(ncp)) { const int lstatus = NC_sync(ncp); /* * N.B.: potentially overrides NC_ERANGE * set by ncx_pad_putn_Idouble */ if(lstatus != ENOERR) return lstatus; } return status; } /* else, redefine using existing array slot */ old = *attrpp; } else { if(!NC_indef(ncp)) return NC_ENOTINDEFINE; if(ncap->nelems >= NC_MAX_ATTRS) return NC_EMAXATTS; } status = NC_check_name(name); if(status != NC_NOERR) return status; attrp = new_NC_attr(name, type, nelems); if(attrp == NULL) return NC_ENOMEM; if(nelems != 0) { void *xp = attrp->xvalue; status = ncx_pad_putn_Idouble(&xp, nelems, value, type); } if(attrpp != NULL) { assert(old != NULL); *attrpp = attrp; free_NC_attr(old); } else { const int lstatus = incr_NC_attrarray(ncap, attrp); /* * N.B.: potentially overrides NC_ERANGE * set by ncx_pad_putn_Idouble */ if(lstatus != NC_NOERR) { free_NC_attr(attrp); return lstatus; } } return status; }
int NC3_rename_dim( int ncid, int dimid, const char *unewname) { int status = NC_NOERR; NC *nc; NC3_INFO* ncp; int existid; NC_dim *dimp; char *newname = NULL; /* normalized */ NC_string *old = NULL; uintptr_t intdata; status = NC_check_id(ncid, &nc); if(status != NC_NOERR) goto done; ncp = NC3_DATA(nc); if(NC_readonly(ncp)) {status = NC_EPERM; goto done;} status = NC_check_name(unewname); if(status != NC_NOERR) goto done; existid = NC_finddim(&ncp->dims, unewname, &dimp); if(existid != -1) {status = NC_ENAMEINUSE; goto done;} dimp = elem_NC_dimarray(&ncp->dims, (size_t)dimid); if(dimp == NULL) {status = NC_EBADDIM; goto done;} old = dimp->name; status = nc_utf8_normalize((const unsigned char *)unewname,(unsigned char **)&newname); if(status != NC_NOERR) goto done; if(NC_indef(ncp)) { NC_string *newStr = new_NC_string(strlen(newname), newname); if(newStr == NULL) {status = NC_ENOMEM; goto done;} /* Remove old name from hashmap; add new... */ NC_hashmapremove(ncp->dims.hashmap, old->cp, strlen(old->cp), NULL); dimp->name = newStr; intdata = dimid; NC_hashmapadd(ncp->dims.hashmap, intdata, newStr->cp, strlen(newStr->cp)); free_NC_string(old); goto done; } /* else, not in define mode */ /* If new name is longer than old, then complain, but otherwise, no change (test is same as set_NC_string)*/ if(dimp->name->nchars < strlen(newname)) { {status = NC_ENOTINDEFINE; goto done;} } /* Remove old name from hashmap; add new... */ /* WARNING: strlen(NC_string.cp) may be less than NC_string.nchars */ NC_hashmapremove(ncp->dims.hashmap, old->cp, strlen(old->cp), NULL); /* WARNING: strlen(NC_string.cp) may be less than NC_string.nchars */ status = set_NC_string(dimp->name, newname); if(status != NC_NOERR) goto done; intdata = (uintptr_t)dimid; NC_hashmapadd(ncp->dims.hashmap, intdata, dimp->name->cp, strlen(dimp->name->cp)); set_NC_hdirty(ncp); if(NC_doHsync(ncp)) { status = NC_sync(ncp); if(status != NC_NOERR) goto done; } done: if(newname) free(newname); return status; }
int NC3_put_att( int ncid, int varid, const char *name, nc_type type, size_t nelems, const void *value, nc_type memtype) { int status; NC *nc; NC3_INFO* ncp; NC_attrarray *ncap; NC_attr **attrpp; NC_attr *old = NULL; NC_attr *attrp; unsigned char fill[8]; /* fill value in internal representation */ status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); if(NC_readonly(ncp)) return NC_EPERM; ncap = NC_attrarray0(ncp, varid); if(ncap == NULL) return NC_ENOTVAR; if (name == NULL) return NC_EBADNAME; /* check NC_EBADTYPE */ status = nc3_cktype(nc->mode, type); if(status != NC_NOERR) return status; if(memtype == NC_NAT) memtype = type; if(memtype != NC_CHAR && type == NC_CHAR) return NC_ECHAR; if(memtype == NC_CHAR && type != NC_CHAR) return NC_ECHAR; /* cast needed for braindead systems with signed size_t */ if((unsigned long) nelems > X_INT_MAX) /* backward compat */ return NC_EINVAL; /* Invalid nelems */ if(nelems != 0 && value == NULL) return NC_EINVAL; /* Null arg */ /* Temporarily removed to preserve extant workflows (NCO based and others). See https://github.com/Unidata/netcdf-c/issues/843 for more information. */ // if (varid != NC_GLOBAL && !strcmp(name, _FillValue)) { // /* Fill value must be of the same data type */ // if (type != ncp->vars.value[varid]->type) return NC_EBADTYPE; // // /* Fill value must have exactly one value */ // if (nelems != 1) return NC_EINVAL; // // /* Only allow for variables defined in initial define mode */ // if (ncp->old != NULL && varid < ncp->old->vars.nelems) // return NC_ELATEFILL; /* try put attribute for an old variable */ // } attrpp = NC_findattr(ncap, name); /* 4 cases: exists X indef */ status = NC3_inq_default_fill_value(type, &fill); if (status != NC_NOERR) return status; if(attrpp != NULL) { /* name in use */ if(!NC_indef(ncp)) { const size_t xsz = ncx_len_NC_attrV(type, nelems); attrp = *attrpp; /* convenience */ if(xsz > attrp->xsz) return NC_ENOTINDEFINE; /* else, we can reuse existing without redef */ attrp->xsz = xsz; attrp->type = type; attrp->nelems = nelems; if(nelems != 0) { void *xp = attrp->xvalue; /* for CDF-1 and CDF-2, NC_BYTE is treated the same type as uchar memtype */ if (!fIsSet(ncp->flags,NC_64BIT_DATA) && type == NC_BYTE && memtype == NC_UBYTE) { status = NC3_inq_default_fill_value(NC_UBYTE, &fill); if (status != NC_NOERR) return status; status = dispatchput(&xp, nelems, value, memtype, memtype, &fill); } else status = dispatchput(&xp, nelems, value, type, memtype, &fill); } set_NC_hdirty(ncp); if(NC_doHsync(ncp)) { const int lstatus = NC_sync(ncp); /* * N.B.: potentially overrides NC_ERANGE * set by ncx_pad_putn_I$1 */ if(lstatus != NC_NOERR) return lstatus; } return status; } /* else, redefine using existing array slot */ old = *attrpp; } else { if(!NC_indef(ncp)) return NC_ENOTINDEFINE; } status = NC_check_name(name); if(status != NC_NOERR) return status; attrp = new_NC_attr(name, type, nelems); if(attrp == NULL) return NC_ENOMEM; if(nelems != 0) { void *xp = attrp->xvalue; /* for CDF-1 and CDF-2, NC_BYTE is treated the same type as uchar memtype */ if (!fIsSet(ncp->flags,NC_64BIT_DATA) && type == NC_BYTE && memtype == NC_UBYTE) { status = NC3_inq_default_fill_value(NC_UBYTE, &fill); if (status != NC_NOERR) return status; status = dispatchput(&xp, nelems, (const void*)value, memtype, memtype, &fill); } else status = dispatchput(&xp, nelems, (const void*)value, type, memtype, &fill); } if(attrpp != NULL) { *attrpp = attrp; if(old != NULL) free_NC_attr(old); } else { const int lstatus = incr_NC_attrarray(ncap, attrp); /* * N.B.: potentially overrides NC_ERANGE * set by ncx_pad_putn_I$1 */ if(lstatus != NC_NOERR) { free_NC_attr(attrp); return lstatus; } } return status; }
int nc_rename_var(int ncid, int varid, const char *newname) { int status; NC *ncp; NC_var *varp; NC_string *old, *newStr; int other; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) { return NC_EPERM; } status = NC_check_name(newname); if(status != NC_NOERR) return status; /* check for name in use */ other = NC_findvar(&ncp->vars, newname, &varp); if(other != -1) { return NC_ENAMEINUSE; } varp = NC_lookupvar(ncp, varid); if(varp == NULL) { /* invalid varid */ return NC_ENOTVAR; /* TODO: is this the right error code? */ } old = varp->name; if(NC_indef(ncp)) { newStr = new_NC_string(strlen(newname),newname); if(newStr == NULL) return(-1); varp->name = newStr; free_NC_string(old); return NC_NOERR; } /* else, not in define mode */ status = set_NC_string(varp->name, newname); if(status != NC_NOERR) return status; set_NC_hdirty(ncp); if(NC_doHsync(ncp)) { status = NC_sync(ncp); if(status != NC_NOERR) return status; } return NC_NOERR; }
int NC3_rename_att( int ncid, int varid, const char *name, const char *unewname) { int status; NC *nc; NC3_INFO* ncp; NC_attrarray *ncap; NC_attr **tmp; NC_attr *attrp; NC_string *newStr, *old; char *newname; /* normalized version */ /* sortof inline clone of NC_lookupattr() */ status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); if(NC_readonly(ncp)) return NC_EPERM; ncap = NC_attrarray0(ncp, varid); if(ncap == NULL) return NC_ENOTVAR; status = NC_check_name(unewname); if(status != NC_NOERR) return status; tmp = NC_findattr(ncap, name); if(tmp == NULL) return NC_ENOTATT; attrp = *tmp; /* end inline clone NC_lookupattr() */ if(NC_findattr(ncap, unewname) != NULL) { /* name in use */ return NC_ENAMEINUSE; } old = attrp->name; status = nc_utf8_normalize((const unsigned char *)unewname,(unsigned char**)&newname); if(status != NC_NOERR) return status; if(NC_indef(ncp)) { newStr = new_NC_string(strlen(newname), newname); free(newname); if( newStr == NULL) return NC_ENOMEM; attrp->name = newStr; free_NC_string(old); return NC_NOERR; } /* else not in define mode */ /* If new name is longer than old, then complain, but otherwise, no change (test is same as set_NC_string)*/ if(old->nchars < strlen(newname)) { free(newname); return NC_ENOTINDEFINE; } status = set_NC_string(old, newname); free(newname); if( status != NC_NOERR) return status; set_NC_hdirty(ncp); if(NC_doHsync(ncp)) { status = NC_sync(ncp); if(status != NC_NOERR) return status; } return NC_NOERR; }
/* This function is collective */ int ncmpio_close(void *ncdp) { int err=NC_NOERR, status=NC_NOERR; NC *ncp = (NC*)ncdp; if (NC_indef(ncp)) { /* currently in define mode */ status = ncmpio__enddef(ncp, 0, 0, 0, 0); /* TODO: defaults */ if (status != NC_NOERR ) { /* To do: Abort new definition, if any */ if (ncp->old != NULL) { ncmpio_free_NC(ncp->old); ncp->old = NULL; fClr(ncp->flags, NC_MODE_DEF); } } } if (!NC_readonly(ncp) && /* file is open for write */ NC_indep(ncp)) { /* exit independent data mode will sync header */ err = ncmpio_end_indep_data(ncp); if (status == NC_NOERR ) status = err; } /* if entering this function in collective data mode, we do not have to * update header in file, as file header is always up-to-date */ #ifdef ENABLE_SUBFILING /* ncmpio__enddef() will update ncp->num_subfiles */ /* TODO: should check ncid_sf? */ /* if the file has subfiles, close them first */ if (ncp->num_subfiles > 1) ncmpio_subfile_close(ncp); #endif /* We can cancel or complete all outstanding nonblocking I/O. * For now, cancelling makes more sense. */ #ifdef COMPLETE_NONBLOCKING_IO if (ncp->numLeadGetReqs > 0) { ncmpio_wait(ncp, NC_GET_REQ_ALL, NULL, NULL, NC_REQ_INDEP); if (status == NC_NOERR ) status = NC_EPENDING; } if (ncp->numLeadPutReqs > 0) { ncmpio_wait(ncp, NC_PUT_REQ_ALL, NULL, NULL, NC_REQ_INDEP); if (status == NC_NOERR ) status = NC_EPENDING; } #else if (ncp->numLeadGetReqs > 0) { int rank; MPI_Comm_rank(ncp->comm, &rank); printf("PnetCDF warning: %d nonblocking get requests still pending on process %d. Cancelling ...\n",ncp->numLeadGetReqs,rank); ncmpio_cancel(ncp, NC_GET_REQ_ALL, NULL, NULL); if (status == NC_NOERR ) status = NC_EPENDING; } if (ncp->numLeadPutReqs > 0) { int rank; MPI_Comm_rank(ncp->comm, &rank); printf("PnetCDF warning: %d nonblocking put requests still pending on process %d. Cancelling ...\n",ncp->numLeadPutReqs,rank); ncmpio_cancel(ncp, NC_PUT_REQ_ALL, NULL, NULL); if (status == NC_NOERR ) status = NC_EPENDING; } #endif /* If the user wants a stronger data consistency by setting NC_SHARE */ if (NC_doFsync(ncp)) ncmpio_file_sync(ncp); /* calling MPI_File_sync() */ /* calling MPI_File_close() */ ncmpio_close_files(ncp, 0); /* free up space occupied by the header metadata */ ncmpio_free_NC(ncp); return status; }
int NC3_rename_att( int ncid, int varid, const char *name, const char *unewname) { int status; NC *nc; NC3_INFO* ncp; NC_attrarray *ncap; NC_attr **tmp; NC_attr *attrp; NC_string *newStr, *old; char *newname; /* normalized version */ /* sortof inline clone of NC_lookupattr() */ status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); if(NC_readonly(ncp)) return NC_EPERM; ncap = NC_attrarray0(ncp, varid); if(ncap == NULL) return NC_ENOTVAR; status = NC_check_name(unewname); if(status != NC_NOERR) return status; tmp = NC_findattr(ncap, name); if(tmp == NULL) return NC_ENOTATT; attrp = *tmp; /* end inline clone NC_lookupattr() */ if(NC_findattr(ncap, unewname) != NULL) { /* name in use */ return NC_ENAMEINUSE; } old = attrp->name; newname = (char *)utf8proc_NFC((const unsigned char *)unewname); if(newname == NULL) return NC_EBADNAME; if(NC_indef(ncp)) { newStr = new_NC_string(strlen(newname), newname); free(newname); if( newStr == NULL) return NC_ENOMEM; attrp->name = newStr; free_NC_string(old); return NC_NOERR; } /* else */ status = set_NC_string(old, newname); free(newname); if( status != NC_NOERR) return status; set_NC_hdirty(ncp); if(NC_doHsync(ncp)) { status = NC_sync(ncp); if(status != NC_NOERR) return status; } return NC_NOERR; }
/*----< ncmpi_def_dim() >---------------------------------------------------*/ int ncmpi_def_dim(int ncid, /* IN: file ID */ const char *name, /* IN: name of dimension */ MPI_Offset size, /* IN: dimension size */ int *dimidp) /* OUT: dimension ID */ { int dimid, file_ver, status; NC *ncp; NC_dim *dimp; /* check if ncid is valid */ status = ncmpii_NC_check_id(ncid, &ncp); if (status != NC_NOERR) return status; /* check if called in define mode */ if (!NC_indef(ncp)) return NC_ENOTINDEFINE; /* check if the name string is legal for netcdf format */ file_ver = 1; if (fIsSet(ncp->flags, NC_64BIT_OFFSET)) file_ver = 2; else if (fIsSet(ncp->flags, NC_64BIT_DATA)) file_ver = 5; status = ncmpii_NC_check_name(name, file_ver); if (status != NC_NOERR) return status; /* MPI_Offset is usually a signed value, but serial netcdf uses * MPI_Offset -- normally unsigned */ if ((ncp->flags & NC_64BIT_OFFSET) && sizeof(off_t) > 4) { /* CDF2 format and LFS */ if (size > X_UINT_MAX - 3 || (size < 0)) /* "-3" handles rounded-up size */ return NC_EDIMSIZE; } else if ((ncp->flags & NC_64BIT_DATA)) { /* CDF5 format*/ if (size < 0) return NC_EDIMSIZE; } else { /* CDF1 format */ if (size > X_INT_MAX - 3 || (size < 0)) /* "-3" handles rounded-up size */ return NC_EDIMSIZE; } if (size == NC_UNLIMITED) { /* check for any existing unlimited dimension, netcdf allows * one per file */ dimid = ncmpii_find_NC_Udim(&ncp->dims, &dimp); if (dimid != -1) return NC_EUNLIMIT; /* found an existing one */ } /* check if exceeds the upperbound has reached */ if (ncp->dims.ndefined >= NC_MAX_DIMS) return NC_EMAXDIMS; /* check if the name string is previously used */ dimid = NC_finddim(&ncp->dims, name, &dimp); if (dimid != -1) return NC_ENAMEINUSE; /* create a new dimension object */ dimp = ncmpii_new_NC_dim(name, size); if (dimp == NULL) return NC_ENOMEM; /* Add a new handle to the end of an array of handles */ status = incr_NC_dimarray(&ncp->dims, dimp); if (status != NC_NOERR) { ncmpii_free_NC_dim(dimp); return status; } if (dimidp != NULL) *dimidp = (int)ncp->dims.ndefined -1; /* ncp->dims.ndefined has been increased in incr_NC_dimarray() */ return NC_NOERR; }
int nc_copy_att(int ncid_in, int varid_in, const char *name, int ncid_out, int ovarid) { int status; NC_attr *iattrp; NC *ncp; NC_attrarray *ncap; NC_attr **attrpp; NC_attr *old = NULL; NC_attr *attrp; status = NC_lookupattr(ncid_in, varid_in, name, &iattrp); if(status != NC_NOERR) return status; status = NC_check_id(ncid_out, &ncp); if(status != NC_NOERR) return status; if(NC_readonly(ncp)) return NC_EPERM; ncap = NC_attrarray0(ncp, ovarid); if(ncap == NULL) return NC_ENOTVAR; attrpp = NC_findattr(ncap, name); if(attrpp != NULL) /* name in use */ { if(!NC_indef(ncp) ) { attrp = *attrpp; /* convenience */ if(iattrp->xsz > attrp->xsz) return NC_ENOTINDEFINE; /* else, we can reuse existing without redef */ attrp->xsz = iattrp->xsz; attrp->type = iattrp->type; attrp->nelems = iattrp->nelems; (void) memcpy(attrp->xvalue, iattrp->xvalue, iattrp->xsz); set_NC_hdirty(ncp); if(NC_doHsync(ncp)) { status = NC_sync(ncp); if(status != NC_NOERR) return status; } return NC_NOERR; } /* else, redefine using existing array slot */ old = *attrpp; } else { if(!NC_indef(ncp)) return NC_ENOTINDEFINE; if(ncap->nelems >= NC_MAX_ATTRS) return NC_EMAXATTS; } attrp = new_NC_attr(name, iattrp->type, iattrp->nelems); if(attrp == NULL) return NC_ENOMEM; (void) memcpy(attrp->xvalue, iattrp->xvalue, iattrp->xsz); if(attrpp != NULL) { assert(old != NULL); *attrpp = attrp; free_NC_attr(old); } else { status = incr_NC_attrarray(ncap, attrp); if(status != NC_NOERR) { free_NC_attr(attrp); return status; } } return NC_NOERR; }
int NC3_rename_var(int ncid, int varid, const char *unewname) { int status; NC *nc; NC3_INFO* ncp; NC_var *varp; NC_string *old, *newStr; int other; char *newname; /* normalized */ status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); if(NC_readonly(ncp)) { return NC_EPERM; } status = NC_check_name(unewname); if(status != NC_NOERR) return status; /* check for name in use */ other = NC_findvar(&ncp->vars, unewname, &varp); if(other != -1) { return NC_ENAMEINUSE; } status = NC_lookupvar(ncp, varid, &varp); if(status != NC_NOERR) { /* invalid varid */ return status; } old = varp->name; newname = (char *)utf8proc_NFC((const unsigned char *)unewname); if(newname == NULL) return NC_ENOMEM; if(NC_indef(ncp)) { newStr = new_NC_string(strlen(newname),newname); free(newname); if(newStr == NULL) return(-1); varp->name = newStr; /* Remove old name from hashmap; add new... */ NC_hashmapRemoveVar(&ncp->vars, old->cp); NC_hashmapAddVar(&ncp->vars, varid, newStr->cp); free_NC_string(old); return NC_NOERR; } /* else, not in define mode */ status = set_NC_string(varp->name, newname); free(newname); if(status != NC_NOERR) return status; /* Remove old name from hashmap; add new... */ NC_hashmapRemoveVar(&ncp->vars, old->cp); NC_hashmapAddVar(&ncp->vars, varid, varp->name->cp); set_NC_hdirty(ncp); if(NC_doHsync(ncp)) { status = NC_sync(ncp); if(status != NC_NOERR) return status; } return NC_NOERR; }
/*----< ncmpi_def_var() >----------------------------------------------------*/ int ncmpi_def_var(int ncid, const char *name, nc_type type, int ndims, const int *dimids, int *varidp) { int varid, file_ver, status; NC *ncp; NC_var *varp; /* check if ncid is valid */ status = ncmpii_NC_check_id(ncid, &ncp); if (status != NC_NOERR) return status; /* check if called in define mode */ if (!NC_indef(ncp)) return NC_ENOTINDEFINE; /* check if the name string is legal for netcdf format */ file_ver = 1; if (fIsSet(ncp->flags, NC_64BIT_OFFSET)) file_ver = 2; else if (fIsSet(ncp->flags, NC_64BIT_DATA)) file_ver = 5; status = ncmpii_NC_check_name(name, file_ver); if (status != NC_NOERR) return status; /* check if type is a valid netcdf type */ status = ncmpii_cktype(type); if (status != NC_NOERR) return status; /* TODO: can ndims > 2^32 in CDF-5 ? */ if ((ndims < 0) || ndims > X_INT_MAX) return NC_EINVAL; /* there is an upperbound for the number of variables defeined in a file */ if (ncp->vars.ndefined >= NC_MAX_VARS) return NC_EMAXVARS; /* check whether the variable name has been used */ varid = ncmpii_NC_findvar(&ncp->vars, name, &varp); if (varid != -1) return NC_ENAMEINUSE; /* create a new variable */ varp = ncmpii_new_NC_var(name, type, ndims, dimids); if (varp == NULL) return NC_ENOMEM; /* set up array dimensional structures */ status = ncmpii_NC_var_shape64(ncp, varp, &ncp->dims); if (status != NC_NOERR) { ncmpii_free_NC_var(varp); return status; } /* Add a new handle to the end of an array of handles */ status = incr_NC_vararray(&ncp->vars, varp); if (status != NC_NOERR) { ncmpii_free_NC_var(varp); return status; } if (varidp != NULL) *varidp = (int)ncp->vars.ndefined - 1; /* varid */ /* ncp->vars.ndefined has been increased in incr_NC_vararray() */ return NC_NOERR; }
int NC3_rename_var(int ncid, int varid, const char *unewname) { int status; NC *nc; NC3_INFO* ncp; NC_var *varp; NC_string *old, *newStr; int other; char *newname; /* normalized */ status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); if(NC_readonly(ncp)) { return NC_EPERM; } status = NC_check_name(unewname); if(status != NC_NOERR) return status; /* check for name in use */ other = NC_findvar(&ncp->vars, unewname, &varp); if(other != -1) { return NC_ENAMEINUSE; } varp = NC_lookupvar(ncp, varid); if(varp == NULL) { /* invalid varid */ return NC_ENOTVAR; /* TODO: is this the right error code? */ } old = varp->name; newname = (char *)utf8proc_NFC((const unsigned char *)unewname); if(newname == NULL) return NC_ENOMEM; if(NC_indef(ncp)) { newStr = new_NC_string(strlen(newname),newname); free(newname); if(newStr == NULL) return(-1); varp->name = newStr; varp->hash = hash_fast(newStr->cp, strlen(newStr->cp)); free_NC_string(old); return NC_NOERR; } /* else, not in define mode */ status = set_NC_string(varp->name, newname); varp->hash = hash_fast(newname, strlen(newname)); free(newname); if(status != NC_NOERR) return status; set_NC_hdirty(ncp); if(NC_doHsync(ncp)) { status = NC_sync(ncp); if(status != NC_NOERR) return status; } return NC_NOERR; }
int NC3_def_var( int ncid, const char *name, nc_type type, int ndims, const int *dimids, int *varidp) { int status; NC *nc; NC3_INFO* ncp; int varid; NC_var *varp; status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); if(!NC_indef(ncp)) { return NC_ENOTINDEFINE; } status = NC_check_name(name); if(status != NC_NOERR) return status; status = nc_cktype(type); if(status != NC_NOERR) return status; /* cast needed for braindead systems with signed size_t */ if((unsigned long) ndims > X_INT_MAX) /* Backward compat */ { return NC_EINVAL; } if(ncp->vars.nelems >= NC_MAX_VARS) { return NC_EMAXVARS; } varid = NC_findvar(&ncp->vars, name, &varp); if(varid != -1) { return NC_ENAMEINUSE; } varp = new_NC_var(name, type, ndims, dimids); if(varp == NULL) return NC_ENOMEM; status = NC_var_shape(varp, &ncp->dims); if(status != NC_NOERR) { free_NC_var(varp); return status; } status = incr_NC_vararray(&ncp->vars, varp); if(status != NC_NOERR) { free_NC_var(varp); return status; } if(varidp != NULL) *varidp = (int)ncp->vars.nelems -1; /* varid */ return NC_NOERR; }
/* * End define mode. * Common code for ncendef, ncclose(endef) * Flushes I/O buffers. */ static int NC_endef(NC *ncp, size_t h_minfree, size_t v_align, size_t v_minfree, size_t r_align) { int status = NC_NOERR; assert(!NC_readonly(ncp)); assert(NC_indef(ncp)); status = NC_check_vlens(ncp); if(status != NC_NOERR) return status; status = NC_begins(ncp, h_minfree, v_align, v_minfree, r_align); if(status != NC_NOERR) return status; if(ncp->old != NULL) { /* a plain redef, not a create */ assert(!NC_IsNew(ncp)); assert(fIsSet(ncp->flags, NC_INDEF)); assert(ncp->begin_rec >= ncp->old->begin_rec); assert(ncp->begin_var >= ncp->old->begin_var); if(ncp->vars.nelems != 0) { if(ncp->begin_rec > ncp->old->begin_rec) { status = move_recs_r(ncp, ncp->old); if(status != NC_NOERR) return status; if(ncp->begin_var > ncp->old->begin_var) { status = move_vars_r(ncp, ncp->old); if(status != NC_NOERR) return status; } /* else if (ncp->begin_var == ncp->old->begin_var) { NOOP } */ } else { /* Even if (ncp->begin_rec == ncp->old->begin_rec) and (ncp->begin_var == ncp->old->begin_var) might still have added a new record variable */ if(ncp->recsize > ncp->old->recsize) { status = move_recs_r(ncp, ncp->old); if(status != NC_NOERR) return status; } } } } status = write_NC(ncp); if(status != NC_NOERR) return status; if(NC_dofill(ncp)) { if(NC_IsNew(ncp)) { status = fillerup(ncp); if(status != NC_NOERR) return status; } else if(ncp->vars.nelems > ncp->old->vars.nelems) { status = fill_added(ncp, ncp->old); if(status != NC_NOERR) return status; status = fill_added_recs(ncp, ncp->old); if(status != NC_NOERR) return status; } } if(ncp->old != NULL) { free_NC(ncp->old); ncp->old = NULL; } fClr(ncp->flags, NC_CREAT | NC_INDEF); return ncp->nciop->sync(ncp->nciop); }
int NC3_rename_dim( int ncid, int dimid, const char *unewname) { int status; NC *nc; NC3_INFO* ncp; int existid; NC_dim *dimp; char *newname; /* normalized */ status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); if(NC_readonly(ncp)) return NC_EPERM; status = NC_check_name(unewname); if(status != NC_NOERR) return status; existid = NC_finddim(&ncp->dims, unewname, &dimp); if(existid != -1) return NC_ENAMEINUSE; dimp = elem_NC_dimarray(&ncp->dims, (size_t)dimid); if(dimp == NULL) return NC_EBADDIM; NC_string *old = dimp->name; newname = (char *)utf8proc_NFC((const unsigned char *)unewname); if(newname == NULL) return NC_ENOMEM; if(NC_indef(ncp)) { NC_string *newStr = new_NC_string(strlen(newname), newname); free(newname); if(newStr == NULL) return NC_ENOMEM; dimp->name = newStr; /* Remove old name from hashmap; add new... */ NC_hashmapRemoveDim(&ncp->dims, old->cp); NC_hashmapAddDim(&ncp->dims, dimid, newStr->cp); free_NC_string(old); return NC_NOERR; } /* else, not in define mode */ status = set_NC_string(dimp->name, newname); free(newname); if(status != NC_NOERR) return status; /* Remove old name from hashmap; add new... */ NC_hashmapRemoveDim(&ncp->dims, old->cp); NC_hashmapAddDim(&ncp->dims, dimid, dimp->name->cp); set_NC_hdirty(ncp); if(NC_doHsync(ncp)) { status = NC_sync(ncp); if(status != NC_NOERR) return status; } return NC_NOERR; }
/*----< ncmpii_mgetput_varm() >-----------------------------------------------*/ static int ncmpii_mgetput_varm(int ncid, int num, int varids[], /* [num] */ MPI_Offset* const starts[], /* [num] */ MPI_Offset* const counts[], /* [num] */ MPI_Offset* const strides[], /* [num] */ MPI_Offset* const imaps[], /* [num] */ void *bufs[], /* [num] */ MPI_Offset bufcounts[], /* [num] */ MPI_Datatype datatypes[], /* [num] */ int rw_flag, /* WRITE_REQ or READ_REQ */ int io_method) /* COLL_IO or INDEP_IO */ { int i, status=NC_NOERR, *req_ids=NULL, *statuses=NULL; NC *ncp=NULL; CHECK_NCID if (rw_flag == WRITE_REQ) CHECK_WRITE_PERMISSION if (NC_indef(ncp)) return NC_EINDEFINE; /* check to see that the desired MPI file handle is opened */ if (io_method == COLL_IO) CHECK_COLLECTIVE_FH else CHECK_INDEP_FH if (num > 0) { req_ids = (int*) NCI_Malloc(2 * num * sizeof(int)); statuses = req_ids + num; } /* for each request call ncmpi_igetput_varm() */ for (i=0; i<num; i++) { NC_var *varp; MPI_Offset *start, *count; CHECK_VARID(varids[i], varp) if (starts == NULL) { /* var */ GET_FULL_DIMENSIONS status = ncmpii_igetput_varm(ncp, varp, start, count, NULL, NULL, bufs[i], bufcounts[i], datatypes[i], &req_ids[i], rw_flag, 0); if (varp->ndims > 0) NCI_Free(start); } else if (counts == NULL) { /* var1 */ GET_FULL_DIMENSIONS GET_ONE_COUNT status = ncmpii_igetput_varm(ncp, varp, starts[i], count, NULL, NULL, bufs[i], bufcounts[i], datatypes[i], &req_ids[i], rw_flag, 0); if (varp->ndims > 0) NCI_Free(count); } else if (strides == NULL) { /* vara */ status = ncmpii_igetput_varm(ncp, varp, starts[i], counts[i], NULL, NULL, bufs[i], bufcounts[i], datatypes[i], &req_ids[i], rw_flag, 0); } else if (imaps == NULL) { /* vars */ status = ncmpii_igetput_varm(ncp, varp, starts[i], counts[i], strides[i], NULL, bufs[i], bufcounts[i], datatypes[i], &req_ids[i], rw_flag, 0); } else { /* varm */ status = ncmpii_igetput_varm(ncp, varp, starts[i], counts[i], strides[i], imaps[i], bufs[i], bufcounts[i], datatypes[i], &req_ids[i], rw_flag, 0); } } if (status != NC_NOERR) return status; if (io_method == COLL_IO) status = ncmpi_wait_all(ncid, num, req_ids, statuses); else status = ncmpi_wait(ncid, num, req_ids, statuses); if (status != NC_NOERR) return status; if (num > 0) NCI_Free(req_ids); for (i=0; i<num; i++) if (statuses[i] != NC_NOERR) return statuses[i]; return NC_NOERR; }