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