19 #include "nc4internal.h" 21 #include "ncdispatch.h" 26 extern size_t nc4_chunk_cache_size;
27 extern size_t nc4_chunk_cache_nelems;
28 extern float nc4_chunk_cache_preemption;
34 int nc_log_level = NC_TURN_OFF_LOGGING;
50 nc4_check_name(
const char *name,
char *norm_name)
64 if ((retval = NC_check_name(name)))
68 if ((retval = nc_utf8_normalize((
const unsigned char *)name,
69 (
unsigned char **)&temp)))
80 strcpy(norm_name, temp);
99 nc4_nc4f_list_add(NC *nc,
const char *path,
int mode)
104 assert(nc && !NC4_DATA(nc) && path);
108 if (!(h5 = calloc(1,
sizeof(NC_FILE_INFO_T))))
110 nc->dispatchdata = h5;
114 h5->cmode = mode | NC_INDEF;
118 h5->next_typeid = NC_FIRSTUSERTYPEID;
121 h5->alldims = nclistnew();
122 h5->alltypes = nclistnew();
123 h5->allgroups = nclistnew();
128 if ((retval = nc4_grp_list_add(h5, NULL, NC_GROUP_NAME, &h5->root_grp)))
147 nc4_find_nc4_grp(
int ncid, NC_GRP_INFO_T **grp)
149 return nc4_find_nc_grp_h5(ncid, NULL, grp, NULL);
168 nc4_find_grp_h5(
int ncid, NC_GRP_INFO_T **grp, NC_FILE_INFO_T **h5)
170 return nc4_find_nc_grp_h5(ncid, NULL, grp, h5);
188 nc4_find_nc_grp_h5(
int ncid, NC **nc, NC_GRP_INFO_T **grp, NC_FILE_INFO_T **h5)
190 NC_GRP_INFO_T *my_grp = NULL;
191 NC_FILE_INFO_T *my_h5 = NULL;
196 if ((retval = NC_check_id(ncid, &my_nc)))
198 my_h5 = my_nc->dispatchdata;
199 assert(my_h5 && my_h5->root_grp);
202 if (!(my_grp = nclistget(my_h5->allgroups, (ncid & GRP_ID_MASK))))
232 nc4_find_grp_h5_var(
int ncid,
int varid, NC_FILE_INFO_T **h5, NC_GRP_INFO_T **grp,
235 NC_FILE_INFO_T *my_h5;
236 NC_GRP_INFO_T *my_grp;
237 NC_VAR_INFO_T *my_var;
241 if ((retval = nc4_find_grp_h5(ncid, &my_grp, &my_h5)))
243 assert(my_grp && my_h5);
246 if (!(my_var = (NC_VAR_INFO_T *)ncindexith(my_grp->vars, varid)))
248 assert(my_var && my_var->hdr.id == varid);
275 nc4_find_dim(NC_GRP_INFO_T *grp,
int dimid, NC_DIM_INFO_T **dim,
276 NC_GRP_INFO_T **dim_grp)
278 assert(grp && grp->nc4_info && dim);
281 if (!((*dim) = nclistget(grp->nc4_info->alldims, dimid)))
286 *dim_grp = (*dim)->container;
302 nc4_find_var(NC_GRP_INFO_T *grp,
const char *name, NC_VAR_INFO_T **var)
304 assert(grp && var && name);
307 *var = (NC_VAR_INFO_T*)ncindexlookup(grp->vars,name);
321 nc4_rec_find_named_type(NC_GRP_INFO_T *start_grp,
char *name)
324 NC_TYPE_INFO_T *type, *res;
330 type = (NC_TYPE_INFO_T*)ncindexlookup(start_grp->type,name);
335 for(i=0;i<ncindexsize(start_grp->children);i++) {
336 g = (NC_GRP_INFO_T*)ncindexith(start_grp->children,i);
337 if(g == NULL)
continue;
338 if ((res = nc4_rec_find_named_type(g, name)))
357 nc4_find_type(
const NC_FILE_INFO_T *h5,
nc_type typeid, NC_TYPE_INFO_T **type)
361 if (
typeid < 0 || !type)
371 if (!(*type = nclistget(h5->alltypes,
typeid)))
393 nc4_find_grp_att(NC_GRP_INFO_T *grp,
int varid,
const char *name,
int attnum,
397 NCindex* attlist = NULL;
400 assert(grp && grp->hdr.name);
401 LOG((4,
"nc4_find_grp_att: grp->name %s varid %d name %s attnum %d",
402 grp->hdr.name, varid, name, attnum));
410 if (grp->atts_not_read)
411 if ((retval = nc4_read_atts(grp, NULL)))
416 var = (NC_VAR_INFO_T*)ncindexith(grp->vars,varid);
420 if (var->atts_not_read)
421 if ((retval = nc4_read_atts(grp, var)))
425 assert(var->hdr.id == varid);
432 NC_ATT_INFO_T *my_att;
434 my_att = (NC_ATT_INFO_T *)ncindexlookup(attlist, name);
436 my_att = (NC_ATT_INFO_T *)ncindexith(attlist, attnum);
465 nc4_find_nc_att(
int ncid,
int varid,
const char *name,
int attnum,
471 LOG((4,
"nc4_find_nc_att: ncid 0x%x varid %d name %s attnum %d",
472 ncid, varid, name, attnum));
475 if ((retval = nc4_find_grp_h5(ncid, &grp, NULL)))
479 return nc4_find_grp_att(grp, varid, name, attnum, att);
491 obj_track(NC_FILE_INFO_T* file, NC_OBJ* obj)
496 case NCDIM: list = file->alldims;
break;
497 case NCTYP: list = file->alltypes;
break;
498 case NCGRP: list = file->allgroups;
break;
503 nclistset(list,obj->id,obj);
521 nc4_var_list_add2(NC_GRP_INFO_T *grp,
const char *name, NC_VAR_INFO_T **var)
523 NC_VAR_INFO_T *new_var;
526 if (!(new_var = calloc(1,
sizeof(NC_VAR_INFO_T))))
528 new_var->hdr.sort = NCVAR;
531 new_var->chunk_cache_size = nc4_chunk_cache_size;
532 new_var->chunk_cache_nelems = nc4_chunk_cache_nelems;
533 new_var->chunk_cache_preemption = nc4_chunk_cache_preemption;
536 new_var->hdr.id = ncindexsize(grp->vars);
537 if (!(new_var->hdr.name = strdup(name)))
539 new_var->hdr.hashkey = NC_hashmapkey(new_var->hdr.name,
540 strlen(new_var->hdr.name));
543 new_var->att = ncindexnew(0);
546 ncindexadd(grp->vars, (NC_OBJ *)new_var);
568 nc4_var_set_ndims(NC_VAR_INFO_T *var,
int ndims)
577 if (!(var->dim = calloc(ndims,
sizeof(NC_DIM_INFO_T *))))
579 if (!(var->dimids = calloc(ndims,
sizeof(
int))))
584 memset(var->dimids, -1, ndims *
sizeof(
int));
605 nc4_var_list_add(NC_GRP_INFO_T* grp,
const char* name,
int ndims,
610 if ((retval = nc4_var_list_add2(grp, name, var)))
612 if ((retval = nc4_var_set_ndims(*var, ndims)))
632 nc4_dim_list_add(NC_GRP_INFO_T *grp,
const char *name,
size_t len,
633 int assignedid, NC_DIM_INFO_T **dim)
635 NC_DIM_INFO_T *new_dim;
640 if (!(new_dim = calloc(1,
sizeof(NC_DIM_INFO_T))))
643 new_dim->hdr.sort = NCDIM;
647 new_dim->hdr.id = assignedid;
649 new_dim->hdr.id = grp->nc4_info->next_dimid++;
652 if (!(new_dim->hdr.name = strdup(name)))
654 new_dim->hdr.hashkey = NC_hashmapkey(new_dim->hdr.name,
655 strlen(new_dim->hdr.name));
660 new_dim->unlimited = NC_TRUE;
663 new_dim->container = grp;
666 ncindexadd(grp->dim, (NC_OBJ *)new_dim);
667 obj_track(grp->nc4_info, (NC_OBJ *)new_dim);
689 nc4_att_list_add(NCindex *list,
const char *name, NC_ATT_INFO_T **att)
691 NC_ATT_INFO_T *new_att;
693 LOG((3,
"%s: name %s ", __func__, name));
695 if (!(new_att = calloc(1,
sizeof(NC_ATT_INFO_T))))
697 new_att->hdr.sort = NCATT;
700 new_att->hdr.id = ncindexsize(list);
701 if (!(new_att->hdr.name = strdup(name)))
705 new_att->hdr.hashkey = NC_hashmapkey(name, strlen(name));
708 ncindexadd(list, (NC_OBJ *)new_att);
732 nc4_grp_list_add(NC_FILE_INFO_T *h5, NC_GRP_INFO_T *parent,
char *name,
735 NC_GRP_INFO_T *new_grp;
739 LOG((3,
"%s: name %s ", __func__, name));
742 if (!(new_grp = calloc(1,
sizeof(NC_GRP_INFO_T))))
746 new_grp->hdr.sort = NCGRP;
747 new_grp->nc4_info = h5;
748 new_grp->parent = parent;
751 new_grp->hdr.id = h5->next_nc_grpid++;
752 assert(parent || !new_grp->hdr.id);
755 if (!(new_grp->hdr.name = strdup(name)))
760 new_grp->hdr.hashkey = NC_hashmapkey(new_grp->hdr.name,
761 strlen(new_grp->hdr.name));
764 new_grp->children = ncindexnew(0);
765 new_grp->dim = ncindexnew(0);
766 new_grp->att = ncindexnew(0);
767 new_grp->type = ncindexnew(0);
768 new_grp->vars = ncindexnew(0);
772 ncindexadd(parent->children, (NC_OBJ *)new_grp);
773 obj_track(h5, (NC_OBJ *)new_grp);
796 nc4_check_dup_name(NC_GRP_INFO_T *grp,
char *name)
798 NC_TYPE_INFO_T *type;
803 type = (NC_TYPE_INFO_T*)ncindexlookup(grp->type,name);
808 g = (NC_GRP_INFO_T*)ncindexlookup(grp->children,name);
813 var = (NC_VAR_INFO_T*)ncindexlookup(grp->vars,name);
835 nc4_type_new(NC_GRP_INFO_T *grp,
size_t size,
const char *name,
int assignedid,
836 NC_TYPE_INFO_T **type)
838 NC_TYPE_INFO_T *new_type;
844 if (!(new_type = calloc(1,
sizeof(NC_TYPE_INFO_T))))
846 new_type->hdr.sort = NCTYP;
849 new_type->hdr.id = assignedid;
850 new_type->size = size;
851 if (!(new_type->hdr.name = strdup(name))) {
856 new_type->hdr.hashkey = NC_hashmapkey(name, strlen(name));
878 nc4_type_list_add(NC_GRP_INFO_T *grp,
size_t size,
const char *name,
879 NC_TYPE_INFO_T **type)
881 NC_TYPE_INFO_T *new_type;
888 if ((retval = nc4_type_new(grp, size, name, grp->nc4_info->next_typeid,
891 grp->nc4_info->next_typeid++;
897 ncindexadd(grp->type, (NC_OBJ *)new_type);
898 obj_track(grp->nc4_info,(NC_OBJ*)new_type);
922 nc4_field_list_add(NC_TYPE_INFO_T *parent,
const char *name,
923 size_t offset, hid_t field_hdf_typeid, hid_t native_typeid,
924 nc_type xtype,
int ndims,
const int *dim_sizesp)
926 NC_FIELD_INFO_T *field;
933 if (!(field = calloc(1,
sizeof(NC_FIELD_INFO_T))))
935 field->hdr.sort = NCFLD;
938 if (!(field->hdr.name = strdup(name)))
943 field->hdr.hashkey = NC_hashmapkey(field->hdr.name,strlen(field->hdr.name));
944 field->hdf_typeid = field_hdf_typeid;
945 field->native_hdf_typeid = native_typeid;
946 field->nc_typeid = xtype;
947 field->offset = offset;
948 field->ndims = ndims;
952 if (!(field->dim_size = malloc(ndims *
sizeof(
int))))
954 free(field->hdr.name);
958 for (i = 0; i < ndims; i++)
959 field->dim_size[i] = dim_sizesp[i];
963 field->hdr.id = nclistlength(parent->u.c.field);
964 nclistpush(parent->u.c.field,field);
982 nc4_enum_member_add(NC_TYPE_INFO_T *parent,
size_t size,
983 const char *name,
const void *value)
985 NC_ENUM_MEMBER_INFO_T *member;
988 assert(name && size > 0 && value);
989 LOG((4,
"%s: size %d name %s", __func__, size, name));
992 if (!(member = calloc(1,
sizeof(NC_ENUM_MEMBER_INFO_T))))
994 if (!(member->value = malloc(size))) {
998 if (!(member->name = strdup(name))) {
1005 memcpy(member->value, value, size);
1008 nclistpush(parent->u.e.enum_member,member);
1022 field_free(NC_FIELD_INFO_T *field)
1025 if (field->hdr.name)
1026 free(field->hdr.name);
1027 if (field->dim_size)
1028 free(field->dim_size);
1044 nc4_type_free(NC_TYPE_INFO_T *type)
1048 assert(type && type->rc && type->hdr.name);
1056 LOG((4,
"%s: deleting type %s", __func__, type->hdr.name));
1059 free(type->hdr.name);
1062 switch (type->nc_type_class)
1066 NC_FIELD_INFO_T *field;
1070 for(i=0;i<nclistlength(type->u.c.field);i++) {
1071 field = nclistget(type->u.c.field,i);
1074 nclistfree(type->u.c.field);
1080 NC_ENUM_MEMBER_INFO_T *enum_member;
1083 for(i=0;i<nclistlength(type->u.e.enum_member);i++) {
1084 enum_member = nclistget(type->u.e.enum_member,i);
1085 free(enum_member->value);
1086 free(enum_member->name);
1089 nclistfree(type->u.e.enum_member);
1113 att_free(NC_ATT_INFO_T *att)
1118 LOG((3,
"%s: name %s ", __func__, att->hdr.name));
1127 free(att->hdr.name);
1137 for (i = 0; i < att->len; i++)
1139 free(att->stdata[i]);
1146 for (i = 0; i < att->len; i++)
1153 if (att->format_att_info)
1154 free(att->format_att_info);
1170 var_free(NC_VAR_INFO_T *var)
1176 LOG((4,
"%s: deleting var %s", __func__, var->hdr.name));
1179 for (i = 0; i < ncindexsize(var->att); i++)
1180 if ((retval = att_free((NC_ATT_INFO_T *)ncindexith(var->att, i))))
1182 ncindexfree(var->att);
1186 if (var->chunksizes)
1187 free(var->chunksizes);
1190 free(var->hdf5_name);
1193 free(var->hdr.name);
1203 if (var->fill_value)
1205 if (var->hdf_datasetid)
1209 if (var->type_info->nc_type_class ==
NC_VLEN)
1211 else if (var->type_info->nc_type_class ==
NC_STRING && *(
char **)var->fill_value)
1212 free(*(
char **)var->fill_value);
1215 free(var->fill_value);
1220 if ((retval = nc4_type_free(var->type_info)))
1224 if (var->dimscale_hdf5_objids)
1225 free(var->dimscale_hdf5_objids);
1228 if (var->dimscale_attached)
1229 free(var->dimscale_attached);
1251 nc4_var_list_del(NC_GRP_INFO_T* grp, NC_VAR_INFO_T *var)
1260 i = ncindexfind(grp->vars,(NC_OBJ*)var);
1262 ncindexidel(grp->vars, i);
1264 return var_free(var);
1276 dim_free(NC_DIM_INFO_T *dim)
1279 LOG((4,
"%s: deleting dim %s", __func__, dim->hdr.name));
1283 free(dim->hdr.name);
1286 if (dim->format_dim_info)
1287 free(dim->format_dim_info);
1303 nc4_dim_list_del(NC_GRP_INFO_T* grp, NC_DIM_INFO_T *dim)
1306 int pos = ncindexfind(grp->dim,(NC_OBJ*)dim);
1308 ncindexidel(grp->dim,pos);
1310 return dim_free(dim);
1323 nc4_rec_grp_del(NC_GRP_INFO_T *grp)
1329 LOG((3,
"%s: grp->name %s", __func__, grp->hdr.name));
1333 for (i = 0; i < ncindexsize(grp->children); i++)
1334 if ((retval = nc4_rec_grp_del((NC_GRP_INFO_T *)ncindexith(grp->children,
1337 ncindexfree(grp->children);
1340 for (i = 0; i < ncindexsize(grp->att); i++)
1341 if ((retval = att_free((NC_ATT_INFO_T *)ncindexith(grp->att, i))))
1343 ncindexfree(grp->att);
1346 for (i = 0; i < ncindexsize(grp->vars); i++)
1347 if ((retval = var_free((NC_VAR_INFO_T *)ncindexith(grp->vars, i))))
1349 ncindexfree(grp->vars);
1352 for (i = 0; i < ncindexsize(grp->dim); i++)
1353 if ((retval = dim_free((NC_DIM_INFO_T *)ncindexith(grp->dim, i))))
1355 ncindexfree(grp->dim);
1358 for (i = 0; i < ncindexsize(grp->type); i++)
1359 if ((retval = nc4_type_free((NC_TYPE_INFO_T *)ncindexith(grp->type, i))))
1361 ncindexfree(grp->type);
1364 free(grp->hdr.name);
1367 if (grp->format_grp_info)
1368 free(grp->format_grp_info);
1387 nc4_att_list_del(NCindex *list, NC_ATT_INFO_T *att)
1389 assert(att && list);
1390 ncindexidel(list, ((NC_OBJ *)att)->
id);
1391 return att_free(att);
1408 nc4_normalize_name(
const char *name,
char *norm_name)
1411 int stat = nc_utf8_normalize((
const unsigned char *)name,(
unsigned char **)&temp_name);
1419 strcpy(norm_name, temp_name);
1424 #ifdef ENABLE_SET_LOG_LEVEL 1441 nc_set_log_level(
int new_level)
1444 if(!nc4_hdf5_initialized)
1445 nc4_hdf5_initialize();
1448 nc_log_level = new_level;
1449 LOG((4,
"log_level changed to %d", nc_log_level));
1456 #define MAX_NESTS 10 1467 rec_print_metadata(NC_GRP_INFO_T *grp,
int tab_count)
1473 NC_TYPE_INFO_T *type;
1474 NC_FIELD_INFO_T *field;
1475 char tabs[MAX_NESTS+1] =
"";
1476 char *dims_string = NULL;
1477 char temp_string[10];
1478 int t, retval, d, i;
1481 for (t = 0; t < tab_count && t < MAX_NESTS; t++)
1485 LOG((2,
"%s GROUP - %s nc_grpid: %d nvars: %d natts: %d",
1486 tabs, grp->hdr.name, grp->hdr.id, ncindexsize(grp->vars), ncindexsize(grp->att)));
1488 for(i=0;i<ncindexsize(grp->att);i++) {
1489 att = (NC_ATT_INFO_T*)ncindexith(grp->att,i);
1490 if(att == NULL)
continue;
1491 LOG((2,
"%s GROUP ATTRIBUTE - attnum: %d name: %s type: %d len: %d",
1492 tabs, att->hdr.id, att->hdr.name, att->nc_typeid, att->len));
1495 for(i=0;i<ncindexsize(grp->dim);i++) {
1496 dim = (NC_DIM_INFO_T*)ncindexith(grp->dim,i);
1497 if(dim == NULL)
continue;
1498 LOG((2,
"%s DIMENSION - dimid: %d name: %s len: %d unlimited: %d",
1499 tabs, dim->hdr.id, dim->hdr.name, dim->len, dim->unlimited));
1502 for(i=0;i<ncindexsize(grp->vars);i++)
1505 var = (NC_VAR_INFO_T*)ncindexith(grp->vars,i);
1506 if (var == NULL)
continue;
1509 dims_string = (
char*)malloc(
sizeof(
char)*(var->ndims*4));
1510 strcpy(dims_string,
"");
1511 for (d = 0; d < var->ndims; d++)
1513 sprintf(temp_string,
" %d", var->dimids[d]);
1514 strcat(dims_string, temp_string);
1517 LOG((2,
"%s VARIABLE - varid: %d name: %s ndims: %d dimscale: %d dimids:%s",
1518 tabs, var->hdr.id, var->hdr.name, var->ndims, (
int)var->dimscale,
1519 (dims_string ? dims_string :
" -")));
1520 for(j=0;j<ncindexsize(var->att);j++) {
1521 att = (NC_ATT_INFO_T*)ncindexith(var->att,j);
1522 if(att == NULL)
continue;
1523 LOG((2,
"%s VAR ATTRIBUTE - attnum: %d name: %s type: %d len: %d",
1524 tabs, att->hdr.id, att->hdr.name, att->nc_typeid, att->len));
1533 for(i=0;i<ncindexsize(grp->type);i++)
1535 if((type = (NC_TYPE_INFO_T*)ncindexith(grp->type,i)) == NULL)
continue;
1536 LOG((2,
"%s TYPE - nc_typeid: %d hdf_typeid: 0x%x committed: %d " 1537 "name: %s num_fields: %d", tabs, type->hdr.id,
1538 type->hdf_typeid, type->size, (
int)type->committed, type->hdr.name));
1543 LOG((3,
"compound type"));
1544 for(j=0;j<nclistlength(type->u.c.field);j++) {
1545 field = (NC_FIELD_INFO_T*)nclistget(type->u.c.field,j);
1546 LOG((4,
"field %s offset %d nctype %d ndims %d", field->hdr.name,
1547 field->offset, field->nc_typeid, field->ndims));
1550 else if (type->nc_type_class ==
NC_VLEN)
1552 LOG((3,
"VLEN type"));
1553 LOG((4,
"base_nc_type: %d", type->u.v.base_nc_typeid));
1555 else if (type->nc_type_class ==
NC_OPAQUE)
1556 LOG((3,
"Opaque type"));
1557 else if (type->nc_type_class ==
NC_ENUM)
1559 LOG((3,
"Enum type"));
1560 LOG((4,
"base_nc_type: %d", type->u.e.base_nc_typeid));
1564 LOG((0,
"Unknown class: %d", type->nc_type_class));
1570 for(i=0;i<ncindexsize(grp->children);i++)
1572 if((g = (NC_GRP_INFO_T*)ncindexith(grp->children,i)) == NULL)
continue;
1573 if ((retval = rec_print_metadata(g, tab_count + 1)))
1590 log_metadata_nc(NC_FILE_INFO_T *h5)
1592 LOG((2,
"*** NetCDF-4 Internal Metadata: int_ncid 0x%x ext_ncid 0x%x",
1593 h5->root_grp->nc4_info->controller->int_ncid,
1594 h5->root_grp->nc4_info->controller->ext_ncid));
1597 LOG((2,
"This is a netCDF-3 file."));
1600 LOG((2,
"FILE - path: %s cmode: 0x%x parallel: %d redef: %d " 1601 "fill_mode: %d no_write: %d next_nc_grpid: %d", h5->root_grp->nc4_info->controller->path,
1602 h5->cmode, (
int)h5->parallel, (
int)h5->redef, h5->fill_mode, (
int)h5->no_write,
1603 h5->next_nc_grpid));
1604 if(nc_log_level >= 2)
1605 return rec_print_metadata(h5->root_grp, 0);
1623 NC4_show_metadata(
int ncid)
1628 int old_log_level = nc_log_level;
1631 if ((retval = nc4_find_grp_h5(ncid, NULL, &h5)))
1636 retval = log_metadata_nc(h5);
1637 nc_log_level = old_log_level;
#define NC_ENOMEM
Memory allocation (malloc) failure.
#define NC_OPAQUE
opaque types
int nc_type
The nc_type type is just an int.
#define NC_EBADDIM
Invalid dimension id or name.
#define NC_ENAMEINUSE
String match to name in use.
#define NC_VLEN
vlen (variable-length) types
#define NC_EBADTYPE
Not a netcdf data type.
#define NC_EINVAL
Invalid Argument.
#define NC_MAX_NAME
Maximum for classic library.
#define NC_EBADTYPID
Bad type ID.
EXTERNL int nc_free_vlen(nc_vlen_t *vl)
Free memory in a VLEN object.
#define NC_EBADID
Not a netcdf id.
#define NC_UNLIMITED
Size argument to nc_def_dim() for an unlimited dimension.
This is the type of arrays of vlens.
#define NC_ENOTVAR
Variable not found.
#define NC_EMAXNAME
NC_MAX_NAME exceeded.
#define NC_NOERR
No Error.
#define NC_ENUM
enum types
#define NC_COMPOUND
compound types
#define NC_GLOBAL
Attribute id to put/get a global attribute.
#define NC_ENOTATT
Attribute not found.