#line 5 "attr.m4" /* Do not edit this file. It is produced from the corresponding .m4 source */ #line 7 /* * Copyright 2018, University Corporation for Atmospheric Research * See netcdf/COPYRIGHT file for copying and redistribution conditions. */ #if HAVE_CONFIG_H #include #endif #include "nc3internal.h" #include "ncdispatch.h" #include "nc3dispatch.h" #include #include #include #include "ncx.h" #include "fbits.h" #include "rnd.h" #include "ncutf8.h" /* * Free attr * Formerly NC_free_attr() */ void free_NC_attr(NC_attr *attrp) { if(attrp == NULL) return; free_NC_string(attrp->name); free(attrp); } /* * How much space will 'nelems' of 'type' take in * external representation (as the values of an attribute)? */ static size_t ncx_len_NC_attrV(nc_type type, size_t nelems) { switch(type) { case NC_BYTE: case NC_CHAR: return ncx_len_char(nelems); case NC_SHORT: return ncx_len_short(nelems); case NC_INT: return ncx_len_int(nelems); case NC_FLOAT: return ncx_len_float(nelems); case NC_DOUBLE: return ncx_len_double(nelems); case NC_UBYTE: return ncx_len_ubyte(nelems); case NC_USHORT: return ncx_len_ushort(nelems); case NC_UINT: return ncx_len_uint(nelems); case NC_INT64: return ncx_len_int64(nelems); case NC_UINT64: return ncx_len_uint64(nelems); default: assert("ncx_len_NC_attr bad type" == 0); } return 0; } NC_attr * new_x_NC_attr( NC_string *strp, nc_type type, size_t nelems) { NC_attr *attrp; const size_t xsz = ncx_len_NC_attrV(type, nelems); size_t sz = M_RNDUP(sizeof(NC_attr)); assert(!(xsz == 0 && nelems != 0)); sz += xsz; attrp = (NC_attr *) malloc(sz); if(attrp == NULL ) return NULL; attrp->xsz = xsz; attrp->name = strp; attrp->type = type; attrp->nelems = nelems; if(xsz != 0) attrp->xvalue = (char *)attrp + M_RNDUP(sizeof(NC_attr)); else attrp->xvalue = NULL; return(attrp); } /* * Formerly NC_new_attr(name,type,count,value) */ static NC_attr * new_NC_attr( const char *uname, nc_type type, size_t nelems) { NC_string *strp = NULL; NC_attr *attrp = NULL; char *name = NULL; int stat = NC_NOERR; stat = nc_utf8_normalize((const unsigned char *)uname,(unsigned char**)&name); if(stat != NC_NOERR) goto done; assert(name != NULL && *name != 0); strp = new_NC_string(strlen(name), name); if(strp == NULL) goto done; attrp = new_x_NC_attr(strp, type, nelems); if(attrp == NULL) { free_NC_string(strp); goto done; } done: if(name) free(name); return (attrp); } static NC_attr * dup_NC_attr(const NC_attr *rattrp) { NC_attr *attrp = new_NC_attr(rattrp->name->cp, rattrp->type, rattrp->nelems); if(attrp == NULL) return NULL; if(attrp->xvalue != NULL && rattrp->xvalue != NULL) (void) memcpy(attrp->xvalue, rattrp->xvalue, rattrp->xsz); return attrp; } /* attrarray */ /* * Free the stuff "in" (referred to by) an NC_attrarray. * Leaves the array itself allocated. */ void free_NC_attrarrayV0(NC_attrarray *ncap) { assert(ncap != NULL); if(ncap->nelems == 0) return; assert(ncap->value != NULL); { NC_attr **app = ncap->value; NC_attr *const *const end = &app[ncap->nelems]; for( /*NADA*/; app < end; app++) { free_NC_attr(*app); *app = NULL; } } ncap->nelems = 0; } /* * Free NC_attrarray values. * formerly NC_free_array() */ void free_NC_attrarrayV(NC_attrarray *ncap) { assert(ncap != NULL); if(ncap->nalloc == 0) return; assert(ncap->value != NULL); free_NC_attrarrayV0(ncap); free(ncap->value); ncap->value = NULL; ncap->nalloc = 0; } int dup_NC_attrarrayV(NC_attrarray *ncap, const NC_attrarray *ref) { int status = NC_NOERR; assert(ref != NULL); assert(ncap != NULL); if(ref->nelems != 0) { const size_t sz = ref->nelems * sizeof(NC_attr *); ncap->value = (NC_attr **) malloc(sz); if(ncap->value == NULL) return NC_ENOMEM; (void) memset(ncap->value, 0, sz); ncap->nalloc = ref->nelems; } ncap->nelems = 0; { NC_attr **app = ncap->value; const NC_attr **drpp = (const NC_attr **)ref->value; NC_attr *const *const end = &app[ref->nelems]; for( /*NADA*/; app < end; drpp++, app++, ncap->nelems++) { *app = dup_NC_attr(*drpp); if(*app == NULL) { status = NC_ENOMEM; break; } } } if(status != NC_NOERR) { free_NC_attrarrayV(ncap); return status; } assert(ncap->nelems == ref->nelems); return NC_NOERR; } /* * Add a new handle on the end of an array of handles * Formerly NC_incr_array(array, tail) */ static int incr_NC_attrarray(NC_attrarray *ncap, NC_attr *newelemp) { NC_attr **vp; assert(ncap != NULL); if(ncap->nalloc == 0) { assert(ncap->nelems == 0); vp = (NC_attr **) malloc(NC_ARRAY_GROWBY * sizeof(NC_attr *)); if(vp == NULL) return NC_ENOMEM; ncap->value = vp; ncap->nalloc = NC_ARRAY_GROWBY; } else if(ncap->nelems +1 > ncap->nalloc) { vp = (NC_attr **) realloc(ncap->value, (ncap->nalloc + NC_ARRAY_GROWBY) * sizeof(NC_attr *)); if(vp == NULL) return NC_ENOMEM; ncap->value = vp; ncap->nalloc += NC_ARRAY_GROWBY; } if(newelemp != NULL) { ncap->value[ncap->nelems] = newelemp; ncap->nelems++; } return NC_NOERR; } NC_attr * elem_NC_attrarray(const NC_attrarray *ncap, size_t elem) { assert(ncap != NULL); /* cast needed for braindead systems with signed size_t */ if(ncap->nelems == 0 || (unsigned long) elem >= ncap->nelems) return NULL; assert(ncap->value != NULL); return ncap->value[elem]; } /* End attarray per se */ /* * Given ncp and varid, return ptr to array of attributes * else NULL on error */ static NC_attrarray * NC_attrarray0(NC3_INFO* ncp, int varid) { NC_attrarray *ap; if(varid == NC_GLOBAL) /* Global attribute, attach to cdf */ { ap = &ncp->attrs; } else if(varid >= 0 && (size_t) varid < ncp->vars.nelems) { NC_var **vpp; vpp = (NC_var **)ncp->vars.value; vpp += varid; ap = &(*vpp)->attrs; } else { ap = NULL; } return(ap); } /* * Step thru NC_ATTRIBUTE array, seeking match on name. * return match or NULL if Not Found or out of memory. */ NC_attr ** NC_findattr(const NC_attrarray *ncap, const char *uname) { NC_attr **attrpp = NULL; size_t attrid; size_t slen; char *name = NULL; int stat = NC_NOERR; assert(ncap != NULL); if(ncap->nelems == 0) goto done; /* normalized version of uname */ stat = nc_utf8_normalize((const unsigned char *)uname,(unsigned char**)&name); if(stat != NC_NOERR) goto done; /* TODO: need better way to indicate no memory */ slen = strlen(name); attrpp = (NC_attr **) ncap->value; for(attrid = 0; attrid < ncap->nelems; attrid++, attrpp++) { if(strlen((*attrpp)->name->cp) == slen && strncmp((*attrpp)->name->cp, name, slen) == 0) goto done; } attrpp = NULL; /* not found */ done: if(name) free(name); return (attrpp); /* Normal return */ } /* * 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; if(name == NULL) return NC_EBADNAME; tmp = NC_findattr(ncap, name); if(tmp == NULL) return NC_ENOTATT; if(attrpp != NULL) *attrpp = *tmp; return NC_NOERR; } /* Public */ 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_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; } int NC3_inq_att(int ncid, int varid, const char *name, /* input, attribute name */ nc_type *datatypep, size_t *lenp) { int status; NC_attr *attrp; status = NC_lookupattr(ncid, varid, name, &attrp); if(status != NC_NOERR) return status; if(datatypep != NULL) *datatypep = attrp->type; if(lenp != NULL) *lenp = attrp->nelems; return NC_NOERR; } int NC3_rename_att( int ncid, int varid, const char *name, const char *unewname) { int status = NC_NOERR; NC *nc = NULL; NC3_INFO* ncp = NULL; NC_attrarray *ncap = NULL; NC_attr **tmp = NULL; NC_attr *attrp = NULL; NC_string *newStr, *old; char *newname = NULL; /* normalized version */ /* start sortof inline clone of NC_lookupattr() */ 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;} ncap = NC_attrarray0(ncp, varid); if(ncap == NULL) {status = NC_ENOTVAR; goto done;} status = NC_check_name(unewname); if(status != NC_NOERR) goto done; tmp = NC_findattr(ncap, name); if(tmp == NULL) {status = NC_ENOTATT; goto done;} attrp = *tmp; /* end inline clone NC_lookupattr() */ if(NC_findattr(ncap, unewname) != NULL) {status = NC_ENAMEINUSE; goto done;} /* name in use */ old = attrp->name; status = nc_utf8_normalize((const unsigned char *)unewname,(unsigned char**)&newname); if(status != NC_NOERR) goto done; if(NC_indef(ncp)) { newStr = new_NC_string(strlen(newname), newname); if( newStr == NULL) {status = NC_ENOMEM; goto done;} attrp->name = newStr; 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(old->nchars < strlen(newname)) {status = NC_ENOTINDEFINE; goto done;} status = set_NC_string(old, newname); if( status != NC_NOERR) goto done; 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_del_att(int ncid, int varid, const char *uname) { int status = NC_NOERR; NC *nc = NULL; NC3_INFO* ncp = NULL; NC_attrarray *ncap = NULL; NC_attr **attrpp = NULL; NC_attr *old = NULL; int attrid; size_t slen; char* name = NULL; status = NC_check_id(ncid, &nc); if(status != NC_NOERR) goto done; ncp = NC3_DATA(nc); if(!NC_indef(ncp)) {status = NC_ENOTINDEFINE; goto done;} ncap = NC_attrarray0(ncp, varid); if(ncap == NULL) {status = NC_ENOTVAR; goto done;} status = nc_utf8_normalize((const unsigned char *)uname,(unsigned char**)&name); if(status != NC_NOERR) goto done; /* start 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; } } if( (size_t) attrid == ncap->nelems ) {status = NC_ENOTATT; goto done;} /* 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); done: if(name) free(name); return status; } #line 713 static int #line 714 ncx_pad_putn_Iuchar(void **xpp, size_t nelems, const uchar *tp, nc_type type, void *fillp) #line 714 { #line 714 switch(type) { #line 714 case NC_CHAR: #line 714 return NC_ECHAR; #line 714 case NC_BYTE: #line 714 return ncx_pad_putn_schar_uchar(xpp, nelems, tp, fillp); #line 714 case NC_SHORT: #line 714 return ncx_pad_putn_short_uchar(xpp, nelems, tp, fillp); #line 714 case NC_INT: #line 714 return ncx_putn_int_uchar(xpp, nelems, tp, fillp); #line 714 case NC_FLOAT: #line 714 return ncx_putn_float_uchar(xpp, nelems, tp, fillp); #line 714 case NC_DOUBLE: #line 714 return ncx_putn_double_uchar(xpp, nelems, tp, fillp); #line 714 case NC_UBYTE: #line 714 return ncx_pad_putn_uchar_uchar(xpp, nelems, tp, fillp); #line 714 case NC_USHORT: #line 714 return ncx_putn_ushort_uchar(xpp, nelems, tp, fillp); #line 714 case NC_UINT: #line 714 return ncx_putn_uint_uchar(xpp, nelems, tp, fillp); #line 714 case NC_INT64: #line 714 return ncx_putn_longlong_uchar(xpp, nelems, tp, fillp); #line 714 case NC_UINT64: #line 714 return ncx_putn_ulonglong_uchar(xpp, nelems, tp, fillp); #line 714 default: #line 714 assert("ncx_pad_putn_Iuchar invalid type" == 0); #line 714 } #line 714 return NC_EBADTYPE; #line 714 } #line 714 static int #line 715 ncx_pad_getn_Iuchar(const void **xpp, size_t nelems, uchar *tp, nc_type type) #line 715 { #line 715 switch(type) { #line 715 case NC_CHAR: #line 715 return NC_ECHAR; #line 715 case NC_BYTE: #line 715 return ncx_pad_getn_schar_uchar(xpp, nelems, tp); #line 715 case NC_SHORT: #line 715 return ncx_pad_getn_short_uchar(xpp, nelems, tp); #line 715 case NC_INT: #line 715 return ncx_getn_int_uchar(xpp, nelems, tp); #line 715 case NC_FLOAT: #line 715 return ncx_getn_float_uchar(xpp, nelems, tp); #line 715 case NC_DOUBLE: #line 715 return ncx_getn_double_uchar(xpp, nelems, tp); #line 715 case NC_UBYTE: #line 715 return ncx_pad_getn_uchar_uchar(xpp, nelems, tp); #line 715 case NC_USHORT: #line 715 return ncx_getn_ushort_uchar(xpp, nelems, tp); #line 715 case NC_UINT: #line 715 return ncx_getn_uint_uchar(xpp, nelems, tp); #line 715 case NC_INT64: #line 715 return ncx_getn_longlong_uchar(xpp, nelems, tp); #line 715 case NC_UINT64: #line 715 return ncx_getn_ulonglong_uchar(xpp, nelems, tp); #line 715 default: #line 715 assert("ncx_pad_getn_Iuchar invalid type" == 0); #line 715 } #line 715 return NC_EBADTYPE; #line 715 } #line 715 static int #line 717 ncx_pad_putn_Ischar(void **xpp, size_t nelems, const schar *tp, nc_type type, void *fillp) #line 717 { #line 717 switch(type) { #line 717 case NC_CHAR: #line 717 return NC_ECHAR; #line 717 case NC_BYTE: #line 717 return ncx_pad_putn_schar_schar(xpp, nelems, tp, fillp); #line 717 case NC_SHORT: #line 717 return ncx_pad_putn_short_schar(xpp, nelems, tp, fillp); #line 717 case NC_INT: #line 717 return ncx_putn_int_schar(xpp, nelems, tp, fillp); #line 717 case NC_FLOAT: #line 717 return ncx_putn_float_schar(xpp, nelems, tp, fillp); #line 717 case NC_DOUBLE: #line 717 return ncx_putn_double_schar(xpp, nelems, tp, fillp); #line 717 case NC_UBYTE: #line 717 return ncx_pad_putn_uchar_schar(xpp, nelems, tp, fillp); #line 717 case NC_USHORT: #line 717 return ncx_putn_ushort_schar(xpp, nelems, tp, fillp); #line 717 case NC_UINT: #line 717 return ncx_putn_uint_schar(xpp, nelems, tp, fillp); #line 717 case NC_INT64: #line 717 return ncx_putn_longlong_schar(xpp, nelems, tp, fillp); #line 717 case NC_UINT64: #line 717 return ncx_putn_ulonglong_schar(xpp, nelems, tp, fillp); #line 717 default: #line 717 assert("ncx_pad_putn_Ischar invalid type" == 0); #line 717 } #line 717 return NC_EBADTYPE; #line 717 } #line 717 static int #line 718 ncx_pad_getn_Ischar(const void **xpp, size_t nelems, schar *tp, nc_type type) #line 718 { #line 718 switch(type) { #line 718 case NC_CHAR: #line 718 return NC_ECHAR; #line 718 case NC_BYTE: #line 718 return ncx_pad_getn_schar_schar(xpp, nelems, tp); #line 718 case NC_SHORT: #line 718 return ncx_pad_getn_short_schar(xpp, nelems, tp); #line 718 case NC_INT: #line 718 return ncx_getn_int_schar(xpp, nelems, tp); #line 718 case NC_FLOAT: #line 718 return ncx_getn_float_schar(xpp, nelems, tp); #line 718 case NC_DOUBLE: #line 718 return ncx_getn_double_schar(xpp, nelems, tp); #line 718 case NC_UBYTE: #line 718 return ncx_pad_getn_uchar_schar(xpp, nelems, tp); #line 718 case NC_USHORT: #line 718 return ncx_getn_ushort_schar(xpp, nelems, tp); #line 718 case NC_UINT: #line 718 return ncx_getn_uint_schar(xpp, nelems, tp); #line 718 case NC_INT64: #line 718 return ncx_getn_longlong_schar(xpp, nelems, tp); #line 718 case NC_UINT64: #line 718 return ncx_getn_ulonglong_schar(xpp, nelems, tp); #line 718 default: #line 718 assert("ncx_pad_getn_Ischar invalid type" == 0); #line 718 } #line 718 return NC_EBADTYPE; #line 718 } #line 718 static int #line 720 ncx_pad_putn_Ishort(void **xpp, size_t nelems, const short *tp, nc_type type, void *fillp) #line 720 { #line 720 switch(type) { #line 720 case NC_CHAR: #line 720 return NC_ECHAR; #line 720 case NC_BYTE: #line 720 return ncx_pad_putn_schar_short(xpp, nelems, tp, fillp); #line 720 case NC_SHORT: #line 720 return ncx_pad_putn_short_short(xpp, nelems, tp, fillp); #line 720 case NC_INT: #line 720 return ncx_putn_int_short(xpp, nelems, tp, fillp); #line 720 case NC_FLOAT: #line 720 return ncx_putn_float_short(xpp, nelems, tp, fillp); #line 720 case NC_DOUBLE: #line 720 return ncx_putn_double_short(xpp, nelems, tp, fillp); #line 720 case NC_UBYTE: #line 720 return ncx_pad_putn_uchar_short(xpp, nelems, tp, fillp); #line 720 case NC_USHORT: #line 720 return ncx_putn_ushort_short(xpp, nelems, tp, fillp); #line 720 case NC_UINT: #line 720 return ncx_putn_uint_short(xpp, nelems, tp, fillp); #line 720 case NC_INT64: #line 720 return ncx_putn_longlong_short(xpp, nelems, tp, fillp); #line 720 case NC_UINT64: #line 720 return ncx_putn_ulonglong_short(xpp, nelems, tp, fillp); #line 720 default: #line 720 assert("ncx_pad_putn_Ishort invalid type" == 0); #line 720 } #line 720 return NC_EBADTYPE; #line 720 } #line 720 static int #line 721 ncx_pad_getn_Ishort(const void **xpp, size_t nelems, short *tp, nc_type type) #line 721 { #line 721 switch(type) { #line 721 case NC_CHAR: #line 721 return NC_ECHAR; #line 721 case NC_BYTE: #line 721 return ncx_pad_getn_schar_short(xpp, nelems, tp); #line 721 case NC_SHORT: #line 721 return ncx_pad_getn_short_short(xpp, nelems, tp); #line 721 case NC_INT: #line 721 return ncx_getn_int_short(xpp, nelems, tp); #line 721 case NC_FLOAT: #line 721 return ncx_getn_float_short(xpp, nelems, tp); #line 721 case NC_DOUBLE: #line 721 return ncx_getn_double_short(xpp, nelems, tp); #line 721 case NC_UBYTE: #line 721 return ncx_pad_getn_uchar_short(xpp, nelems, tp); #line 721 case NC_USHORT: #line 721 return ncx_getn_ushort_short(xpp, nelems, tp); #line 721 case NC_UINT: #line 721 return ncx_getn_uint_short(xpp, nelems, tp); #line 721 case NC_INT64: #line 721 return ncx_getn_longlong_short(xpp, nelems, tp); #line 721 case NC_UINT64: #line 721 return ncx_getn_ulonglong_short(xpp, nelems, tp); #line 721 default: #line 721 assert("ncx_pad_getn_Ishort invalid type" == 0); #line 721 } #line 721 return NC_EBADTYPE; #line 721 } #line 721 static int #line 723 ncx_pad_putn_Iint(void **xpp, size_t nelems, const int *tp, nc_type type, void *fillp) #line 723 { #line 723 switch(type) { #line 723 case NC_CHAR: #line 723 return NC_ECHAR; #line 723 case NC_BYTE: #line 723 return ncx_pad_putn_schar_int(xpp, nelems, tp, fillp); #line 723 case NC_SHORT: #line 723 return ncx_pad_putn_short_int(xpp, nelems, tp, fillp); #line 723 case NC_INT: #line 723 return ncx_putn_int_int(xpp, nelems, tp, fillp); #line 723 case NC_FLOAT: #line 723 return ncx_putn_float_int(xpp, nelems, tp, fillp); #line 723 case NC_DOUBLE: #line 723 return ncx_putn_double_int(xpp, nelems, tp, fillp); #line 723 case NC_UBYTE: #line 723 return ncx_pad_putn_uchar_int(xpp, nelems, tp, fillp); #line 723 case NC_USHORT: #line 723 return ncx_putn_ushort_int(xpp, nelems, tp, fillp); #line 723 case NC_UINT: #line 723 return ncx_putn_uint_int(xpp, nelems, tp, fillp); #line 723 case NC_INT64: #line 723 return ncx_putn_longlong_int(xpp, nelems, tp, fillp); #line 723 case NC_UINT64: #line 723 return ncx_putn_ulonglong_int(xpp, nelems, tp, fillp); #line 723 default: #line 723 assert("ncx_pad_putn_Iint invalid type" == 0); #line 723 } #line 723 return NC_EBADTYPE; #line 723 } #line 723 static int #line 724 ncx_pad_getn_Iint(const void **xpp, size_t nelems, int *tp, nc_type type) #line 724 { #line 724 switch(type) { #line 724 case NC_CHAR: #line 724 return NC_ECHAR; #line 724 case NC_BYTE: #line 724 return ncx_pad_getn_schar_int(xpp, nelems, tp); #line 724 case NC_SHORT: #line 724 return ncx_pad_getn_short_int(xpp, nelems, tp); #line 724 case NC_INT: #line 724 return ncx_getn_int_int(xpp, nelems, tp); #line 724 case NC_FLOAT: #line 724 return ncx_getn_float_int(xpp, nelems, tp); #line 724 case NC_DOUBLE: #line 724 return ncx_getn_double_int(xpp, nelems, tp); #line 724 case NC_UBYTE: #line 724 return ncx_pad_getn_uchar_int(xpp, nelems, tp); #line 724 case NC_USHORT: #line 724 return ncx_getn_ushort_int(xpp, nelems, tp); #line 724 case NC_UINT: #line 724 return ncx_getn_uint_int(xpp, nelems, tp); #line 724 case NC_INT64: #line 724 return ncx_getn_longlong_int(xpp, nelems, tp); #line 724 case NC_UINT64: #line 724 return ncx_getn_ulonglong_int(xpp, nelems, tp); #line 724 default: #line 724 assert("ncx_pad_getn_Iint invalid type" == 0); #line 724 } #line 724 return NC_EBADTYPE; #line 724 } #line 724 static int #line 726 ncx_pad_putn_Ifloat(void **xpp, size_t nelems, const float *tp, nc_type type, void *fillp) #line 726 { #line 726 switch(type) { #line 726 case NC_CHAR: #line 726 return NC_ECHAR; #line 726 case NC_BYTE: #line 726 return ncx_pad_putn_schar_float(xpp, nelems, tp, fillp); #line 726 case NC_SHORT: #line 726 return ncx_pad_putn_short_float(xpp, nelems, tp, fillp); #line 726 case NC_INT: #line 726 return ncx_putn_int_float(xpp, nelems, tp, fillp); #line 726 case NC_FLOAT: #line 726 return ncx_putn_float_float(xpp, nelems, tp, fillp); #line 726 case NC_DOUBLE: #line 726 return ncx_putn_double_float(xpp, nelems, tp, fillp); #line 726 case NC_UBYTE: #line 726 return ncx_pad_putn_uchar_float(xpp, nelems, tp, fillp); #line 726 case NC_USHORT: #line 726 return ncx_putn_ushort_float(xpp, nelems, tp, fillp); #line 726 case NC_UINT: #line 726 return ncx_putn_uint_float(xpp, nelems, tp, fillp); #line 726 case NC_INT64: #line 726 return ncx_putn_longlong_float(xpp, nelems, tp, fillp); #line 726 case NC_UINT64: #line 726 return ncx_putn_ulonglong_float(xpp, nelems, tp, fillp); #line 726 default: #line 726 assert("ncx_pad_putn_Ifloat invalid type" == 0); #line 726 } #line 726 return NC_EBADTYPE; #line 726 } #line 726 static int #line 727 ncx_pad_getn_Ifloat(const void **xpp, size_t nelems, float *tp, nc_type type) #line 727 { #line 727 switch(type) { #line 727 case NC_CHAR: #line 727 return NC_ECHAR; #line 727 case NC_BYTE: #line 727 return ncx_pad_getn_schar_float(xpp, nelems, tp); #line 727 case NC_SHORT: #line 727 return ncx_pad_getn_short_float(xpp, nelems, tp); #line 727 case NC_INT: #line 727 return ncx_getn_int_float(xpp, nelems, tp); #line 727 case NC_FLOAT: #line 727 return ncx_getn_float_float(xpp, nelems, tp); #line 727 case NC_DOUBLE: #line 727 return ncx_getn_double_float(xpp, nelems, tp); #line 727 case NC_UBYTE: #line 727 return ncx_pad_getn_uchar_float(xpp, nelems, tp); #line 727 case NC_USHORT: #line 727 return ncx_getn_ushort_float(xpp, nelems, tp); #line 727 case NC_UINT: #line 727 return ncx_getn_uint_float(xpp, nelems, tp); #line 727 case NC_INT64: #line 727 return ncx_getn_longlong_float(xpp, nelems, tp); #line 727 case NC_UINT64: #line 727 return ncx_getn_ulonglong_float(xpp, nelems, tp); #line 727 default: #line 727 assert("ncx_pad_getn_Ifloat invalid type" == 0); #line 727 } #line 727 return NC_EBADTYPE; #line 727 } #line 727 static int #line 729 ncx_pad_putn_Idouble(void **xpp, size_t nelems, const double *tp, nc_type type, void *fillp) #line 729 { #line 729 switch(type) { #line 729 case NC_CHAR: #line 729 return NC_ECHAR; #line 729 case NC_BYTE: #line 729 return ncx_pad_putn_schar_double(xpp, nelems, tp, fillp); #line 729 case NC_SHORT: #line 729 return ncx_pad_putn_short_double(xpp, nelems, tp, fillp); #line 729 case NC_INT: #line 729 return ncx_putn_int_double(xpp, nelems, tp, fillp); #line 729 case NC_FLOAT: #line 729 return ncx_putn_float_double(xpp, nelems, tp, fillp); #line 729 case NC_DOUBLE: #line 729 return ncx_putn_double_double(xpp, nelems, tp, fillp); #line 729 case NC_UBYTE: #line 729 return ncx_pad_putn_uchar_double(xpp, nelems, tp, fillp); #line 729 case NC_USHORT: #line 729 return ncx_putn_ushort_double(xpp, nelems, tp, fillp); #line 729 case NC_UINT: #line 729 return ncx_putn_uint_double(xpp, nelems, tp, fillp); #line 729 case NC_INT64: #line 729 return ncx_putn_longlong_double(xpp, nelems, tp, fillp); #line 729 case NC_UINT64: #line 729 return ncx_putn_ulonglong_double(xpp, nelems, tp, fillp); #line 729 default: #line 729 assert("ncx_pad_putn_Idouble invalid type" == 0); #line 729 } #line 729 return NC_EBADTYPE; #line 729 } #line 729 static int #line 730 ncx_pad_getn_Idouble(const void **xpp, size_t nelems, double *tp, nc_type type) #line 730 { #line 730 switch(type) { #line 730 case NC_CHAR: #line 730 return NC_ECHAR; #line 730 case NC_BYTE: #line 730 return ncx_pad_getn_schar_double(xpp, nelems, tp); #line 730 case NC_SHORT: #line 730 return ncx_pad_getn_short_double(xpp, nelems, tp); #line 730 case NC_INT: #line 730 return ncx_getn_int_double(xpp, nelems, tp); #line 730 case NC_FLOAT: #line 730 return ncx_getn_float_double(xpp, nelems, tp); #line 730 case NC_DOUBLE: #line 730 return ncx_getn_double_double(xpp, nelems, tp); #line 730 case NC_UBYTE: #line 730 return ncx_pad_getn_uchar_double(xpp, nelems, tp); #line 730 case NC_USHORT: #line 730 return ncx_getn_ushort_double(xpp, nelems, tp); #line 730 case NC_UINT: #line 730 return ncx_getn_uint_double(xpp, nelems, tp); #line 730 case NC_INT64: #line 730 return ncx_getn_longlong_double(xpp, nelems, tp); #line 730 case NC_UINT64: #line 730 return ncx_getn_ulonglong_double(xpp, nelems, tp); #line 730 default: #line 730 assert("ncx_pad_getn_Idouble invalid type" == 0); #line 730 } #line 730 return NC_EBADTYPE; #line 730 } #line 730 #ifdef IGNORE static int #line 733 ncx_pad_putn_Ilong(void **xpp, size_t nelems, const long *tp, nc_type type, void *fillp) #line 733 { #line 733 switch(type) { #line 733 case NC_CHAR: #line 733 return NC_ECHAR; #line 733 case NC_BYTE: #line 733 return ncx_pad_putn_schar_long(xpp, nelems, tp, fillp); #line 733 case NC_SHORT: #line 733 return ncx_pad_putn_short_long(xpp, nelems, tp, fillp); #line 733 case NC_INT: #line 733 return ncx_putn_int_long(xpp, nelems, tp, fillp); #line 733 case NC_FLOAT: #line 733 return ncx_putn_float_long(xpp, nelems, tp, fillp); #line 733 case NC_DOUBLE: #line 733 return ncx_putn_double_long(xpp, nelems, tp, fillp); #line 733 case NC_UBYTE: #line 733 return ncx_pad_putn_uchar_long(xpp, nelems, tp, fillp); #line 733 case NC_USHORT: #line 733 return ncx_putn_ushort_long(xpp, nelems, tp, fillp); #line 733 case NC_UINT: #line 733 return ncx_putn_uint_long(xpp, nelems, tp, fillp); #line 733 case NC_INT64: #line 733 return ncx_putn_longlong_long(xpp, nelems, tp, fillp); #line 733 case NC_UINT64: #line 733 return ncx_putn_ulonglong_long(xpp, nelems, tp, fillp); #line 733 default: #line 733 assert("ncx_pad_putn_Ilong invalid type" == 0); #line 733 } #line 733 return NC_EBADTYPE; #line 733 } #line 733 static int #line 734 ncx_pad_getn_Ilong(const void **xpp, size_t nelems, long *tp, nc_type type) #line 734 { #line 734 switch(type) { #line 734 case NC_CHAR: #line 734 return NC_ECHAR; #line 734 case NC_BYTE: #line 734 return ncx_pad_getn_schar_long(xpp, nelems, tp); #line 734 case NC_SHORT: #line 734 return ncx_pad_getn_short_long(xpp, nelems, tp); #line 734 case NC_INT: #line 734 return ncx_getn_int_long(xpp, nelems, tp); #line 734 case NC_FLOAT: #line 734 return ncx_getn_float_long(xpp, nelems, tp); #line 734 case NC_DOUBLE: #line 734 return ncx_getn_double_long(xpp, nelems, tp); #line 734 case NC_UBYTE: #line 734 return ncx_pad_getn_uchar_long(xpp, nelems, tp); #line 734 case NC_USHORT: #line 734 return ncx_getn_ushort_long(xpp, nelems, tp); #line 734 case NC_UINT: #line 734 return ncx_getn_uint_long(xpp, nelems, tp); #line 734 case NC_INT64: #line 734 return ncx_getn_longlong_long(xpp, nelems, tp); #line 734 case NC_UINT64: #line 734 return ncx_getn_ulonglong_long(xpp, nelems, tp); #line 734 default: #line 734 assert("ncx_pad_getn_Ilong invalid type" == 0); #line 734 } #line 734 return NC_EBADTYPE; #line 734 } #line 734 #endif static int #line 737 ncx_pad_putn_Ilonglong(void **xpp, size_t nelems, const longlong *tp, nc_type type, void *fillp) #line 737 { #line 737 switch(type) { #line 737 case NC_CHAR: #line 737 return NC_ECHAR; #line 737 case NC_BYTE: #line 737 return ncx_pad_putn_schar_longlong(xpp, nelems, tp, fillp); #line 737 case NC_SHORT: #line 737 return ncx_pad_putn_short_longlong(xpp, nelems, tp, fillp); #line 737 case NC_INT: #line 737 return ncx_putn_int_longlong(xpp, nelems, tp, fillp); #line 737 case NC_FLOAT: #line 737 return ncx_putn_float_longlong(xpp, nelems, tp, fillp); #line 737 case NC_DOUBLE: #line 737 return ncx_putn_double_longlong(xpp, nelems, tp, fillp); #line 737 case NC_UBYTE: #line 737 return ncx_pad_putn_uchar_longlong(xpp, nelems, tp, fillp); #line 737 case NC_USHORT: #line 737 return ncx_putn_ushort_longlong(xpp, nelems, tp, fillp); #line 737 case NC_UINT: #line 737 return ncx_putn_uint_longlong(xpp, nelems, tp, fillp); #line 737 case NC_INT64: #line 737 return ncx_putn_longlong_longlong(xpp, nelems, tp, fillp); #line 737 case NC_UINT64: #line 737 return ncx_putn_ulonglong_longlong(xpp, nelems, tp, fillp); #line 737 default: #line 737 assert("ncx_pad_putn_Ilonglong invalid type" == 0); #line 737 } #line 737 return NC_EBADTYPE; #line 737 } #line 737 static int #line 738 ncx_pad_getn_Ilonglong(const void **xpp, size_t nelems, longlong *tp, nc_type type) #line 738 { #line 738 switch(type) { #line 738 case NC_CHAR: #line 738 return NC_ECHAR; #line 738 case NC_BYTE: #line 738 return ncx_pad_getn_schar_longlong(xpp, nelems, tp); #line 738 case NC_SHORT: #line 738 return ncx_pad_getn_short_longlong(xpp, nelems, tp); #line 738 case NC_INT: #line 738 return ncx_getn_int_longlong(xpp, nelems, tp); #line 738 case NC_FLOAT: #line 738 return ncx_getn_float_longlong(xpp, nelems, tp); #line 738 case NC_DOUBLE: #line 738 return ncx_getn_double_longlong(xpp, nelems, tp); #line 738 case NC_UBYTE: #line 738 return ncx_pad_getn_uchar_longlong(xpp, nelems, tp); #line 738 case NC_USHORT: #line 738 return ncx_getn_ushort_longlong(xpp, nelems, tp); #line 738 case NC_UINT: #line 738 return ncx_getn_uint_longlong(xpp, nelems, tp); #line 738 case NC_INT64: #line 738 return ncx_getn_longlong_longlong(xpp, nelems, tp); #line 738 case NC_UINT64: #line 738 return ncx_getn_ulonglong_longlong(xpp, nelems, tp); #line 738 default: #line 738 assert("ncx_pad_getn_Ilonglong invalid type" == 0); #line 738 } #line 738 return NC_EBADTYPE; #line 738 } #line 738 static int #line 740 ncx_pad_putn_Iushort(void **xpp, size_t nelems, const ushort *tp, nc_type type, void *fillp) #line 740 { #line 740 switch(type) { #line 740 case NC_CHAR: #line 740 return NC_ECHAR; #line 740 case NC_BYTE: #line 740 return ncx_pad_putn_schar_ushort(xpp, nelems, tp, fillp); #line 740 case NC_SHORT: #line 740 return ncx_pad_putn_short_ushort(xpp, nelems, tp, fillp); #line 740 case NC_INT: #line 740 return ncx_putn_int_ushort(xpp, nelems, tp, fillp); #line 740 case NC_FLOAT: #line 740 return ncx_putn_float_ushort(xpp, nelems, tp, fillp); #line 740 case NC_DOUBLE: #line 740 return ncx_putn_double_ushort(xpp, nelems, tp, fillp); #line 740 case NC_UBYTE: #line 740 return ncx_pad_putn_uchar_ushort(xpp, nelems, tp, fillp); #line 740 case NC_USHORT: #line 740 return ncx_putn_ushort_ushort(xpp, nelems, tp, fillp); #line 740 case NC_UINT: #line 740 return ncx_putn_uint_ushort(xpp, nelems, tp, fillp); #line 740 case NC_INT64: #line 740 return ncx_putn_longlong_ushort(xpp, nelems, tp, fillp); #line 740 case NC_UINT64: #line 740 return ncx_putn_ulonglong_ushort(xpp, nelems, tp, fillp); #line 740 default: #line 740 assert("ncx_pad_putn_Iushort invalid type" == 0); #line 740 } #line 740 return NC_EBADTYPE; #line 740 } #line 740 static int #line 741 ncx_pad_getn_Iushort(const void **xpp, size_t nelems, ushort *tp, nc_type type) #line 741 { #line 741 switch(type) { #line 741 case NC_CHAR: #line 741 return NC_ECHAR; #line 741 case NC_BYTE: #line 741 return ncx_pad_getn_schar_ushort(xpp, nelems, tp); #line 741 case NC_SHORT: #line 741 return ncx_pad_getn_short_ushort(xpp, nelems, tp); #line 741 case NC_INT: #line 741 return ncx_getn_int_ushort(xpp, nelems, tp); #line 741 case NC_FLOAT: #line 741 return ncx_getn_float_ushort(xpp, nelems, tp); #line 741 case NC_DOUBLE: #line 741 return ncx_getn_double_ushort(xpp, nelems, tp); #line 741 case NC_UBYTE: #line 741 return ncx_pad_getn_uchar_ushort(xpp, nelems, tp); #line 741 case NC_USHORT: #line 741 return ncx_getn_ushort_ushort(xpp, nelems, tp); #line 741 case NC_UINT: #line 741 return ncx_getn_uint_ushort(xpp, nelems, tp); #line 741 case NC_INT64: #line 741 return ncx_getn_longlong_ushort(xpp, nelems, tp); #line 741 case NC_UINT64: #line 741 return ncx_getn_ulonglong_ushort(xpp, nelems, tp); #line 741 default: #line 741 assert("ncx_pad_getn_Iushort invalid type" == 0); #line 741 } #line 741 return NC_EBADTYPE; #line 741 } #line 741 static int #line 743 ncx_pad_putn_Iuint(void **xpp, size_t nelems, const uint *tp, nc_type type, void *fillp) #line 743 { #line 743 switch(type) { #line 743 case NC_CHAR: #line 743 return NC_ECHAR; #line 743 case NC_BYTE: #line 743 return ncx_pad_putn_schar_uint(xpp, nelems, tp, fillp); #line 743 case NC_SHORT: #line 743 return ncx_pad_putn_short_uint(xpp, nelems, tp, fillp); #line 743 case NC_INT: #line 743 return ncx_putn_int_uint(xpp, nelems, tp, fillp); #line 743 case NC_FLOAT: #line 743 return ncx_putn_float_uint(xpp, nelems, tp, fillp); #line 743 case NC_DOUBLE: #line 743 return ncx_putn_double_uint(xpp, nelems, tp, fillp); #line 743 case NC_UBYTE: #line 743 return ncx_pad_putn_uchar_uint(xpp, nelems, tp, fillp); #line 743 case NC_USHORT: #line 743 return ncx_putn_ushort_uint(xpp, nelems, tp, fillp); #line 743 case NC_UINT: #line 743 return ncx_putn_uint_uint(xpp, nelems, tp, fillp); #line 743 case NC_INT64: #line 743 return ncx_putn_longlong_uint(xpp, nelems, tp, fillp); #line 743 case NC_UINT64: #line 743 return ncx_putn_ulonglong_uint(xpp, nelems, tp, fillp); #line 743 default: #line 743 assert("ncx_pad_putn_Iuint invalid type" == 0); #line 743 } #line 743 return NC_EBADTYPE; #line 743 } #line 743 static int #line 744 ncx_pad_getn_Iuint(const void **xpp, size_t nelems, uint *tp, nc_type type) #line 744 { #line 744 switch(type) { #line 744 case NC_CHAR: #line 744 return NC_ECHAR; #line 744 case NC_BYTE: #line 744 return ncx_pad_getn_schar_uint(xpp, nelems, tp); #line 744 case NC_SHORT: #line 744 return ncx_pad_getn_short_uint(xpp, nelems, tp); #line 744 case NC_INT: #line 744 return ncx_getn_int_uint(xpp, nelems, tp); #line 744 case NC_FLOAT: #line 744 return ncx_getn_float_uint(xpp, nelems, tp); #line 744 case NC_DOUBLE: #line 744 return ncx_getn_double_uint(xpp, nelems, tp); #line 744 case NC_UBYTE: #line 744 return ncx_pad_getn_uchar_uint(xpp, nelems, tp); #line 744 case NC_USHORT: #line 744 return ncx_getn_ushort_uint(xpp, nelems, tp); #line 744 case NC_UINT: #line 744 return ncx_getn_uint_uint(xpp, nelems, tp); #line 744 case NC_INT64: #line 744 return ncx_getn_longlong_uint(xpp, nelems, tp); #line 744 case NC_UINT64: #line 744 return ncx_getn_ulonglong_uint(xpp, nelems, tp); #line 744 default: #line 744 assert("ncx_pad_getn_Iuint invalid type" == 0); #line 744 } #line 744 return NC_EBADTYPE; #line 744 } #line 744 static int #line 746 ncx_pad_putn_Iulonglong(void **xpp, size_t nelems, const ulonglong *tp, nc_type type, void *fillp) #line 746 { #line 746 switch(type) { #line 746 case NC_CHAR: #line 746 return NC_ECHAR; #line 746 case NC_BYTE: #line 746 return ncx_pad_putn_schar_ulonglong(xpp, nelems, tp, fillp); #line 746 case NC_SHORT: #line 746 return ncx_pad_putn_short_ulonglong(xpp, nelems, tp, fillp); #line 746 case NC_INT: #line 746 return ncx_putn_int_ulonglong(xpp, nelems, tp, fillp); #line 746 case NC_FLOAT: #line 746 return ncx_putn_float_ulonglong(xpp, nelems, tp, fillp); #line 746 case NC_DOUBLE: #line 746 return ncx_putn_double_ulonglong(xpp, nelems, tp, fillp); #line 746 case NC_UBYTE: #line 746 return ncx_pad_putn_uchar_ulonglong(xpp, nelems, tp, fillp); #line 746 case NC_USHORT: #line 746 return ncx_putn_ushort_ulonglong(xpp, nelems, tp, fillp); #line 746 case NC_UINT: #line 746 return ncx_putn_uint_ulonglong(xpp, nelems, tp, fillp); #line 746 case NC_INT64: #line 746 return ncx_putn_longlong_ulonglong(xpp, nelems, tp, fillp); #line 746 case NC_UINT64: #line 746 return ncx_putn_ulonglong_ulonglong(xpp, nelems, tp, fillp); #line 746 default: #line 746 assert("ncx_pad_putn_Iulonglong invalid type" == 0); #line 746 } #line 746 return NC_EBADTYPE; #line 746 } #line 746 static int #line 747 ncx_pad_getn_Iulonglong(const void **xpp, size_t nelems, ulonglong *tp, nc_type type) #line 747 { #line 747 switch(type) { #line 747 case NC_CHAR: #line 747 return NC_ECHAR; #line 747 case NC_BYTE: #line 747 return ncx_pad_getn_schar_ulonglong(xpp, nelems, tp); #line 747 case NC_SHORT: #line 747 return ncx_pad_getn_short_ulonglong(xpp, nelems, tp); #line 747 case NC_INT: #line 747 return ncx_getn_int_ulonglong(xpp, nelems, tp); #line 747 case NC_FLOAT: #line 747 return ncx_getn_float_ulonglong(xpp, nelems, tp); #line 747 case NC_DOUBLE: #line 747 return ncx_getn_double_ulonglong(xpp, nelems, tp); #line 747 case NC_UBYTE: #line 747 return ncx_pad_getn_uchar_ulonglong(xpp, nelems, tp); #line 747 case NC_USHORT: #line 747 return ncx_getn_ushort_ulonglong(xpp, nelems, tp); #line 747 case NC_UINT: #line 747 return ncx_getn_uint_ulonglong(xpp, nelems, tp); #line 747 case NC_INT64: #line 747 return ncx_getn_longlong_ulonglong(xpp, nelems, tp); #line 747 case NC_UINT64: #line 747 return ncx_getn_ulonglong_ulonglong(xpp, nelems, tp); #line 747 default: #line 747 assert("ncx_pad_getn_Iulonglong invalid type" == 0); #line 747 } #line 747 return NC_EBADTYPE; #line 747 } #line 747 /* Common dispatcher for put cases */ static int dispatchput(void **xpp, size_t nelems, const void* tp, nc_type atype, nc_type memtype, void *fillp) { 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, fillp); case NC_SHORT: return ncx_pad_putn_Ishort(xpp, nelems, (short*)tp, atype, fillp); case NC_INT: return ncx_pad_putn_Iint(xpp, nelems, (int*)tp, atype, fillp); case NC_FLOAT: return ncx_pad_putn_Ifloat(xpp, nelems, (float*)tp, atype, fillp); case NC_DOUBLE: return ncx_pad_putn_Idouble(xpp, nelems, (double*)tp, atype, fillp); case NC_UBYTE: /*Synthetic*/ return ncx_pad_putn_Iuchar(xpp,nelems, (uchar *)tp, atype, fillp); case NC_INT64: return ncx_pad_putn_Ilonglong(xpp, nelems, (longlong*)tp, atype, fillp); case NC_USHORT: return ncx_pad_putn_Iushort(xpp, nelems, (ushort*)tp, atype, fillp); case NC_UINT: return ncx_pad_putn_Iuint(xpp, nelems, (uint*)tp, atype, fillp); case NC_UINT64: return ncx_pad_putn_Iulonglong(xpp, nelems, (ulonglong*)tp, atype, fillp); case NC_NAT: return NC_EBADTYPE; default: break; } return NC_EBADTYPE; } 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 0 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 */ } #endif 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_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; }