1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 36 #include "spdk_cunit.h" 37 38 #include "json/json_write.c" 39 #include "json/json_parse.c" 40 41 #include "spdk/util.h" 42 43 static uint8_t g_buf[1000]; 44 static uint8_t *g_write_pos; 45 46 static int 47 write_cb(void *cb_ctx, const void *data, size_t size) 48 { 49 size_t buf_free = g_buf + sizeof(g_buf) - g_write_pos; 50 51 if (size > buf_free) { 52 return -1; 53 } 54 55 memcpy(g_write_pos, data, size); 56 g_write_pos += size; 57 58 return 0; 59 } 60 61 #define BEGIN() \ 62 memset(g_buf, 0, sizeof(g_buf)); \ 63 g_write_pos = g_buf; \ 64 w = spdk_json_write_begin(write_cb, NULL, 0); \ 65 CU_ASSERT_FATAL(w != NULL) 66 67 #define END(json) \ 68 CU_ASSERT(spdk_json_write_end(w) == 0); \ 69 CU_ASSERT(g_write_pos - g_buf == sizeof(json) - 1); \ 70 CU_ASSERT(memcmp(json, g_buf, sizeof(json) - 1) == 0) 71 72 #define END_NOCMP() \ 73 CU_ASSERT(spdk_json_write_end(w) == 0) 74 75 #define END_FAIL() \ 76 CU_ASSERT(spdk_json_write_end(w) < 0) 77 78 #define VAL_STRING(str) \ 79 CU_ASSERT(spdk_json_write_string_raw(w, str, sizeof(str) - 1) == 0) 80 81 #define VAL_STRING_FAIL(str) \ 82 CU_ASSERT(spdk_json_write_string_raw(w, str, sizeof(str) - 1) < 0) 83 84 #define STR_PASS(in, out) \ 85 BEGIN(); VAL_STRING(in); END("\"" out "\"") 86 87 #define STR_FAIL(in) \ 88 BEGIN(); VAL_STRING_FAIL(in); END_FAIL() 89 90 #define VAL_STRING_UTF16LE(str) \ 91 CU_ASSERT(spdk_json_write_string_utf16le_raw(w, (const uint16_t *)str, sizeof(str) / sizeof(uint16_t) - 1) == 0) 92 93 #define VAL_STRING_UTF16LE_FAIL(str) \ 94 CU_ASSERT(spdk_json_write_string_utf16le_raw(w, (const uint16_t *)str, sizeof(str) / sizeof(uint16_t) - 1) < 0) 95 96 #define STR_UTF16LE_PASS(in, out) \ 97 BEGIN(); VAL_STRING_UTF16LE(in); END("\"" out "\"") 98 99 #define STR_UTF16LE_FAIL(in) \ 100 BEGIN(); VAL_STRING_UTF16LE_FAIL(in); END_FAIL() 101 102 #define VAL_NAME(name) \ 103 CU_ASSERT(spdk_json_write_name_raw(w, name, sizeof(name) - 1) == 0) 104 105 #define VAL_NULL() CU_ASSERT(spdk_json_write_null(w) == 0) 106 #define VAL_TRUE() CU_ASSERT(spdk_json_write_bool(w, true) == 0) 107 #define VAL_FALSE() CU_ASSERT(spdk_json_write_bool(w, false) == 0) 108 109 #define VAL_INT32(i) CU_ASSERT(spdk_json_write_int32(w, i) == 0); 110 #define VAL_UINT32(u) CU_ASSERT(spdk_json_write_uint32(w, u) == 0); 111 112 #define VAL_INT64(i) CU_ASSERT(spdk_json_write_int64(w, i) == 0); 113 #define VAL_UINT64(u) CU_ASSERT(spdk_json_write_uint64(w, u) == 0); 114 115 #define VAL_ARRAY_BEGIN() CU_ASSERT(spdk_json_write_array_begin(w) == 0) 116 #define VAL_ARRAY_END() CU_ASSERT(spdk_json_write_array_end(w) == 0) 117 118 #define VAL_OBJECT_BEGIN() CU_ASSERT(spdk_json_write_object_begin(w) == 0) 119 #define VAL_OBJECT_END() CU_ASSERT(spdk_json_write_object_end(w) == 0) 120 121 #define VAL(v) CU_ASSERT(spdk_json_write_val(w, v) == 0) 122 123 static void 124 test_write_literal(void) 125 { 126 struct spdk_json_write_ctx *w; 127 128 BEGIN(); 129 VAL_NULL(); 130 END("null"); 131 132 BEGIN(); 133 VAL_TRUE(); 134 END("true"); 135 136 BEGIN(); 137 VAL_FALSE(); 138 END("false"); 139 } 140 141 static void 142 test_write_string_simple(void) 143 { 144 struct spdk_json_write_ctx *w; 145 146 STR_PASS("hello world", "hello world"); 147 STR_PASS(" ", " "); 148 STR_PASS("~", "~"); 149 } 150 151 static void 152 test_write_string_escapes(void) 153 { 154 struct spdk_json_write_ctx *w; 155 156 /* Two-character escapes */ 157 STR_PASS("\b", "\\b"); 158 STR_PASS("\f", "\\f"); 159 STR_PASS("\n", "\\n"); 160 STR_PASS("\r", "\\r"); 161 STR_PASS("\t", "\\t"); 162 STR_PASS("\"", "\\\""); 163 STR_PASS("\\", "\\\\"); 164 165 /* JSON defines an escape for forward slash, but it is optional */ 166 STR_PASS("/", "/"); 167 168 STR_PASS("hello\nworld", "hello\\nworld"); 169 170 STR_PASS("\x00", "\\u0000"); 171 STR_PASS("\x01", "\\u0001"); 172 STR_PASS("\x02", "\\u0002"); 173 174 STR_PASS("\xC3\xB6", "\\u00F6"); 175 STR_PASS("\xE2\x88\x9A", "\\u221A"); 176 STR_PASS("\xEA\xAA\xAA", "\\uAAAA"); 177 178 /* Surrogate pairs */ 179 STR_PASS("\xF0\x9D\x84\x9E", "\\uD834\\uDD1E"); 180 STR_PASS("\xF0\xA0\x9C\x8E", "\\uD841\\uDF0E"); 181 182 /* Examples from RFC 3629 */ 183 STR_PASS("\x41\xE2\x89\xA2\xCE\x91\x2E", "A\\u2262\\u0391."); 184 STR_PASS("\xED\x95\x9C\xEA\xB5\xAD\xEC\x96\xB4", "\\uD55C\\uAD6D\\uC5B4"); 185 STR_PASS("\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E", "\\u65E5\\u672C\\u8A9E"); 186 STR_PASS("\xEF\xBB\xBF\xF0\xA3\x8E\xB4", "\\uFEFF\\uD84C\\uDFB4"); 187 188 /* UTF-8 edge cases */ 189 STR_PASS("\x7F", "\\u007F"); 190 STR_FAIL("\x80"); 191 STR_FAIL("\xC1"); 192 STR_FAIL("\xC2"); 193 STR_PASS("\xC2\x80", "\\u0080"); 194 STR_PASS("\xC2\xBF", "\\u00BF"); 195 STR_PASS("\xDF\x80", "\\u07C0"); 196 STR_PASS("\xDF\xBF", "\\u07FF"); 197 STR_FAIL("\xDF"); 198 STR_FAIL("\xE0\x80"); 199 STR_FAIL("\xE0\x1F"); 200 STR_FAIL("\xE0\x1F\x80"); 201 STR_FAIL("\xE0"); 202 STR_FAIL("\xE0\xA0"); 203 STR_PASS("\xE0\xA0\x80", "\\u0800"); 204 STR_PASS("\xE0\xA0\xBF", "\\u083F"); 205 STR_FAIL("\xE0\xA0\xC0"); 206 STR_PASS("\xE0\xBF\x80", "\\u0FC0"); 207 STR_PASS("\xE0\xBF\xBF", "\\u0FFF"); 208 STR_FAIL("\xE0\xC0\x80"); 209 STR_FAIL("\xE1"); 210 STR_FAIL("\xE1\x80"); 211 STR_FAIL("\xE1\x7F\x80"); 212 STR_FAIL("\xE1\x80\x7F"); 213 STR_PASS("\xE1\x80\x80", "\\u1000"); 214 STR_PASS("\xE1\x80\xBF", "\\u103F"); 215 STR_PASS("\xE1\xBF\x80", "\\u1FC0"); 216 STR_PASS("\xE1\xBF\xBF", "\\u1FFF"); 217 STR_FAIL("\xE1\xC0\x80"); 218 STR_FAIL("\xE1\x80\xC0"); 219 STR_PASS("\xEF\x80\x80", "\\uF000"); 220 STR_PASS("\xEF\xBF\xBF", "\\uFFFF"); 221 STR_FAIL("\xF0"); 222 STR_FAIL("\xF0\x90"); 223 STR_FAIL("\xF0\x90\x80"); 224 STR_FAIL("\xF0\x80\x80\x80"); 225 STR_FAIL("\xF0\x8F\x80\x80"); 226 STR_PASS("\xF0\x90\x80\x80", "\\uD800\\uDC00"); 227 STR_PASS("\xF0\x90\x80\xBF", "\\uD800\\uDC3F"); 228 STR_PASS("\xF0\x90\xBF\x80", "\\uD803\\uDFC0"); 229 STR_PASS("\xF0\xBF\x80\x80", "\\uD8BC\\uDC00"); 230 STR_FAIL("\xF0\xC0\x80\x80"); 231 STR_FAIL("\xF1"); 232 STR_FAIL("\xF1\x80"); 233 STR_FAIL("\xF1\x80\x80"); 234 STR_FAIL("\xF1\x80\x80\x7F"); 235 STR_PASS("\xF1\x80\x80\x80", "\\uD8C0\\uDC00"); 236 STR_PASS("\xF1\x80\x80\xBF", "\\uD8C0\\uDC3F"); 237 STR_PASS("\xF1\x80\xBF\x80", "\\uD8C3\\uDFC0"); 238 STR_PASS("\xF1\xBF\x80\x80", "\\uD9BC\\uDC00"); 239 STR_PASS("\xF3\x80\x80\x80", "\\uDAC0\\uDC00"); 240 STR_FAIL("\xF3\xC0\x80\x80"); 241 STR_FAIL("\xF3\x80\xC0\x80"); 242 STR_FAIL("\xF3\x80\x80\xC0"); 243 STR_FAIL("\xF4"); 244 STR_FAIL("\xF4\x80"); 245 STR_FAIL("\xF4\x80\x80"); 246 STR_PASS("\xF4\x80\x80\x80", "\\uDBC0\\uDC00"); 247 STR_PASS("\xF4\x8F\x80\x80", "\\uDBFC\\uDC00"); 248 STR_PASS("\xF4\x8F\xBF\xBF", "\\uDBFF\\uDFFF"); 249 STR_FAIL("\xF4\x90\x80\x80"); 250 STR_FAIL("\xF5"); 251 STR_FAIL("\xF5\x80"); 252 STR_FAIL("\xF5\x80\x80"); 253 STR_FAIL("\xF5\x80\x80\x80"); 254 STR_FAIL("\xF5\x80\x80\x80\x80"); 255 256 /* Overlong encodings */ 257 STR_FAIL("\xC0\x80"); 258 259 /* Surrogate pairs */ 260 STR_FAIL("\xED\xA0\x80"); /* U+D800 First high surrogate */ 261 STR_FAIL("\xED\xAF\xBF"); /* U+DBFF Last high surrogate */ 262 STR_FAIL("\xED\xB0\x80"); /* U+DC00 First low surrogate */ 263 STR_FAIL("\xED\xBF\xBF"); /* U+DFFF Last low surrogate */ 264 STR_FAIL("\xED\xA1\x8C\xED\xBE\xB4"); /* U+233B4 (invalid surrogate pair encoding) */ 265 } 266 267 static void 268 test_write_string_utf16le(void) 269 { 270 struct spdk_json_write_ctx *w; 271 272 /* All characters in BMP */ 273 STR_UTF16LE_PASS(((uint8_t[]) { 274 'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o', 0, 0x15, 0xFE, 0, 0 275 }), "Hello\\uFE15"); 276 277 /* Surrogate pair */ 278 STR_UTF16LE_PASS(((uint8_t[]) { 279 'H', 0, 'i', 0, 0x34, 0xD8, 0x1E, 0xDD, '!', 0, 0, 0 280 }), "Hi\\uD834\\uDD1E!"); 281 282 /* Valid high surrogate, but no low surrogate */ 283 STR_UTF16LE_FAIL(((uint8_t[]) { 284 0x00, 0xD8, 0, 0 /* U+D800 */ 285 })); 286 287 /* Invalid leading low surrogate */ 288 STR_UTF16LE_FAIL(((uint8_t[]) { 289 0x00, 0xDC, 0x00, 0xDC, 0, 0 /* U+DC00 U+DC00 */ 290 })); 291 292 /* Valid high surrogate followed by another high surrogate (invalid) */ 293 STR_UTF16LE_FAIL(((uint8_t[]) { 294 0x00, 0xD8, 0x00, 0xD8, 0, 0 /* U+D800 U+D800 */ 295 })); 296 } 297 298 static void 299 test_write_number_int32(void) 300 { 301 struct spdk_json_write_ctx *w; 302 303 BEGIN(); 304 VAL_INT32(0); 305 END("0"); 306 307 BEGIN(); 308 VAL_INT32(1); 309 END("1"); 310 311 BEGIN(); 312 VAL_INT32(123); 313 END("123"); 314 315 BEGIN(); 316 VAL_INT32(-123); 317 END("-123"); 318 319 BEGIN(); 320 VAL_INT32(2147483647); 321 END("2147483647"); 322 323 BEGIN(); 324 VAL_INT32(-2147483648); 325 END("-2147483648"); 326 } 327 328 static void 329 test_write_number_uint32(void) 330 { 331 struct spdk_json_write_ctx *w; 332 333 BEGIN(); 334 VAL_UINT32(0); 335 END("0"); 336 337 BEGIN(); 338 VAL_UINT32(1); 339 END("1"); 340 341 BEGIN(); 342 VAL_UINT32(123); 343 END("123"); 344 345 BEGIN(); 346 VAL_UINT32(2147483647); 347 END("2147483647"); 348 349 BEGIN(); 350 VAL_UINT32(4294967295); 351 END("4294967295"); 352 } 353 354 static void 355 test_write_number_int64(void) 356 { 357 struct spdk_json_write_ctx *w; 358 359 BEGIN(); 360 VAL_INT64(0); 361 END("0"); 362 363 BEGIN(); 364 VAL_INT64(1); 365 END("1"); 366 367 BEGIN(); 368 VAL_INT64(123); 369 END("123"); 370 371 BEGIN(); 372 VAL_INT64(-123); 373 END("-123"); 374 375 BEGIN(); 376 VAL_INT64(INT64_MAX); 377 END("9223372036854775807"); 378 379 BEGIN(); 380 VAL_INT64(INT64_MIN); 381 END("-9223372036854775808"); 382 } 383 384 static void 385 test_write_number_uint64(void) 386 { 387 struct spdk_json_write_ctx *w; 388 389 BEGIN(); 390 VAL_UINT64(0); 391 END("0"); 392 393 BEGIN(); 394 VAL_UINT64(1); 395 END("1"); 396 397 BEGIN(); 398 VAL_UINT64(123); 399 END("123"); 400 401 BEGIN(); 402 VAL_UINT64(INT64_MAX); 403 END("9223372036854775807"); 404 405 BEGIN(); 406 VAL_UINT64(UINT64_MAX); 407 END("18446744073709551615"); 408 } 409 410 static void 411 test_write_array(void) 412 { 413 struct spdk_json_write_ctx *w; 414 415 BEGIN(); 416 VAL_ARRAY_BEGIN(); 417 VAL_ARRAY_END(); 418 END("[]"); 419 420 BEGIN(); 421 VAL_ARRAY_BEGIN(); 422 VAL_INT32(0); 423 VAL_ARRAY_END(); 424 END("[0]"); 425 426 BEGIN(); 427 VAL_ARRAY_BEGIN(); 428 VAL_INT32(0); 429 VAL_INT32(1); 430 VAL_ARRAY_END(); 431 END("[0,1]"); 432 433 BEGIN(); 434 VAL_ARRAY_BEGIN(); 435 VAL_INT32(0); 436 VAL_INT32(1); 437 VAL_INT32(2); 438 VAL_ARRAY_END(); 439 END("[0,1,2]"); 440 441 BEGIN(); 442 VAL_ARRAY_BEGIN(); 443 VAL_STRING("a"); 444 VAL_ARRAY_END(); 445 END("[\"a\"]"); 446 447 BEGIN(); 448 VAL_ARRAY_BEGIN(); 449 VAL_STRING("a"); 450 VAL_STRING("b"); 451 VAL_ARRAY_END(); 452 END("[\"a\",\"b\"]"); 453 454 BEGIN(); 455 VAL_ARRAY_BEGIN(); 456 VAL_STRING("a"); 457 VAL_STRING("b"); 458 VAL_STRING("c"); 459 VAL_ARRAY_END(); 460 END("[\"a\",\"b\",\"c\"]"); 461 462 BEGIN(); 463 VAL_ARRAY_BEGIN(); 464 VAL_TRUE(); 465 VAL_ARRAY_END(); 466 END("[true]"); 467 468 BEGIN(); 469 VAL_ARRAY_BEGIN(); 470 VAL_TRUE(); 471 VAL_FALSE(); 472 VAL_ARRAY_END(); 473 END("[true,false]"); 474 475 BEGIN(); 476 VAL_ARRAY_BEGIN(); 477 VAL_TRUE(); 478 VAL_FALSE(); 479 VAL_TRUE(); 480 VAL_ARRAY_END(); 481 END("[true,false,true]"); 482 } 483 484 static void 485 test_write_object(void) 486 { 487 struct spdk_json_write_ctx *w; 488 489 BEGIN(); 490 VAL_OBJECT_BEGIN(); 491 VAL_OBJECT_END(); 492 END("{}"); 493 494 BEGIN(); 495 VAL_OBJECT_BEGIN(); 496 VAL_NAME("a"); 497 VAL_INT32(0); 498 VAL_OBJECT_END(); 499 END("{\"a\":0}"); 500 501 BEGIN(); 502 VAL_OBJECT_BEGIN(); 503 VAL_NAME("a"); 504 VAL_INT32(0); 505 VAL_NAME("b"); 506 VAL_INT32(1); 507 VAL_OBJECT_END(); 508 END("{\"a\":0,\"b\":1}"); 509 510 BEGIN(); 511 VAL_OBJECT_BEGIN(); 512 VAL_NAME("a"); 513 VAL_INT32(0); 514 VAL_NAME("b"); 515 VAL_INT32(1); 516 VAL_NAME("c"); 517 VAL_INT32(2); 518 VAL_OBJECT_END(); 519 END("{\"a\":0,\"b\":1,\"c\":2}"); 520 } 521 522 static void 523 test_write_nesting(void) 524 { 525 struct spdk_json_write_ctx *w; 526 527 BEGIN(); 528 VAL_ARRAY_BEGIN(); 529 VAL_ARRAY_BEGIN(); 530 VAL_ARRAY_END(); 531 VAL_ARRAY_END(); 532 END("[[]]"); 533 534 BEGIN(); 535 VAL_ARRAY_BEGIN(); 536 VAL_ARRAY_BEGIN(); 537 VAL_ARRAY_BEGIN(); 538 VAL_ARRAY_END(); 539 VAL_ARRAY_END(); 540 VAL_ARRAY_END(); 541 END("[[[]]]"); 542 543 BEGIN(); 544 VAL_ARRAY_BEGIN(); 545 VAL_INT32(0); 546 VAL_ARRAY_BEGIN(); 547 VAL_ARRAY_END(); 548 VAL_ARRAY_END(); 549 END("[0,[]]"); 550 551 BEGIN(); 552 VAL_ARRAY_BEGIN(); 553 VAL_ARRAY_BEGIN(); 554 VAL_ARRAY_END(); 555 VAL_INT32(0); 556 VAL_ARRAY_END(); 557 END("[[],0]"); 558 559 BEGIN(); 560 VAL_ARRAY_BEGIN(); 561 VAL_INT32(0); 562 VAL_ARRAY_BEGIN(); 563 VAL_INT32(1); 564 VAL_ARRAY_END(); 565 VAL_INT32(2); 566 VAL_ARRAY_END(); 567 END("[0,[1],2]"); 568 569 BEGIN(); 570 VAL_ARRAY_BEGIN(); 571 VAL_INT32(0); 572 VAL_INT32(1); 573 VAL_ARRAY_BEGIN(); 574 VAL_INT32(2); 575 VAL_INT32(3); 576 VAL_ARRAY_END(); 577 VAL_INT32(4); 578 VAL_INT32(5); 579 VAL_ARRAY_END(); 580 END("[0,1,[2,3],4,5]"); 581 582 BEGIN(); 583 VAL_OBJECT_BEGIN(); 584 VAL_NAME("a"); 585 VAL_OBJECT_BEGIN(); 586 VAL_OBJECT_END(); 587 VAL_OBJECT_END(); 588 END("{\"a\":{}}"); 589 590 BEGIN(); 591 VAL_OBJECT_BEGIN(); 592 VAL_NAME("a"); 593 VAL_OBJECT_BEGIN(); 594 VAL_NAME("b"); 595 VAL_INT32(0); 596 VAL_OBJECT_END(); 597 VAL_OBJECT_END(); 598 END("{\"a\":{\"b\":0}}"); 599 600 BEGIN(); 601 VAL_OBJECT_BEGIN(); 602 VAL_NAME("a"); 603 VAL_ARRAY_BEGIN(); 604 VAL_INT32(0); 605 VAL_ARRAY_END(); 606 VAL_OBJECT_END(); 607 END("{\"a\":[0]}"); 608 609 BEGIN(); 610 VAL_ARRAY_BEGIN(); 611 VAL_OBJECT_BEGIN(); 612 VAL_NAME("a"); 613 VAL_INT32(0); 614 VAL_OBJECT_END(); 615 VAL_ARRAY_END(); 616 END("[{\"a\":0}]"); 617 618 BEGIN(); 619 VAL_ARRAY_BEGIN(); 620 VAL_OBJECT_BEGIN(); 621 VAL_NAME("a"); 622 VAL_OBJECT_BEGIN(); 623 VAL_NAME("b"); 624 VAL_ARRAY_BEGIN(); 625 VAL_OBJECT_BEGIN(); 626 VAL_NAME("c"); 627 VAL_INT32(1); 628 VAL_OBJECT_END(); 629 VAL_INT32(2); 630 VAL_ARRAY_END(); 631 VAL_NAME("d"); 632 VAL_INT32(3); 633 VAL_OBJECT_END(); 634 VAL_NAME("e"); 635 VAL_INT32(4); 636 VAL_OBJECT_END(); 637 VAL_INT32(5); 638 VAL_ARRAY_END(); 639 END("[{\"a\":{\"b\":[{\"c\":1},2],\"d\":3},\"e\":4},5]"); 640 641 /* Examples from RFC 7159 */ 642 BEGIN(); 643 VAL_OBJECT_BEGIN(); 644 VAL_NAME("Image"); 645 VAL_OBJECT_BEGIN(); 646 VAL_NAME("Width"); 647 VAL_INT32(800); 648 VAL_NAME("Height"); 649 VAL_INT32(600); 650 VAL_NAME("Title"); 651 VAL_STRING("View from 15th Floor"); 652 VAL_NAME("Thumbnail"); 653 VAL_OBJECT_BEGIN(); 654 VAL_NAME("Url"); 655 VAL_STRING("http://www.example.com/image/481989943"); 656 VAL_NAME("Height"); 657 VAL_INT32(125); 658 VAL_NAME("Width"); 659 VAL_INT32(100); 660 VAL_OBJECT_END(); 661 VAL_NAME("Animated"); 662 VAL_FALSE(); 663 VAL_NAME("IDs"); 664 VAL_ARRAY_BEGIN(); 665 VAL_INT32(116); 666 VAL_INT32(943); 667 VAL_INT32(234); 668 VAL_INT32(38793); 669 VAL_ARRAY_END(); 670 VAL_OBJECT_END(); 671 VAL_OBJECT_END(); 672 END( 673 "{\"Image\":" 674 "{" 675 "\"Width\":800," 676 "\"Height\":600," 677 "\"Title\":\"View from 15th Floor\"," 678 "\"Thumbnail\":{" 679 "\"Url\":\"http://www.example.com/image/481989943\"," 680 "\"Height\":125," 681 "\"Width\":100" 682 "}," 683 "\"Animated\":false," 684 "\"IDs\":[116,943,234,38793]" 685 "}" 686 "}"); 687 } 688 689 /* Round-trip parse and write test */ 690 static void 691 test_write_val(void) 692 { 693 struct spdk_json_write_ctx *w; 694 struct spdk_json_val values[100]; 695 char src[] = "{\"a\":[1,2,3],\"b\":{\"c\":\"d\"},\"e\":true,\"f\":false,\"g\":null}"; 696 697 CU_ASSERT(spdk_json_parse(src, strlen(src), values, SPDK_COUNTOF(values), NULL, 698 SPDK_JSON_PARSE_FLAG_DECODE_IN_PLACE) == 19); 699 700 BEGIN(); 701 VAL(values); 702 END("{\"a\":[1,2,3],\"b\":{\"c\":\"d\"},\"e\":true,\"f\":false,\"g\":null}"); 703 } 704 705 int main(int argc, char **argv) 706 { 707 CU_pSuite suite = NULL; 708 unsigned int num_failures; 709 710 if (CU_initialize_registry() != CUE_SUCCESS) { 711 return CU_get_error(); 712 } 713 714 suite = CU_add_suite("json", NULL, NULL); 715 if (suite == NULL) { 716 CU_cleanup_registry(); 717 return CU_get_error(); 718 } 719 720 if ( 721 CU_add_test(suite, "write_literal", test_write_literal) == NULL || 722 CU_add_test(suite, "write_string_simple", test_write_string_simple) == NULL || 723 CU_add_test(suite, "write_string_escapes", test_write_string_escapes) == NULL || 724 CU_add_test(suite, "write_string_utf16le", test_write_string_utf16le) == NULL || 725 CU_add_test(suite, "write_number_int32", test_write_number_int32) == NULL || 726 CU_add_test(suite, "write_number_uint32", test_write_number_uint32) == NULL || 727 CU_add_test(suite, "write_number_int64", test_write_number_int64) == NULL || 728 CU_add_test(suite, "write_number_uint64", test_write_number_uint64) == NULL || 729 CU_add_test(suite, "write_array", test_write_array) == NULL || 730 CU_add_test(suite, "write_object", test_write_object) == NULL || 731 CU_add_test(suite, "write_nesting", test_write_nesting) == NULL || 732 CU_add_test(suite, "write_val", test_write_val) == NULL) { 733 CU_cleanup_registry(); 734 return CU_get_error(); 735 } 736 737 CU_basic_set_mode(CU_BRM_VERBOSE); 738 739 CU_basic_run_tests(); 740 741 num_failures = CU_get_number_of_failures(); 742 CU_cleanup_registry(); 743 744 return num_failures; 745 } 746