Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support opening dataset with UD filter #109

Merged
merged 2 commits into from
Jan 16, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 102 additions & 15 deletions src/rest_vol_dataset.c
Original file line number Diff line number Diff line change
Expand Up @@ -1776,12 +1776,13 @@ static herr_t
RV_parse_dataset_creation_properties_callback(char *HTTP_response, void *callback_data_in,
void *callback_data_out)
{
yajl_val parse_tree = NULL, creation_properties_obj, key_obj;
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;
herr_t ret_value = SUCCEED;
yajl_val parse_tree = NULL, creation_properties_obj, key_obj;
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;
herr_t ret_value = SUCCEED;

#ifdef RV_CONNECTOR_DEBUG
printf("-> Retrieving dataset's creation properties from server's HTTP response\n\n");
Expand Down Expand Up @@ -2274,13 +2275,45 @@ RV_parse_dataset_creation_properties_callback(char *HTTP_response, void *callbac
break;
}

/* TODO: support for other/user-defined filters */

default:
/* Push error to stack; but don't fail this function */
FUNC_DONE_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL,
"warning: invalid filter with class '%s' and ID '%lld' on DCPL",
filter_class, filter_ID);
if (strcmp(filter_class, "H5Z_FILTER_USER")) {
/* Push error to stack; but don't fail this function */
FUNC_DONE_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL,
"warning: invalid filter with class '%s' and ID '%lld' on DCPL",
filter_class, filter_ID);
}

/* Parse user-defined filter from JSON */
const char *ud_parameter_keys[] = {"parameters", (const char *)0};

yajl_val params_array = NULL;

if (NULL == (params_array = yajl_tree_get(filter_obj, ud_parameter_keys, yajl_t_array)))
FUNC_GOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
"retrieval of user-defined filter parameters failed");

if (NULL ==
(ud_parameters = RV_calloc(sizeof(unsigned int) * YAJL_GET_ARRAY(params_array)->len)))
FUNC_GOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL,
"can't allocate memory for user-defined filter parameters");

for (size_t j = 0; j < YAJL_GET_ARRAY(params_array)->len; j++) {
/* Get each integer parameter */
long long int val = YAJL_GET_INTEGER(YAJL_GET_ARRAY(params_array)->values[j]);

if (val < 0)
FUNC_GOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
"invalid parameter value for user-defined filter");

ud_parameters[j] = (unsigned int)val;
}

if (H5Pset_filter(*DCPL, (H5Z_filter_t)filter_ID, H5Z_FLAG_OPTIONAL,
YAJL_GET_ARRAY(params_array)->len, ud_parameters) < 0)
FUNC_GOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL,
"can't set user-defined filter on DCPL");

break;
}

#ifdef RV_CONNECTOR_DEBUG
Expand Down Expand Up @@ -2407,7 +2440,11 @@ RV_parse_dataset_creation_properties_callback(char *HTTP_response, void *callbac
if (H5Tclose(fill_type) < 0)
FUNC_DONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "can't close datatype of fill value");

if (ud_parameters)
RV_free(ud_parameters);

return ret_value;

} /* end RV_parse_dataset_creation_properties_callback() */

/*-------------------------------------------------------------------------
Expand Down Expand Up @@ -2444,6 +2481,7 @@ RV_convert_dataset_creation_properties_to_JSON(hid_t dcpl, char **creation_prope
void *fill_value = NULL;
char *encode_buf_out = NULL;
char *fill_value_str = NULL;
char *ud_parameters = NULL;
herr_t ret_value = SUCCEED;

#ifdef RV_CONNECTOR_DEBUG
Expand Down Expand Up @@ -3130,7 +3168,9 @@ RV_convert_dataset_creation_properties_to_JSON(hid_t dcpl, char **creation_prope

default: /* User-defined filter */
{
char *parameters = NULL;
size_t ud_parameters_size = 0;
size_t ud_parameters_len = 0;

const char *const fmt_string = "{"
"\"class\": \"H5Z_FILTER_USER\","
"\"id\": %d,"
Expand All @@ -3149,8 +3189,52 @@ RV_convert_dataset_creation_properties_to_JSON(hid_t dcpl, char **creation_prope

/* Retrieve all of the parameters for the user-defined filter */

/* Start/end brackets and null byte */
ud_parameters_size += 3;

for (size_t j = 0; j < cd_nelmts; j++) {
/* N bytes needed to store an N digit number,
* floor(log10) + 1 of an N digit number is >= N,
* plus two bytes for space and comma characters in the list */
double num_digits = 0;

if (cd_values[j] == 0) {
num_digits = 1;
}
else {
num_digits = floor(log10((double)cd_values[j]));
}

ud_parameters_size += (size_t)num_digits + 1 + 2;
}

if ((ud_parameters = RV_calloc(ud_parameters_size)) == NULL)
FUNC_GOTO_ERROR(H5E_CANTFILTER, H5E_CANTALLOC, FAIL,
"can't allocate memory for filter parameters");

/* Assemble JSON array for user-defined filter parameters */
memset(ud_parameters, '[', 1);
ud_parameters_len += 1;

for (size_t j = 0; j < cd_nelmts; j++) {
int _param_len =
snprintf(ud_parameters + ud_parameters_len,
ud_parameters_size - ud_parameters_len, "%d", cd_values[j]);
ud_parameters_len += (size_t)_param_len;

if (j != cd_nelmts - 1) {
strcat(ud_parameters + (size_t)ud_parameters_len, ", ");
ud_parameters_len += 2;
}
}

memset(ud_parameters + ud_parameters_len, ']', 1);
ud_parameters_len += 1;
memset(ud_parameters + ud_parameters_len, '\0', 1);
ud_parameters_len += 1;

/* Check whether the buffer needs to be grown */
bytes_to_print = strlen(fmt_string) + MAX_NUM_LENGTH + strlen(parameters) + 1;
bytes_to_print = strlen(fmt_string) + MAX_NUM_LENGTH + strlen(ud_parameters) + 1;

buf_ptrdiff = out_string_curr_pos - out_string;
if (buf_ptrdiff < 0)
Expand All @@ -3163,7 +3247,7 @@ RV_convert_dataset_creation_properties_to_JSON(hid_t dcpl, char **creation_prope

if ((bytes_printed =
snprintf(out_string_curr_pos, out_string_len - (size_t)buf_ptrdiff,
fmt_string, filter_id, parameters)) < 0)
fmt_string, filter_id, ud_parameters)) < 0)
FUNC_GOTO_ERROR(H5E_DATASET, H5E_SYSERRSTR, FAIL, "snprintf error");

if ((size_t)bytes_printed >= out_string_len - (size_t)buf_ptrdiff)
Expand Down Expand Up @@ -3534,6 +3618,9 @@ RV_convert_dataset_creation_properties_to_JSON(hid_t dcpl, char **creation_prope
if (fill_value_str)
RV_free(fill_value_str);

if (ud_parameters)
RV_free(ud_parameters);

return ret_value;
} /* end RV_convert_dataset_creation_properties_to_JSON() */

Expand Down