xref: /spdk/test/unit/lib/json/json_write.c/json_write_ut.c (revision 94a84ae98590bea46939eb1dcd7a9876bd393b54)
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_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 	CU_set_error_action(CUEA_ABORT);
711 	CU_initialize_registry();
712 
713 	suite = CU_add_suite("json", NULL, NULL);
714 
715 	CU_ADD_TEST(suite, test_write_literal);
716 	CU_ADD_TEST(suite, test_write_string_simple);
717 	CU_ADD_TEST(suite, test_write_string_escapes);
718 	CU_ADD_TEST(suite, test_write_string_utf16le);
719 	CU_ADD_TEST(suite, test_write_number_int32);
720 	CU_ADD_TEST(suite, test_write_number_uint32);
721 	CU_ADD_TEST(suite, test_write_number_int64);
722 	CU_ADD_TEST(suite, test_write_number_uint64);
723 	CU_ADD_TEST(suite, test_write_array);
724 	CU_ADD_TEST(suite, test_write_object);
725 	CU_ADD_TEST(suite, test_write_nesting);
726 	CU_ADD_TEST(suite, test_write_val);
727 
728 	CU_basic_set_mode(CU_BRM_VERBOSE);
729 
730 	CU_basic_run_tests();
731 
732 	num_failures = CU_get_number_of_failures();
733 	CU_cleanup_registry();
734 
735 	return num_failures;
736 }
737