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