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 48 : fail(struct spdk_json_write_ctx *w)
26 : {
27 48 : w->failed = true;
28 48 : return -1;
29 : }
30 :
31 : static int
32 194 : flush_buf(struct spdk_json_write_ctx *w)
33 : {
34 : int rc;
35 :
36 194 : rc = w->write_cb(w->cb_ctx, w->buf, w->buf_filled);
37 194 : if (rc != 0) {
38 0 : return fail(w);
39 : }
40 :
41 194 : w->buf_filled = 0;
42 :
43 194 : return 0;
44 : }
45 :
46 : struct spdk_json_write_ctx *
47 194 : 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 194 : w = calloc(1, sizeof(*w));
52 194 : if (w == NULL) {
53 0 : return w;
54 : }
55 :
56 194 : w->write_cb = write_cb;
57 194 : w->cb_ctx = cb_ctx;
58 194 : w->flags = flags;
59 194 : w->indent = 0;
60 194 : w->new_indent = false;
61 194 : w->first_value = true;
62 194 : w->failed = false;
63 194 : w->buf_filled = 0;
64 :
65 194 : return w;
66 : }
67 :
68 : int
69 194 : spdk_json_write_end(struct spdk_json_write_ctx *w)
70 : {
71 : bool failed;
72 : int rc;
73 :
74 194 : if (w == NULL) {
75 0 : return 0;
76 : }
77 :
78 194 : failed = w->failed;
79 :
80 194 : rc = flush_buf(w);
81 194 : if (rc != 0) {
82 0 : failed = true;
83 : }
84 :
85 194 : free(w);
86 :
87 194 : return failed ? -1 : 0;
88 : }
89 :
90 : static inline int
91 2540 : emit(struct spdk_json_write_ctx *w, const void *data, size_t size)
92 : {
93 2540 : size_t buf_remain = sizeof(w->buf) - w->buf_filled;
94 :
95 2540 : if (spdk_unlikely(size > buf_remain)) {
96 : /* Not enough space in buffer for the new data. */
97 0 : return emit_buf_full(w, data, size);
98 : }
99 :
100 : /* Copy the new data into buf. */
101 2540 : memcpy(w->buf + w->buf_filled, data, size);
102 2540 : w->buf_filled += size;
103 2540 : return 0;
104 : }
105 :
106 : static int
107 0 : emit_buf_full(struct spdk_json_write_ctx *w, const void *data, size_t size)
108 : {
109 0 : size_t buf_remain = sizeof(w->buf) - w->buf_filled;
110 : int rc;
111 :
112 0 : assert(size > buf_remain);
113 :
114 : /* Copy as much of the new data as possible into the buffer and flush it. */
115 0 : memcpy(w->buf + w->buf_filled, data, buf_remain);
116 0 : w->buf_filled += buf_remain;
117 :
118 0 : rc = flush_buf(w);
119 0 : if (rc != 0) {
120 0 : return fail(w);
121 : }
122 :
123 : /* Recurse to emit the rest of the data. */
124 0 : return emit(w, data + buf_remain, size - buf_remain);
125 : }
126 :
127 : static int
128 389 : emit_fmt(struct spdk_json_write_ctx *w, const void *data, size_t size)
129 : {
130 389 : if (w->flags & SPDK_JSON_WRITE_FLAG_FORMATTED) {
131 0 : return emit(w, data, size);
132 : }
133 389 : return 0;
134 : }
135 :
136 : static int
137 254 : emit_indent(struct spdk_json_write_ctx *w)
138 : {
139 : uint32_t i;
140 :
141 254 : if (w->flags & SPDK_JSON_WRITE_FLAG_FORMATTED) {
142 0 : for (i = 0; i < w->indent; i++) {
143 0 : if (emit(w, " ", 2)) { return fail(w); }
144 : }
145 : }
146 254 : return 0;
147 : }
148 :
149 : static int
150 508 : begin_value(struct spdk_json_write_ctx *w)
151 : {
152 : /* TODO: check for value state */
153 508 : if (w->new_indent) {
154 76 : if (emit_fmt(w, "\n", 1)) { return fail(w); }
155 76 : if (emit_indent(w)) { return fail(w); }
156 : }
157 508 : if (!w->first_value) {
158 104 : if (emit(w, ",", 1)) { return fail(w); }
159 104 : if (emit_fmt(w, "\n", 1)) { return fail(w); }
160 104 : if (emit_indent(w)) { return fail(w); }
161 : }
162 508 : w->first_value = false;
163 508 : w->new_indent = false;
164 508 : return 0;
165 : }
166 :
167 : int
168 7 : spdk_json_write_val_raw(struct spdk_json_write_ctx *w, const void *data, size_t len)
169 : {
170 7 : if (begin_value(w)) { return fail(w); }
171 7 : return emit(w, data, len);
172 : }
173 :
174 : int
175 13 : spdk_json_write_null(struct spdk_json_write_ctx *w)
176 : {
177 13 : if (begin_value(w)) { return fail(w); }
178 13 : return emit(w, "null", 4);
179 : }
180 :
181 : int
182 15 : spdk_json_write_bool(struct spdk_json_write_ctx *w, bool val)
183 : {
184 15 : if (begin_value(w)) { return fail(w); }
185 15 : if (val) {
186 10 : return emit(w, "true", 4);
187 : } else {
188 5 : return emit(w, "false", 5);
189 : }
190 : }
191 :
192 : int
193 0 : spdk_json_write_uint8(struct spdk_json_write_ctx *w, uint8_t val)
194 : {
195 : char buf[32];
196 : int count;
197 :
198 0 : if (begin_value(w)) { return fail(w); }
199 0 : count = snprintf(buf, sizeof(buf), "%" PRIu8, val);
200 0 : if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
201 0 : return emit(w, buf, count);
202 : }
203 :
204 : int
205 0 : spdk_json_write_uint16(struct spdk_json_write_ctx *w, uint16_t val)
206 : {
207 : char buf[32];
208 : int count;
209 :
210 0 : if (begin_value(w)) { return fail(w); }
211 0 : count = snprintf(buf, sizeof(buf), "%" PRIu16, val);
212 0 : if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
213 0 : return emit(w, buf, count);
214 : }
215 :
216 : int
217 54 : spdk_json_write_int32(struct spdk_json_write_ctx *w, int32_t val)
218 : {
219 : char buf[32];
220 : int count;
221 :
222 54 : if (begin_value(w)) { return fail(w); }
223 54 : count = snprintf(buf, sizeof(buf), "%" PRId32, val);
224 54 : if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
225 54 : return emit(w, buf, count);
226 : }
227 :
228 : int
229 9 : spdk_json_write_uint32(struct spdk_json_write_ctx *w, uint32_t val)
230 : {
231 : char buf[32];
232 : int count;
233 :
234 9 : if (begin_value(w)) { return fail(w); }
235 9 : count = snprintf(buf, sizeof(buf), "%" PRIu32, val);
236 9 : if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
237 9 : return emit(w, buf, count);
238 : }
239 :
240 : int
241 6 : spdk_json_write_int64(struct spdk_json_write_ctx *w, int64_t val)
242 : {
243 : char buf[32];
244 : int count;
245 :
246 6 : if (begin_value(w)) { return fail(w); }
247 6 : count = snprintf(buf, sizeof(buf), "%" PRId64, val);
248 6 : if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
249 6 : return emit(w, buf, count);
250 : }
251 :
252 : int
253 13 : spdk_json_write_uint64(struct spdk_json_write_ctx *w, uint64_t val)
254 : {
255 : char buf[32];
256 : int count;
257 :
258 13 : if (begin_value(w)) { return fail(w); }
259 13 : count = snprintf(buf, sizeof(buf), "%" PRIu64, val);
260 13 : if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
261 13 : return emit(w, buf, count);
262 : }
263 :
264 : int
265 16 : spdk_json_write_uint128(struct spdk_json_write_ctx *w, uint64_t low_val, uint64_t high_val)
266 : {
267 16 : char buf[128] = {'\0'};
268 16 : uint64_t low = low_val, high = high_val;
269 16 : int count = 0;
270 :
271 16 : if (begin_value(w)) { return fail(w); }
272 :
273 16 : if (high != 0) {
274 8 : char temp_buf[128] = {'\0'};
275 : uint64_t seg;
276 8 : unsigned __int128 total = (unsigned __int128)low +
277 8 : ((unsigned __int128)high << 64);
278 :
279 28 : while (total) {
280 20 : seg = total % 10000000000;
281 20 : total = total / 10000000000;
282 20 : if (total) {
283 12 : count = snprintf(temp_buf, 128, "%010" PRIu64 "%s", seg, buf);
284 : } else {
285 8 : count = snprintf(temp_buf, 128, "%" PRIu64 "%s", seg, buf);
286 : }
287 :
288 20 : if (count <= 0 || (size_t)count >= sizeof(temp_buf)) {
289 0 : return fail(w);
290 : }
291 :
292 20 : snprintf(buf, 128, "%s", temp_buf);
293 : }
294 : } else {
295 8 : count = snprintf(buf, sizeof(buf), "%" PRIu64, low);
296 :
297 8 : if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
298 : }
299 :
300 16 : return emit(w, buf, count);
301 : }
302 :
303 : int
304 8 : 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 8 : int rc = spdk_json_write_name(w, name);
308 :
309 8 : return rc ? rc : spdk_json_write_uint128(w, low_val, high_val);
310 : }
311 :
312 : int
313 4 : spdk_json_write_double(struct spdk_json_write_ctx *w, double val)
314 : {
315 : char buf[32];
316 : int count;
317 :
318 4 : if (begin_value(w)) { return fail(w); }
319 4 : count = snprintf(buf, sizeof(buf), "%.20e", val);
320 4 : if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
321 4 : return emit(w, buf, count);
322 : }
323 :
324 : static void
325 126 : write_hex_2(void *dest, uint8_t val)
326 : {
327 126 : char *p = dest;
328 126 : char hex[] = "0123456789ABCDEF";
329 :
330 126 : p[0] = hex[val >> 4];
331 126 : p[1] = hex[val & 0xf];
332 126 : }
333 :
334 : static void
335 63 : write_hex_4(void *dest, uint16_t val)
336 : {
337 63 : write_hex_2(dest, (uint8_t)(val >> 8));
338 63 : write_hex_2((char *)dest + 2, (uint8_t)(val & 0xff));
339 63 : }
340 :
341 : static inline int
342 1472 : 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 : uint16_t high, low;
358 : char out[13];
359 : size_t out_len;
360 :
361 1472 : if (codepoint < sizeof(escapes) && escapes[codepoint]) {
362 8 : out[0] = '\\';
363 8 : out[1] = escapes[codepoint];
364 8 : out_len = 2;
365 1464 : } 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 1417 : out[0] = (uint8_t)codepoint;
371 1417 : out_len = 1;
372 47 : } else if (codepoint < 0x10000) {
373 31 : out[0] = '\\';
374 31 : out[1] = 'u';
375 31 : write_hex_4(&out[2], (uint16_t)codepoint);
376 31 : out_len = 6;
377 : } else {
378 16 : utf16_encode_surrogate_pair(codepoint, &high, &low);
379 16 : out[0] = '\\';
380 16 : out[1] = 'u';
381 16 : write_hex_4(&out[2], high);
382 16 : out[6] = '\\';
383 16 : out[7] = 'u';
384 16 : write_hex_4(&out[8], low);
385 16 : out_len = 12;
386 : }
387 :
388 1472 : return emit(w, out, out_len);
389 : }
390 :
391 : static int
392 283 : write_string_or_name(struct spdk_json_write_ctx *w, const char *val, size_t len)
393 : {
394 283 : const uint8_t *p = val;
395 283 : const uint8_t *end = val + len;
396 :
397 283 : if (emit(w, "\"", 1)) { return fail(w); }
398 :
399 1745 : while (p != end) {
400 : int codepoint_len;
401 : uint32_t codepoint;
402 :
403 1507 : codepoint_len = utf8_valid(p, end);
404 1507 : switch (codepoint_len) {
405 1421 : case 1:
406 1421 : codepoint = utf8_decode_unsafe_1(p);
407 1421 : break;
408 6 : case 2:
409 6 : codepoint = utf8_decode_unsafe_2(p);
410 6 : break;
411 20 : case 3:
412 20 : codepoint = utf8_decode_unsafe_3(p);
413 20 : break;
414 15 : case 4:
415 15 : codepoint = utf8_decode_unsafe_4(p);
416 15 : break;
417 45 : default:
418 45 : return fail(w);
419 : }
420 :
421 1462 : if (write_codepoint(w, codepoint)) { return fail(w); }
422 1462 : p += codepoint_len;
423 : }
424 :
425 238 : return emit(w, "\"", 1);
426 : }
427 :
428 : static int
429 5 : write_string_or_name_utf16le(struct spdk_json_write_ctx *w, const uint16_t *val, size_t len)
430 : {
431 5 : const uint16_t *p = val;
432 5 : const uint16_t *end = val + len;
433 :
434 5 : if (emit(w, "\"", 1)) { return fail(w); }
435 :
436 15 : while (p != end) {
437 : int codepoint_len;
438 : uint32_t codepoint;
439 :
440 13 : codepoint_len = utf16le_valid(p, end);
441 13 : switch (codepoint_len) {
442 9 : case 1:
443 9 : codepoint = from_le16(&p[0]);
444 9 : break;
445 1 : case 2:
446 1 : codepoint = utf16_decode_surrogate_pair(from_le16(&p[0]), from_le16(&p[1]));
447 1 : break;
448 3 : default:
449 3 : return fail(w);
450 : }
451 :
452 10 : if (write_codepoint(w, codepoint)) { return fail(w); }
453 10 : p += codepoint_len;
454 : }
455 :
456 2 : return emit(w, "\"", 1);
457 : }
458 :
459 : int
460 148 : spdk_json_write_string_raw(struct spdk_json_write_ctx *w, const char *val, size_t len)
461 : {
462 148 : if (begin_value(w)) { return fail(w); }
463 148 : return write_string_or_name(w, val, len);
464 : }
465 :
466 : int
467 43 : spdk_json_write_string(struct spdk_json_write_ctx *w, const char *val)
468 : {
469 43 : return spdk_json_write_string_raw(w, val, strlen(val));
470 : }
471 :
472 : int
473 5 : spdk_json_write_string_utf16le_raw(struct spdk_json_write_ctx *w, const uint16_t *val, size_t len)
474 : {
475 5 : if (begin_value(w)) { return fail(w); }
476 5 : 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 0 : spdk_json_write_string_fmt(struct spdk_json_write_ctx *w, const char *fmt, ...)
494 : {
495 : va_list args;
496 : int rc;
497 :
498 0 : va_start(args, fmt);
499 0 : rc = spdk_json_write_string_fmt_v(w, fmt, args);
500 0 : va_end(args);
501 :
502 0 : return rc;
503 : }
504 :
505 : int
506 0 : 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 0 : s = spdk_vsprintf_alloc(fmt, args);
512 0 : if (s == NULL) {
513 0 : return -1;
514 : }
515 :
516 0 : rc = spdk_json_write_string(w, s);
517 0 : free(s);
518 0 : 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 1 : spdk_json_write_uuid(struct spdk_json_write_ctx *w, const struct spdk_uuid *uuid)
546 : {
547 : char str[SPDK_UUID_STRING_LEN];
548 :
549 1 : spdk_uuid_fmt_lower(str, sizeof(str), uuid);
550 :
551 1 : return spdk_json_write_string(w, str);
552 : }
553 :
554 : int
555 33 : spdk_json_write_array_begin(struct spdk_json_write_ctx *w)
556 : {
557 33 : if (begin_value(w)) { return fail(w); }
558 33 : w->first_value = true;
559 33 : w->new_indent = true;
560 33 : w->indent++;
561 33 : if (emit(w, "[", 1)) { return fail(w); }
562 33 : return 0;
563 : }
564 :
565 : int
566 33 : spdk_json_write_array_end(struct spdk_json_write_ctx *w)
567 : {
568 33 : w->first_value = false;
569 33 : if (w->indent == 0) { return fail(w); }
570 33 : w->indent--;
571 33 : if (!w->new_indent) {
572 28 : if (emit_fmt(w, "\n", 1)) { return fail(w); }
573 28 : if (emit_indent(w)) { return fail(w); }
574 : }
575 33 : w->new_indent = false;
576 33 : return emit(w, "]", 1);
577 : }
578 :
579 : int
580 50 : spdk_json_write_object_begin(struct spdk_json_write_ctx *w)
581 : {
582 50 : if (begin_value(w)) { return fail(w); }
583 50 : w->first_value = true;
584 50 : w->new_indent = true;
585 50 : w->indent++;
586 50 : if (emit(w, "{", 1)) { return fail(w); }
587 50 : return 0;
588 : }
589 :
590 : int
591 48 : spdk_json_write_object_end(struct spdk_json_write_ctx *w)
592 : {
593 48 : w->first_value = false;
594 48 : w->indent--;
595 48 : if (!w->new_indent) {
596 46 : if (emit_fmt(w, "\n", 1)) { return fail(w); }
597 46 : if (emit_indent(w)) { return fail(w); }
598 : }
599 48 : w->new_indent = false;
600 48 : return emit(w, "}", 1);
601 : }
602 :
603 : int
604 135 : 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 135 : if (begin_value(w)) { return fail(w); }
608 135 : if (write_string_or_name(w, name, len)) { return fail(w); }
609 135 : w->first_value = true;
610 135 : if (emit(w, ":", 1)) { return fail(w); }
611 135 : return emit_fmt(w, " ", 1);
612 : }
613 :
614 : int
615 103 : spdk_json_write_name(struct spdk_json_write_ctx *w, const char *name)
616 : {
617 103 : return spdk_json_write_name_raw(w, name, strlen(name));
618 : }
619 :
620 : int
621 24 : 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 24 : switch (val->type) {
626 7 : case SPDK_JSON_VAL_NUMBER:
627 7 : return spdk_json_write_val_raw(w, val->start, val->len);
628 :
629 1 : case SPDK_JSON_VAL_STRING:
630 1 : return spdk_json_write_string_raw(w, val->start, val->len);
631 :
632 6 : case SPDK_JSON_VAL_NAME:
633 6 : return spdk_json_write_name_raw(w, val->start, val->len);
634 :
635 1 : case SPDK_JSON_VAL_TRUE:
636 1 : return spdk_json_write_bool(w, true);
637 :
638 1 : case SPDK_JSON_VAL_FALSE:
639 1 : return spdk_json_write_bool(w, false);
640 :
641 2 : case SPDK_JSON_VAL_NULL:
642 2 : return spdk_json_write_null(w);
643 :
644 3 : case SPDK_JSON_VAL_ARRAY_BEGIN:
645 : case SPDK_JSON_VAL_OBJECT_BEGIN:
646 3 : num_values = val[0].len;
647 :
648 3 : if (val[0].type == SPDK_JSON_VAL_OBJECT_BEGIN) {
649 2 : if (spdk_json_write_object_begin(w)) {
650 0 : return fail(w);
651 : }
652 : } else {
653 1 : 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 21 : for (i = 0; i < num_values + 1;) {
660 18 : if (spdk_json_write_val(w, &val[i + 1])) {
661 0 : return fail(w);
662 : }
663 18 : if (val[i + 1].type == SPDK_JSON_VAL_ARRAY_BEGIN ||
664 17 : val[i + 1].type == SPDK_JSON_VAL_OBJECT_BEGIN) {
665 2 : i += val[i + 1].len + 2;
666 : } else {
667 16 : i++;
668 : }
669 : }
670 3 : return 0;
671 :
672 1 : case SPDK_JSON_VAL_ARRAY_END:
673 1 : return spdk_json_write_array_end(w);
674 :
675 2 : case SPDK_JSON_VAL_OBJECT_END:
676 2 : 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 4 : spdk_json_write_named_bool(struct spdk_json_write_ctx *w, const char *name, bool val)
695 : {
696 4 : int rc = spdk_json_write_name(w, name);
697 :
698 4 : return rc ? rc : spdk_json_write_bool(w, val);
699 : }
700 :
701 : int
702 0 : spdk_json_write_named_uint8(struct spdk_json_write_ctx *w, const char *name, uint8_t val)
703 : {
704 0 : int rc = spdk_json_write_name(w, name);
705 :
706 0 : return rc ? rc : spdk_json_write_uint8(w, val);
707 : }
708 :
709 : int
710 0 : spdk_json_write_named_uint16(struct spdk_json_write_ctx *w, const char *name, uint16_t val)
711 : {
712 0 : int rc = spdk_json_write_name(w, name);
713 :
714 0 : return rc ? rc : spdk_json_write_uint16(w, val);
715 : }
716 :
717 : int
718 9 : spdk_json_write_named_int32(struct spdk_json_write_ctx *w, const char *name, int32_t val)
719 : {
720 9 : int rc = spdk_json_write_name(w, name);
721 :
722 9 : return rc ? rc : spdk_json_write_int32(w, val);
723 : }
724 :
725 : int
726 4 : spdk_json_write_named_uint32(struct spdk_json_write_ctx *w, const char *name, uint32_t val)
727 : {
728 4 : int rc = spdk_json_write_name(w, name);
729 :
730 4 : return rc ? rc : spdk_json_write_uint32(w, val);
731 : }
732 :
733 : int
734 0 : spdk_json_write_named_int64(struct spdk_json_write_ctx *w, const char *name, int64_t val)
735 : {
736 0 : int rc = spdk_json_write_name(w, name);
737 :
738 0 : return rc ? rc : spdk_json_write_int64(w, val);
739 : }
740 :
741 : int
742 8 : spdk_json_write_named_uint64(struct spdk_json_write_ctx *w, const char *name, uint64_t val)
743 : {
744 8 : int rc = spdk_json_write_name(w, name);
745 :
746 8 : return rc ? rc : spdk_json_write_uint64(w, val);
747 : }
748 :
749 : int
750 0 : spdk_json_write_named_double(struct spdk_json_write_ctx *w, const char *name, double val)
751 : {
752 0 : int rc = spdk_json_write_name(w, name);
753 :
754 0 : return rc ? rc : spdk_json_write_double(w, val);
755 : }
756 :
757 : int
758 27 : spdk_json_write_named_string(struct spdk_json_write_ctx *w, const char *name, const char *val)
759 : {
760 27 : int rc = spdk_json_write_name(w, name);
761 :
762 27 : return rc ? rc : spdk_json_write_string(w, val);
763 : }
764 :
765 : int
766 0 : spdk_json_write_named_string_fmt(struct spdk_json_write_ctx *w, const char *name,
767 : const char *fmt, ...)
768 : {
769 : va_list args;
770 : int rc;
771 :
772 0 : va_start(args, fmt);
773 0 : rc = spdk_json_write_named_string_fmt_v(w, name, fmt, args);
774 0 : va_end(args);
775 :
776 0 : return rc;
777 : }
778 :
779 : int
780 9 : 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 9 : rc = spdk_json_write_name(w, name);
787 9 : if (rc) {
788 0 : return rc;
789 : }
790 :
791 9 : s = spdk_vsprintf_alloc(fmt, args);
792 :
793 9 : if (s == NULL) {
794 0 : return -1;
795 : }
796 :
797 9 : rc = spdk_json_write_string(w, s);
798 9 : free(s);
799 9 : 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 4 : spdk_json_write_named_array_begin(struct spdk_json_write_ctx *w, const char *name)
813 : {
814 4 : int rc = spdk_json_write_name(w, name);
815 :
816 4 : return rc ? rc : spdk_json_write_array_begin(w);
817 : }
818 :
819 : int
820 9 : spdk_json_write_named_object_begin(struct spdk_json_write_ctx *w, const char *name)
821 : {
822 9 : int rc = spdk_json_write_name(w, name);
823 :
824 9 : return rc ? rc : spdk_json_write_object_begin(w);
825 : }
826 :
827 : int
828 0 : spdk_json_write_named_uuid(struct spdk_json_write_ctx *w, const char *name,
829 : const struct spdk_uuid *uuid)
830 : {
831 0 : int rc = spdk_json_write_name(w, name);
832 :
833 0 : return rc ? rc : spdk_json_write_uuid(w, uuid);
834 : }
|