18 #include "nc4internal.h" 20 #include "nc4dispatch.h" 21 #include "ncdispatch.h" 44 nc4_get_att_special(NC_HDF5_FILE_INFO_T* h5,
const char* name,
46 int* attnump,
int is_long,
void* data)
52 if(strcmp(name,NCPROPS)==0) {
53 char* propdata = NULL;
56 if(h5->fileinfo->propattr.version == 0)
61 if(filetypep) *filetypep =
NC_CHAR;
62 stat = NC4_buildpropinfo(&h5->fileinfo->propattr, &propdata);
64 len = strlen(propdata);
66 if(data) strncpy((
char*)data,propdata,len+1);
68 }
else if(strcmp(name,ISNETCDF4ATT)==0
69 || strcmp(name,SUPERBLOCKATT)==0) {
70 unsigned long long iv = 0;
71 if(filetypep) *filetypep =
NC_INT;
73 if(strcmp(name,SUPERBLOCKATT)==0)
74 iv = (
unsigned long long)h5->fileinfo->superblockversion;
76 iv = NC4_isnetcdf4(h5);
80 case NC_BYTE: *((
char*)data) = (char)iv;
break;
81 case NC_SHORT: *((
short*)data) = (short)iv;
break;
82 case NC_INT: *((
int*)data) = (int)iv;
break;
83 case NC_UBYTE: *((
unsigned char*)data) = (
unsigned char)iv;
break;
84 case NC_USHORT: *((
unsigned short*)data) = (
unsigned short)iv;
break;
85 case NC_UINT: *((
unsigned int*)data) = (
unsigned int)iv;
break;
86 case NC_INT64: *((
long long*)data) = (
long long)iv;
break;
87 case NC_UINT64: *((
unsigned long long*)data) = (
unsigned long long)iv;
break;
114 nc4_get_att(
int ncid,
int varid,
const char *name,
nc_type *xtype,
115 nc_type mem_type,
size_t *lenp,
int *attnum,
void *data)
119 NC_HDF5_FILE_INFO_T *h5;
120 NC_ATT_INFO_T *att = NULL;
122 int need_to_convert = 0;
133 LOG((3,
"%s: ncid 0x%x varid %d name %s attnum %d mem_type %d",
134 __func__, ncid, varid, name, my_attnum, mem_type));
137 if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
142 if (varid < 0 || varid >= grp->vars.nelems)
144 if (grp->vars.value[varid] == NULL)
146 assert(grp->vars.value[varid]->varid == varid);
153 if ((retval = nc4_normalize_name(name, norm_name)))
157 if (nc->ext_ncid == ncid && varid ==
NC_GLOBAL) {
159 for (sp = NC_RESERVED_SPECIAL_LIST; *sp; sp++) {
160 if (strcmp(name,*sp)==0) {
161 return nc4_get_att_special(h5, norm_name, xtype, mem_type, lenp,
168 if ((retval = nc4_find_grp_att(grp, varid, norm_name, my_attnum, &att)))
174 mem_type = att->nc_typeid;
180 if (data && att->len)
189 *xtype = att->nc_typeid;
191 *attnum = att->attnum;
199 if ((retval = nc4_get_typelen_mem(h5, mem_type, 0, &type_size)))
205 if (data && att->len && mem_type != att->nc_typeid &&
210 if (!(bufr = malloc((
size_t)(att->len * type_size))))
213 if ((retval = nc4_convert_type(att->data, bufr, att->nc_typeid,
214 mem_type, (
size_t)att->len, &range_error,
240 hvl_t *vldest = data;
241 NC_TYPE_INFO_T *type;
244 if ((retval = nc4_find_type(h5, att->nc_typeid, &type)))
248 if ((retval = nc4_get_typelen_mem(h5, type->u.v.base_nc_typeid, 0, &base_typelen)))
251 for (i = 0; i < att->len; i++)
253 vldest[i].len = att->vldata[i].len;
254 if (!(vldest[i].p = malloc(vldest[i].len * base_typelen)))
256 memcpy(vldest[i].p, att->vldata[i].p, vldest[i].len * base_typelen);
259 else if (att->stdata)
261 for (i = 0; i < att->len; i++)
266 if (!(((
char **)data)[i] = strdup(att->stdata[i])))
270 ((
char **)data)[i] = att->stdata[i];
275 memcpy(data, bufr, (
size_t)(att->len * type_size));
302 NC4_inq_att(
int ncid,
int varid,
const char *name,
nc_type *xtypep,
305 LOG((2,
"%s: ncid 0x%x varid %d name %s", __func__, ncid, varid, name));
306 return nc4_get_att(ncid, varid, name, xtypep,
NC_NAT, lenp, NULL, NULL);
321 NC4_inq_attid(
int ncid,
int varid,
const char *name,
int *attnump)
323 LOG((2,
"%s: ncid 0x%x varid %d name %s", __func__, ncid, varid, name));
324 return nc4_get_att(ncid, varid, name, NULL,
NC_NAT, NULL, attnump, NULL);
341 NC4_inq_attname(
int ncid,
int varid,
int attnum,
char *name)
345 NC_HDF5_FILE_INFO_T *h5;
348 LOG((2,
"nc_inq_attname: ncid 0x%x varid %d attnum %d",
349 ncid, varid, attnum));
352 if (!(nc = nc4_find_nc_file(ncid,NULL)))
360 if ((retval = nc4_find_nc_att(ncid, varid, NULL, attnum, &att)))
365 strcpy(name, att->name);
384 NC4_rename_att(
int ncid,
int varid,
const char *name,
const char *newname)
388 NC_HDF5_FILE_INFO_T *h5;
389 NC_VAR_INFO_T *var = NULL;
390 NC_ATT_INFO_T *att, *list;
395 if (!name || !newname)
398 LOG((2,
"nc_rename_att: ncid 0x%x varid %d name %s newname %s",
399 ncid, varid, name, newname));
406 if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
408 assert(h5 && grp && h5);
415 if ((retval = nc4_check_name(newname, norm_newname)))
425 if (varid < 0 || varid >= grp->vars.nelems)
427 var = grp->vars.value[varid];
429 assert(var->varid == varid);
432 for (att = list; att; att = att->l.next)
433 if (!strncmp(att->name, norm_newname,
NC_MAX_NAME))
437 if ((retval = nc4_normalize_name(name, norm_name)))
439 for (att = list; att; att = att->l.next)
447 if (!(h5->flags & NC_INDEF) && strlen(norm_newname) > strlen(att->name) &&
456 if (H5Adelete(grp->hdf_grpid, att->name) < 0)
461 if ((retval = nc4_open_var_grp2(grp, varid, &datasetid)))
463 if (H5Adelete(datasetid, att->name) < 0)
466 att->created = NC_FALSE;
471 if (!(att->name = malloc((strlen(norm_newname) + 1) *
sizeof(
char))))
473 strcpy(att->name, norm_newname);
474 att->dirty = NC_TRUE;
478 var->attr_dirty = NC_TRUE;
497 NC4_del_att(
int ncid,
int varid,
const char *name)
501 NC_HDF5_FILE_INFO_T *h5;
502 NC_ATT_INFO_T *att, *natt;
504 NC_ATT_INFO_T **attlist = NULL;
505 hid_t locid = 0, datasetid = 0;
511 LOG((2,
"nc_del_att: ncid 0x%x varid %d name %s",
515 if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
525 if (!(h5->flags & NC_INDEF))
529 if ((retval = NC4_redef(ncid)))
538 locid = grp->hdf_grpid;
542 if (varid < 0 || varid >= grp->vars.nelems)
544 var = grp->vars.value[varid];
547 assert(var->varid == varid);
549 locid = var->hdf_datasetid;
553 for (att = *attlist; att; att = att->l.next)
554 if (!strcmp(att->name, name))
566 if(H5Adelete(locid, att->name) < 0)
571 for (natt = att->l.next; natt; natt = natt->l.next)
575 if ((retval = nc4_att_list_del(attlist, att)))
579 if (datasetid > 0) H5Dclose(datasetid);
604 NC4_put_att(
int ncid,
int varid,
const char *name,
nc_type file_type,
605 size_t len,
const void *data,
nc_type mem_type)
609 NC_HDF5_FILE_INFO_T *h5;
610 NC_VAR_INFO_T *var = NULL;
611 NC_ATT_INFO_T *att, **attlist = NULL;
613 nc_bool_t new_att = NC_FALSE;
614 int retval =
NC_NOERR, range_error = 0;
620 if ((ret = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
622 assert(nc && grp && h5);
630 if (varid < 0 || varid >= grp->vars.nelems)
632 var = grp->vars.value[varid];
635 assert(var->varid == varid);
640 if((
unsigned long) len > X_INT_MAX)
647 LOG((1,
"%s: ncid 0x%x varid %d name %s file_type %d mem_type %d len %d",
648 __func__, ncid, varid, name, file_type, mem_type, len));
659 if ((retval = nc4_check_name(name, norm_name)))
663 if (nc->ext_ncid == ncid && varid ==
NC_GLOBAL) {
664 const char** reserved = NC_RESERVED_ATT_LIST;
665 for ( ; *reserved; reserved++) {
666 if (strcmp(name, *reserved)==0)
673 const char** reserved = NC_RESERVED_VARATT_LIST;
674 for ( ; *reserved; reserved++) {
675 if (strcmp(name, *reserved) == 0)
681 for (att = *attlist; att; att = att->l.next)
682 if (!strcmp(att->name, norm_name))
685 LOG((1,
"%s: ncid 0x%x varid %d name %s file_type %d mem_type %d len %d",
686 __func__, ncid, varid, name, file_type, mem_type, len));
691 if (!(h5->flags & NC_INDEF))
695 if ((retval = NC4_redef(ncid)))
704 if (!(h5->flags & NC_INDEF) &&
705 len * nc4typelen(file_type) > (
size_t)att->len * nc4typelen(att->nc_typeid))
709 if ((retval = NC4_redef(ncid)))
719 if ((retval = nc4_get_typelen_mem(h5, file_type, 0, &type_size)))
723 if (file_type != mem_type &&
737 LOG((3,
"adding attribute %s to the list...", norm_name));
738 if ((ret = nc4_att_list_add(attlist, &att)))
740 if (!(att->name = strdup(norm_name)))
745 att->dirty = NC_TRUE;
746 att->nc_typeid = file_type;
751 for (i = 0; i < att->len; i++)
753 free(att->stdata[i]);
759 for (i = 0; i < att->len; i++)
767 att->attnum = ((NC_ATT_INFO_T *)att->l.prev)->attnum + 1;
780 if (att->nc_typeid != var->type_info->nc_typeid)
790 if ((retval = nc4_get_typelen_mem(grp->nc4_info, var->type_info->nc_typeid, 0,
798 if (var->type_info->nc_type_class ==
NC_VLEN)
803 else if (var->type_info->nc_type_class ==
NC_STRING)
805 if (*(
char **)var->fill_value)
806 free(*(
char **)var->fill_value);
808 free(var->fill_value);
812 if (var->type_info->nc_type_class ==
NC_VLEN)
813 size =
sizeof(hvl_t);
814 else if (var->type_info->nc_type_class ==
NC_STRING)
815 size =
sizeof(
char *);
820 if (!(var->fill_value = calloc(1, size)))
824 LOG((4,
"Copying fill value into metadata for variable %s", var->name));
825 if (var->type_info->nc_type_class ==
NC_VLEN)
829 fv_vlen->
len = in_vlen->
len;
830 if (!(fv_vlen->p = malloc(size * in_vlen->
len)))
832 memcpy(fv_vlen->p, in_vlen->
p, in_vlen->
len * size);
834 else if (var->type_info->nc_type_class ==
NC_STRING)
838 if (!(*(
char **)(var->fill_value) = malloc(strlen(*(
char **)data) + 1)))
840 strcpy(*(
char **)var->fill_value, *(
char **)data);
843 *(
char **)var->fill_value = NULL;
846 memcpy(var->fill_value, data, type_size);
851 var->fill_val_changed = NC_TRUE;
861 if ((retval = nc4_get_typeclass(h5, file_type, &type_class)))
867 const hvl_t *vldata1;
868 NC_TYPE_INFO_T *type;
872 if ((retval = nc4_find_type(h5, file_type, &type)))
876 if ((retval = nc4_get_typelen_mem(h5, type->u.v.base_nc_typeid, 0, &base_typelen)))
880 if (!(att->vldata = (
nc_vlen_t*)malloc(att->len *
sizeof(hvl_t))))
882 for (i = 0; i < att->len; i++)
884 att->vldata[i].len = vldata1[i].len;
885 if (!(att->vldata[i].p = malloc(base_typelen * att->vldata[i].len)))
887 memcpy(att->vldata[i].p, vldata1[i].p, base_typelen * att->vldata[i].len);
892 LOG((4,
"copying array of NC_STRING"));
893 if (!(att->stdata = malloc(
sizeof(
char *) * att->len))) {
900 if (!new_att && att->data) {
905 for (i = 0; i < att->len; i++)
907 if(NULL != ((
char **)data)[i]) {
908 LOG((5,
"copying string %d of size %d", i, strlen(((
char **)data)[i]) + 1));
909 if (!(att->stdata[i] = strdup(((
char **)data)[i])))
913 att->stdata[i] = ((
char **)data)[i];
921 if (!(att->data = malloc(att->len * type_size)))
926 memcpy(att->data, data, len * type_size);
930 if ((retval = nc4_convert_type(data, att->data, mem_type, file_type,
931 len, &range_error, NULL,
937 att->dirty = NC_TRUE;
938 att->created = NC_FALSE;
942 var->attr_dirty = NC_TRUE;
968 NC4_get_att(
int ncid,
int varid,
const char *name,
void *value,
nc_type memtype)
970 return nc4_get_att(ncid, varid, name, NULL, memtype, NULL, NULL, value);
#define _FillValue
Name of fill value attribute.
#define NC_ENOMEM
Memory allocation (malloc) failure.
#define NC_CHAR
ISO/ASCII character.
#define NC_UBYTE
unsigned 1 byte int
#define NC_CLASSIC_MODEL
Enforce classic model on netCDF-4.
#define NC_ERANGE
Math result not representable.
#define NC_UINT
unsigned 4-byte int
#define NC_EHDFERR
Error at HDF5 layer.
#define NC_OPAQUE
opaque types
#define NC_ELATEFILL
Attempt to define fill value when data already exists.
#define NC_INT64
signed 8-byte int
#define NC_ENOTINDEFINE
Operation not allowed in data mode.
#define NC_DOUBLE
double precision floating point number
int nc_type
The nc_type type is just an int.
#define NC_BYTE
signed 1 byte integer
#define NC_EINDEFINE
Operation not allowed in define mode.
size_t len
Length of VL data (in base type units)
#define NC_ENAMEINUSE
String match to name in use.
#define NC_EATTMETA
Problem with attribute metadata.
#define NC_VLEN
vlen (variable-length) types
#define NC_EBADTYPE
Not a netcdf data type.
#define NC_EBADNAME
Attribute or variable name contains illegal characters.
#define NC_EINVAL
Invalid Argument.
#define NC_INT
signed 4 byte integer
#define NC_ESTRICTNC3
Attempting netcdf-4 operation on strict nc3 netcdf-4 file.
#define NC_MAX_NAME
Maximum for classic library.
void * p
Pointer to VL data.
#define NC_NAT
Not A Type.
EXTERNL int nc_free_vlen(nc_vlen_t *vl)
Free memory in a VLEN object.
#define NC_USHORT
unsigned 2-byte int
#define NC_EBADID
Not a netcdf id.
This is the type of arrays of vlens.
#define NC_SHORT
signed 2 byte integer
#define NC_ENOTVAR
Variable not found.
#define NC_EMAXNAME
NC_MAX_NAME exceeded.
#define NC_EPERM
Write to read only.
#define NC_NOERR
No Error.
#define NC_ENUM
enum types
#define NC_ECHAR
Attempt to convert between text & numbers.
#define NC_COMPOUND
compound types
#define NC_GLOBAL
Attribute id to put/get a global attribute.
#define NC_ENOTATT
Attribute not found.
#define NC_UINT64
unsigned 8-byte int