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