xref: /spdk/test/unit/lib/json/json_write.c/json_write_ut.c (revision 927f1fd57bd004df581518466ec4c1b8083e5d23)
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