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/json.h"
7 : :
8 : : #include "spdk_internal/utf.h"
9 : :
10 : : struct spdk_json_write_ctx {
11 : : spdk_json_write_cb write_cb;
12 : : void *cb_ctx;
13 : : uint32_t flags;
14 : : uint32_t indent;
15 : : bool new_indent;
16 : : bool first_value;
17 : : bool failed;
18 : : size_t buf_filled;
19 : : uint8_t buf[4096];
20 : : };
21 : :
22 : : static int emit_buf_full(struct spdk_json_write_ctx *w, const void *data, size_t size);
23 : :
24 : : static int
25 : 192 : fail(struct spdk_json_write_ctx *w)
26 : : {
27 : 192 : w->failed = true;
28 : 192 : return -1;
29 : : }
30 : :
31 : : static int
32 : 327064 : flush_buf(struct spdk_json_write_ctx *w)
33 : : {
34 : : int rc;
35 : :
36 : 327064 : rc = w->write_cb(w->cb_ctx, w->buf, w->buf_filled);
37 [ - + ]: 327064 : if (rc != 0) {
38 : 0 : return fail(w);
39 : : }
40 : :
41 : 327064 : w->buf_filled = 0;
42 : :
43 : 327064 : return 0;
44 : : }
45 : :
46 : : struct spdk_json_write_ctx *
47 : 321634 : spdk_json_write_begin(spdk_json_write_cb write_cb, void *cb_ctx, uint32_t flags)
48 : : {
49 : : struct spdk_json_write_ctx *w;
50 : :
51 : 321634 : w = calloc(1, sizeof(*w));
52 [ - + ]: 321634 : if (w == NULL) {
53 : 0 : return w;
54 : : }
55 : :
56 : 321634 : w->write_cb = write_cb;
57 : 321634 : w->cb_ctx = cb_ctx;
58 : 321634 : w->flags = flags;
59 : 321634 : w->indent = 0;
60 : 321634 : w->new_indent = false;
61 : 321634 : w->first_value = true;
62 : 321634 : w->failed = false;
63 : 321634 : w->buf_filled = 0;
64 : :
65 : 321634 : return w;
66 : : }
67 : :
68 : : int
69 : 321628 : spdk_json_write_end(struct spdk_json_write_ctx *w)
70 : : {
71 : : bool failed;
72 : : int rc;
73 : :
74 [ - + ]: 321628 : if (w == NULL) {
75 : 0 : return 0;
76 : : }
77 : :
78 [ - + ]: 321628 : failed = w->failed;
79 : :
80 : 321628 : rc = flush_buf(w);
81 [ - + ]: 321628 : if (rc != 0) {
82 : 0 : failed = true;
83 : : }
84 : :
85 : 321628 : free(w);
86 : :
87 [ + + ]: 321628 : return failed ? -1 : 0;
88 : : }
89 : :
90 : : static inline int
91 : 79077373 : emit(struct spdk_json_write_ctx *w, const void *data, size_t size)
92 : : {
93 : 79077373 : size_t buf_remain = sizeof(w->buf) - w->buf_filled;
94 : :
95 [ + + ]: 79077373 : if (spdk_unlikely(size > buf_remain)) {
96 : : /* Not enough space in buffer for the new data. */
97 : 5436 : return emit_buf_full(w, data, size);
98 : : }
99 : :
100 : : /* Copy the new data into buf. */
101 [ - + - + ]: 79071941 : memcpy(w->buf + w->buf_filled, data, size);
102 : 79071941 : w->buf_filled += size;
103 : 79071941 : return 0;
104 : : }
105 : :
106 : : static int
107 : 5436 : emit_buf_full(struct spdk_json_write_ctx *w, const void *data, size_t size)
108 : : {
109 : 5436 : size_t buf_remain = sizeof(w->buf) - w->buf_filled;
110 : : int rc;
111 : :
112 [ - + ]: 5436 : assert(size > buf_remain);
113 : :
114 : : /* Copy as much of the new data as possible into the buffer and flush it. */
115 [ - + - + ]: 5436 : memcpy(w->buf + w->buf_filled, data, buf_remain);
116 : 5436 : w->buf_filled += buf_remain;
117 : :
118 : 5436 : rc = flush_buf(w);
119 [ - + ]: 5436 : if (rc != 0) {
120 : 0 : return fail(w);
121 : : }
122 : :
123 : : /* Recurse to emit the rest of the data. */
124 : 5436 : return emit(w, data + buf_remain, size - buf_remain);
125 : : }
126 : :
127 : : static int
128 : 8699146 : emit_fmt(struct spdk_json_write_ctx *w, const void *data, size_t size)
129 : : {
130 [ + + ]: 8699146 : if (w->flags & SPDK_JSON_WRITE_FLAG_FORMATTED) {
131 : 4275025 : return emit(w, data, size);
132 : : }
133 : 4424121 : return 0;
134 : : }
135 : :
136 : : static int
137 : 4844673 : emit_indent(struct spdk_json_write_ctx *w)
138 : : {
139 : : uint32_t i;
140 : :
141 [ + + ]: 4844673 : if (w->flags & SPDK_JSON_WRITE_FLAG_FORMATTED) {
142 [ + + ]: 4017394 : for (i = 0; i < w->indent; i++) {
143 [ - + ]: 1878944 : if (emit(w, " ", 2)) { return fail(w); }
144 : : }
145 : : }
146 : 4844673 : return 0;
147 : : }
148 : :
149 : : static int
150 : 8380015 : begin_value(struct spdk_json_write_ctx *w)
151 : : {
152 : : /* TODO: check for value state */
153 [ + + + + ]: 8380015 : if (w->new_indent) {
154 [ - + ]: 640763 : if (emit_fmt(w, "\n", 1)) { return fail(w); }
155 [ - + ]: 640763 : if (emit_indent(w)) { return fail(w); }
156 : : }
157 [ + + + + ]: 8380015 : if (!w->first_value) {
158 [ - + ]: 3563155 : if (emit(w, ",", 1)) { return fail(w); }
159 [ - + ]: 3563155 : if (emit_fmt(w, "\n", 1)) { return fail(w); }
160 [ - + ]: 3563155 : if (emit_indent(w)) { return fail(w); }
161 : : }
162 : 8380015 : w->first_value = false;
163 : 8380015 : w->new_indent = false;
164 : 8380015 : return 0;
165 : : }
166 : :
167 : : int
168 : 56970 : spdk_json_write_val_raw(struct spdk_json_write_ctx *w, const void *data, size_t len)
169 : : {
170 [ - + ]: 56970 : if (begin_value(w)) { return fail(w); }
171 : 56970 : return emit(w, data, len);
172 : : }
173 : :
174 : : int
175 : 4299 : spdk_json_write_null(struct spdk_json_write_ctx *w)
176 : : {
177 [ - + ]: 4299 : if (begin_value(w)) { return fail(w); }
178 : 4299 : return emit(w, "null", 4);
179 : : }
180 : :
181 : : int
182 : 727610 : spdk_json_write_bool(struct spdk_json_write_ctx *w, bool val)
183 : : {
184 [ - + ]: 727610 : if (begin_value(w)) { return fail(w); }
185 [ + + ]: 727610 : if (val) {
186 : 301929 : return emit(w, "true", 4);
187 : : } else {
188 : 425681 : return emit(w, "false", 5);
189 : : }
190 : : }
191 : :
192 : : int
193 : 338 : spdk_json_write_uint8(struct spdk_json_write_ctx *w, uint8_t val)
194 : : {
195 : 128 : char buf[32];
196 : : int count;
197 : :
198 [ - + ]: 338 : if (begin_value(w)) { return fail(w); }
199 [ - + ]: 338 : count = snprintf(buf, sizeof(buf), "%" PRIu8, val);
200 [ + - - + ]: 338 : if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
201 : 338 : return emit(w, buf, count);
202 : : }
203 : :
204 : : int
205 : 2113 : spdk_json_write_uint16(struct spdk_json_write_ctx *w, uint16_t val)
206 : : {
207 : 1110 : char buf[32];
208 : : int count;
209 : :
210 [ - + ]: 2113 : if (begin_value(w)) { return fail(w); }
211 [ - + ]: 2113 : count = snprintf(buf, sizeof(buf), "%" PRIu16, val);
212 [ + - - + ]: 2113 : if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
213 : 2113 : return emit(w, buf, count);
214 : : }
215 : :
216 : : int
217 : 55864 : spdk_json_write_int32(struct spdk_json_write_ctx *w, int32_t val)
218 : : {
219 : 22745 : char buf[32];
220 : : int count;
221 : :
222 [ - + ]: 55864 : if (begin_value(w)) { return fail(w); }
223 [ - + ]: 55864 : count = snprintf(buf, sizeof(buf), "%" PRId32, val);
224 [ + - - + ]: 55864 : if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
225 : 55864 : return emit(w, buf, count);
226 : : }
227 : :
228 : : int
229 : 1687307 : spdk_json_write_uint32(struct spdk_json_write_ctx *w, uint32_t val)
230 : : {
231 : 50192 : char buf[32];
232 : : int count;
233 : :
234 [ - + ]: 1687307 : if (begin_value(w)) { return fail(w); }
235 [ - + ]: 1687307 : count = snprintf(buf, sizeof(buf), "%" PRIu32, val);
236 [ + - - + ]: 1687307 : if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
237 : 1687307 : return emit(w, buf, count);
238 : : }
239 : :
240 : : int
241 : 28 : spdk_json_write_int64(struct spdk_json_write_ctx *w, int64_t val)
242 : : {
243 : 28 : char buf[32];
244 : : int count;
245 : :
246 [ - + ]: 28 : if (begin_value(w)) { return fail(w); }
247 [ - + ]: 28 : count = snprintf(buf, sizeof(buf), "%" PRId64, val);
248 [ + - - + ]: 28 : if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
249 : 28 : return emit(w, buf, count);
250 : : }
251 : :
252 : : int
253 : 208590 : spdk_json_write_uint64(struct spdk_json_write_ctx *w, uint64_t val)
254 : : {
255 : 126824 : char buf[32];
256 : : int count;
257 : :
258 [ - + ]: 208590 : if (begin_value(w)) { return fail(w); }
259 [ - + ]: 208590 : count = snprintf(buf, sizeof(buf), "%" PRIu64, val);
260 [ + - - + ]: 208590 : if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
261 : 208590 : return emit(w, buf, count);
262 : : }
263 : :
264 : : int
265 : 64 : spdk_json_write_uint128(struct spdk_json_write_ctx *w, uint64_t low_val, uint64_t high_val)
266 : : {
267 : 64 : char buf[128] = {'\0'};
268 : 64 : uint64_t low = low_val, high = high_val;
269 : 64 : int count = 0;
270 : :
271 [ - + ]: 64 : if (begin_value(w)) { return fail(w); }
272 : :
273 [ + + ]: 64 : if (high != 0) {
274 : 32 : char temp_buf[128] = {'\0'};
275 : : uint64_t seg;
276 : 32 : unsigned __int128 total = (unsigned __int128)low +
277 : 32 : ((unsigned __int128)high << 64);
278 : :
279 [ + + ]: 112 : while (total) {
280 : 80 : seg = total % 10000000000;
281 : 80 : total = total / 10000000000;
282 [ + + ]: 80 : if (total) {
283 [ - + ]: 48 : count = snprintf(temp_buf, 128, "%010" PRIu64 "%s", seg, buf);
284 : : } else {
285 [ - + ]: 32 : count = snprintf(temp_buf, 128, "%" PRIu64 "%s", seg, buf);
286 : : }
287 : :
288 [ + - - + ]: 80 : if (count <= 0 || (size_t)count >= sizeof(temp_buf)) {
289 : 0 : return fail(w);
290 : : }
291 : :
292 [ - + ]: 80 : snprintf(buf, 128, "%s", temp_buf);
293 : : }
294 : : } else {
295 [ - + ]: 32 : count = snprintf(buf, sizeof(buf), "%" PRIu64, low);
296 : :
297 [ + - - + ]: 32 : if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
298 : : }
299 : :
300 : 64 : return emit(w, buf, count);
301 : : }
302 : :
303 : : int
304 : 32 : spdk_json_write_named_uint128(struct spdk_json_write_ctx *w, const char *name,
305 : : uint64_t low_val, uint64_t high_val)
306 : : {
307 : 32 : int rc = spdk_json_write_name(w, name);
308 : :
309 [ + - ]: 32 : return rc ? rc : spdk_json_write_uint128(w, low_val, high_val);
310 : : }
311 : :
312 : : int
313 : 85 : spdk_json_write_double(struct spdk_json_write_ctx *w, double val)
314 : : {
315 : 85 : char buf[32];
316 : : int count;
317 : :
318 [ - + ]: 85 : if (begin_value(w)) { return fail(w); }
319 [ - + ]: 85 : count = snprintf(buf, sizeof(buf), "%.20e", val);
320 [ + - - + ]: 85 : if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
321 : 85 : return emit(w, buf, count);
322 : : }
323 : :
324 : : static void
325 : 518 : write_hex_2(void *dest, uint8_t val)
326 : : {
327 : 518 : char *p = dest;
328 : 518 : char hex[] = "0123456789ABCDEF";
329 : :
330 : 518 : p[0] = hex[val >> 4];
331 : 518 : p[1] = hex[val & 0xf];
332 : 518 : }
333 : :
334 : : static void
335 : 259 : write_hex_4(void *dest, uint16_t val)
336 : : {
337 : 259 : write_hex_2(dest, (uint8_t)(val >> 8));
338 : 259 : write_hex_2((char *)dest + 2, (uint8_t)(val & 0xff));
339 : 259 : }
340 : :
341 : : static inline int
342 : 51483775 : write_codepoint(struct spdk_json_write_ctx *w, uint32_t codepoint)
343 : : {
344 : : static const uint8_t escapes[] = {
345 : : ['\b'] = 'b',
346 : : ['\f'] = 'f',
347 : : ['\n'] = 'n',
348 : : ['\r'] = 'r',
349 : : ['\t'] = 't',
350 : : ['"'] = '"',
351 : : ['\\'] = '\\',
352 : : /*
353 : : * Forward slash (/) is intentionally not converted to an escape
354 : : * (it is valid unescaped).
355 : : */
356 : : };
357 : 16786375 : uint16_t high, low;
358 : 16786375 : char out[13];
359 : : size_t out_len;
360 : :
361 [ + + + + ]: 51483775 : if (codepoint < sizeof(escapes) && escapes[codepoint]) {
362 : 46 : out[0] = '\\';
363 : 46 : out[1] = escapes[codepoint];
364 : 46 : out_len = 2;
365 [ + + + + ]: 51483729 : } else if (codepoint >= 0x20 && codepoint < 0x7F) {
366 : : /*
367 : : * Encode plain ASCII directly (except 0x7F, since it is really
368 : : * a control character, despite the JSON spec not considering it one).
369 : : */
370 : 51483534 : out[0] = (uint8_t)codepoint;
371 : 51483534 : out_len = 1;
372 [ + + ]: 195 : } else if (codepoint < 0x10000) {
373 : 131 : out[0] = '\\';
374 : 131 : out[1] = 'u';
375 : 131 : write_hex_4(&out[2], (uint16_t)codepoint);
376 : 131 : out_len = 6;
377 : : } else {
378 : 64 : utf16_encode_surrogate_pair(codepoint, &high, &low);
379 : 64 : out[0] = '\\';
380 : 64 : out[1] = 'u';
381 : 64 : write_hex_4(&out[2], high);
382 : 64 : out[6] = '\\';
383 : 64 : out[7] = 'u';
384 : 64 : write_hex_4(&out[8], low);
385 : 64 : out_len = 12;
386 : : }
387 : :
388 : 51483775 : return emit(w, out, out_len);
389 : : }
390 : :
391 : : static int
392 : 4961557 : write_string_or_name(struct spdk_json_write_ctx *w, const char *val, size_t len)
393 : : {
394 : 4961557 : const uint8_t *p = val;
395 : 4961557 : const uint8_t *end = val + len;
396 : :
397 [ - + ]: 4961557 : if (emit(w, "\"", 1)) { return fail(w); }
398 : :
399 [ + + ]: 56444925 : while (p != end) {
400 : : int codepoint_len;
401 : : uint32_t codepoint;
402 : :
403 : 51483545 : codepoint_len = utf8_valid(p, end);
404 [ + + + + : 51483545 : switch (codepoint_len) {
+ ]
405 : 51483201 : case 1:
406 : 51483201 : codepoint = utf8_decode_unsafe_1(p);
407 : 51483201 : break;
408 : 24 : case 2:
409 : 24 : codepoint = utf8_decode_unsafe_2(p);
410 : 24 : break;
411 : 80 : case 3:
412 : 80 : codepoint = utf8_decode_unsafe_3(p);
413 : 80 : break;
414 : 60 : case 4:
415 : 60 : codepoint = utf8_decode_unsafe_4(p);
416 : 60 : break;
417 : 180 : default:
418 : 180 : return fail(w);
419 : : }
420 : :
421 [ - + ]: 51483365 : if (write_codepoint(w, codepoint)) { return fail(w); }
422 : 51483365 : p += codepoint_len;
423 : : }
424 : :
425 : 4961377 : return emit(w, "\"", 1);
426 : : }
427 : :
428 : : static int
429 : 44 : write_string_or_name_utf16le(struct spdk_json_write_ctx *w, const uint16_t *val, size_t len)
430 : : {
431 : 44 : const uint16_t *p = val;
432 : 44 : const uint16_t *end = val + len;
433 : :
434 [ - + ]: 44 : if (emit(w, "\"", 1)) { return fail(w); }
435 : :
436 [ + + ]: 456 : while (p != end) {
437 : : int codepoint_len;
438 : : uint32_t codepoint;
439 : :
440 : 424 : codepoint_len = utf16le_valid(p, end);
441 [ + + + ]: 424 : switch (codepoint_len) {
442 : 408 : case 1:
443 : 408 : codepoint = from_le16(&p[0]);
444 : 408 : break;
445 : 4 : case 2:
446 : 4 : codepoint = utf16_decode_surrogate_pair(from_le16(&p[0]), from_le16(&p[1]));
447 : 4 : break;
448 : 12 : default:
449 : 12 : return fail(w);
450 : : }
451 : :
452 [ - + ]: 412 : if (write_codepoint(w, codepoint)) { return fail(w); }
453 : 412 : p += codepoint_len;
454 : : }
455 : :
456 : 32 : return emit(w, "\"", 1);
457 : : }
458 : :
459 : : int
460 : 1107084 : spdk_json_write_string_raw(struct spdk_json_write_ctx *w, const char *val, size_t len)
461 : : {
462 [ - + ]: 1107084 : if (begin_value(w)) { return fail(w); }
463 : 1107084 : return write_string_or_name(w, val, len);
464 : : }
465 : :
466 : : int
467 : 1106664 : spdk_json_write_string(struct spdk_json_write_ctx *w, const char *val)
468 : : {
469 [ - + ]: 1106664 : return spdk_json_write_string_raw(w, val, strlen(val));
470 : : }
471 : :
472 : : int
473 : 44 : spdk_json_write_string_utf16le_raw(struct spdk_json_write_ctx *w, const uint16_t *val, size_t len)
474 : : {
475 [ - + ]: 44 : if (begin_value(w)) { return fail(w); }
476 : 44 : return write_string_or_name_utf16le(w, val, len);
477 : : }
478 : :
479 : : int
480 : 0 : spdk_json_write_string_utf16le(struct spdk_json_write_ctx *w, const uint16_t *val)
481 : : {
482 : : const uint16_t *p;
483 : : size_t len;
484 : :
485 [ # # ]: 0 : for (len = 0, p = val; *p; p++) {
486 : 0 : len++;
487 : : }
488 : :
489 : 0 : return spdk_json_write_string_utf16le_raw(w, val, len);
490 : : }
491 : :
492 : : int
493 : 1294 : spdk_json_write_string_fmt(struct spdk_json_write_ctx *w, const char *fmt, ...)
494 : : {
495 : 1063 : va_list args;
496 : : int rc;
497 : :
498 : 1294 : va_start(args, fmt);
499 : 1294 : rc = spdk_json_write_string_fmt_v(w, fmt, args);
500 : 1294 : va_end(args);
501 : :
502 : 1294 : return rc;
503 : : }
504 : :
505 : : int
506 : 1294 : spdk_json_write_string_fmt_v(struct spdk_json_write_ctx *w, const char *fmt, va_list args)
507 : : {
508 : : char *s;
509 : : int rc;
510 : :
511 : 1294 : s = spdk_vsprintf_alloc(fmt, args);
512 [ - + ]: 1294 : if (s == NULL) {
513 : 0 : return -1;
514 : : }
515 : :
516 : 1294 : rc = spdk_json_write_string(w, s);
517 : 1294 : free(s);
518 : 1294 : return rc;
519 : : }
520 : :
521 : : int
522 : 0 : spdk_json_write_bytearray(struct spdk_json_write_ctx *w, const void *val, size_t len)
523 : : {
524 : 0 : const uint8_t *v = val;
525 : : size_t i;
526 : : char *s;
527 : : int rc;
528 : :
529 : 0 : s = malloc(2 * len + 1);
530 [ # # ]: 0 : if (s == NULL) {
531 : 0 : return -1;
532 : : }
533 : :
534 [ # # ]: 0 : for (i = 0; i < len; ++i) {
535 : 0 : write_hex_2(&s[2 * i], *v++);
536 : : }
537 : 0 : s[2 * len] = '\0';
538 : :
539 : 0 : rc = spdk_json_write_string(w, s);
540 : 0 : free(s);
541 : 0 : return rc;
542 : : }
543 : :
544 : : int
545 : 58615 : spdk_json_write_uuid(struct spdk_json_write_ctx *w, const struct spdk_uuid *uuid)
546 : : {
547 : 39651 : char str[SPDK_UUID_STRING_LEN];
548 : :
549 : 58615 : spdk_uuid_fmt_lower(str, sizeof(str), uuid);
550 : :
551 : 58615 : return spdk_json_write_string(w, str);
552 : : }
553 : :
554 : : int
555 : 106157 : spdk_json_write_array_begin(struct spdk_json_write_ctx *w)
556 : : {
557 [ - + ]: 106157 : if (begin_value(w)) { return fail(w); }
558 : 106157 : w->first_value = true;
559 : 106157 : w->new_indent = true;
560 : 106157 : w->indent++;
561 [ - + ]: 106157 : if (emit(w, "[", 1)) { return fail(w); }
562 : 106157 : return 0;
563 : : }
564 : :
565 : : int
566 : 106157 : spdk_json_write_array_end(struct spdk_json_write_ctx *w)
567 : : {
568 : 106157 : w->first_value = false;
569 [ - + ]: 106157 : if (w->indent == 0) { return fail(w); }
570 : 106157 : w->indent--;
571 [ + + + + ]: 106157 : if (!w->new_indent) {
572 [ - + ]: 93091 : if (emit_fmt(w, "\n", 1)) { return fail(w); }
573 [ - + ]: 93091 : if (emit_indent(w)) { return fail(w); }
574 : : }
575 : 106157 : w->new_indent = false;
576 : 106157 : return emit(w, "]", 1);
577 : : }
578 : :
579 : : int
580 : 568989 : spdk_json_write_object_begin(struct spdk_json_write_ctx *w)
581 : : {
582 [ - + ]: 568989 : if (begin_value(w)) { return fail(w); }
583 : 568989 : w->first_value = true;
584 : 568989 : w->new_indent = true;
585 : 568989 : w->indent++;
586 [ - + ]: 568989 : if (emit(w, "{", 1)) { return fail(w); }
587 : 568989 : return 0;
588 : : }
589 : :
590 : : int
591 : 568981 : spdk_json_write_object_end(struct spdk_json_write_ctx *w)
592 : : {
593 : 568981 : w->first_value = false;
594 : 568981 : w->indent--;
595 [ + + + + ]: 568981 : if (!w->new_indent) {
596 [ - + ]: 547664 : if (emit_fmt(w, "\n", 1)) { return fail(w); }
597 [ - + ]: 547664 : if (emit_indent(w)) { return fail(w); }
598 : : }
599 : 568981 : w->new_indent = false;
600 : 568981 : return emit(w, "}", 1);
601 : : }
602 : :
603 : : int
604 : 3854473 : spdk_json_write_name_raw(struct spdk_json_write_ctx *w, const char *name, size_t len)
605 : : {
606 : : /* TODO: check that container is an object */
607 [ - + ]: 3854473 : if (begin_value(w)) { return fail(w); }
608 [ - + ]: 3854473 : if (write_string_or_name(w, name, len)) { return fail(w); }
609 : 3854473 : w->first_value = true;
610 [ - + ]: 3854473 : if (emit(w, ":", 1)) { return fail(w); }
611 : 3854473 : return emit_fmt(w, " ", 1);
612 : : }
613 : :
614 : : int
615 : 3854345 : spdk_json_write_name(struct spdk_json_write_ctx *w, const char *name)
616 : : {
617 [ - + ]: 3854345 : return spdk_json_write_name_raw(w, name, strlen(name));
618 : : }
619 : :
620 : : int
621 : 52803 : spdk_json_write_val(struct spdk_json_write_ctx *w, const struct spdk_json_val *val)
622 : : {
623 : : size_t num_values, i;
624 : :
625 [ + + + + : 52803 : switch (val->type) {
+ + + + +
- - ]
626 : 52735 : case SPDK_JSON_VAL_NUMBER:
627 : 52735 : return spdk_json_write_val_raw(w, val->start, val->len);
628 : :
629 : 4 : case SPDK_JSON_VAL_STRING:
630 : 4 : return spdk_json_write_string_raw(w, val->start, val->len);
631 : :
632 : 24 : case SPDK_JSON_VAL_NAME:
633 : 24 : return spdk_json_write_name_raw(w, val->start, val->len);
634 : :
635 : 4 : case SPDK_JSON_VAL_TRUE:
636 : 4 : return spdk_json_write_bool(w, true);
637 : :
638 : 4 : case SPDK_JSON_VAL_FALSE:
639 : 4 : return spdk_json_write_bool(w, false);
640 : :
641 : 8 : case SPDK_JSON_VAL_NULL:
642 : 8 : return spdk_json_write_null(w);
643 : :
644 : 12 : case SPDK_JSON_VAL_ARRAY_BEGIN:
645 : : case SPDK_JSON_VAL_OBJECT_BEGIN:
646 : 12 : num_values = val[0].len;
647 : :
648 [ + + ]: 12 : if (val[0].type == SPDK_JSON_VAL_OBJECT_BEGIN) {
649 [ - + ]: 8 : if (spdk_json_write_object_begin(w)) {
650 : 0 : return fail(w);
651 : : }
652 : : } else {
653 [ - + ]: 4 : if (spdk_json_write_array_begin(w)) {
654 : 0 : return fail(w);
655 : : }
656 : : }
657 : :
658 : : /* Loop up to and including the _END value */
659 [ + + ]: 84 : for (i = 0; i < num_values + 1;) {
660 [ - + ]: 72 : if (spdk_json_write_val(w, &val[i + 1])) {
661 : 0 : return fail(w);
662 : : }
663 [ + + ]: 72 : if (val[i + 1].type == SPDK_JSON_VAL_ARRAY_BEGIN ||
664 [ + + ]: 68 : val[i + 1].type == SPDK_JSON_VAL_OBJECT_BEGIN) {
665 : 8 : i += val[i + 1].len + 2;
666 : : } else {
667 : 64 : i++;
668 : : }
669 : : }
670 : 12 : return 0;
671 : :
672 : 4 : case SPDK_JSON_VAL_ARRAY_END:
673 : 4 : return spdk_json_write_array_end(w);
674 : :
675 : 8 : case SPDK_JSON_VAL_OBJECT_END:
676 : 8 : return spdk_json_write_object_end(w);
677 : :
678 : 0 : case SPDK_JSON_VAL_INVALID:
679 : : /* Handle INVALID to make the compiler happy (and catch other unhandled types) */
680 : 0 : return fail(w);
681 : : }
682 : :
683 : 0 : return fail(w);
684 : : }
685 : :
686 : : int
687 : 0 : spdk_json_write_named_null(struct spdk_json_write_ctx *w, const char *name)
688 : : {
689 : 0 : int rc = spdk_json_write_name(w, name);
690 [ # # ]: 0 : return rc ? rc : spdk_json_write_null(w);
691 : : }
692 : :
693 : : int
694 : 711113 : spdk_json_write_named_bool(struct spdk_json_write_ctx *w, const char *name, bool val)
695 : : {
696 : 711113 : int rc = spdk_json_write_name(w, name);
697 : :
698 [ + - ]: 711113 : return rc ? rc : spdk_json_write_bool(w, val);
699 : : }
700 : :
701 : : int
702 : 338 : spdk_json_write_named_uint8(struct spdk_json_write_ctx *w, const char *name, uint8_t val)
703 : : {
704 : 338 : int rc = spdk_json_write_name(w, name);
705 : :
706 [ + - ]: 338 : return rc ? rc : spdk_json_write_uint8(w, val);
707 : : }
708 : :
709 : : int
710 : 2113 : spdk_json_write_named_uint16(struct spdk_json_write_ctx *w, const char *name, uint16_t val)
711 : : {
712 : 2113 : int rc = spdk_json_write_name(w, name);
713 : :
714 [ + - ]: 2113 : return rc ? rc : spdk_json_write_uint16(w, val);
715 : : }
716 : :
717 : : int
718 : 55642 : spdk_json_write_named_int32(struct spdk_json_write_ctx *w, const char *name, int32_t val)
719 : : {
720 : 55642 : int rc = spdk_json_write_name(w, name);
721 : :
722 [ + - ]: 55642 : return rc ? rc : spdk_json_write_int32(w, val);
723 : : }
724 : :
725 : : int
726 : 1684359 : spdk_json_write_named_uint32(struct spdk_json_write_ctx *w, const char *name, uint32_t val)
727 : : {
728 : 1684359 : int rc = spdk_json_write_name(w, name);
729 : :
730 [ + - ]: 1684359 : return rc ? rc : spdk_json_write_uint32(w, val);
731 : : }
732 : :
733 : : int
734 : 4 : spdk_json_write_named_int64(struct spdk_json_write_ctx *w, const char *name, int64_t val)
735 : : {
736 : 4 : int rc = spdk_json_write_name(w, name);
737 : :
738 [ + - ]: 4 : return rc ? rc : spdk_json_write_int64(w, val);
739 : : }
740 : :
741 : : int
742 : 208347 : spdk_json_write_named_uint64(struct spdk_json_write_ctx *w, const char *name, uint64_t val)
743 : : {
744 : 208347 : int rc = spdk_json_write_name(w, name);
745 : :
746 [ + - ]: 208347 : return rc ? rc : spdk_json_write_uint64(w, val);
747 : : }
748 : :
749 : : int
750 : 69 : spdk_json_write_named_double(struct spdk_json_write_ctx *w, const char *name, double val)
751 : : {
752 : 69 : int rc = spdk_json_write_name(w, name);
753 : :
754 [ + - ]: 69 : return rc ? rc : spdk_json_write_double(w, val);
755 : : }
756 : :
757 : : int
758 : 537959 : spdk_json_write_named_string(struct spdk_json_write_ctx *w, const char *name, const char *val)
759 : : {
760 : 537959 : int rc = spdk_json_write_name(w, name);
761 : :
762 [ + - ]: 537959 : return rc ? rc : spdk_json_write_string(w, val);
763 : : }
764 : :
765 : : int
766 : 2187 : spdk_json_write_named_string_fmt(struct spdk_json_write_ctx *w, const char *name,
767 : : const char *fmt, ...)
768 : : {
769 : 1848 : va_list args;
770 : : int rc;
771 : :
772 : 2187 : va_start(args, fmt);
773 : 2187 : rc = spdk_json_write_named_string_fmt_v(w, name, fmt, args);
774 : 2187 : va_end(args);
775 : :
776 : 2187 : return rc;
777 : : }
778 : :
779 : : int
780 : 2364 : spdk_json_write_named_string_fmt_v(struct spdk_json_write_ctx *w, const char *name,
781 : : const char *fmt, va_list args)
782 : : {
783 : : char *s;
784 : : int rc;
785 : :
786 : 2364 : rc = spdk_json_write_name(w, name);
787 [ - + ]: 2364 : if (rc) {
788 : 0 : return rc;
789 : : }
790 : :
791 : 2364 : s = spdk_vsprintf_alloc(fmt, args);
792 : :
793 [ - + ]: 2364 : if (s == NULL) {
794 : 0 : return -1;
795 : : }
796 : :
797 : 2364 : rc = spdk_json_write_string(w, s);
798 : 2364 : free(s);
799 : 2364 : return rc;
800 : : }
801 : :
802 : : int
803 : 0 : spdk_json_write_named_bytearray(struct spdk_json_write_ctx *w, const char *name, const void *val,
804 : : size_t len)
805 : : {
806 : 0 : int rc = spdk_json_write_name(w, name);
807 : :
808 [ # # ]: 0 : return rc ? rc : spdk_json_write_bytearray(w, val, len);
809 : : }
810 : :
811 : : int
812 : 74612 : spdk_json_write_named_array_begin(struct spdk_json_write_ctx *w, const char *name)
813 : : {
814 : 74612 : int rc = spdk_json_write_name(w, name);
815 : :
816 [ + - ]: 74612 : return rc ? rc : spdk_json_write_array_begin(w);
817 : : }
818 : :
819 : : int
820 : 380405 : spdk_json_write_named_object_begin(struct spdk_json_write_ctx *w, const char *name)
821 : : {
822 : 380405 : int rc = spdk_json_write_name(w, name);
823 : :
824 [ + - ]: 380405 : return rc ? rc : spdk_json_write_object_begin(w);
825 : : }
826 : :
827 : : int
828 : 58469 : spdk_json_write_named_uuid(struct spdk_json_write_ctx *w, const char *name,
829 : : const struct spdk_uuid *uuid)
830 : : {
831 : 58469 : int rc = spdk_json_write_name(w, name);
832 : :
833 [ + - ]: 58469 : return rc ? rc : spdk_json_write_uuid(w, uuid);
834 : : }
|