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