From 787c2c7e870c93bc717d6d28f9d395891a2a250b Mon Sep 17 00:00:00 2001 From: Matthew Larson Date: Tue, 21 Nov 2023 09:27:02 -0600 Subject: [PATCH] Generalize subset handling functions --- src/rest_vol.h | 15 ++- src/rest_vol_dataset.c | 38 +++--- src/rest_vol_datatype.c | 276 +++++++++++++++++++++------------------- 3 files changed, 181 insertions(+), 148 deletions(-) diff --git a/src/rest_vol.h b/src/rest_vol.h index 807a4c2a..f8422836 100644 --- a/src/rest_vol.h +++ b/src/rest_vol.h @@ -428,12 +428,21 @@ typedef struct RV_type_info { rv_hash_table_t *table; } RV_type_info; +/* Copy of H5T_subset_t struct defn for compound subsetting */ +typedef enum { + H5T_SUBSET_BADVALUE = -1, /* Invalid value */ + H5T_SUBSET_FALSE = 0, /* Source and destination aren't subset of each other */ + H5T_SUBSET_SRC, /* Source is the subset of dest and no conversion is needed */ + H5T_SUBSET_DST, /* Dest is the subset of source and no conversion is needed */ + H5T_SUBSET_CAP /* Must be the last value */ +} RV_subset_t; + /* Information about members of a compound type for subsetting */ typedef struct RV_compound_info_t { int nmembers; /* Number of offset/length pairs used */ int nalloc; /* Number of offset/length pairs allocated */ - size_t *mem_offsets; - size_t *file_offsets; + size_t *src_offsets; + size_t *dst_offsets; size_t *lengths; } RV_compound_info_t; @@ -771,7 +780,7 @@ herr_t RV_convert_datatype_to_JSON(hid_t type_id, char **type_body, size_t *type server_api_version server_version); /* Determine if a read from file to mem dtype is a compound subset read */ -htri_t RV_is_compound_subset_read(hid_t mem_type_id, hid_t file_type_id); +herr_t RV_get_compound_subset_info(hid_t src_type_id, hid_t dst_type_id, RV_subset_t *subset_info); /* Helper to get information about fields that are unused due to compound subsetting */ herr_t RV_get_unused_compound_fields(hid_t mem_type_id, hid_t file_type_id, diff --git a/src/rest_vol_dataset.c b/src/rest_vol_dataset.c index be7914c3..198d6553 100644 --- a/src/rest_vol_dataset.c +++ b/src/rest_vol_dataset.c @@ -1201,6 +1201,8 @@ RV_dataset_write(size_t count, void *dset[], hid_t mem_type_id[], hid_t _mem_spa #endif } /* end if */ + // TODO - Compound subset handling on write + transfer_info[i].u.write_info.uinfo.buffer = is_transfer_binary ? buf_to_write : transfer_info[i].u.write_info.write_body; transfer_info[i].u.write_info.uinfo.buffer_size = write_body_len; @@ -4530,7 +4532,7 @@ rv_dataset_read_cb(hid_t mem_type_id, hid_t mem_space_id, hid_t file_type_id, hi htri_t is_variable_str; H5T_class_t mem_dtype_class = H5T_NO_CLASS; hssize_t file_select_npoints; - htri_t is_compound_subset_read = false; + RV_subset_t subset_info = H5T_SUBSET_BADVALUE; void *obj_ref_buf = NULL; @@ -4548,9 +4550,9 @@ rv_dataset_read_cb(hid_t mem_type_id, hid_t mem_space_id, hid_t file_type_id, hi int file_nmembs = 0; RV_compound_info_t compound_info; - compound_info.mem_offsets = NULL; - compound_info.file_offsets = NULL; - compound_info.lengths = NULL; + compound_info.src_offsets = NULL; + compound_info.dst_offsets = NULL; + compound_info.lengths = NULL; void *subset_buffer = NULL; @@ -4600,10 +4602,16 @@ rv_dataset_read_cb(hid_t mem_type_id, hid_t mem_space_id, hid_t file_type_id, hi resp_info.buffer = json_buf; } - if ((is_compound_subset_read = RV_is_compound_subset_read(mem_type_id, file_type_id)) < 0) + /* On a read, file dtype is src and mem dtype is dst */ + if (RV_get_compound_subset_info(file_type_id, mem_type_id, &subset_info) < 0) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "can't check if types are compound subsets"); - if (is_compound_subset_read > 0) { + if (subset_info < 0) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, + "error while checking if types are compound subsets"); + + // TODO - Move this to a helper function + if (subset_info > 0) { /* Copy unselected fields from user buffer to resp info buffer to avoid overwriting fields that * weren't selected */ @@ -4615,10 +4623,10 @@ rv_dataset_read_cb(hid_t mem_type_id, hid_t mem_space_id, hid_t file_type_id, hi if ((compound_info.lengths = RV_calloc(sizeof(size_t) * (size_t)file_nmembs)) == NULL) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "can't allocate memory for compound info"); - if ((compound_info.mem_offsets = RV_calloc(sizeof(size_t) * (size_t)file_nmembs)) == NULL) + if ((compound_info.src_offsets = RV_calloc(sizeof(size_t) * (size_t)file_nmembs)) == NULL) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "can't allocate memory for compound info"); - if ((compound_info.file_offsets = RV_calloc(sizeof(size_t) * (size_t)file_nmembs)) == NULL) + if ((compound_info.dst_offsets = RV_calloc(sizeof(size_t) * (size_t)file_nmembs)) == NULL) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "can't allocate memory for compound info"); compound_info.nmembers = 0; @@ -4640,8 +4648,8 @@ rv_dataset_read_cb(hid_t mem_type_id, hid_t mem_space_id, hid_t file_type_id, hi for (size_t i = 0; i < file_select_npoints; i++) { /* Copy unused field information from subset buffer to response buffer before scattering */ for (size_t j = 0; j < compound_info.nmembers; j++) { - src = (char *)subset_buffer + (i * mem_type_size) + compound_info.mem_offsets[j]; - dst = (char *)resp_info.buffer + (i * file_type_size) + compound_info.file_offsets[j]; + src = (char *)subset_buffer + (i * mem_type_size) + compound_info.src_offsets[j]; + dst = (char *)resp_info.buffer + (i * file_type_size) + compound_info.dst_offsets[j]; memcpy(dst, src, compound_info.lengths[j]); } @@ -4654,7 +4662,7 @@ rv_dataset_read_cb(hid_t mem_type_id, hid_t mem_space_id, hid_t file_type_id, hi if ((needs_tconv = RV_need_tconv(file_type_id, mem_type_id)) < 0) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "unable to check if datatypes need conversion"); - if (!is_compound_subset_read && needs_tconv) { + if (!subset_info && needs_tconv) { #ifdef RV_CONNECTOR_DEBUG printf("-> Beginning type conversion\n"); #endif @@ -4716,11 +4724,11 @@ rv_dataset_read_cb(hid_t mem_type_id, hid_t mem_space_id, hid_t file_type_id, hi if (compound_info.lengths) RV_free(compound_info.lengths); - if (compound_info.mem_offsets) - RV_free(compound_info.mem_offsets); + if (compound_info.src_offsets) + RV_free(compound_info.src_offsets); - if (compound_info.file_offsets) - RV_free(compound_info.file_offsets); + if (compound_info.dst_offsets) + RV_free(compound_info.dst_offsets); if (subset_buffer) RV_free(subset_buffer); diff --git a/src/rest_vol_datatype.c b/src/rest_vol_datatype.c index 9a39b6b1..7a64a152 100644 --- a/src/rest_vol_datatype.c +++ b/src/rest_vol_datatype.c @@ -2639,241 +2639,257 @@ RV_tconv_init(hid_t src_type_id, size_t *src_type_size, hid_t dst_type_id, size_ return ret_value; } /* end RV_tconv_init() */ -/* Determine if a read from file to mem dtype is a compound subset read */ -htri_t -RV_is_compound_subset_read(hid_t mem_type_id, hid_t file_type_id) +/* Determine if a read from src to dst dtype is a compound subset read */ +herr_t +RV_get_compound_subset_info(hid_t src_type_id, hid_t dst_type_id, RV_subset_t *subset) { - htri_t ret_value = false; - H5T_class_t file_type_class = H5T_NO_CLASS, mem_type_class = H5T_NO_CLASS; - hid_t mem_member_type = H5I_INVALID_HID, file_member_type = H5I_INVALID_HID; - int file_nmembs = 0, mem_nmembs = 0; - char *mem_member_name = NULL, *file_member_name = NULL; + herr_t ret_value = SUCCEED; + H5T_class_t dst_type_class = H5T_NO_CLASS, src_type_class = H5T_NO_CLASS; + hid_t src_member_type = H5I_INVALID_HID, dst_member_type = H5I_INVALID_HID; + int dst_nmembs = 0, src_nmembs = 0; + char *src_member_name = NULL, *dst_member_name = NULL; htri_t types_same = false; - bool match_for_mem_member = false; + bool match_for_src_member = false; - if (H5T_NO_CLASS == (mem_type_class = H5Tget_class(mem_type_id))) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "memory datatype is invalid"); + if (H5T_NO_CLASS == (src_type_class = H5Tget_class(src_type_id))) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "source datatype is invalid"); - if (H5T_NO_CLASS == (file_type_class = H5Tget_class(file_type_id))) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "file datatype is invalid"); + if (H5T_NO_CLASS == (dst_type_class = H5Tget_class(dst_type_id))) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "destination datatype is invalid"); - if ((file_type_class != H5T_COMPOUND) || (mem_type_class != H5T_COMPOUND)) - FUNC_GOTO_DONE(false); + if ((dst_type_class != H5T_COMPOUND) || (src_type_class != H5T_COMPOUND)) { + *subset = H5T_SUBSET_FALSE; + FUNC_GOTO_DONE(SUCCEED); + } - if ((file_nmembs = H5Tget_nmembers(file_type_id)) < 0) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get nmembers of file datatype"); + if ((dst_nmembs = H5Tget_nmembers(dst_type_id)) < 0) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get nmembers of destination datatype"); - if ((mem_nmembs = H5Tget_nmembers(mem_type_id)) < 0) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get nmembers of memory datatype"); + if ((src_nmembs = H5Tget_nmembers(src_type_id)) < 0) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get nmembers of source datatype"); - if (mem_nmembs > file_nmembs) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "memory datatype is superset of file datatype"); + if (src_nmembs > dst_nmembs) { + *subset = H5T_SUBSET_DST; + } + else if (src_nmembs < dst_nmembs) { + *subset = H5T_SUBSET_SRC; + } + else { + *subset = H5T_SUBSET_FALSE; + } - if (mem_nmembs == file_nmembs) - FUNC_GOTO_DONE(false); + /* TODO - Library just compares the number of fields in each to determine if two + * compounds are subsets, so that should suffice here as well. */ - /* Every field in memory dtype must be found in file dtype */ - // TODO - Optimize this - for (unsigned int mem_idx = 0; mem_idx < mem_nmembs; mem_idx++) { - match_for_mem_member = false; + /* + for (unsigned int src_idx = 0; src_idx < src_nmembs; src_idx++) { + match_for_src_member = false; - if ((mem_member_name = H5Tget_member_name(mem_type_id, mem_idx)) == NULL) - FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get memory datatype member name"); + if ((src_member_name = H5Tget_member_name(src_type_id, src_idx)) == NULL) + FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get source datatype member name"); - if ((mem_member_type = H5Tget_member_type(mem_type_id, mem_idx)) == H5I_INVALID_HID) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get memory datatype member type"); + if ((src_member_type = H5Tget_member_type(src_type_id, src_idx)) == H5I_INVALID_HID) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get source datatype member type"); - for (unsigned int file_idx = 0; file_idx < file_nmembs; file_idx++) { - if ((file_member_name = H5Tget_member_name(file_type_id, file_idx)) == NULL) - FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get file datatype member name"); + for (unsigned int dst_idx = 0; dst_idx < dst_nmembs; dst_idx++) { + if ((dst_member_name = H5Tget_member_name(dst_type_id, dst_idx)) == NULL) + FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get destination datatype member + name"); - if ((file_member_type = H5Tget_member_type(file_type_id, file_idx)) == H5I_INVALID_HID) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get file datatype member type"); + if ((dst_member_type = H5Tget_member_type(dst_type_id, dst_idx)) == H5I_INVALID_HID) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get destination datatype member + type"); - if ((types_same = H5Tequal(mem_member_type, file_member_type)) < 0) + if ((types_same = H5Tequal(src_member_type, dst_member_type)) < 0) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "can't check if member datatypes are equal"); - if (types_same && !strcmp(file_member_name, mem_member_name)) - match_for_mem_member = true; + if (types_same && !strcmp(dst_member_name, src_member_name)) + match_for_src_member = true; - if (H5Tclose(file_member_type) < 0) + if (H5Tclose(dst_member_type) < 0) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close datatype member"); - file_member_type = H5I_INVALID_HID; + dst_member_type = H5I_INVALID_HID; - if (H5free_memory(file_member_name) < 0) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free file datatype member name"); + if (H5free_memory(dst_member_name) < 0) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free destination datatype member + name"); - file_member_name = NULL; + dst_member_name = NULL; } - if (!match_for_mem_member) + if (!match_for_src_member) FUNC_GOTO_DONE(false); - if (H5Tclose(mem_member_type) < 0) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close memory datatype member"); + if (H5Tclose(src_member_type) < 0) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close source datatype member"); - mem_member_type = H5I_INVALID_HID; + src_member_type = H5I_INVALID_HID; - if (H5free_memory(mem_member_name) < 0) + if (H5free_memory(src_member_name) < 0) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free member datatype member name"); - mem_member_name = NULL; + src_member_name = NULL; } ret_value = true; + */ + done: - if (mem_member_name) { - if (H5free_memory(mem_member_name) < 0) + if (src_member_name) { + if (H5free_memory(src_member_name) < 0) FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free member datatype member name"); - mem_member_name = NULL; + src_member_name = NULL; } - if (file_member_name) { - if (H5free_memory(file_member_name) < 0) - FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free file datatype member name"); + if (dst_member_name) { + if (H5free_memory(dst_member_name) < 0) + FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free destination datatype member name"); - file_member_name = NULL; + dst_member_name = NULL; } - if (mem_member_type > 0) - if (H5Tclose(mem_member_type) < 0) - FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close memory datatype member"); + if (src_member_type > 0) + if (H5Tclose(src_member_type) < 0) + FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close source datatype member"); - if (file_member_type > 0) - if (H5Tclose(file_member_type) < 0) - FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close memory datatype member"); + if (dst_member_type > 0) + if (H5Tclose(dst_member_type) < 0) + FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close destination datatype member"); return ret_value; } -/* Helper to get information about fields in the file type that are unused in the memory type. */ +/* Helper to get information about fields in the destination type that are unused in the source type. */ herr_t -RV_get_unused_compound_fields(hid_t mem_type_id, hid_t file_type_id, RV_compound_info_t *compound_info) +RV_get_unused_compound_fields(hid_t src_type_id, hid_t dst_type_id, RV_compound_info_t *compound_info) { - herr_t ret_value = SUCCEED; - H5T_class_t file_type_class = H5T_NO_CLASS, mem_type_class = H5T_NO_CLASS; - hid_t mem_member_type = H5I_INVALID_HID, file_member_type = H5I_INVALID_HID; - int file_nmembs = 0, mem_nmembs = 0; - char *mem_member_name = NULL, *file_member_name = NULL; - htri_t types_same = false; - bool match_for_file_member = false; - size_t file_member_offset = 0, mem_member_offset = 0; + herr_t ret_value = SUCCEED; + H5T_class_t dst_type_class = H5T_NO_CLASS, src_type_class = H5T_NO_CLASS; + hid_t src_member_type = H5I_INVALID_HID, dst_member_type = H5I_INVALID_HID; + int dst_nmembs = 0, src_nmembs = 0; + char *src_member_name = NULL, *dst_member_name = NULL; + htri_t types_same = false; + bool match_for_dst_member = false; + size_t dst_member_offset = 0, src_member_offset = 0; size_t member_size = 0; if (!compound_info) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "provided compound info struct is NULL"); - if (H5T_NO_CLASS == (mem_type_class = H5Tget_class(mem_type_id))) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "memory datatype is invalid"); + if (H5T_NO_CLASS == (src_type_class = H5Tget_class(src_type_id))) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "source datatype is invalid"); - if (H5T_NO_CLASS == (file_type_class = H5Tget_class(file_type_id))) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "file datatype is invalid"); + if (H5T_NO_CLASS == (dst_type_class = H5Tget_class(dst_type_id))) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "destination datatype is invalid"); - if ((file_type_class != H5T_COMPOUND) || (mem_type_class != H5T_COMPOUND)) + if ((dst_type_class != H5T_COMPOUND) || (src_type_class != H5T_COMPOUND)) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "datatypes must be compound to compare members"); - if ((file_nmembs = H5Tget_nmembers(file_type_id)) < 0) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get nmembers of file datatype"); + if ((dst_nmembs = H5Tget_nmembers(dst_type_id)) < 0) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get nmembers of destination datatype"); - if ((mem_nmembs = H5Tget_nmembers(mem_type_id)) < 0) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get nmembers of memory datatype"); + if ((src_nmembs = H5Tget_nmembers(src_type_id)) < 0) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get nmembers of source datatype"); - if (file_nmembs > compound_info->nalloc) + if (dst_nmembs > compound_info->nalloc) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "not enough space in compound info"); // TODO - Optimize this - for (unsigned int file_idx = 0; file_idx < file_nmembs; file_idx++) { - match_for_file_member = false; - mem_member_offset = 0; + for (unsigned int dst_idx = 0; dst_idx < dst_nmembs; dst_idx++) { + match_for_dst_member = false; + src_member_offset = 0; - if ((file_member_name = H5Tget_member_name(file_type_id, file_idx)) == NULL) - FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get file datatype member name"); + if ((dst_member_name = H5Tget_member_name(dst_type_id, dst_idx)) == NULL) + FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get destination datatype member name"); - if ((file_member_type = H5Tget_member_type(file_type_id, file_idx)) == H5I_INVALID_HID) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get file datatype member type"); + if ((dst_member_type = H5Tget_member_type(dst_type_id, dst_idx)) == H5I_INVALID_HID) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get destination datatype member type"); - for (unsigned int mem_idx = 0; mem_idx < mem_nmembs; mem_idx++) { - if ((mem_member_name = H5Tget_member_name(mem_type_id, mem_idx)) == NULL) - FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get memory datatype member name"); + for (unsigned int src_idx = 0; src_idx < src_nmembs; src_idx++) { + if ((src_member_name = H5Tget_member_name(src_type_id, src_idx)) == NULL) + FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get source datatype member name"); - if ((mem_member_type = H5Tget_member_type(mem_type_id, mem_idx)) == H5I_INVALID_HID) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get memory datatype member type"); + if ((src_member_type = H5Tget_member_type(src_type_id, src_idx)) == H5I_INVALID_HID) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get source datatype member type"); - mem_member_offset = H5Tget_member_offset(mem_type_id, mem_idx); + src_member_offset = H5Tget_member_offset(src_type_id, src_idx); - if ((types_same = H5Tequal(mem_member_type, file_member_type)) < 0) + if ((types_same = H5Tequal(src_member_type, dst_member_type)) < 0) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "can't check if member datatypes are equal"); - if (types_same && !strcmp(file_member_name, mem_member_name)) - match_for_file_member = true; + if (types_same && !strcmp(dst_member_name, src_member_name)) + match_for_dst_member = true; - if (H5Tclose(mem_member_type) < 0) + if (H5Tclose(src_member_type) < 0) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close datatype member"); - mem_member_type = H5I_INVALID_HID; + src_member_type = H5I_INVALID_HID; - if (H5free_memory(mem_member_name) < 0) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free file datatype member name"); + if (H5free_memory(src_member_name) < 0) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, + "can't free destination datatype member name"); - mem_member_name = NULL; + src_member_name = NULL; - if (match_for_file_member) + if (match_for_dst_member) break; } - if (!match_for_file_member) { - file_member_offset = H5Tget_member_offset(file_type_id, file_idx); + /* If member in dst type is omitted by subsetting, copy its offset and length */ + if (!match_for_dst_member) { + dst_member_offset = H5Tget_member_offset(dst_type_id, dst_idx); - if ((member_size = H5Tget_size(file_member_type)) == 0) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get size of file datatype member"); + if ((member_size = H5Tget_size(dst_member_type)) == 0) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, + "can't get size of destination datatype member"); if (compound_info->nmembers >= compound_info->nalloc) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "compound info struct is full"); - compound_info->file_offsets[compound_info->nmembers] = file_member_offset; - compound_info->mem_offsets[compound_info->nmembers] = mem_member_offset; - compound_info->lengths[compound_info->nmembers] = member_size; + compound_info->dst_offsets[compound_info->nmembers] = dst_member_offset; + compound_info->src_offsets[compound_info->nmembers] = src_member_offset; + compound_info->lengths[compound_info->nmembers] = member_size; compound_info->nmembers++; } - if (H5Tclose(file_member_type) < 0) - FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close file datatype member"); + if (H5Tclose(dst_member_type) < 0) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close destination datatype member"); - file_member_type = H5I_INVALID_HID; + dst_member_type = H5I_INVALID_HID; - if (H5free_memory(file_member_name) < 0) + if (H5free_memory(dst_member_name) < 0) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free member datatype name"); - file_member_name = NULL; + dst_member_name = NULL; } done: - if (mem_member_name) { - if (H5free_memory(mem_member_name) < 0) + if (src_member_name) { + if (H5free_memory(src_member_name) < 0) FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free member datatype name"); - mem_member_name = NULL; + src_member_name = NULL; } - if (file_member_name) { - if (H5free_memory(file_member_name) < 0) - FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free file datatype member name"); + if (dst_member_name) { + if (H5free_memory(dst_member_name) < 0) + FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free destination datatype member name"); - file_member_name = NULL; + dst_member_name = NULL; } - if (mem_member_type > 0) - if (H5Tclose(mem_member_type) < 0) - FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close memory datatype member"); + if (src_member_type > 0) + if (H5Tclose(src_member_type) < 0) + FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close source datatype member"); - if (file_member_type > 0) - if (H5Tclose(file_member_type) < 0) - FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close memory datatype member"); + if (dst_member_type > 0) + if (H5Tclose(dst_member_type) < 0) + FUNC_DONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close destination datatype member"); return ret_value; } \ No newline at end of file