/* Common dispatcher for put cases */ static int dispatchput(void **xpp, size_t nelems, const void* tp, nc_type atype, nc_type memtype) { switch (memtype) { case NC_CHAR: return ncx_pad_putn_text(xpp,nelems, (char *)tp); case NC_BYTE: return ncx_pad_putn_Ischar(xpp, nelems, (schar*)tp, atype); case NC_SHORT: return ncx_pad_putn_Ishort(xpp, nelems, (short*)tp, atype); case NC_INT: return ncx_pad_putn_Iint(xpp, nelems, (int*)tp, atype); case NC_FLOAT: return ncx_pad_putn_Ifloat(xpp, nelems, (float*)tp, atype); case NC_DOUBLE: return ncx_pad_putn_Idouble(xpp, nelems, (double*)tp, atype); case NC_UBYTE: /*Synthetic*/ return ncx_pad_putn_Iuchar(xpp,nelems, (uchar *)tp, atype); case NC_INT64: return ncx_pad_putn_Ilonglong(xpp, nelems, (longlong*)tp, atype); case NC_NAT: return NC_EBADTYPE; default: break; } return NC_EBADTYPE; }
/* Write a NC_string to the header */ static int v1h_put_NC_string(v1hs *psp, const NC_string *ncstrp) { int status; #if 0 assert(ncstrp->nchars % X_ALIGN == 0); #endif status = v1h_put_size_t(psp, &ncstrp->nchars); if(status != ENOERR) return status; status = check_v1hs(psp, _RNDUP(ncstrp->nchars, X_ALIGN)); if(status != ENOERR) return status; status = ncx_pad_putn_text(&psp->pos, ncstrp->nchars, ncstrp->cp); if(status != ENOERR) return status; return ENOERR; }
int nc_put_att_text(int ncid, int varid, const char *name, size_t nelems, const char *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_check_name(name); if(status != NC_NOERR) return status; /* 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(NC_CHAR, nelems); attrp = *attrpp; /* convenience */ if(xsz > attrp->xsz) return NC_ENOTINDEFINE; /* else, we can reuse existing without redef */ attrp->xsz = xsz; attrp->type = NC_CHAR; attrp->nelems = nelems; if(nelems != 0) { void *xp = attrp->xvalue; status = ncx_pad_putn_text(&xp, nelems, value); 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; } /* 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, NC_CHAR, nelems); if(attrp == NULL) return NC_ENOMEM; if(nelems != 0) { void *xp = attrp->xvalue; status = ncx_pad_putn_text(&xp, nelems, value); if(status != NC_NOERR) return status; } 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; }