4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
34 #include "spdk/stdinc.h"
36 #include "spdk_cunit.h"
38 #include "json/json_write.c"
39 #include "json/json_parse.c"
41 #include "spdk/util.h"
43 static uint8_t g_buf
[1000];
44 static uint8_t *g_write_pos
;
47 write_cb(void *cb_ctx
, const void *data
, size_t size
)
49 size_t buf_free
= g_buf
+ sizeof(g_buf
) - g_write_pos
;
51 if (size
> buf_free
) {
55 memcpy(g_write_pos
, data
, size
);
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)
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)
73 CU_ASSERT(spdk_json_write_end(w) == 0)
76 CU_ASSERT(spdk_json_write_end(w) < 0)
78 #define VAL_STRING(str) \
79 CU_ASSERT(spdk_json_write_string_raw(w, str, sizeof(str) - 1) == 0)
81 #define VAL_STRING_FAIL(str) \
82 CU_ASSERT(spdk_json_write_string_raw(w, str, sizeof(str) - 1) < 0)
84 #define STR_PASS(in, out) \
85 BEGIN(); VAL_STRING(in); END("\"" out "\"")
87 #define STR_FAIL(in) \
88 BEGIN(); VAL_STRING_FAIL(in); END_FAIL()
90 #define VAL_STRING_UTF16LE(str) \
91 CU_ASSERT(spdk_json_write_string_utf16le_raw(w, (const uint16_t *)str, sizeof(str) / sizeof(uint16_t) - 1) == 0)
93 #define VAL_STRING_UTF16LE_FAIL(str) \
94 CU_ASSERT(spdk_json_write_string_utf16le_raw(w, (const uint16_t *)str, sizeof(str) / sizeof(uint16_t) - 1) < 0)
96 #define STR_UTF16LE_PASS(in, out) \
97 BEGIN(); VAL_STRING_UTF16LE(in); END("\"" out "\"")
99 #define STR_UTF16LE_FAIL(in) \
100 BEGIN(); VAL_STRING_UTF16LE_FAIL(in); END_FAIL()
102 #define VAL_NAME(name) \
103 CU_ASSERT(spdk_json_write_name_raw(w, name, sizeof(name) - 1) == 0)
105 #define VAL_NULL() CU_ASSERT(spdk_json_write_null(w) == 0)
106 #define VAL_TRUE() CU_ASSERT(spdk_json_write_bool(w, true) == 0)
107 #define VAL_FALSE() CU_ASSERT(spdk_json_write_bool(w, false) == 0)
109 #define VAL_INT32(i) CU_ASSERT(spdk_json_write_int32(w, i) == 0);
110 #define VAL_UINT32(u) CU_ASSERT(spdk_json_write_uint32(w, u) == 0);
112 #define VAL_INT64(i) CU_ASSERT(spdk_json_write_int64(w, i) == 0);
113 #define VAL_UINT64(u) CU_ASSERT(spdk_json_write_uint64(w, u) == 0);
115 #define VAL_ARRAY_BEGIN() CU_ASSERT(spdk_json_write_array_begin(w) == 0)
116 #define VAL_ARRAY_END() CU_ASSERT(spdk_json_write_array_end(w) == 0)
118 #define VAL_OBJECT_BEGIN() CU_ASSERT(spdk_json_write_object_begin(w) == 0)
119 #define VAL_OBJECT_END() CU_ASSERT(spdk_json_write_object_end(w) == 0)
121 #define VAL(v) CU_ASSERT(spdk_json_write_val(w, v) == 0)
124 test_write_literal(void)
126 struct spdk_json_write_ctx
*w
;
142 test_write_string_simple(void)
144 struct spdk_json_write_ctx
*w
;
146 STR_PASS("hello world", "hello world");
152 test_write_string_escapes(void)
154 struct spdk_json_write_ctx
*w
;
156 /* Two-character escapes */
157 STR_PASS("\b", "\\b");
158 STR_PASS("\f", "\\f");
159 STR_PASS("\n", "\\n");
160 STR_PASS("\r", "\\r");
161 STR_PASS("\t", "\\t");
162 STR_PASS("\"", "\\\"");
163 STR_PASS("\\", "\\\\");
165 /* JSON defines an escape for forward slash, but it is optional */
168 STR_PASS("hello\nworld", "hello\\nworld");
170 STR_PASS("\x00", "\\u0000");
171 STR_PASS("\x01", "\\u0001");
172 STR_PASS("\x02", "\\u0002");
174 STR_PASS("\xC3\xB6", "\\u00F6");
175 STR_PASS("\xE2\x88\x9A", "\\u221A");
176 STR_PASS("\xEA\xAA\xAA", "\\uAAAA");
178 /* Surrogate pairs */
179 STR_PASS("\xF0\x9D\x84\x9E", "\\uD834\\uDD1E");
180 STR_PASS("\xF0\xA0\x9C\x8E", "\\uD841\\uDF0E");
182 /* Examples from RFC 3629 */
183 STR_PASS("\x41\xE2\x89\xA2\xCE\x91\x2E", "A\\u2262\\u0391.");
184 STR_PASS("\xED\x95\x9C\xEA\xB5\xAD\xEC\x96\xB4", "\\uD55C\\uAD6D\\uC5B4");
185 STR_PASS("\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E", "\\u65E5\\u672C\\u8A9E");
186 STR_PASS("\xEF\xBB\xBF\xF0\xA3\x8E\xB4", "\\uFEFF\\uD84C\\uDFB4");
188 /* UTF-8 edge cases */
189 STR_PASS("\x7F", "\\u007F");
193 STR_PASS("\xC2\x80", "\\u0080");
194 STR_PASS("\xC2\xBF", "\\u00BF");
195 STR_PASS("\xDF\x80", "\\u07C0");
196 STR_PASS("\xDF\xBF", "\\u07FF");
198 STR_FAIL("\xE0\x80");
199 STR_FAIL("\xE0\x1F");
200 STR_FAIL("\xE0\x1F\x80");
202 STR_FAIL("\xE0\xA0");
203 STR_PASS("\xE0\xA0\x80", "\\u0800");
204 STR_PASS("\xE0\xA0\xBF", "\\u083F");
205 STR_FAIL("\xE0\xA0\xC0");
206 STR_PASS("\xE0\xBF\x80", "\\u0FC0");
207 STR_PASS("\xE0\xBF\xBF", "\\u0FFF");
208 STR_FAIL("\xE0\xC0\x80");
210 STR_FAIL("\xE1\x80");
211 STR_FAIL("\xE1\x7F\x80");
212 STR_FAIL("\xE1\x80\x7F");
213 STR_PASS("\xE1\x80\x80", "\\u1000");
214 STR_PASS("\xE1\x80\xBF", "\\u103F");
215 STR_PASS("\xE1\xBF\x80", "\\u1FC0");
216 STR_PASS("\xE1\xBF\xBF", "\\u1FFF");
217 STR_FAIL("\xE1\xC0\x80");
218 STR_FAIL("\xE1\x80\xC0");
219 STR_PASS("\xEF\x80\x80", "\\uF000");
220 STR_PASS("\xEF\xBF\xBF", "\\uFFFF");
222 STR_FAIL("\xF0\x90");
223 STR_FAIL("\xF0\x90\x80");
224 STR_FAIL("\xF0\x80\x80\x80");
225 STR_FAIL("\xF0\x8F\x80\x80");
226 STR_PASS("\xF0\x90\x80\x80", "\\uD800\\uDC00");
227 STR_PASS("\xF0\x90\x80\xBF", "\\uD800\\uDC3F");
228 STR_PASS("\xF0\x90\xBF\x80", "\\uD803\\uDFC0");
229 STR_PASS("\xF0\xBF\x80\x80", "\\uD8BC\\uDC00");
230 STR_FAIL("\xF0\xC0\x80\x80");
232 STR_FAIL("\xF1\x80");
233 STR_FAIL("\xF1\x80\x80");
234 STR_FAIL("\xF1\x80\x80\x7F");
235 STR_PASS("\xF1\x80\x80\x80", "\\uD8C0\\uDC00");
236 STR_PASS("\xF1\x80\x80\xBF", "\\uD8C0\\uDC3F");
237 STR_PASS("\xF1\x80\xBF\x80", "\\uD8C3\\uDFC0");
238 STR_PASS("\xF1\xBF\x80\x80", "\\uD9BC\\uDC00");
239 STR_PASS("\xF3\x80\x80\x80", "\\uDAC0\\uDC00");
240 STR_FAIL("\xF3\xC0\x80\x80");
241 STR_FAIL("\xF3\x80\xC0\x80");
242 STR_FAIL("\xF3\x80\x80\xC0");
244 STR_FAIL("\xF4\x80");
245 STR_FAIL("\xF4\x80\x80");
246 STR_PASS("\xF4\x80\x80\x80", "\\uDBC0\\uDC00");
247 STR_PASS("\xF4\x8F\x80\x80", "\\uDBFC\\uDC00");
248 STR_PASS("\xF4\x8F\xBF\xBF", "\\uDBFF\\uDFFF");
249 STR_FAIL("\xF4\x90\x80\x80");
251 STR_FAIL("\xF5\x80");
252 STR_FAIL("\xF5\x80\x80");
253 STR_FAIL("\xF5\x80\x80\x80");
254 STR_FAIL("\xF5\x80\x80\x80\x80");
256 /* Overlong encodings */
257 STR_FAIL("\xC0\x80");
259 /* Surrogate pairs */
260 STR_FAIL("\xED\xA0\x80"); /* U+D800 First high surrogate */
261 STR_FAIL("\xED\xAF\xBF"); /* U+DBFF Last high surrogate */
262 STR_FAIL("\xED\xB0\x80"); /* U+DC00 First low surrogate */
263 STR_FAIL("\xED\xBF\xBF"); /* U+DFFF Last low surrogate */
264 STR_FAIL("\xED\xA1\x8C\xED\xBE\xB4"); /* U+233B4 (invalid surrogate pair encoding) */
268 test_write_string_utf16le(void)
270 struct spdk_json_write_ctx
*w
;
272 /* All characters in BMP */
273 STR_UTF16LE_PASS(((uint8_t[]) {
274 'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o', 0, 0x15, 0xFE, 0, 0
278 STR_UTF16LE_PASS(((uint8_t[]) {
279 'H', 0, 'i', 0, 0x34, 0xD8, 0x1E, 0xDD, '!', 0, 0, 0
280 }), "Hi\\uD834\\uDD1E!");
282 /* Valid high surrogate, but no low surrogate */
283 STR_UTF16LE_FAIL(((uint8_t[]) {
284 0x00, 0xD8, 0, 0 /* U+D800 */
287 /* Invalid leading low surrogate */
288 STR_UTF16LE_FAIL(((uint8_t[]) {
289 0x00, 0xDC, 0x00, 0xDC, 0, 0 /* U+DC00 U+DC00 */
292 /* Valid high surrogate followed by another high surrogate (invalid) */
293 STR_UTF16LE_FAIL(((uint8_t[]) {
294 0x00, 0xD8, 0x00, 0xD8, 0, 0 /* U+D800 U+D800 */
299 test_write_number_int32(void)
301 struct spdk_json_write_ctx
*w
;
320 VAL_INT32(2147483647);
324 VAL_INT32(-2147483648);
329 test_write_number_uint32(void)
331 struct spdk_json_write_ctx
*w
;
346 VAL_UINT32(2147483647);
350 VAL_UINT32(4294967295);
355 test_write_number_int64(void)
357 struct spdk_json_write_ctx
*w
;
376 VAL_INT64(INT64_MAX
);
377 END("9223372036854775807");
380 VAL_INT64(INT64_MIN
);
381 END("-9223372036854775808");
385 test_write_number_uint64(void)
387 struct spdk_json_write_ctx
*w
;
402 VAL_UINT64(INT64_MAX
);
403 END("9223372036854775807");
406 VAL_UINT64(UINT64_MAX
);
407 END("18446744073709551615");
411 test_write_array(void)
413 struct spdk_json_write_ctx
*w
;
452 END("[\"a\",\"b\"]");
460 END("[\"a\",\"b\",\"c\"]");
481 END("[true,false,true]");
485 test_write_object(void)
487 struct spdk_json_write_ctx
*w
;
508 END("{\"a\":0,\"b\":1}");
519 END("{\"a\":0,\"b\":1,\"c\":2}");
523 test_write_nesting(void)
525 struct spdk_json_write_ctx
*w
;
580 END("[0,1,[2,3],4,5]");
598 END("{\"a\":{\"b\":0}}");
639 END("[{\"a\":{\"b\":[{\"c\":1},2],\"d\":3},\"e\":4},5]");
641 /* Examples from RFC 7159 */
651 VAL_STRING("View from 15th Floor");
652 VAL_NAME("Thumbnail");
655 VAL_STRING("http://www.example.com/image/481989943");
661 VAL_NAME("Animated");
677 "\"Title\":\"View from 15th Floor\","
679 "\"Url\":\"http://www.example.com/image/481989943\","
683 "\"Animated\":false,"
684 "\"IDs\":[116,943,234,38793]"
689 /* Round-trip parse and write test */
693 struct spdk_json_write_ctx
*w
;
694 struct spdk_json_val values
[100];
695 char src
[] = "{\"a\":[1,2,3],\"b\":{\"c\":\"d\"},\"e\":true,\"f\":false,\"g\":null}";
697 CU_ASSERT(spdk_json_parse(src
, strlen(src
), values
, SPDK_COUNTOF(values
), NULL
,
698 SPDK_JSON_PARSE_FLAG_DECODE_IN_PLACE
) == 19);
702 END("{\"a\":[1,2,3],\"b\":{\"c\":\"d\"},\"e\":true,\"f\":false,\"g\":null}");
705 int main(int argc
, char **argv
)
707 CU_pSuite suite
= NULL
;
708 unsigned int num_failures
;
710 if (CU_initialize_registry() != CUE_SUCCESS
) {
711 return CU_get_error();
714 suite
= CU_add_suite("json", NULL
, NULL
);
716 CU_cleanup_registry();
717 return CU_get_error();
721 CU_add_test(suite
, "write_literal", test_write_literal
) == NULL
||
722 CU_add_test(suite
, "write_string_simple", test_write_string_simple
) == NULL
||
723 CU_add_test(suite
, "write_string_escapes", test_write_string_escapes
) == NULL
||
724 CU_add_test(suite
, "write_string_utf16le", test_write_string_utf16le
) == NULL
||
725 CU_add_test(suite
, "write_number_int32", test_write_number_int32
) == NULL
||
726 CU_add_test(suite
, "write_number_uint32", test_write_number_uint32
) == NULL
||
727 CU_add_test(suite
, "write_number_int64", test_write_number_int64
) == NULL
||
728 CU_add_test(suite
, "write_number_uint64", test_write_number_uint64
) == NULL
||
729 CU_add_test(suite
, "write_array", test_write_array
) == NULL
||
730 CU_add_test(suite
, "write_object", test_write_object
) == NULL
||
731 CU_add_test(suite
, "write_nesting", test_write_nesting
) == NULL
||
732 CU_add_test(suite
, "write_val", test_write_val
) == NULL
) {
733 CU_cleanup_registry();
734 return CU_get_error();
737 CU_basic_set_mode(CU_BRM_VERBOSE
);
739 CU_basic_run_tests();
741 num_failures
= CU_get_number_of_failures();
742 CU_cleanup_registry();