Handle vlen strings for NX_class attributes

This commit is contained in:
Charles Mita
2018-03-28 11:44:22 +01:00
parent db16131db4
commit 5f57e5329a
+48 -35
View File
@@ -500,9 +500,9 @@ herr_t det_visit_callback(hid_t root_id, const char *name, const H5O_info_t *inf
/* check for an "NX_class" attribute */
{
char* buffer = NULL;
hid_t a_id, t_id;
H5A_info_t a_info;
int str_size = 0;
void* buffer = NULL;
hid_t a_id, t_id, mt_id;
if (H5Aexists(g_id, "NX_class") <= 0) {
/* not an error - just close group and allow continuation */
retval = 0;
@@ -516,53 +516,66 @@ herr_t det_visit_callback(hid_t root_id, const char *name, const H5O_info_t *inf
name);
ERROR_JUMP(-1, close_group, message);
}
if (H5Aget_info(a_id, &a_info) < 0) {
char message[256];
sprintf(message,
"H5OVisit callback: Error getting NX_class attribute info for %.128s",
name);
ERROR_JUMP(-1, close_attr, message);
t_id = H5Aget_type(a_id);
if (t_id < 0) {
ERROR_JUMP(-1, close_attr, "Error getting datatype");
}
/* TODO: handle vlen string */
t_id = H5Tcreate(H5T_STRING, a_info.data_size);
if (t_id <= 0) {
char message[256];
sprintf(message,
"H5OVisit callback: Error creating string datatype of length %d on group %.128s",
(int) a_info.data_size,
name);
ERROR_JUMP(-1, close_attr, message);
if (H5Tis_variable_str(t_id) > 0) {
str_size = -1;
buffer = malloc(sizeof(char*));
} else {
str_size = H5Tget_size(t_id);
buffer = malloc(str_size + 1);
}
buffer = malloc(a_info.data_size + 1);
if (buffer == NULL) {
char message[256];
sprintf(message,
"H5OVisit callback: Error allocating string buffer with size %d on group %.128s",
(int) a_info.data_size + 1,
name);
ERROR_JUMP(-1, close_type, message);
if (!buffer) {
ERROR_JUMP(-1, close_type, "Error allocating string buffer");
}
if (H5Aread(a_id, t_id, buffer) < 0) {
mt_id = H5Tcopy(H5T_C_S1);
if (mt_id < 0) {
ERROR_JUMP(-1, free_buffer, "Error creating HDF5 String datatype");
}
if (H5Tset_size(mt_id, str_size == -1 ? H5T_VARIABLE : str_size) < 0) {
char message[64];
sprintf(message, "Error setting string datatype to size %d", str_size);
ERROR_JUMP(-1, close_mtype, message);
}
if (H5Aread(a_id, mt_id, buffer) < 0) {
char message[256];
sprintf(message,
"H5OVisit callback: Error reading NX_class attribute on group %.128s",
name);
ERROR_JUMP(-1, free_buffer, message);
ERROR_JUMP(-1, close_mtype, message);
}
/* at least one file has been seen where the NX_class attribute was not null terminated
* and extraneous bytes where being read by strcmp - set the end byte to null
*/
buffer[a_info.data_size] = '\0';
if (strcmp("NXdata", buffer) == 0) {
hid_t out_id = H5Gopen(root_id, name, H5P_DEFAULT);
output_data->nxdata = out_id;
} else if (strcmp("NXdetector", buffer) == 0) {
hid_t out_id = H5Gopen(root_id, name, H5P_DEFAULT);
output_data->nxdetector = out_id;
if (str_size > 0) ((char*) buffer)[str_size] = '\0';
/* test for NXdata or NXdetector */
{
char *nxclass = str_size > 0 ? (char*) buffer : *((char**) buffer);
if (strcmp("NXdata", nxclass) == 0) {
hid_t out_id = H5Gopen(root_id, name, H5P_DEFAULT);
output_data->nxdata = out_id;
} else if (strcmp("NXdetector", nxclass) == 0) {
hid_t out_id = H5Gopen(root_id, name, H5P_DEFAULT);
output_data->nxdetector = out_id;
}
}
if (str_size == -1) {
hsize_t dims[1] = {1};
hid_t s_id = H5Screate_simple(1, dims, NULL);
H5Sselect_all(s_id);
H5Dvlen_reclaim(mt_id, s_id, H5P_DEFAULT, buffer);
H5Sclose(s_id);
}
close_mtype:
H5Tclose(mt_id);
free_buffer:
free(buffer);
close_type: