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