19 #include "nc4internal.h" 21 #include "nc4dispatch.h" 22 #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;
116 nc4_get_att(
int ncid, NC *nc,
int varid,
const char *name,
nc_type *xtype,
117 nc_type mem_type,
size_t *lenp,
int *attnum,
int is_long,
121 NC_HDF5_FILE_INFO_T *h5;
122 NC_ATT_INFO_T *att = NULL;
125 int need_to_convert = 0;
137 LOG((3,
"%s: ncid 0x%x varid %d name %s attnum %d mem_type %d",
138 __func__, ncid, varid, name, my_attnum, mem_type));
142 if (!(grp = nc4_rec_find_grp(h5->root_grp, (ncid & GRP_ID_MASK))))
147 if (varid < 0 || varid >= grp->vars.nelems)
149 if (grp->vars.value[varid] == NULL)
151 assert(grp->vars.value[varid]->varid == varid);
158 if ((retval = nc4_normalize_name(name, norm_name)))
161 if(nc->ext_ncid == ncid && varid ==
NC_GLOBAL) {
163 for(sp = NC_RESERVED_SPECIAL_LIST;*sp;sp++) {
164 if(strcmp(name,*sp)==0) {
165 return nc4_get_att_special(h5, norm_name, xtype, mem_type, lenp, attnum, is_long, data);
173 if ((retval = nc4_find_grp_att(grp, varid, norm_name, my_attnum, &att))) {
183 mem_type = att->nc_typeid;
189 if (data && att->len &&
198 *xtype = att->nc_typeid;
200 *attnum = att->attnum;
208 if ((retval = nc4_get_typelen_mem(h5, mem_type, is_long, &type_size)))
214 if (data && att->len && mem_type != att->nc_typeid &&
219 if (!(bufr = malloc((
size_t)(att->len * type_size))))
222 if ((retval = nc4_convert_type(att->data, bufr, att->nc_typeid,
223 mem_type, (
size_t)att->len, &range_error,
249 hvl_t *vldest = data;
250 NC_TYPE_INFO_T *type;
253 if ((retval = nc4_find_type(h5, att->nc_typeid, &type)))
257 if ((retval = nc4_get_typelen_mem(h5, type->u.v.base_nc_typeid, 0, &base_typelen)))
260 for (i = 0; i < att->len; i++)
262 vldest[i].len = att->vldata[i].len;
263 if (!(vldest[i].p = malloc(vldest[i].len * base_typelen)))
265 memcpy(vldest[i].p, att->vldata[i].p, vldest[i].len * base_typelen);
268 else if (att->stdata)
270 for (i = 0; i < att->len; i++)
275 if (!(((
char **)data)[i] = strdup(att->stdata[i])))
279 ((
char **)data)[i] = att->stdata[i];
285 if (is_long && att->nc_typeid ==
NC_INT)
290 for (i = 0; i < att->len; i++)
294 memcpy(data, bufr, (
size_t)(att->len * type_size));
324 nc4_put_att(
int ncid, NC *nc,
int varid,
const char *name,
329 NC_HDF5_FILE_INFO_T *h5;
330 NC_VAR_INFO_T *var = NULL;
331 NC_ATT_INFO_T *att, **attlist = NULL;
333 nc_bool_t new_att = NC_FALSE;
334 int retval =
NC_NOERR, range_error = 0;
341 assert(nc && NC4_DATA(nc));
343 LOG((1,
"nc4_put_att: ncid 0x%x varid %d name %s " 344 "file_type %d mem_type %d len %d", ncid, varid,
345 name, file_type, mem_type, len));
353 if (!(grp = nc4_rec_find_grp(h5->root_grp, (ncid & GRP_ID_MASK))))
365 if (varid < 0 || varid >= grp->vars.nelems)
367 var = grp->vars.value[varid];
370 assert(var->varid == varid);
377 if ((retval = nc4_check_name(name, norm_name)))
380 if(nc->ext_ncid == ncid && varid ==
NC_GLOBAL) {
382 for(sp = NC_RESERVED_SPECIAL_LIST;*sp;sp++) {
383 if(strcmp(name,*sp)==0) {
389 for (att = *attlist; att; att = att->l.next)
390 if (!strcmp(att->name, norm_name))
397 LOG((1,
"nc4_put_att: ncid 0x%x varid %d name %s " 398 "file_type %d mem_type %d len %d", ncid, varid,
399 name, file_type, mem_type, len));
404 if (!(h5->flags & NC_INDEF))
408 if ((retval = NC4_redef(ncid)))
417 if (!(h5->flags & NC_INDEF) &&
418 len * nc4typelen(file_type) > (
size_t)att->len * nc4typelen(att->nc_typeid))
422 if ((retval = NC4_redef(ncid)))
432 if ((retval = nc4_get_typelen_mem(h5, file_type, is_long, &type_size)))
436 if (file_type != mem_type &&
450 LOG((3,
"adding attribute %s to the list...", norm_name));
451 if ((res = nc4_att_list_add(attlist, &att)))
453 if (!(att->name = strdup(norm_name)))
458 att->dirty = NC_TRUE;
459 att->nc_typeid = file_type;
464 for (i = 0; i < att->len; i++)
466 free(att->stdata[i]);
472 for (i = 0; i < att->len; i++)
480 att->attnum = ((NC_ATT_INFO_T *)att->l.prev)->attnum + 1;
493 if (att->nc_typeid != var->type_info->nc_typeid)
504 if ((retval = nc4_get_typelen_mem(grp->nc4_info, var->type_info->nc_typeid, 0,
512 if (var->type_info->nc_type_class ==
NC_VLEN)
517 else if (var->type_info->nc_type_class ==
NC_STRING)
519 if (*(
char **)var->fill_value)
520 free(*(
char **)var->fill_value);
522 free(var->fill_value);
526 if (var->type_info->nc_type_class ==
NC_VLEN)
527 size =
sizeof(hvl_t);
528 else if (var->type_info->nc_type_class ==
NC_STRING)
529 size =
sizeof(
char *);
533 if (!(var->fill_value = calloc(1, size)))
537 LOG((4,
"Copying fill value into metadata for variable %s", var->name));
538 if (var->type_info->nc_type_class ==
NC_VLEN)
542 fv_vlen->
len = in_vlen->
len;
543 if (!(fv_vlen->p = malloc(size * in_vlen->
len)))
545 memcpy(fv_vlen->p, in_vlen->
p, in_vlen->
len * size);
547 else if (var->type_info->nc_type_class ==
NC_STRING)
549 if(NULL != (*(
char **)data))
551 if (!(*(
char **)(var->fill_value) = malloc(strlen(*(
char **)data) + 1)))
553 strcpy(*(
char **)var->fill_value, *(
char **)data);
556 *(
char **)var->fill_value = NULL;
559 memcpy(var->fill_value, data, type_size);
564 var->fill_val_changed = NC_TRUE;
574 if ((retval = nc4_get_typeclass(h5, file_type, &type_class)))
580 const hvl_t *vldata1;
581 NC_TYPE_INFO_T *type;
585 if ((retval = nc4_find_type(h5, file_type, &type)))
589 if ((retval = nc4_get_typelen_mem(h5, type->u.v.base_nc_typeid, 0, &base_typelen)))
593 if (!(att->vldata = (
nc_vlen_t*)malloc(att->len *
sizeof(hvl_t))))
595 for (i = 0; i < att->len; i++)
597 att->vldata[i].len = vldata1[i].len;
598 if (!(att->vldata[i].p = malloc(base_typelen * att->vldata[i].len)))
600 memcpy(att->vldata[i].p, vldata1[i].p, base_typelen * att->vldata[i].len);
605 LOG((4,
"copying array of NC_STRING"));
606 if (!(att->stdata = malloc(
sizeof(
char *) * att->len))) {
613 if (!new_att && att->data) {
618 for (i = 0; i < att->len; i++)
620 if(NULL != ((
char **)data)[i]) {
621 LOG((5,
"copying string %d of size %d", i, strlen(((
char **)data)[i]) + 1));
622 if (!(att->stdata[i] = strdup(((
char **)data)[i])))
626 att->stdata[i] = ((
char **)data)[i];
634 if (!(att->data = malloc(att->len * type_size)))
639 memcpy(att->data, data, len * type_size);
643 if ((retval = nc4_convert_type(data, att->data, mem_type, file_type,
644 len, &range_error, NULL,
650 att->dirty = NC_TRUE;
651 att->created = NC_FALSE;
655 var->attr_dirty = NC_TRUE;
682 NC4_inq_att(
int ncid,
int varid,
const char *name,
nc_type *xtypep,
size_t *lenp)
685 NC_HDF5_FILE_INFO_T *h5;
687 LOG((2,
"nc_inq_att: ncid 0x%x varid %d name %s", ncid, varid, name));
690 if (!(nc = nc4_find_nc_file(ncid,NULL)))
698 return nc4_get_att(ncid, nc, varid, name, xtypep,
NC_NAT, lenp, NULL, 0, NULL);
713 NC4_inq_attid(
int ncid,
int varid,
const char *name,
int *attnump)
716 NC_HDF5_FILE_INFO_T *h5;
719 LOG((2,
"nc_inq_attid: ncid 0x%x varid %d name %s", ncid, varid, name));
722 if (!(nc = nc4_find_nc_file(ncid,NULL)))
730 stat = nc4_get_att(ncid, nc, varid, name, NULL,
NC_NAT,
731 NULL, attnump, 0, NULL);
749 NC4_inq_attname(
int ncid,
int varid,
int attnum,
char *name)
753 NC_HDF5_FILE_INFO_T *h5;
756 LOG((2,
"nc_inq_attname: ncid 0x%x varid %d attnum %d",
757 ncid, varid, attnum));
760 if (!(nc = nc4_find_nc_file(ncid,NULL)))
768 if ((retval = nc4_find_nc_att(ncid, varid, NULL, attnum, &att)))
773 strcpy(name, att->name);
792 NC4_rename_att(
int ncid,
int varid,
const char *name,
const char *newname)
796 NC_HDF5_FILE_INFO_T *h5;
797 NC_VAR_INFO_T *var = NULL;
798 NC_ATT_INFO_T *att, *list;
803 if (!name || !newname)
806 LOG((2,
"nc_rename_att: ncid 0x%x varid %d name %s newname %s",
807 ncid, varid, name, newname));
814 if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
824 if ((retval = nc4_check_name(newname, norm_newname)))
834 if (varid < 0 || varid >= grp->vars.nelems)
836 var = grp->vars.value[varid];
838 assert(var->varid == varid);
841 for (att = list; att; att = att->l.next)
842 if (!strncmp(att->name, norm_newname,
NC_MAX_NAME))
846 if ((retval = nc4_normalize_name(name, norm_name)))
848 for (att = list; att; att = att->l.next)
856 if (!(h5->flags & NC_INDEF) && strlen(norm_newname) > strlen(att->name) &&
865 if (H5Adelete(grp->hdf_grpid, att->name) < 0)
870 if ((retval = nc4_open_var_grp2(grp, varid, &datasetid)))
872 if (H5Adelete(datasetid, att->name) < 0)
875 att->created = NC_FALSE;
880 if (!(att->name = malloc((strlen(norm_newname) + 1) *
sizeof(
char))))
882 strcpy(att->name, norm_newname);
883 att->dirty = NC_TRUE;
887 var->attr_dirty = NC_TRUE;
906 NC4_del_att(
int ncid,
int varid,
const char *name)
910 NC_HDF5_FILE_INFO_T *h5;
911 NC_ATT_INFO_T *att, *natt;
913 NC_ATT_INFO_T **attlist = NULL;
914 hid_t locid = 0, datasetid = 0;
920 LOG((2,
"nc_del_att: ncid 0x%x varid %d name %s",
924 if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
934 if (!(h5->flags & NC_INDEF))
938 if ((retval = NC4_redef(ncid)))
947 locid = grp->hdf_grpid;
951 if (varid < 0 || varid >= grp->vars.nelems)
953 var = grp->vars.value[varid];
956 assert(var->varid == varid);
958 locid = var->hdf_datasetid;
962 for (att = *attlist; att; att = att->l.next)
963 if (!strcmp(att->name, name))
975 if(H5Adelete(locid, att->name) < 0)
980 for (natt = att->l.next; natt; natt = natt->l.next)
984 if ((retval = nc4_att_list_del(attlist, att)))
988 if (datasetid > 0) H5Dclose(datasetid);
1010 nc4_put_att_tc(
int ncid,
int varid,
const char *name,
nc_type file_type,
1011 nc_type mem_type,
int mem_type_is_long,
size_t len,
1015 NC_HDF5_FILE_INFO_T *h5;
1019 if((
unsigned long) len > X_INT_MAX)
1023 if (!(nc = nc4_find_nc_file(ncid,NULL)))
1034 if (!(grp = nc4_rec_find_grp(h5->root_grp, (ncid & GRP_ID_MASK))))
1037 if (varid < 0 || varid >= grp->vars.nelems)
1039 if (grp->vars.value[varid] == NULL)
1041 assert(grp->vars.value[varid]->varid == varid);
1047 LOG((3,
"nc4_put_att_tc: ncid 0x%x varid %d name %s file_type %d " 1048 "mem_type %d len %d", ncid, varid, name, file_type, mem_type, len));
1050 if(nc->ext_ncid == ncid && varid ==
NC_GLOBAL) {
1051 const char** reserved = NC_RESERVED_ATT_LIST;
1052 for(;*reserved;reserved++) {
1053 if(strcmp(name,*reserved)==0)
1059 const char** reserved = NC_RESERVED_VARATT_LIST;
1060 for(;*reserved;reserved++) {
1061 if(strcmp(name,*reserved)==0)
1067 return nc4_put_att(ncid, nc, varid, name, file_type, mem_type, len,
1068 mem_type_is_long, op);
1088 nc4_get_att_tc(
int ncid,
int varid,
const char *name,
nc_type mem_type,
1089 int mem_type_is_long,
void *ip)
1092 NC_HDF5_FILE_INFO_T *h5;
1094 LOG((3,
"nc4_get_att_tc: ncid 0x%x varid %d name %s mem_type %d",
1095 ncid, varid, name, mem_type));
1098 if (!(nc = nc4_find_nc_file(ncid,NULL)))
1105 return nc4_get_att(ncid, nc, varid, name, NULL, mem_type,
1106 NULL, NULL, mem_type_is_long, ip);
1125 NC4_put_att(
int ncid,
int varid,
const char *name,
nc_type xtype,
1126 size_t nelems,
const void *value,
nc_type memtype)
1128 return nc4_put_att_tc(ncid, varid, name, xtype, memtype, 0, nelems, value);
1145 NC4_get_att(
int ncid,
int varid,
const char *name,
void *value,
nc_type memtype)
1147 return nc4_get_att_tc(ncid, varid, name, memtype, 0, 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_EBADGRPID
Bad group ID.
#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