int NC3_inq_attid(int ncid, int varid, const char *name, int *attnump) { int status; NC *nc; NC3_INFO* ncp; NC_attrarray *ncap; NC_attr **attrpp; status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); ncap = NC_attrarray0(ncp, varid); if(ncap == NULL) return NC_ENOTVAR; attrpp = NC_findattr(ncap, name); if(attrpp == NULL) return NC_ENOTATT; if(attnump != NULL) *attnump = (int)(attrpp - ncap->value); return NC_NOERR; }
/* * Look up by ncid, varid and name, return NULL if not found */ static int NC_lookupattr(int ncid, int varid, const char *name, /* attribute name */ NC_attr **attrpp) /* modified on return */ { int status; NC* nc; NC3_INFO *ncp; NC_attrarray *ncap; NC_attr **tmp; status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); ncap = NC_attrarray0(ncp, varid); if(ncap == NULL) return NC_ENOTVAR; tmp = NC_findattr(ncap, name); if(tmp == NULL) return NC_ENOTATT; if(attrpp != NULL) *attrpp = *tmp; return NC_NOERR; }
int NC3_inq_dim(int ncid, int dimid, char *name, size_t *sizep) { int status; NC *nc; NC3_INFO* ncp; NC_dim *dimp; status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); dimp = elem_NC_dimarray(&ncp->dims, (size_t)dimid); if(dimp == NULL) return NC_EBADDIM; if(name != NULL) { (void)strncpy(name, dimp->name->cp, dimp->name->nchars); name[dimp->name->nchars] = 0; } if(sizep != NULL) { if(dimp->size == NC_UNLIMITED) *sizep = NC_get_numrecs(ncp); else *sizep = dimp->size; } 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 NC3_inq_attname(int ncid, int varid, int attnum, char *name) { int status; NC* nc; NC3_INFO *ncp; NC_attrarray *ncap; NC_attr *attrp; status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); ncap = NC_attrarray0(ncp, varid); if(ncap == NULL) return NC_ENOTVAR; attrp = elem_NC_attrarray(ncap, (size_t)attnum); if(attrp == NULL) return NC_ENOTATT; (void) strncpy(name, attrp->name->cp, attrp->name->nchars); name[attrp->name->nchars] = 0; return NC_NOERR; }
int NC3_inq_var(int ncid, int varid, char *name, nc_type *typep, int *ndimsp, int *dimids, int *nattsp) { int status; NC *nc; NC3_INFO* ncp; NC_var *varp; size_t ii; status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); varp = elem_NC_vararray(&ncp->vars, (size_t)varid); if(varp == NULL) return NC_ENOTVAR; if(name != NULL) { (void) strncpy(name, varp->name->cp, varp->name->nchars); name[varp->name->nchars] = 0; } if(typep != 0) *typep = varp->type; if(ndimsp != 0) { *ndimsp = (int) varp->ndims; } if(dimids != 0) { for(ii = 0; ii < varp->ndims; ii++) { dimids[ii] = varp->dimids[ii]; } } if(nattsp != 0) { *nattsp = (int) varp->attrs.nelems; } return NC_NOERR; }
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 NC3_inq_dimid(int ncid, const char *name, int *dimid_ptr) { int status; NC *nc; NC3_INFO* ncp; int dimid; status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); dimid = NC_finddim(&ncp->dims, name, NULL); if(dimid == -1) return NC_EBADDIM; if (dimid_ptr) *dimid_ptr = dimid; return NC_NOERR; }
int NC3_inq_varid(int ncid, const char *name, int *varid_ptr) { int status; NC *nc; NC3_INFO* ncp; NC_var *varp; int varid; status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); varid = NC_findvar(&ncp->vars, name, &varp); if(varid == -1) { return NC_ENOTVAR; } *varid_ptr = varid; 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; 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; }
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_get_att( int ncid, int varid, const char *name, void *value, nc_type memtype) { int status; NC *nc; NC3_INFO* ncp; NC_attr *attrp; const void *xp; status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); status = NC_lookupattr(ncid, varid, name, &attrp); if(status != NC_NOERR) return status; if(attrp->nelems == 0) return NC_NOERR; if(memtype == NC_NAT) memtype = attrp->type; if(memtype != NC_CHAR && attrp->type == NC_CHAR) return NC_ECHAR; if(memtype == NC_CHAR && attrp->type != NC_CHAR) return NC_ECHAR; xp = attrp->xvalue; switch (memtype) { case NC_CHAR: return ncx_pad_getn_text(&xp, attrp->nelems, (char *)value); case NC_BYTE: return ncx_pad_getn_Ischar(&xp,attrp->nelems,(schar*)value,attrp->type); case NC_SHORT: return ncx_pad_getn_Ishort(&xp,attrp->nelems,(short*)value,attrp->type); case NC_INT: return ncx_pad_getn_Iint(&xp,attrp->nelems,(int*)value,attrp->type); case NC_FLOAT: return ncx_pad_getn_Ifloat(&xp,attrp->nelems,(float*)value,attrp->type); case NC_DOUBLE: return ncx_pad_getn_Idouble(&xp,attrp->nelems,(double*)value,attrp->type); case NC_INT64: return ncx_pad_getn_Ilonglong(&xp,attrp->nelems,(longlong*)value,attrp->type); case NC_UBYTE: /* Synthetic */ /* for CDF-1 and CDF-2, NC_BYTE is treated the same type as uchar memtype */ if (!fIsSet(ncp->flags,NC_64BIT_DATA) && attrp->type == NC_BYTE) return ncx_pad_getn_Iuchar(&xp, attrp->nelems, (uchar *)value, NC_UBYTE); else return ncx_pad_getn_Iuchar(&xp, attrp->nelems, (uchar *)value, attrp->type); case NC_USHORT: return ncx_pad_getn_Iushort(&xp,attrp->nelems,(ushort*)value,attrp->type); case NC_UINT: return ncx_pad_getn_Iuint(&xp,attrp->nelems,(uint*)value,attrp->type); case NC_UINT64: return ncx_pad_getn_Iulonglong(&xp,attrp->nelems,(ulonglong*)value,attrp->type); case NC_NAT: return NC_EBADTYPE; default: break; } status = NC_EBADTYPE; return status; }
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; }
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_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; }
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 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; }
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; 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 = 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 */ attrpp = NC_findattr(ncap, name); /* 4 cases: exists X indef */ 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 = dispatchput(&xp, nelems, (const void*)value, type, memtype); } 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; 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 = dispatchput(&xp, nelems, (const void*)value, type, memtype); } 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 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; }
int NC3_del_att(int ncid, int varid, const char *uname) { int status; NC *nc; NC3_INFO* ncp; NC_attrarray *ncap; NC_attr **attrpp; NC_attr *old = NULL; int attrid; size_t slen; status = NC_check_id(ncid, &nc); if(status != NC_NOERR) return status; ncp = NC3_DATA(nc); 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; }