From 6f872f5ab9aea70fa4f0bc52bf25bc3916afab81 Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Sat, 2 Jun 2018 00:10:40 +0900 Subject: [PATCH] json: Add spdk_json_decode_uint16 int16_t is not used in SPDK yet. Hence add decode function only for uint16_t. Change-Id: I86f86a6768d95896d1840370f2d176c770c41418 Signed-off-by: Shuhei Matsumoto Reviewed-on: https://review.gerrithub.io/413711 Tested-by: SPDK Automated Test System Reviewed-by: Pawel Wodkowski Reviewed-by: Daniel Verkamp Reviewed-by: Ben Walker --- include/spdk/json.h | 2 + lib/json/json_util.c | 30 +++++ test/unit/lib/json/json_util.c/json_util_ut.c | 124 ++++++++++++++++++ 3 files changed, 156 insertions(+) diff --git a/include/spdk/json.h b/include/spdk/json.h index cd76c5e903..62db4439c9 100644 --- a/include/spdk/json.h +++ b/include/spdk/json.h @@ -147,6 +147,7 @@ int spdk_json_decode_array(const struct spdk_json_val *values, spdk_json_decode_ void *out, size_t max_size, size_t *out_size, size_t stride); int spdk_json_decode_bool(const struct spdk_json_val *val, void *out); +int spdk_json_decode_uint16(const struct spdk_json_val *val, void *out); int spdk_json_decode_int32(const struct spdk_json_val *val, void *out); 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); @@ -181,6 +182,7 @@ bool spdk_json_strequal(const struct spdk_json_val *val, const char *str); */ char *spdk_json_strdup(const struct spdk_json_val *val); +int spdk_json_number_to_uint16(const struct spdk_json_val *val, uint16_t *num); int spdk_json_number_to_int32(const struct spdk_json_val *val, int32_t *num); int spdk_json_number_to_uint32(const struct spdk_json_val *val, uint32_t *num); int spdk_json_number_to_uint64(const struct spdk_json_val *val, uint64_t *num); diff --git a/lib/json/json_util.c b/lib/json/json_util.c index 5acc2e1ed4..f9669d4684 100644 --- a/lib/json/json_util.c +++ b/lib/json/json_util.c @@ -201,6 +201,28 @@ spdk_json_number_split(const struct spdk_json_val *val, struct spdk_json_num *nu return 0; } +int +spdk_json_number_to_uint16(const struct spdk_json_val *val, uint16_t *num) +{ + struct spdk_json_num split_num; + int rc; + + rc = spdk_json_number_split(val, &split_num); + if (rc) { + return rc; + } + + if (split_num.exponent || split_num.negative) { + return -ERANGE; + } + + if (split_num.significand > UINT16_MAX) { + return -ERANGE; + } + *num = (uint16_t)split_num.significand; + return 0; +} + int spdk_json_number_to_int32(const struct spdk_json_val *val, int32_t *num) { @@ -383,6 +405,14 @@ spdk_json_decode_bool(const struct spdk_json_val *val, void *out) return 0; } +int +spdk_json_decode_uint16(const struct spdk_json_val *val, void *out) +{ + uint16_t *i = out; + + return spdk_json_number_to_uint16(val, i); +} + int spdk_json_decode_int32(const struct spdk_json_val *val, void *out) { diff --git a/test/unit/lib/json/json_util.c/json_util_ut.c b/test/unit/lib/json/json_util.c/json_util_ut.c index e1996a18fd..2afd963e2d 100644 --- a/test/unit/lib/json/json_util.c/json_util_ut.c +++ b/test/unit/lib/json/json_util.c/json_util_ut.c @@ -43,6 +43,15 @@ v.start = buf; \ v.len = sizeof(x) - 1 +#define NUM_UINT16_PASS(s, i) \ + NUM_SETUP(s); \ + CU_ASSERT(spdk_json_number_to_uint16(&v, &u16) == 0); \ + CU_ASSERT(u16 == i) + +#define NUM_UINT16_FAIL(s) \ + NUM_SETUP(s); \ + CU_ASSERT(spdk_json_number_to_uint16(&v, &u16) != 0) + #define NUM_INT32_PASS(s, i) \ NUM_SETUP(s); \ CU_ASSERT(spdk_json_number_to_int32(&v, &i32) == 0); \ @@ -86,6 +95,30 @@ test_strequal(void) CU_ASSERT(spdk_json_strequal(&v, "test") == false); } +static void +test_num_to_uint16(void) +{ + struct spdk_json_val v; + char buf[100]; + uint16_t u16 = 0; + + NUM_SETUP("1234"); + CU_ASSERT(spdk_json_number_to_uint16(&v, &u16) == 0); + CU_ASSERT(u16 == 1234); + + NUM_UINT16_PASS("0", 0); + NUM_UINT16_PASS("1234", 1234); + NUM_UINT16_PASS("1234.00000", 1234); + NUM_UINT16_PASS("1.2e1", 12); + NUM_UINT16_PASS("12340e-1", 1234); + + NUM_UINT16_FAIL("1.2"); + NUM_UINT16_FAIL("-1234"); + NUM_UINT16_FAIL("1.2E0"); + NUM_UINT16_FAIL("1.234e1"); + NUM_UINT16_FAIL("12341e-1"); +} + static void test_num_to_int32(void) { @@ -409,6 +442,95 @@ test_decode_int32(void) CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); } +static void +test_decode_uint16(void) +{ + struct spdk_json_val v; + uint32_t i; + + /* incorrect type */ + v.type = SPDK_JSON_VAL_STRING; + v.start = "Strin"; + v.len = 5; + CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); + + /* invalid value (float) */ + v.type = SPDK_JSON_VAL_NUMBER; + v.start = "123.4"; + v.len = 5; + CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); + + /* edge case (0) */ + v.start = "0"; + v.len = 1; + i = 456; + CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0); + CU_ASSERT(i == 0); + + /* invalid value (negative) */ + v.start = "-1"; + v.len = 2; + CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); + + /* edge case (maximum) */ + v.start = "65535"; + v.len = 5; + i = 0; + CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0); + CU_ASSERT(i == 65535); + + /* invalid value (overflow) */ + v.start = "65536"; + v.len = 5; + i = 0; + CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); + + /* valid exponent */ + v.start = "66E2"; + v.len = 4; + i = 0; + CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0); + CU_ASSERT(i == 6600); + + /* invalid exponent (overflow) */ + v.start = "66E3"; + v.len = 4; + i = 0; + CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); + + /* invalid exponent (decimal) */ + v.start = "65.535E2"; + v.len = 7; + i = 0; + CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); + + /* valid exponent with decimal */ + v.start = "65.53E2"; + v.len = 7; + i = 0; + CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0); + CU_ASSERT(i == 6553); + + /* invalid negative exponent */ + v.start = "40e-2"; + v.len = 5; + i = 0; + CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); + + /* invalid negative exponent */ + v.start = "-40e-1"; + v.len = 6; + i = 0; + CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); + + /* valid negative exponent */ + v.start = "40e-1"; + v.len = 5; + i = 0; + CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0); + CU_ASSERT(i == 4); +} + static void test_decode_uint32(void) { @@ -658,11 +780,13 @@ int main(int argc, char **argv) if ( CU_add_test(suite, "strequal", test_strequal) == NULL || + CU_add_test(suite, "num_to_uint16", test_num_to_uint16) == NULL || CU_add_test(suite, "num_to_int32", test_num_to_int32) == NULL || CU_add_test(suite, "num_to_uint64", test_num_to_uint64) == NULL || CU_add_test(suite, "decode_object", test_decode_object) == NULL || CU_add_test(suite, "decode_array", test_decode_array) == NULL || CU_add_test(suite, "decode_bool", test_decode_bool) == NULL || + CU_add_test(suite, "decode_uint16", test_decode_uint16) == NULL || CU_add_test(suite, "decode_int32", test_decode_int32) == NULL || CU_add_test(suite, "decode_uint32", test_decode_uint32) == NULL || CU_add_test(suite, "decode_uint64", test_decode_uint64) == NULL ||