json: add spdk_json_free_object()

After decoding a JSON object we had to free the parsed
strings one-by-one. Not anymore.

Change-Id: I819f1d533e397aa9babca58b5500c38ac01a963d
Signed-off-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2753
Reviewed-by: Mellanox Build Bot
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Darek Stojaczyk 2020-06-03 12:31:23 +02:00 committed by Tomasz Zawadzki
parent 944a480ea7
commit c77c655987
5 changed files with 62 additions and 0 deletions

View File

@ -84,6 +84,8 @@ through the JSON context provided via spdk_nvmf_target_opts->transport_specific.
## v20.07: SPDK CSI driver, new accel_fw commands, I/O abort support
spdk_json_free_object() was added to free memory allocated by spdk_json_decode_object().
### accel
A new API was added `spdk_accel_get_capabilities` that allows applications to

View File

@ -156,6 +156,9 @@ int spdk_json_decode_uint32(const struct spdk_json_val *val, void *out);
int spdk_json_decode_uint64(const struct spdk_json_val *val, void *out);
int spdk_json_decode_string(const struct spdk_json_val *val, void *out);
void spdk_json_free_object(const struct spdk_json_object_decoder *decoders, size_t num_decoders,
void *obj);
/**
* Get length of a value in number of values.
*

View File

@ -364,6 +364,29 @@ _json_decode_object(const struct spdk_json_val *values,
return invalid ? -1 : 0;
}
void
spdk_json_free_object(const struct spdk_json_object_decoder *decoders, size_t num_decoders,
void *obj)
{
struct spdk_json_val invalid_val = {
.start = "",
.len = 0,
.type = SPDK_JSON_VAL_INVALID
};
size_t decidx;
for (decidx = 0; decidx < num_decoders; decidx++) {
const struct spdk_json_object_decoder *dec = &decoders[decidx];
void *field = (void *)((uintptr_t)obj + dec->offset);
/* decoding an invalid value will free the
* previous memory without allocating it again.
*/
dec->decode_func(&invalid_val, field);
}
}
int
spdk_json_decode_object(const struct spdk_json_val *values,
const struct spdk_json_object_decoder *decoders, size_t num_decoders, void *out)

View File

@ -13,6 +13,8 @@
spdk_json_decode_uint64;
spdk_json_decode_string;
spdk_json_free_object;
spdk_json_val_len;
spdk_json_strequal;
spdk_json_strdup;

View File

@ -251,6 +251,37 @@ test_decode_object(void)
free(output.my_name);
}
static void
test_free_object(void)
{
struct my_object {
char *my_name;
uint32_t my_int;
char *my_other_name;
char *empty_string;
};
struct spdk_json_object_decoder decoders[] = {
{"first", offsetof(struct my_object, my_name), spdk_json_decode_string, false},
{"second", offsetof(struct my_object, my_int), spdk_json_decode_uint32, false},
{"third", offsetof(struct my_object, my_other_name), spdk_json_decode_string, true},
{"fourth", offsetof(struct my_object, empty_string), spdk_json_decode_string, false},
};
struct my_object output = {
.my_name = strdup("hello"),
.my_int = 3,
.my_other_name = strdup("world"),
.empty_string = NULL
};
SPDK_CU_ASSERT_FATAL(output.my_name != NULL);
SPDK_CU_ASSERT_FATAL(output.my_other_name != NULL);
spdk_json_free_object(decoders, 4, &output);
CU_ASSERT(output.my_name == NULL);
CU_ASSERT(output.my_other_name == NULL);
CU_ASSERT(output.empty_string == NULL);
}
static void
test_decode_array(void)
{
@ -942,6 +973,7 @@ int main(int argc, char **argv)
CU_ADD_TEST(suite, test_decode_string);
CU_ADD_TEST(suite, test_find);
CU_ADD_TEST(suite, test_iterating);
CU_ADD_TEST(suite, test_free_object);
CU_basic_set_mode(CU_BRM_VERBOSE);