json: add the spdk_json_write_uint128 function

Add the paired spdk_json_write_named_uint128 function

Change-Id: I222f0c5076efe150ab2861c0d915d18476815e37
Signed-off-by: GangCao <gang.cao@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/8797
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Community-CI: Mellanox Build Bot
This commit is contained in:
WindYu 2021-07-21 16:44:23 -04:00 committed by Tomasz Zawadzki
parent 585e808e06
commit 2d629511f5
6 changed files with 203 additions and 1 deletions

View File

@ -2,6 +2,11 @@
## v21.07: (Upcoming Release)
### json
Added API `spdk_json_write_named_uint128` and `spdk_json_write_uint128` to perform
the uint128 related data.
### accel_fw
Added API `spdk_accel_submit_copy_crc32c` to perform a CRC32C while copying data.

View File

@ -208,6 +208,7 @@ int spdk_json_write_int32(struct spdk_json_write_ctx *w, int32_t val);
int spdk_json_write_uint32(struct spdk_json_write_ctx *w, uint32_t val);
int spdk_json_write_int64(struct spdk_json_write_ctx *w, int64_t val);
int spdk_json_write_uint64(struct spdk_json_write_ctx *w, uint64_t val);
int spdk_json_write_uint128(struct spdk_json_write_ctx *w, uint64_t low_val, uint64_t high_val);
int spdk_json_write_string(struct spdk_json_write_ctx *w, const char *val);
int spdk_json_write_string_raw(struct spdk_json_write_ctx *w, const char *val, size_t len);
@ -257,6 +258,8 @@ int spdk_json_write_named_bool(struct spdk_json_write_ctx *w, const char *name,
int spdk_json_write_named_int32(struct spdk_json_write_ctx *w, const char *name, int32_t val);
int spdk_json_write_named_uint32(struct spdk_json_write_ctx *w, const char *name, uint32_t val);
int spdk_json_write_named_uint64(struct spdk_json_write_ctx *w, const char *name, uint64_t val);
int spdk_json_write_named_uint128(struct spdk_json_write_ctx *w, const char *name,
uint64_t low_val, uint64_t high_val);
int spdk_json_write_named_int64(struct spdk_json_write_ctx *w, const char *name, int64_t val);
int spdk_json_write_named_string(struct spdk_json_write_ctx *w, const char *name, const char *val);
int spdk_json_write_named_string_fmt(struct spdk_json_write_ctx *w, const char *name,

View File

@ -35,7 +35,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
SO_VER := 3
SO_MINOR := 0
SO_MINOR := 1
C_SRCS = json_parse.c json_util.c json_write.c
LIBNAME = json

View File

@ -265,6 +265,54 @@ spdk_json_write_uint64(struct spdk_json_write_ctx *w, uint64_t val)
return emit(w, buf, count);
}
int
spdk_json_write_uint128(struct spdk_json_write_ctx *w, uint64_t low_val, uint64_t high_val)
{
char buf[128] = {'\0'};
uint64_t low = low_val, high = high_val;
int count = 0;
if (begin_value(w)) { return fail(w); }
if (high != 0) {
char temp_buf[128] = {'\0'};
uint64_t seg;
unsigned __int128 total = (unsigned __int128)low +
((unsigned __int128)high << 64);
while (total) {
seg = total % 10000000000;
total = total / 10000000000;
if (total) {
count = snprintf(temp_buf, 128, "%010" PRIu64 "%s", seg, buf);
} else {
count = snprintf(temp_buf, 128, "%" PRIu64 "%s", seg, buf);
}
if (count <= 0 || (size_t)count >= sizeof(temp_buf)) {
return fail(w);
}
snprintf(buf, 128, "%s", temp_buf);
}
} else {
count = snprintf(buf, sizeof(buf), "%" PRIu64, low);
if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
}
return emit(w, buf, count);
}
int
spdk_json_write_named_uint128(struct spdk_json_write_ctx *w, const char *name,
uint64_t low_val, uint64_t high_val)
{
int rc = spdk_json_write_name(w, name);
return rc ? rc : spdk_json_write_uint128(w, low_val, high_val);
}
static void
write_hex_4(void *dest, uint16_t val)
{

View File

@ -32,6 +32,7 @@
spdk_json_write_uint32;
spdk_json_write_int64;
spdk_json_write_uint64;
spdk_json_write_uint128;
spdk_json_write_string;
spdk_json_write_string_raw;
spdk_json_write_string_utf16le;
@ -53,6 +54,7 @@
spdk_json_write_named_uint32;
spdk_json_write_named_uint64;
spdk_json_write_named_int64;
spdk_json_write_named_uint128;
spdk_json_write_named_string;
spdk_json_write_named_string_fmt;
spdk_json_write_named_string_fmt_v;

View File

@ -69,6 +69,11 @@ write_cb(void *cb_ctx, const void *data, size_t size)
CU_ASSERT(g_write_pos - g_buf == sizeof(json) - 1); \
CU_ASSERT(memcmp(json, g_buf, sizeof(json) - 1) == 0)
#define END_SIZE(val, size) \
CU_ASSERT(spdk_json_write_end(w) == 0); \
CU_ASSERT(g_write_pos - g_buf == size); \
CU_ASSERT(memcmp(val, g_buf, size) == 0)
#define END_NOCMP() \
CU_ASSERT(spdk_json_write_end(w) == 0)
@ -112,6 +117,11 @@ write_cb(void *cb_ctx, const void *data, size_t size)
#define VAL_INT64(i) CU_ASSERT(spdk_json_write_int64(w, i) == 0);
#define VAL_UINT64(u) CU_ASSERT(spdk_json_write_uint64(w, u) == 0);
#define VAL_UINT128(low, high) \
CU_ASSERT(spdk_json_write_uint128(w, low, high) == 0);
#define VAL_NAME_UINT128(name, low, high) \
CU_ASSERT(spdk_json_write_named_uint128(w, name, low, high) == 0);
#define VAL_ARRAY_BEGIN() CU_ASSERT(spdk_json_write_array_begin(w) == 0)
#define VAL_ARRAY_END() CU_ASSERT(spdk_json_write_array_end(w) == 0)
@ -351,6 +361,138 @@ test_write_number_uint32(void)
END("4294967295");
}
static int
test_generate_string_uint128(char *buf, int buf_size, uint64_t low, uint64_t high)
{
char tmp_buf[256] = {0};
unsigned __int128 total;
uint64_t seg;
int count = 0;
memset(buf, 0, buf_size);
total = ((unsigned __int128)high << 64) + (unsigned __int128)low;
while (total) {
/* Use the different calculation to get the 128bits decimal value in UT */
seg = total % 1000000000000000;
total = total / 1000000000000000;
if (total) {
snprintf(tmp_buf, buf_size, "%015" PRIu64 "%s", seg, buf);
} else {
snprintf(tmp_buf, buf_size, "%" PRIu64 "%s", seg, buf);
}
count = snprintf(buf, buf_size, "%s", tmp_buf);
}
return count;
}
static int
test_generate_string_name_uint128(char *name, char *buf, int buf_size, uint64_t low, uint64_t high)
{
char tmp_buf[256] = {0};
int count = test_generate_string_uint128(buf, buf_size, low, high);
memcpy(tmp_buf, buf, buf_size);
count = snprintf(buf, 256, "\"%s\":%s", name, tmp_buf);
return count;
}
static void
test_write_number_uint128(void)
{
struct spdk_json_write_ctx *w;
char buf[256] = {0};
int used_count = 0;
BEGIN();
VAL_UINT128(0, 0);
END("0");
BEGIN();
VAL_UINT128(1, 0);
used_count = test_generate_string_uint128(buf, sizeof(buf), 1, 0);
END_SIZE(buf, used_count);
BEGIN();
VAL_UINT128(123, 0);
used_count = test_generate_string_uint128(buf, sizeof(buf), 123, 0);
END_SIZE(buf, used_count);
BEGIN();
VAL_UINT128(2147483647, 0);
used_count = test_generate_string_uint128(buf, sizeof(buf), 2147483647, 0);
END_SIZE(buf, used_count);
BEGIN();
VAL_UINT128(0, 1);
used_count = test_generate_string_uint128(buf, sizeof(buf), 0, 1);
END_SIZE(buf, used_count);
BEGIN();
VAL_UINT128(4294967295, 1);
used_count = test_generate_string_uint128(buf, sizeof(buf), 4294967295, 1);
END_SIZE(buf, used_count);
BEGIN();
VAL_UINT128(2147483647, 4294967295);
used_count = test_generate_string_uint128(buf, sizeof(buf), 2147483647, 4294967295);
END_SIZE(buf, used_count);
BEGIN();
VAL_UINT128(4294967295, 4294967295);
used_count = test_generate_string_uint128(buf, sizeof(buf), 4294967295, 4294967295);
END_SIZE(buf, used_count);
}
static void
test_write_string_number_uint128(void)
{
struct spdk_json_write_ctx *w;
char buf[256] = {0};
int used_count = 0;
BEGIN();
VAL_NAME_UINT128("case1", 0, 0);
END("\"case1\":0");
BEGIN();
VAL_NAME_UINT128("case2", 1, 0);
used_count = test_generate_string_name_uint128("case2", buf, sizeof(buf), 1, 0);
END_SIZE(buf, used_count);
BEGIN();
VAL_NAME_UINT128("case3", 123, 0);
used_count = test_generate_string_name_uint128("case3", buf, sizeof(buf), 123, 0);
END_SIZE(buf, used_count);
BEGIN();
VAL_NAME_UINT128("case4", 2147483647, 0);
used_count = test_generate_string_name_uint128("case4", buf, sizeof(buf), 2147483647, 0);
END_SIZE(buf, used_count);
BEGIN();
VAL_NAME_UINT128("case5", 0, 1);
used_count = test_generate_string_name_uint128("case5", buf, sizeof(buf), 0, 1);
END_SIZE(buf, used_count);
BEGIN();
VAL_NAME_UINT128("case6", 4294967295, 1);
used_count = test_generate_string_name_uint128("case6", buf, sizeof(buf), 4294967295, 1);
END_SIZE(buf, used_count);
BEGIN();
VAL_NAME_UINT128("case7", 2147483647, 4294967295);
used_count = test_generate_string_name_uint128("case7", buf, sizeof(buf), 2147483647, 4294967295);
END_SIZE(buf, used_count);
BEGIN();
VAL_NAME_UINT128("case8", 4294967295, 4294967295);
used_count = test_generate_string_name_uint128("case8", buf, sizeof(buf), 4294967295, 4294967295);
END_SIZE(buf, used_count);
}
static void
test_write_number_int64(void)
{
@ -718,6 +860,8 @@ int main(int argc, char **argv)
CU_ADD_TEST(suite, test_write_string_utf16le);
CU_ADD_TEST(suite, test_write_number_int32);
CU_ADD_TEST(suite, test_write_number_uint32);
CU_ADD_TEST(suite, test_write_number_uint128);
CU_ADD_TEST(suite, test_write_string_number_uint128);
CU_ADD_TEST(suite, test_write_number_int64);
CU_ADD_TEST(suite, test_write_number_uint64);
CU_ADD_TEST(suite, test_write_array);