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