Changed from discovering attributes and then looping through them to using H5Aiterate2 instead.

This commit is contained in:
M. Scot Breitenfeld 2016-06-14 09:33:52 -05:00
parent c95bfe394d
commit 4f43988e84

View File

@ -42,6 +42,73 @@ extern int num_spaces;
#define MIN_DEFLATE_LEVEL 0
#define MAX_DEFLATE_LEVEL 9
static int
read_hdf5_att(NC_GRP_INFO_T *grp, hid_t attid, NC_ATT_INFO_T *att);
/* Custom iteration callback data */
typedef struct {
NC_GRP_INFO_T *grp;
NC_VAR_INFO_T *var;
} att_iter_info;
static herr_t
att_read_var_callbk(hid_t loc_id, const char *att_name, const H5A_info_t *ainfo, void *att_data)
{
hid_t attid = 0;
int retval = NC_NOERR;
NC_ATT_INFO_T *att;
att_iter_info *att_info = (att_iter_info *)att_data;
const char** reserved;
/* Should we ignore this attribute? */
for(reserved=NC_RESERVED_VARATT_LIST;*reserved;reserved++) {
if (strcmp(att_name, *reserved)==0) break;
}
if(*reserved == NULL) {
/* Open the att by name. */
if ((attid = H5Aopen(loc_id, att_name, H5P_DEFAULT)) < 0)
BAIL(NC_EATTMETA);
LOG((4, "%s:: att_name %s", __func__, att_name));
/* Add to the end of the list of atts for this var. */
if ((retval = nc4_att_list_add(&att_info->var->att, &att)))
BAIL(retval);
/* Fill in the information we know. */
att->attnum = att_info->var->natts++;
if (!(att->name = strdup(att_name)))
BAIL(NC_ENOMEM);
/* Read the rest of the info about the att,
* including its values. */
if ((retval = read_hdf5_att(att_info->grp, attid, att)))
{
if (NC_EBADTYPID == retval)
{
if ((retval = nc4_att_list_del(&att_info->var->att, att)))
BAIL(retval);
}
else
BAIL(retval);
}
att->created = NC_TRUE;
if (attid > 0 && H5Aclose(attid) < 0)
BAIL2(NC_EHDFERR);
} /* endif not HDF5 att */
return NC_NOERR;
exit:
if (attid > 0 && H5Aclose(attid) < 0)
BAIL2(NC_EHDFERR);
return retval;
}
/* Define the illegal mode flags */
static const int ILLEGAL_OPEN_FLAGS = (NC_MMAP|NC_64BIT_OFFSET);
@ -1519,7 +1586,7 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
const char** reserved;
NC_ATT_INFO_T *att;
hid_t attid = 0;
att_iter_info att_info; /* Custom iteration information */
char att_name[NC_MAX_HDF5_NAME + 1];
#define CD_NELEMS_ZLIB 1
@ -1767,54 +1834,12 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
/* Now read all the attributes of this variable, ignoring the
ones that hold HDF5 dimension scale information. */
if ((natts = H5Aget_num_attrs(var->hdf_datasetid)) < 0)
BAIL(NC_EATTMETA);
for (a = 0; a < natts; a++)
{
/* Close the attribute and try to move on with our
* lives. Like bits through the network port, so
* flows the Days of Our Lives! */
if (attid && H5Aclose(attid) < 0)
BAIL(NC_EHDFERR);
/* Open the att and get its name. */
if ((attid = H5Aopen_idx(var->hdf_datasetid, (unsigned int)a)) < 0)
BAIL(NC_EATTMETA);
if (H5Aget_name(attid, NC_MAX_HDF5_NAME, att_name) < 0)
BAIL(NC_EATTMETA);
LOG((4, "%s:: a %d att_name %s", __func__, a, att_name));
att_info.var = var;
att_info.grp = grp;
/* Should we ignore this attribute? */
for(reserved=NC_RESERVED_VARATT_LIST;*reserved;reserved++) {
if (strcmp(att_name, *reserved)==0) break;
}
if(*reserved == NULL) {
/* Add to the end of the list of atts for this var. */
if ((retval = nc4_att_list_add(&var->att, &att)))
BAIL(retval);
/* Fill in the information we know. */
att->attnum = var->natts++;
if (!(att->name = strdup(att_name)))
BAIL(NC_ENOMEM);
/* Read the rest of the info about the att,
* including its values. */
if ((retval = read_hdf5_att(grp, attid, att)))
{
if (NC_EBADTYPID == retval)
{
if ((retval = nc4_att_list_del(&var->att, att)))
BAIL(retval);
continue;
}
else
BAIL(retval);
}
att->created = NC_TRUE;
} /* endif not HDF5 att */
} /* next attribute */
if ((H5Aiterate2(var->hdf_datasetid, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, att_read_var_callbk, &att_info)) < 0)
BAIL(NC_EATTMETA);
/* Is this a deflated variable with a chunksize greater than the
* current cache size? */
@ -1839,8 +1864,6 @@ exit:
#ifdef EXTRA_TESTS
num_plists--;
#endif
if (attid > 0 && H5Aclose(attid) < 0)
BAIL2(NC_EHDFERR);
return retval;
}