From 0394e18485efbec33e852e604b11623ac1a03517 Mon Sep 17 00:00:00 2001 From: Matthew Larson Date: Fri, 7 Jul 2023 15:11:31 -0500 Subject: [PATCH] Implement H5Iget_name for hard/soft links Doesn't match what the vol-tests expect for external links --- src/rest_vol.h | 1 + src/rest_vol_attr.c | 73 ++++++++++++++++++++++++++++++++++++++--- src/rest_vol_dataset.c | 45 +++++++++++++++++++++++++ src/rest_vol_datatype.c | 45 +++++++++++++++++++++++++ src/rest_vol_group.c | 11 +++---- src/rest_vol_object.c | 17 ++++++---- 6 files changed, 175 insertions(+), 17 deletions(-) diff --git a/src/rest_vol.h b/src/rest_vol.h index 43f6ed46..715bfff5 100644 --- a/src/rest_vol.h +++ b/src/rest_vol.h @@ -495,6 +495,7 @@ typedef struct RV_attr_t { hid_t aapl_id; hid_t acpl_id; char *attr_name; + char *parent_name; } RV_attr_t; typedef struct RV_datatype_t { diff --git a/src/rest_vol_attr.c b/src/rest_vol_attr.c index 126b0937..4b21be12 100644 --- a/src/rest_vol_attr.c +++ b/src/rest_vol_attr.c @@ -59,6 +59,8 @@ RV_attr_create(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_ size_t host_header_len = 0; size_t datatype_body_len = 0; size_t attr_name_len = 0; + size_t path_size = 0; + size_t path_len = 0; char *host_header = NULL; char *create_request_body = NULL; char *datatype_body = NULL; @@ -115,6 +117,35 @@ RV_attr_create(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_ new_attribute->domain = parent->domain; parent->domain->u.file.ref_count++; + new_attribute->handle_path = NULL; + + if (attr_name) { + /* parent_path + "/" + name + null byte */ + path_size = (!strcmp(parent->handle_path, "/") ? 1 + strlen(attr_name) + 1 : strlen(parent->handle_path) + 1 + strlen(attr_name) + 1); + + if ((new_attribute->handle_path = RV_malloc(path_size)) == NULL) + FUNC_GOTO_ERROR(H5E_SYM, H5E_CANTALLOC, NULL, "can't allocate space for handle path"); + + if (strcmp(parent->handle_path, "/") != 0) { + strncpy(new_attribute->handle_path, parent->handle_path, strlen(parent->handle_path)); + path_len += strlen(parent->handle_path); + } + + new_attribute->handle_path[path_len] = '/'; + strncpy(new_attribute->handle_path + path_len + 1, attr_name, strlen(attr_name) + 1); + path_len += (1 + strlen(attr_name) + 1); + + } + + new_attribute->u.attribute.parent_name = NULL; + + if (parent->handle_path) { + if ((new_attribute->u.attribute.parent_name = RV_malloc(strlen(parent->handle_path) + 1)) == NULL) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, NULL, "can't allocate space for attribute parent name"); + + strncpy(new_attribute->u.attribute.parent_name, parent->handle_path, strlen(parent->handle_path) + 1); + } + /* If this is a call to H5Acreate_by_name, locate the real parent object */ if (H5VL_OBJECT_BY_NAME == loc_params->type) { htri_t search_ret; @@ -387,6 +418,8 @@ RV_attr_open(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_na RV_object_t *attribute = NULL; size_t attr_name_len = 0; size_t host_header_len = 0; + size_t path_size = 0; + size_t path_len = 0; char *host_header = NULL; char request_url[URL_MAX_LENGTH]; char *url_encoded_attr_name = NULL; @@ -438,6 +471,35 @@ RV_attr_open(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_na attribute->domain = parent->domain; parent->domain->u.file.ref_count++; + attribute->handle_path = NULL; + + if (attr_name) { + /* parent_path + "/" + name + null byte */ + path_size = (!strcmp(parent->handle_path, "/") ? 1 + strlen(attr_name) + 1 : strlen(parent->handle_path) + 1 + strlen(attr_name) + 1); + + if ((attribute->handle_path = RV_malloc(path_size)) == NULL) + FUNC_GOTO_ERROR(H5E_SYM, H5E_CANTALLOC, NULL, "can't allocate space for handle path"); + + if (strcmp(parent->handle_path, "/") != 0) { + strncpy(attribute->handle_path, parent->handle_path, strlen(parent->handle_path)); + path_len += strlen(parent->handle_path); + } + + attribute->handle_path[path_len] = '/'; + strncpy(attribute->handle_path + path_len + 1, attr_name, strlen(attr_name) + 1); + path_len += (1 + strlen(attr_name) + 1); + + } + + attribute->u.attribute.parent_name = NULL; + + if (parent->handle_path) { + if ((attribute->u.attribute.parent_name = RV_malloc(strlen(parent->handle_path) + 1)) == NULL) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, NULL, "can't allocate space for attribute parent name"); + + strncpy(attribute->u.attribute.parent_name, parent->handle_path, strlen(parent->handle_path) + 1); + } + /* Set the parent object's type and URI in the attribute's appropriate fields */ switch (loc_params->type) { /* H5Aopen */ @@ -1830,6 +1892,11 @@ RV_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_speci RV_object_t *attr_iter_obj = (RV_object_t *)attr_iter_object; + if ((attr_iter_obj->handle_path = RV_malloc(strlen(loc_obj->handle_path) +1)) == NULL) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "can't allocate space for copy of object path"); + + strncpy(attr_iter_obj->handle_path, loc_obj->handle_path, strlen(loc_obj->handle_path) + 1); + switch (parent_obj_type) { case H5I_FILE: /* Copy fapl, fcpl, and filepath name to new object */ @@ -1860,10 +1927,6 @@ RV_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_speci "attribute's parent group"); } - if ((attr_iter_obj->handle_path = RV_malloc(strlen(loc_obj->handle_path) +1)) == NULL) - FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "can't allocate space for copy of group path"); - - strncpy(attr_iter_obj->handle_path, loc_obj->handle_path, strlen(loc_obj->handle_path) + 1); break; case H5I_DATATYPE: @@ -2261,6 +2324,8 @@ RV_attr_close(void *attr, hid_t dxpl_id, void **req) if (RV_file_close(_attr->domain, H5P_DEFAULT, NULL) < 0) FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "couldn't close attr domain"); + RV_free(_attr->u.attribute.parent_name); + RV_free(_attr->handle_path); RV_free(_attr); _attr = NULL; diff --git a/src/rest_vol_dataset.c b/src/rest_vol_dataset.c index 848981a0..a57e90fd 100644 --- a/src/rest_vol_dataset.c +++ b/src/rest_vol_dataset.c @@ -105,6 +105,8 @@ RV_dataset_create(void *obj, const H5VL_loc_params_t *loc_params, const char *na RV_object_t *new_dataset = NULL; curl_off_t create_request_body_len = 0; size_t host_header_len = 0; + size_t path_size = 0; + size_t path_len = 0; char *host_header = NULL; char *create_request_body = NULL; char request_url[URL_MAX_LENGTH]; @@ -144,6 +146,26 @@ RV_dataset_create(void *obj, const H5VL_loc_params_t *loc_params, const char *na new_dataset->domain = parent->domain; parent->domain->u.file.ref_count++; + new_dataset->handle_path = NULL; + + if (name) { + /* parent_path + "/" + name + null byte */ + path_size = (!strcmp(parent->handle_path, "/") ? 1 + strlen(name) + 1 : strlen(parent->handle_path) + 1 + strlen(name) + 1); + + if ((new_dataset->handle_path = RV_malloc(path_size)) == NULL) + FUNC_GOTO_ERROR(H5E_SYM, H5E_CANTALLOC, NULL, "can't allocate space for handle path"); + + if (strcmp(parent->handle_path, "/") != 0) { + strncpy(new_dataset->handle_path, parent->handle_path, strlen(parent->handle_path)); + path_len += strlen(parent->handle_path); + } + + new_dataset->handle_path[path_len] = '/'; + strncpy(new_dataset->handle_path + path_len + 1, name, strlen(name) + 1); + path_len += (1 + strlen(name) + 1); + + } + /* Copy the DAPL if it wasn't H5P_DEFAULT, else set up a default one so that * H5Dget_access_plist() will function correctly */ @@ -303,6 +325,8 @@ RV_dataset_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name htri_t search_ret; void *ret_value = NULL; loc_info loc_info_out; + size_t path_size = 0; + size_t path_len = 0; #ifdef RV_CONNECTOR_DEBUG printf("-> Received dataset open call with following parameters:\n"); @@ -331,6 +355,26 @@ RV_dataset_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name dataset->domain = parent->domain; parent->domain->u.file.ref_count++; + dataset->handle_path = NULL; + + if (name) { + /* parent_path + "/" + name + null byte */ + path_size = (!strcmp(parent->handle_path, "/") ? 1 + strlen(name) + 1 : strlen(parent->handle_path) + 1 + strlen(name) + 1); + + if ((dataset->handle_path = RV_malloc(path_size)) == NULL) + FUNC_GOTO_ERROR(H5E_SYM, H5E_CANTALLOC, NULL, "can't allocate space for handle path"); + + if (strcmp(parent->handle_path, "/") != 0) { + strncpy(dataset->handle_path, parent->handle_path, strlen(parent->handle_path)); + path_len += strlen(parent->handle_path); + } + + dataset->handle_path[path_len] = '/'; + strncpy(dataset->handle_path + path_len + 1, name, strlen(name) + 1); + path_len += (1 + strlen(name) + 1); + + } + loc_info_out.URI = dataset->URI; loc_info_out.domain = dataset->domain; loc_info_out.GCPL_base64 = NULL; @@ -1169,6 +1213,7 @@ RV_dataset_close(void *dset, hid_t dxpl_id, void **req) FUNC_DONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file"); } + RV_free(_dset->handle_path); RV_free(_dset); _dset = NULL; diff --git a/src/rest_vol_datatype.c b/src/rest_vol_datatype.c index 274e4567..209c13b8 100644 --- a/src/rest_vol_datatype.c +++ b/src/rest_vol_datatype.c @@ -72,6 +72,8 @@ RV_datatype_commit(void *obj, const H5VL_loc_params_t *loc_params, const char *n size_t link_body_nalloc = 0; size_t host_header_len = 0; size_t datatype_body_len = 0; + size_t path_size = 0; + size_t path_len = 0; char *host_header = NULL; char *commit_request_body = NULL; char *datatype_body = NULL; @@ -117,6 +119,26 @@ RV_datatype_commit(void *obj, const H5VL_loc_params_t *loc_params, const char *n new_datatype->domain = parent->domain; parent->domain->u.file.ref_count++; + new_datatype->handle_path = NULL; + + if (name) { + /* parent_path + "/" + name + null byte */ + path_size = (!strcmp(parent->handle_path, "/") ? 1 + strlen(name) + 1 : strlen(parent->handle_path) + 1 + strlen(name) + 1); + + if ((new_datatype->handle_path = RV_malloc(path_size)) == NULL) + FUNC_GOTO_ERROR(H5E_SYM, H5E_CANTALLOC, NULL, "can't allocate space for handle path"); + + if (strcmp(parent->handle_path, "/") != 0) { + strncpy(new_datatype->handle_path, parent->handle_path, strlen(parent->handle_path)); + path_len += strlen(parent->handle_path); + } + + new_datatype->handle_path[path_len] = '/'; + strncpy(new_datatype->handle_path + path_len + 1, name, strlen(name) + 1); + path_len += (1 + strlen(name) + 1); + + } + /* Copy the TAPL if it wasn't H5P_DEFAULT, else set up a default one so that * datatype access property list functions will function correctly */ @@ -331,6 +353,8 @@ RV_datatype_open(void *obj, const H5VL_loc_params_t *loc_params, const char *nam H5I_type_t obj_type = H5I_UNINIT; loc_info loc_info; htri_t search_ret; + size_t path_size = 0; + size_t path_len = 0; void *ret_value = NULL; #ifdef RV_CONNECTOR_DEBUG @@ -358,6 +382,26 @@ RV_datatype_open(void *obj, const H5VL_loc_params_t *loc_params, const char *nam datatype->domain = parent->domain; parent->domain->u.file.ref_count++; + datatype->handle_path = NULL; + + if (name) { + /* parent_path + "/" + name + null byte */ + path_size = (!strcmp(parent->handle_path, "/") ? 1 + strlen(name) + 1 : strlen(parent->handle_path) + 1 + strlen(name) + 1); + + if ((datatype->handle_path = RV_malloc(path_size)) == NULL) + FUNC_GOTO_ERROR(H5E_SYM, H5E_CANTALLOC, NULL, "can't allocate space for handle path"); + + if (strcmp(parent->handle_path, "/") != 0) { + strncpy(datatype->handle_path, parent->handle_path, strlen(parent->handle_path)); + path_len += strlen(parent->handle_path); + } + + datatype->handle_path[path_len] = '/'; + strncpy(datatype->handle_path + path_len + 1, name, strlen(name) + 1); + path_len += (1 + strlen(name) + 1); + + } + loc_info.URI = datatype->URI; loc_info.domain = datatype->domain; loc_info.GCPL_base64 = NULL; @@ -545,6 +589,7 @@ RV_datatype_close(void *dt, hid_t dxpl_id, void **req) if (RV_file_close(_dtype->domain, H5P_DEFAULT, NULL) < 0) FUNC_DONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file"); + RV_free(_dtype->handle_path); RV_free(_dtype); _dtype = NULL; diff --git a/src/rest_vol_group.c b/src/rest_vol_group.c index e45cfe86..0dac5fa6 100644 --- a/src/rest_vol_group.c +++ b/src/rest_vol_group.c @@ -47,6 +47,8 @@ RV_group_create(void *obj, const H5VL_loc_params_t *loc_params, const char *name size_t host_header_len = 0; size_t base64_buf_size = 0; size_t plist_nalloc = 0; + size_t path_size = 0; + size_t path_len = 0; char *host_header = NULL; char *create_request_body = NULL; char *path_dirname = NULL; @@ -94,9 +96,6 @@ RV_group_create(void *obj, const H5VL_loc_params_t *loc_params, const char *name new_group->handle_path = NULL; - size_t path_size = 0; - size_t path_len = 0; - if (name) { /* parent_path + "/" + name + null byte */ path_size = (!strcmp(parent->handle_path, "/") ? 1 + strlen(name) + 1 : strlen(parent->handle_path) + 1 + strlen(name) + 1); @@ -362,7 +361,8 @@ RV_group_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, // char *base64_binary_gcpl = NULL; void *binary_gcpl = NULL; size_t *binary_gcpl_size = 0; - + size_t path_size = 0; + size_t path_len = 0; H5I_type_t obj_type = H5I_UNINIT; #ifdef RV_CONNECTOR_DEBUG @@ -395,9 +395,6 @@ RV_group_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, group->handle_path = NULL; - size_t path_size = 0; - size_t path_len = 0; - /* parent_path + "/" + name + null byte */ if (name) { path_size = !strcmp(parent->handle_path, "/") ? 1 + strlen(name) + 1 : strlen(parent->handle_path) + 1 + strlen(name) + 1; diff --git a/src/rest_vol_object.c b/src/rest_vol_object.c index c6d05891..75c6a433 100644 --- a/src/rest_vol_object.c +++ b/src/rest_vol_object.c @@ -271,25 +271,30 @@ RV_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_ar switch (args->op_type) { case H5VL_OBJECT_GET_NAME: { - // TODO: Work for all obj not just groups // TODO: Special attr functionality size_t copy_size = 0; + char *name = loc_obj->handle_path; - if (!loc_obj->handle_path) - FUNC_GOTO_ERROR(H5E_OBJECT, H5E_PATH, FAIL, "object has NULL handle path"); + if (!name) + FUNC_GOTO_ERROR(H5E_OBJECT, H5E_PATH, FAIL, "object has NULL name"); /* Only return the name if the user provided an allocate buffer */ if (args->args.get_name.buf) { /* Initialize entire buffer regardless of path size */ memset(args->args.get_name.buf, 0, args->args.get_name.buf_size); - copy_size = (strlen(loc_obj->handle_path) < args->args.get_name.buf_size - 1) ? strlen(loc_obj->handle_path) : args->args.get_name.buf_size - 1; - strncpy(args->args.get_name.buf, loc_obj->handle_path, copy_size); + /* If given an attribute, H5Iget_name returns the name of the object an attribute is attached to */ + if (loc_obj->obj_type == H5I_ATTR) + if ((name = loc_obj->u.attribute.parent_name) == NULL) + FUNC_GOTO_ERROR(H5E_OBJECT, H5E_BADVALUE, FAIL, "attribute parent has NULL name"); + + copy_size = (strlen(name) < args->args.get_name.buf_size - 1) ? strlen(name) : args->args.get_name.buf_size - 1; + strncpy(args->args.get_name.buf, name, copy_size); args->args.get_name.buf[copy_size + 1] = '\0'; } if (args->args.get_name.name_len) { - *args->args.get_name.name_len = strlen(loc_obj->handle_path); + *args->args.get_name.name_len = strlen(name); } }