1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2016 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/stdinc.h" 7 8 #include "spdk_internal/cunit.h" 9 10 #include "json/json_write.c" 11 #include "json/json_parse.c" 12 13 #include "spdk/util.h" 14 15 static uint8_t g_buf[1000]; 16 static uint8_t *g_write_pos; 17 18 static int 19 write_cb(void *cb_ctx, const void *data, size_t size) 20 { 21 size_t buf_free = g_buf + sizeof(g_buf) - g_write_pos; 22 23 if (size > buf_free) { 24 return -1; 25 } 26 27 memcpy(g_write_pos, data, size); 28 g_write_pos += size; 29 30 return 0; 31 } 32 33 #define BEGIN() \ 34 memset(g_buf, 0, sizeof(g_buf)); \ 35 g_write_pos = g_buf; \ 36 w = spdk_json_write_begin(write_cb, NULL, 0); \ 37 SPDK_CU_ASSERT_FATAL(w != NULL) 38 39 #define END(json) \ 40 CU_ASSERT(spdk_json_write_end(w) == 0); \ 41 CU_ASSERT(g_write_pos - g_buf == sizeof(json) - 1); \ 42 CU_ASSERT(memcmp(json, g_buf, sizeof(json) - 1) == 0) 43 44 #define END_SIZE(val, size) \ 45 CU_ASSERT(spdk_json_write_end(w) == 0); \ 46 CU_ASSERT(g_write_pos - g_buf == size); \ 47 CU_ASSERT(memcmp(val, g_buf, size) == 0) 48 49 #define END_NOCMP() \ 50 CU_ASSERT(spdk_json_write_end(w) == 0) 51 52 #define END_SIZE_NOCMP(size) \ 53 CU_ASSERT(spdk_json_write_end(w) == 0); \ 54 CU_ASSERT(g_write_pos - g_buf == size) 55 56 #define END_FAIL() \ 57 CU_ASSERT(spdk_json_write_end(w) < 0) 58 59 #define VAL_STRING(str) \ 60 CU_ASSERT(spdk_json_write_string_raw(w, str, sizeof(str) - 1) == 0) 61 62 #define VAL_STRING_FAIL(str) \ 63 CU_ASSERT(spdk_json_write_string_raw(w, str, sizeof(str) - 1) < 0) 64 65 #define STR_PASS(in, out) \ 66 BEGIN(); VAL_STRING(in); END("\"" out "\"") 67 68 #define STR_FAIL(in) \ 69 BEGIN(); VAL_STRING_FAIL(in); END_FAIL() 70 71 #define VAL_STRING_UTF16LE(str) \ 72 CU_ASSERT(spdk_json_write_string_utf16le_raw(w, (const uint16_t *)str, sizeof(str) / sizeof(uint16_t) - 1) == 0) 73 74 #define VAL_STRING_UTF16LE_FAIL(str) \ 75 CU_ASSERT(spdk_json_write_string_utf16le_raw(w, (const uint16_t *)str, sizeof(str) / sizeof(uint16_t) - 1) < 0) 76 77 #define STR_UTF16LE_PASS(in, out) \ 78 BEGIN(); VAL_STRING_UTF16LE(in); END("\"" out "\"") 79 80 #define STR_UTF16LE_FAIL(in) \ 81 BEGIN(); VAL_STRING_UTF16LE_FAIL(in); END_FAIL() 82 83 #define VAL_NAME(name) \ 84 CU_ASSERT(spdk_json_write_name_raw(w, name, sizeof(name) - 1) == 0) 85 86 #define VAL_NULL() CU_ASSERT(spdk_json_write_null(w) == 0) 87 #define VAL_TRUE() CU_ASSERT(spdk_json_write_bool(w, true) == 0) 88 #define VAL_FALSE() CU_ASSERT(spdk_json_write_bool(w, false) == 0) 89 90 #define VAL_INT32(i) CU_ASSERT(spdk_json_write_int32(w, i) == 0); 91 #define VAL_UINT32(u) CU_ASSERT(spdk_json_write_uint32(w, u) == 0); 92 93 #define VAL_INT64(i) CU_ASSERT(spdk_json_write_int64(w, i) == 0); 94 #define VAL_UINT64(u) CU_ASSERT(spdk_json_write_uint64(w, u) == 0); 95 96 #define VAL_UINT128(low, high) \ 97 CU_ASSERT(spdk_json_write_uint128(w, low, high) == 0); 98 #define VAL_NAME_UINT128(name, low, high) \ 99 CU_ASSERT(spdk_json_write_named_uint128(w, name, low, high) == 0); 100 101 #define VAL_DOUBLE(d) CU_ASSERT(spdk_json_write_double(w, d) == 0); 102 103 #define VAL_UUID(u) CU_ASSERT(spdk_json_write_uuid(w, u) == 0) 104 105 #define VAL_ARRAY_BEGIN() CU_ASSERT(spdk_json_write_array_begin(w) == 0) 106 #define VAL_ARRAY_END() CU_ASSERT(spdk_json_write_array_end(w) == 0) 107 108 #define VAL_OBJECT_BEGIN() CU_ASSERT(spdk_json_write_object_begin(w) == 0) 109 #define VAL_OBJECT_END() CU_ASSERT(spdk_json_write_object_end(w) == 0) 110 111 #define VAL(v) CU_ASSERT(spdk_json_write_val(w, v) == 0) 112 113 static void 114 test_write_literal(void) 115 { 116 struct spdk_json_write_ctx *w; 117 118 BEGIN(); 119 VAL_NULL(); 120 END("null"); 121 122 BEGIN(); 123 VAL_TRUE(); 124 END("true"); 125 126 BEGIN(); 127 VAL_FALSE(); 128 END("false"); 129 } 130 131 static void 132 test_write_string_simple(void) 133 { 134 struct spdk_json_write_ctx *w; 135 136 STR_PASS("hello world", "hello world"); 137 STR_PASS(" ", " "); 138 STR_PASS("~", "~"); 139 } 140 141 static void 142 test_write_string_escapes(void) 143 { 144 struct spdk_json_write_ctx *w; 145 146 /* Two-character escapes */ 147 STR_PASS("\b", "\\b"); 148 STR_PASS("\f", "\\f"); 149 STR_PASS("\n", "\\n"); 150 STR_PASS("\r", "\\r"); 151 STR_PASS("\t", "\\t"); 152 STR_PASS("\"", "\\\""); 153 STR_PASS("\\", "\\\\"); 154 155 /* JSON defines an escape for forward slash, but it is optional */ 156 STR_PASS("/", "/"); 157 158 STR_PASS("hello\nworld", "hello\\nworld"); 159 160 STR_PASS("\x00", "\\u0000"); 161 STR_PASS("\x01", "\\u0001"); 162 STR_PASS("\x02", "\\u0002"); 163 164 STR_PASS("\xC3\xB6", "\\u00F6"); 165 STR_PASS("\xE2\x88\x9A", "\\u221A"); 166 STR_PASS("\xEA\xAA\xAA", "\\uAAAA"); 167 168 /* Surrogate pairs */ 169 STR_PASS("\xF0\x9D\x84\x9E", "\\uD834\\uDD1E"); 170 STR_PASS("\xF0\xA0\x9C\x8E", "\\uD841\\uDF0E"); 171 172 /* Examples from RFC 3629 */ 173 STR_PASS("\x41\xE2\x89\xA2\xCE\x91\x2E", "A\\u2262\\u0391."); 174 STR_PASS("\xED\x95\x9C\xEA\xB5\xAD\xEC\x96\xB4", "\\uD55C\\uAD6D\\uC5B4"); 175 STR_PASS("\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E", "\\u65E5\\u672C\\u8A9E"); 176 STR_PASS("\xEF\xBB\xBF\xF0\xA3\x8E\xB4", "\\uFEFF\\uD84C\\uDFB4"); 177 178 /* UTF-8 edge cases */ 179 STR_PASS("\x7F", "\\u007F"); 180 STR_FAIL("\x80"); 181 STR_FAIL("\xC1"); 182 STR_FAIL("\xC2"); 183 STR_PASS("\xC2\x80", "\\u0080"); 184 STR_PASS("\xC2\xBF", "\\u00BF"); 185 STR_PASS("\xDF\x80", "\\u07C0"); 186 STR_PASS("\xDF\xBF", "\\u07FF"); 187 STR_FAIL("\xDF"); 188 STR_FAIL("\xE0\x80"); 189 STR_FAIL("\xE0\x1F"); 190 STR_FAIL("\xE0\x1F\x80"); 191 STR_FAIL("\xE0"); 192 STR_FAIL("\xE0\xA0"); 193 STR_PASS("\xE0\xA0\x80", "\\u0800"); 194 STR_PASS("\xE0\xA0\xBF", "\\u083F"); 195 STR_FAIL("\xE0\xA0\xC0"); 196 STR_PASS("\xE0\xBF\x80", "\\u0FC0"); 197 STR_PASS("\xE0\xBF\xBF", "\\u0FFF"); 198 STR_FAIL("\xE0\xC0\x80"); 199 STR_FAIL("\xE1"); 200 STR_FAIL("\xE1\x80"); 201 STR_FAIL("\xE1\x7F\x80"); 202 STR_FAIL("\xE1\x80\x7F"); 203 STR_PASS("\xE1\x80\x80", "\\u1000"); 204 STR_PASS("\xE1\x80\xBF", "\\u103F"); 205 STR_PASS("\xE1\xBF\x80", "\\u1FC0"); 206 STR_PASS("\xE1\xBF\xBF", "\\u1FFF"); 207 STR_FAIL("\xE1\xC0\x80"); 208 STR_FAIL("\xE1\x80\xC0"); 209 STR_PASS("\xEF\x80\x80", "\\uF000"); 210 STR_PASS("\xEF\xBF\xBF", "\\uFFFF"); 211 STR_FAIL("\xF0"); 212 STR_FAIL("\xF0\x90"); 213 STR_FAIL("\xF0\x90\x80"); 214 STR_FAIL("\xF0\x80\x80\x80"); 215 STR_FAIL("\xF0\x8F\x80\x80"); 216 STR_PASS("\xF0\x90\x80\x80", "\\uD800\\uDC00"); 217 STR_PASS("\xF0\x90\x80\xBF", "\\uD800\\uDC3F"); 218 STR_PASS("\xF0\x90\xBF\x80", "\\uD803\\uDFC0"); 219 STR_PASS("\xF0\xBF\x80\x80", "\\uD8BC\\uDC00"); 220 STR_FAIL("\xF0\xC0\x80\x80"); 221 STR_FAIL("\xF1"); 222 STR_FAIL("\xF1\x80"); 223 STR_FAIL("\xF1\x80\x80"); 224 STR_FAIL("\xF1\x80\x80\x7F"); 225 STR_PASS("\xF1\x80\x80\x80", "\\uD8C0\\uDC00"); 226 STR_PASS("\xF1\x80\x80\xBF", "\\uD8C0\\uDC3F"); 227 STR_PASS("\xF1\x80\xBF\x80", "\\uD8C3\\uDFC0"); 228 STR_PASS("\xF1\xBF\x80\x80", "\\uD9BC\\uDC00"); 229 STR_PASS("\xF3\x80\x80\x80", "\\uDAC0\\uDC00"); 230 STR_FAIL("\xF3\xC0\x80\x80"); 231 STR_FAIL("\xF3\x80\xC0\x80"); 232 STR_FAIL("\xF3\x80\x80\xC0"); 233 STR_FAIL("\xF4"); 234 STR_FAIL("\xF4\x80"); 235 STR_FAIL("\xF4\x80\x80"); 236 STR_PASS("\xF4\x80\x80\x80", "\\uDBC0\\uDC00"); 237 STR_PASS("\xF4\x8F\x80\x80", "\\uDBFC\\uDC00"); 238 STR_PASS("\xF4\x8F\xBF\xBF", "\\uDBFF\\uDFFF"); 239 STR_FAIL("\xF4\x90\x80\x80"); 240 STR_FAIL("\xF5"); 241 STR_FAIL("\xF5\x80"); 242 STR_FAIL("\xF5\x80\x80"); 243 STR_FAIL("\xF5\x80\x80\x80"); 244 STR_FAIL("\xF5\x80\x80\x80\x80"); 245 246 /* Overlong encodings */ 247 STR_FAIL("\xC0\x80"); 248 249 /* Surrogate pairs */ 250 STR_FAIL("\xED\xA0\x80"); /* U+D800 First high surrogate */ 251 STR_FAIL("\xED\xAF\xBF"); /* U+DBFF Last high surrogate */ 252 STR_FAIL("\xED\xB0\x80"); /* U+DC00 First low surrogate */ 253 STR_FAIL("\xED\xBF\xBF"); /* U+DFFF Last low surrogate */ 254 STR_FAIL("\xED\xA1\x8C\xED\xBE\xB4"); /* U+233B4 (invalid surrogate pair encoding) */ 255 } 256 257 static void 258 test_write_string_utf16le(void) 259 { 260 struct spdk_json_write_ctx *w; 261 262 /* All characters in BMP */ 263 STR_UTF16LE_PASS(((uint8_t[]) { 264 'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o', 0, 0x15, 0xFE, 0, 0 265 }), "Hello\\uFE15"); 266 267 /* Surrogate pair */ 268 STR_UTF16LE_PASS(((uint8_t[]) { 269 'H', 0, 'i', 0, 0x34, 0xD8, 0x1E, 0xDD, '!', 0, 0, 0 270 }), "Hi\\uD834\\uDD1E!"); 271 272 /* Valid high surrogate, but no low surrogate */ 273 STR_UTF16LE_FAIL(((uint8_t[]) { 274 0x00, 0xD8, 0, 0 /* U+D800 */ 275 })); 276 277 /* Invalid leading low surrogate */ 278 STR_UTF16LE_FAIL(((uint8_t[]) { 279 0x00, 0xDC, 0x00, 0xDC, 0, 0 /* U+DC00 U+DC00 */ 280 })); 281 282 /* Valid high surrogate followed by another high surrogate (invalid) */ 283 STR_UTF16LE_FAIL(((uint8_t[]) { 284 0x00, 0xD8, 0x00, 0xD8, 0, 0 /* U+D800 U+D800 */ 285 })); 286 } 287 288 static void 289 test_write_number_int32(void) 290 { 291 struct spdk_json_write_ctx *w; 292 293 BEGIN(); 294 VAL_INT32(0); 295 END("0"); 296 297 BEGIN(); 298 VAL_INT32(1); 299 END("1"); 300 301 BEGIN(); 302 VAL_INT32(123); 303 END("123"); 304 305 BEGIN(); 306 VAL_INT32(-123); 307 END("-123"); 308 309 BEGIN(); 310 VAL_INT32(2147483647); 311 END("2147483647"); 312 313 BEGIN(); 314 VAL_INT32(-2147483648); 315 END("-2147483648"); 316 } 317 318 static void 319 test_write_number_uint32(void) 320 { 321 struct spdk_json_write_ctx *w; 322 323 BEGIN(); 324 VAL_UINT32(0); 325 END("0"); 326 327 BEGIN(); 328 VAL_UINT32(1); 329 END("1"); 330 331 BEGIN(); 332 VAL_UINT32(123); 333 END("123"); 334 335 BEGIN(); 336 VAL_UINT32(2147483647); 337 END("2147483647"); 338 339 BEGIN(); 340 VAL_UINT32(4294967295); 341 END("4294967295"); 342 } 343 344 static int 345 test_generate_string_uint128(char *buf, int buf_size, uint64_t low, uint64_t high) 346 { 347 char tmp_buf[256] = {0}; 348 unsigned __int128 total; 349 uint64_t seg; 350 int count = 0; 351 352 memset(buf, 0, buf_size); 353 total = ((unsigned __int128)high << 64) + (unsigned __int128)low; 354 while (total) { 355 /* Use the different calculation to get the 128bits decimal value in UT */ 356 seg = total % 1000000000000000; 357 total = total / 1000000000000000; 358 if (total) { 359 snprintf(tmp_buf, buf_size, "%015" PRIu64 "%s", seg, buf); 360 } else { 361 snprintf(tmp_buf, buf_size, "%" PRIu64 "%s", seg, buf); 362 } 363 364 count = snprintf(buf, buf_size, "%s", tmp_buf); 365 } 366 367 return count; 368 } 369 370 static int 371 test_generate_string_name_uint128(char *name, char *buf, int buf_size, uint64_t low, uint64_t high) 372 { 373 char tmp_buf[256] = {0}; 374 int count = test_generate_string_uint128(buf, buf_size, low, high); 375 376 memcpy(tmp_buf, buf, buf_size); 377 count = snprintf(buf, 256, "\"%s\":%s", name, tmp_buf); 378 379 return count; 380 } 381 382 static void 383 test_write_number_uint128(void) 384 { 385 struct spdk_json_write_ctx *w; 386 char buf[256] = {0}; 387 int used_count = 0; 388 389 BEGIN(); 390 VAL_UINT128(0, 0); 391 END("0"); 392 393 BEGIN(); 394 VAL_UINT128(1, 0); 395 used_count = test_generate_string_uint128(buf, sizeof(buf), 1, 0); 396 END_SIZE(buf, used_count); 397 398 BEGIN(); 399 VAL_UINT128(123, 0); 400 used_count = test_generate_string_uint128(buf, sizeof(buf), 123, 0); 401 END_SIZE(buf, used_count); 402 403 BEGIN(); 404 VAL_UINT128(2147483647, 0); 405 used_count = test_generate_string_uint128(buf, sizeof(buf), 2147483647, 0); 406 END_SIZE(buf, used_count); 407 408 BEGIN(); 409 VAL_UINT128(0, 1); 410 used_count = test_generate_string_uint128(buf, sizeof(buf), 0, 1); 411 END_SIZE(buf, used_count); 412 413 BEGIN(); 414 VAL_UINT128(4294967295, 1); 415 used_count = test_generate_string_uint128(buf, sizeof(buf), 4294967295, 1); 416 END_SIZE(buf, used_count); 417 418 BEGIN(); 419 VAL_UINT128(2147483647, 4294967295); 420 used_count = test_generate_string_uint128(buf, sizeof(buf), 2147483647, 4294967295); 421 END_SIZE(buf, used_count); 422 423 BEGIN(); 424 VAL_UINT128(4294967295, 4294967295); 425 used_count = test_generate_string_uint128(buf, sizeof(buf), 4294967295, 4294967295); 426 END_SIZE(buf, used_count); 427 } 428 429 static void 430 test_write_string_number_uint128(void) 431 { 432 struct spdk_json_write_ctx *w; 433 char buf[256] = {0}; 434 int used_count = 0; 435 436 BEGIN(); 437 VAL_NAME_UINT128("case1", 0, 0); 438 END("\"case1\":0"); 439 440 BEGIN(); 441 VAL_NAME_UINT128("case2", 1, 0); 442 used_count = test_generate_string_name_uint128("case2", buf, sizeof(buf), 1, 0); 443 END_SIZE(buf, used_count); 444 445 BEGIN(); 446 VAL_NAME_UINT128("case3", 123, 0); 447 used_count = test_generate_string_name_uint128("case3", buf, sizeof(buf), 123, 0); 448 END_SIZE(buf, used_count); 449 450 BEGIN(); 451 VAL_NAME_UINT128("case4", 2147483647, 0); 452 used_count = test_generate_string_name_uint128("case4", buf, sizeof(buf), 2147483647, 0); 453 END_SIZE(buf, used_count); 454 455 BEGIN(); 456 VAL_NAME_UINT128("case5", 0, 1); 457 used_count = test_generate_string_name_uint128("case5", buf, sizeof(buf), 0, 1); 458 END_SIZE(buf, used_count); 459 460 BEGIN(); 461 VAL_NAME_UINT128("case6", 4294967295, 1); 462 used_count = test_generate_string_name_uint128("case6", buf, sizeof(buf), 4294967295, 1); 463 END_SIZE(buf, used_count); 464 465 BEGIN(); 466 VAL_NAME_UINT128("case7", 2147483647, 4294967295); 467 used_count = test_generate_string_name_uint128("case7", buf, sizeof(buf), 2147483647, 4294967295); 468 END_SIZE(buf, used_count); 469 470 BEGIN(); 471 VAL_NAME_UINT128("case8", 4294967295, 4294967295); 472 used_count = test_generate_string_name_uint128("case8", buf, sizeof(buf), 4294967295, 4294967295); 473 END_SIZE(buf, used_count); 474 } 475 476 static void 477 test_write_number_int64(void) 478 { 479 struct spdk_json_write_ctx *w; 480 481 BEGIN(); 482 VAL_INT64(0); 483 END("0"); 484 485 BEGIN(); 486 VAL_INT64(1); 487 END("1"); 488 489 BEGIN(); 490 VAL_INT64(123); 491 END("123"); 492 493 BEGIN(); 494 VAL_INT64(-123); 495 END("-123"); 496 497 BEGIN(); 498 VAL_INT64(INT64_MAX); 499 END("9223372036854775807"); 500 501 BEGIN(); 502 VAL_INT64(INT64_MIN); 503 END("-9223372036854775808"); 504 } 505 506 static void 507 test_write_number_uint64(void) 508 { 509 struct spdk_json_write_ctx *w; 510 511 BEGIN(); 512 VAL_UINT64(0); 513 END("0"); 514 515 BEGIN(); 516 VAL_UINT64(1); 517 END("1"); 518 519 BEGIN(); 520 VAL_UINT64(123); 521 END("123"); 522 523 BEGIN(); 524 VAL_UINT64(INT64_MAX); 525 END("9223372036854775807"); 526 527 BEGIN(); 528 VAL_UINT64(UINT64_MAX); 529 END("18446744073709551615"); 530 } 531 532 static void 533 test_write_number_double(void) 534 { 535 struct spdk_json_write_ctx *w; 536 537 BEGIN(); 538 VAL_DOUBLE(0); 539 END_SIZE("0.00000000000000000000e+00", 26); 540 541 BEGIN(); 542 VAL_DOUBLE(1.2); 543 END_SIZE("1.19999999999999995559e+00", 26); 544 545 546 BEGIN(); 547 VAL_DOUBLE(1234.5678); 548 END_SIZE("1.23456780000000003383e+03", 26); 549 550 BEGIN(); 551 VAL_DOUBLE(-1234.5678); 552 END_SIZE("-1.23456780000000003383e+03", 27); 553 } 554 555 static void 556 test_write_uuid(void) 557 { 558 #define UT_UUID "e524acae-8c26-43e4-882a-461b8690583b" 559 struct spdk_json_write_ctx *w; 560 struct spdk_uuid uuid; 561 int rc; 562 563 rc = spdk_uuid_parse(&uuid, UT_UUID); 564 CU_ASSERT_EQUAL(rc, 0); 565 566 BEGIN(); 567 VAL_UUID(&uuid); 568 END("\"" UT_UUID "\""); 569 } 570 571 static void 572 test_write_array(void) 573 { 574 struct spdk_json_write_ctx *w; 575 576 BEGIN(); 577 VAL_ARRAY_BEGIN(); 578 VAL_ARRAY_END(); 579 END("[]"); 580 581 BEGIN(); 582 VAL_ARRAY_BEGIN(); 583 VAL_INT32(0); 584 VAL_ARRAY_END(); 585 END("[0]"); 586 587 BEGIN(); 588 VAL_ARRAY_BEGIN(); 589 VAL_INT32(0); 590 VAL_INT32(1); 591 VAL_ARRAY_END(); 592 END("[0,1]"); 593 594 BEGIN(); 595 VAL_ARRAY_BEGIN(); 596 VAL_INT32(0); 597 VAL_INT32(1); 598 VAL_INT32(2); 599 VAL_ARRAY_END(); 600 END("[0,1,2]"); 601 602 BEGIN(); 603 VAL_ARRAY_BEGIN(); 604 VAL_STRING("a"); 605 VAL_ARRAY_END(); 606 END("[\"a\"]"); 607 608 BEGIN(); 609 VAL_ARRAY_BEGIN(); 610 VAL_STRING("a"); 611 VAL_STRING("b"); 612 VAL_ARRAY_END(); 613 END("[\"a\",\"b\"]"); 614 615 BEGIN(); 616 VAL_ARRAY_BEGIN(); 617 VAL_STRING("a"); 618 VAL_STRING("b"); 619 VAL_STRING("c"); 620 VAL_ARRAY_END(); 621 END("[\"a\",\"b\",\"c\"]"); 622 623 BEGIN(); 624 VAL_ARRAY_BEGIN(); 625 VAL_TRUE(); 626 VAL_ARRAY_END(); 627 END("[true]"); 628 629 BEGIN(); 630 VAL_ARRAY_BEGIN(); 631 VAL_TRUE(); 632 VAL_FALSE(); 633 VAL_ARRAY_END(); 634 END("[true,false]"); 635 636 BEGIN(); 637 VAL_ARRAY_BEGIN(); 638 VAL_TRUE(); 639 VAL_FALSE(); 640 VAL_TRUE(); 641 VAL_ARRAY_END(); 642 END("[true,false,true]"); 643 } 644 645 static void 646 test_write_object(void) 647 { 648 struct spdk_json_write_ctx *w; 649 650 BEGIN(); 651 VAL_OBJECT_BEGIN(); 652 VAL_OBJECT_END(); 653 END("{}"); 654 655 BEGIN(); 656 VAL_OBJECT_BEGIN(); 657 VAL_NAME("a"); 658 VAL_INT32(0); 659 VAL_OBJECT_END(); 660 END("{\"a\":0}"); 661 662 BEGIN(); 663 VAL_OBJECT_BEGIN(); 664 VAL_NAME("a"); 665 VAL_INT32(0); 666 VAL_NAME("b"); 667 VAL_INT32(1); 668 VAL_OBJECT_END(); 669 END("{\"a\":0,\"b\":1}"); 670 671 BEGIN(); 672 VAL_OBJECT_BEGIN(); 673 VAL_NAME("a"); 674 VAL_INT32(0); 675 VAL_NAME("b"); 676 VAL_INT32(1); 677 VAL_NAME("c"); 678 VAL_INT32(2); 679 VAL_OBJECT_END(); 680 END("{\"a\":0,\"b\":1,\"c\":2}"); 681 } 682 683 static void 684 test_write_nesting(void) 685 { 686 struct spdk_json_write_ctx *w; 687 688 BEGIN(); 689 VAL_ARRAY_BEGIN(); 690 VAL_ARRAY_BEGIN(); 691 VAL_ARRAY_END(); 692 VAL_ARRAY_END(); 693 END("[[]]"); 694 695 BEGIN(); 696 VAL_ARRAY_BEGIN(); 697 VAL_ARRAY_BEGIN(); 698 VAL_ARRAY_BEGIN(); 699 VAL_ARRAY_END(); 700 VAL_ARRAY_END(); 701 VAL_ARRAY_END(); 702 END("[[[]]]"); 703 704 BEGIN(); 705 VAL_ARRAY_BEGIN(); 706 VAL_INT32(0); 707 VAL_ARRAY_BEGIN(); 708 VAL_ARRAY_END(); 709 VAL_ARRAY_END(); 710 END("[0,[]]"); 711 712 BEGIN(); 713 VAL_ARRAY_BEGIN(); 714 VAL_ARRAY_BEGIN(); 715 VAL_ARRAY_END(); 716 VAL_INT32(0); 717 VAL_ARRAY_END(); 718 END("[[],0]"); 719 720 BEGIN(); 721 VAL_ARRAY_BEGIN(); 722 VAL_INT32(0); 723 VAL_ARRAY_BEGIN(); 724 VAL_INT32(1); 725 VAL_ARRAY_END(); 726 VAL_INT32(2); 727 VAL_ARRAY_END(); 728 END("[0,[1],2]"); 729 730 BEGIN(); 731 VAL_ARRAY_BEGIN(); 732 VAL_INT32(0); 733 VAL_INT32(1); 734 VAL_ARRAY_BEGIN(); 735 VAL_INT32(2); 736 VAL_INT32(3); 737 VAL_ARRAY_END(); 738 VAL_INT32(4); 739 VAL_INT32(5); 740 VAL_ARRAY_END(); 741 END("[0,1,[2,3],4,5]"); 742 743 BEGIN(); 744 VAL_OBJECT_BEGIN(); 745 VAL_NAME("a"); 746 VAL_OBJECT_BEGIN(); 747 VAL_OBJECT_END(); 748 VAL_OBJECT_END(); 749 END("{\"a\":{}}"); 750 751 BEGIN(); 752 VAL_OBJECT_BEGIN(); 753 VAL_NAME("a"); 754 VAL_OBJECT_BEGIN(); 755 VAL_NAME("b"); 756 VAL_INT32(0); 757 VAL_OBJECT_END(); 758 VAL_OBJECT_END(); 759 END("{\"a\":{\"b\":0}}"); 760 761 BEGIN(); 762 VAL_OBJECT_BEGIN(); 763 VAL_NAME("a"); 764 VAL_ARRAY_BEGIN(); 765 VAL_INT32(0); 766 VAL_ARRAY_END(); 767 VAL_OBJECT_END(); 768 END("{\"a\":[0]}"); 769 770 BEGIN(); 771 VAL_ARRAY_BEGIN(); 772 VAL_OBJECT_BEGIN(); 773 VAL_NAME("a"); 774 VAL_INT32(0); 775 VAL_OBJECT_END(); 776 VAL_ARRAY_END(); 777 END("[{\"a\":0}]"); 778 779 BEGIN(); 780 VAL_ARRAY_BEGIN(); 781 VAL_OBJECT_BEGIN(); 782 VAL_NAME("a"); 783 VAL_OBJECT_BEGIN(); 784 VAL_NAME("b"); 785 VAL_ARRAY_BEGIN(); 786 VAL_OBJECT_BEGIN(); 787 VAL_NAME("c"); 788 VAL_INT32(1); 789 VAL_OBJECT_END(); 790 VAL_INT32(2); 791 VAL_ARRAY_END(); 792 VAL_NAME("d"); 793 VAL_INT32(3); 794 VAL_OBJECT_END(); 795 VAL_NAME("e"); 796 VAL_INT32(4); 797 VAL_OBJECT_END(); 798 VAL_INT32(5); 799 VAL_ARRAY_END(); 800 END("[{\"a\":{\"b\":[{\"c\":1},2],\"d\":3},\"e\":4},5]"); 801 802 /* Examples from RFC 7159 */ 803 BEGIN(); 804 VAL_OBJECT_BEGIN(); 805 VAL_NAME("Image"); 806 VAL_OBJECT_BEGIN(); 807 VAL_NAME("Width"); 808 VAL_INT32(800); 809 VAL_NAME("Height"); 810 VAL_INT32(600); 811 VAL_NAME("Title"); 812 VAL_STRING("View from 15th Floor"); 813 VAL_NAME("Thumbnail"); 814 VAL_OBJECT_BEGIN(); 815 VAL_NAME("Url"); 816 VAL_STRING("http://www.example.com/image/481989943"); 817 VAL_NAME("Height"); 818 VAL_INT32(125); 819 VAL_NAME("Width"); 820 VAL_INT32(100); 821 VAL_OBJECT_END(); 822 VAL_NAME("Animated"); 823 VAL_FALSE(); 824 VAL_NAME("IDs"); 825 VAL_ARRAY_BEGIN(); 826 VAL_INT32(116); 827 VAL_INT32(943); 828 VAL_INT32(234); 829 VAL_INT32(38793); 830 VAL_ARRAY_END(); 831 VAL_OBJECT_END(); 832 VAL_OBJECT_END(); 833 END( 834 "{\"Image\":" 835 "{" 836 "\"Width\":800," 837 "\"Height\":600," 838 "\"Title\":\"View from 15th Floor\"," 839 "\"Thumbnail\":{" 840 "\"Url\":\"http://www.example.com/image/481989943\"," 841 "\"Height\":125," 842 "\"Width\":100" 843 "}," 844 "\"Animated\":false," 845 "\"IDs\":[116,943,234,38793]" 846 "}" 847 "}"); 848 } 849 850 /* Round-trip parse and write test */ 851 static void 852 test_write_val(void) 853 { 854 struct spdk_json_write_ctx *w; 855 struct spdk_json_val values[100]; 856 char src[] = "{\"a\":[1,2,3],\"b\":{\"c\":\"d\"},\"e\":true,\"f\":false,\"g\":null}"; 857 858 CU_ASSERT(spdk_json_parse(src, strlen(src), values, SPDK_COUNTOF(values), NULL, 859 SPDK_JSON_PARSE_FLAG_DECODE_IN_PLACE) == 19); 860 861 BEGIN(); 862 VAL(values); 863 END("{\"a\":[1,2,3],\"b\":{\"c\":\"d\"},\"e\":true,\"f\":false,\"g\":null}"); 864 } 865 866 int 867 main(int argc, char **argv) 868 { 869 CU_pSuite suite = NULL; 870 unsigned int num_failures; 871 872 CU_initialize_registry(); 873 874 suite = CU_add_suite("json", NULL, NULL); 875 876 CU_ADD_TEST(suite, test_write_literal); 877 CU_ADD_TEST(suite, test_write_string_simple); 878 CU_ADD_TEST(suite, test_write_string_escapes); 879 CU_ADD_TEST(suite, test_write_string_utf16le); 880 CU_ADD_TEST(suite, test_write_number_int32); 881 CU_ADD_TEST(suite, test_write_number_uint32); 882 CU_ADD_TEST(suite, test_write_number_uint128); 883 CU_ADD_TEST(suite, test_write_string_number_uint128); 884 CU_ADD_TEST(suite, test_write_number_int64); 885 CU_ADD_TEST(suite, test_write_number_uint64); 886 CU_ADD_TEST(suite, test_write_number_double); 887 CU_ADD_TEST(suite, test_write_uuid); 888 CU_ADD_TEST(suite, test_write_array); 889 CU_ADD_TEST(suite, test_write_object); 890 CU_ADD_TEST(suite, test_write_nesting); 891 CU_ADD_TEST(suite, test_write_val); 892 893 894 num_failures = spdk_ut_run_tests(argc, argv, NULL); 895 896 CU_cleanup_registry(); 897 898 return num_failures; 899 } 900