Skip to content

Commit

Permalink
Support long links with HSDS >0.8.5 (#115)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattjala authored Apr 9, 2024
1 parent 420ff43 commit cf6ef45
Show file tree
Hide file tree
Showing 6 changed files with 507 additions and 160 deletions.
223 changes: 182 additions & 41 deletions src/rest_vol.c

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions src/rest_vol.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,12 @@ extern const char *link_creation_time_keys[];
*/
extern const char *link_collection_keys2[];

/* JSON keys to retrieve objects accessed through path(s) */
extern const char *h5paths_keys[];

/* JSON keys to retrieve the path to a domain in HSDS */
extern const char *domain_keys[];

/* A global struct containing the buffer which cURL will write its
* responses out to after making a call to the server. The buffer
* in this struct is allocated upon connector initialization and is
Expand Down Expand Up @@ -803,6 +809,8 @@ herr_t RV_JSON_escape_string(const char *in, char *out, size_t *out_size);
#define SERVER_VERSION_SUPPORTS_FIXED_LENGTH_UTF8(version) \
(SERVER_VERSION_MATCHES_OR_EXCEEDS(version, 0, 8, 5))

#define SERVER_VERSION_SUPPORTS_LONG_NAMES(version) (SERVER_VERSION_MATCHES_OR_EXCEEDS(version, 0, 8, 6))

#ifdef __cplusplus
}
#endif
Expand Down
33 changes: 22 additions & 11 deletions src/rest_vol_dataset.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ RV_dataset_create(void *obj, const H5VL_loc_params_t *loc_params, const char *na
"dataset create URL size exceeded maximum URL size");

#ifdef RV_CONNECTOR_DEBUG
printf("-> Dataset creation request URL: %s\n\n", request_url);
printf("-> Dataset creation request endpoint: %s\n\n", request_endpoint);
#endif

http_response = RV_curl_post(curl, &new_dataset->domain->u.file.server_info, request_endpoint,
Expand Down Expand Up @@ -722,10 +722,6 @@ RV_dataset_read(size_t count, void *dset[], hid_t mem_type_id[], hid_t _mem_spac

#ifdef RV_CONNECTOR_DEBUG
printf("-> Reading dataset\n\n");

printf(" /***************************************\\\n");
printf("-> | Making GET/POST request to the server |\n");
printf(" \\***************************************/\n\n");
#endif

if (CURLM_OK != curl_multi_setopt(curl_multi_handle, CURLMOPT_MAX_HOST_CONNECTIONS, NUM_MAX_HOST_CONNS))
Expand Down Expand Up @@ -1194,10 +1190,6 @@ RV_dataset_write(size_t count, void *dset[], hid_t mem_type_id[], hid_t _mem_spa

#ifdef RV_CONNECTOR_DEBUG
printf("-> Writing dataset\n\n");

printf(" /**********************************\\\n");
printf("-> | Making PUT request to the server |\n");
printf(" \\**********************************/\n\n");
#endif

if (CURLM_OK != curl_multi_setopt(curl_multi_handle, CURLMOPT_MAX_HOST_CONNECTIONS, NUM_MAX_HOST_CONNS))
Expand Down Expand Up @@ -1695,12 +1687,13 @@ static herr_t
RV_parse_dataset_creation_properties_callback(char *HTTP_response, const void *callback_data_in,
void *callback_data_out)
{
yajl_val parse_tree = NULL, creation_properties_obj, key_obj;
yajl_val parse_tree = NULL, creation_properties_obj = NULL, key_obj = NULL, target_tree = NULL;
hid_t *DCPL = (hid_t *)callback_data_out;
hid_t fill_type = H5I_INVALID_HID;
char *encoded_fill_value = NULL;
char *decoded_fill_value = NULL;
unsigned int *ud_parameters = NULL;
const char *path_name = NULL;
herr_t ret_value = SUCCEED;

#ifdef RV_CONNECTOR_DEBUG
Expand All @@ -1715,9 +1708,27 @@ RV_parse_dataset_creation_properties_callback(char *HTTP_response, const void *c
if (NULL == (parse_tree = yajl_tree_parse(HTTP_response, NULL, 0)))
FUNC_GOTO_ERROR(H5E_DATASET, H5E_PARSEERROR, FAIL, "parsing JSON failed");

target_tree = parse_tree;

/* If the response contains 'h5paths',
* it may describe multiple objects. Needs to be unwrapped first. */
if (NULL != yajl_tree_get(parse_tree, h5paths_keys, yajl_t_object)) {
if (NULL == (target_tree = yajl_tree_get(parse_tree, h5paths_keys, yajl_t_object)))
FUNC_GOTO_ERROR(H5E_OBJECT, H5E_PARSEERROR, FAIL, "can't parse h5paths object");

/* Access the first object under h5paths */
if (NULL == (path_name = target_tree->u.object.keys[0]))
FUNC_GOTO_ERROR(H5E_OBJECT, H5E_PARSEERROR, FAIL, "parsed path name was NULL");

const char *path_keys[] = {path_name, (const char *)0};

if (NULL == (target_tree = yajl_tree_get(target_tree, path_keys, yajl_t_object)))
FUNC_GOTO_ERROR(H5E_OBJECT, H5E_PARSEERROR, FAIL, "unable to parse object under path key");
}

/* Retrieve the creationProperties object */
if (NULL ==
(creation_properties_obj = yajl_tree_get(parse_tree, creation_properties_keys, yajl_t_object)))
(creation_properties_obj = yajl_tree_get(target_tree, creation_properties_keys, yajl_t_object)))
FUNC_GOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "retrieval of creationProperties object failed");

/********************************************************************************************
Expand Down
43 changes: 31 additions & 12 deletions src/rest_vol_datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -1426,18 +1426,19 @@ RV_convert_datatype_to_JSON(hid_t type_id, char **type_body, size_t *type_body_l
static hid_t
RV_convert_JSON_to_datatype(const char *type)
{
yajl_val parse_tree = NULL, key_obj = NULL;
hsize_t *array_dims = NULL;
size_t i;
hid_t datatype = FAIL;
hid_t *compound_member_type_array = NULL;
hid_t enum_base_type = FAIL;
char **compound_member_names = NULL;
char *datatype_class = NULL;
char *array_base_type_substring = NULL;
char *tmp_cmpd_type_buffer = NULL;
char *tmp_enum_base_type_buffer = NULL;
hid_t ret_value = FAIL;
yajl_val parse_tree = NULL, key_obj = NULL, target_tree = NULL;
hsize_t *array_dims = NULL;
size_t i;
hid_t datatype = FAIL;
hid_t *compound_member_type_array = NULL;
hid_t enum_base_type = FAIL;
char **compound_member_names = NULL;
char *datatype_class = NULL;
char *array_base_type_substring = NULL;
char *tmp_cmpd_type_buffer = NULL;
char *tmp_enum_base_type_buffer = NULL;
const char *path_name = NULL;
hid_t ret_value = FAIL;

#ifdef RV_CONNECTOR_DEBUG
printf("-> Converting JSON buffer %s to hid_t\n", type);
Expand All @@ -1447,6 +1448,24 @@ RV_convert_JSON_to_datatype(const char *type)
if (NULL == (parse_tree = yajl_tree_parse(type, NULL, 0)))
FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_PARSEERROR, FAIL, "JSON parse tree creation failed");

target_tree = parse_tree;

/* If the response contains 'h5paths',
* it may describe multiple objects. Needs to be unwrapped first. */
if (NULL != yajl_tree_get(parse_tree, h5paths_keys, yajl_t_object)) {
if (NULL == (target_tree = yajl_tree_get(parse_tree, h5paths_keys, yajl_t_object)))
FUNC_GOTO_ERROR(H5E_OBJECT, H5E_PARSEERROR, FAIL, "can't parse h5paths object");

/* Access the first object under h5paths */
if (NULL == (path_name = target_tree->u.object.keys[0]))
FUNC_GOTO_ERROR(H5E_OBJECT, H5E_PARSEERROR, FAIL, "parsed path name was NULL");

const char *path_keys[] = {path_name, (const char *)0};

if (NULL == (target_tree = yajl_tree_get(target_tree, path_keys, yajl_t_object)))
FUNC_GOTO_ERROR(H5E_OBJECT, H5E_PARSEERROR, FAIL, "unable to parse object under path key");
}

if (NULL == (key_obj = yajl_tree_get(parse_tree, type_class_keys, yajl_t_string)))
FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_PARSEERROR, FAIL, "can't parse datatype from JSON representation");

Expand Down
Loading

0 comments on commit cf6ef45

Please sign in to comment.