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