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