Commit c77c6559 authored by Darek Stojaczyk's avatar Darek Stojaczyk Committed by Tomasz Zawadzki
Browse files

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: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2753


Reviewed-by: Mellanox Build Bot
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 944a480e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -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.
 *
+23 −0
Original line number Diff line number Diff line
@@ -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)
+2 −0
Original line number Diff line number Diff line
@@ -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;
+32 −0
Original line number Diff line number Diff line
@@ -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);