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