xref: /spdk/lib/json/json_write.c (revision 5d91b0749fa89f64e0f9f5f90c6e5e7cec5e1682)
1488570ebSJim Harris /*   SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse  *   Copyright (C) 2016 Intel Corporation.
3f9193f4cSDaniel Verkamp  *   All rights reserved.
4f9193f4cSDaniel Verkamp  */
5f9193f4cSDaniel Verkamp 
67d716668SDaniel Verkamp #include "spdk/json.h"
77d716668SDaniel Verkamp 
80a97bd14SSeth Howell #include "spdk_internal/utf.h"
9f9193f4cSDaniel Verkamp 
10f9193f4cSDaniel Verkamp struct spdk_json_write_ctx {
11f9193f4cSDaniel Verkamp 	spdk_json_write_cb write_cb;
12f9193f4cSDaniel Verkamp 	void *cb_ctx;
13c56b53a8SDaniel Verkamp 	uint32_t flags;
14c56b53a8SDaniel Verkamp 	uint32_t indent;
15c56b53a8SDaniel Verkamp 	bool new_indent;
16f9193f4cSDaniel Verkamp 	bool first_value;
17f9193f4cSDaniel Verkamp 	bool failed;
18a509ddebSDaniel Verkamp 	size_t buf_filled;
19a509ddebSDaniel Verkamp 	uint8_t buf[4096];
20f9193f4cSDaniel Verkamp };
21f9193f4cSDaniel Verkamp 
22a509ddebSDaniel Verkamp static int emit_buf_full(struct spdk_json_write_ctx *w, const void *data, size_t size);
23a509ddebSDaniel Verkamp 
24a509ddebSDaniel Verkamp static int
fail(struct spdk_json_write_ctx * w)25a509ddebSDaniel Verkamp fail(struct spdk_json_write_ctx *w)
26a509ddebSDaniel Verkamp {
27a509ddebSDaniel Verkamp 	w->failed = true;
28a509ddebSDaniel Verkamp 	return -1;
29a509ddebSDaniel Verkamp }
30a509ddebSDaniel Verkamp 
31a509ddebSDaniel Verkamp static int
flush_buf(struct spdk_json_write_ctx * w)32a509ddebSDaniel Verkamp flush_buf(struct spdk_json_write_ctx *w)
33a509ddebSDaniel Verkamp {
34a509ddebSDaniel Verkamp 	int rc;
35a509ddebSDaniel Verkamp 
36a509ddebSDaniel Verkamp 	rc = w->write_cb(w->cb_ctx, w->buf, w->buf_filled);
37a509ddebSDaniel Verkamp 	if (rc != 0) {
38a509ddebSDaniel Verkamp 		return fail(w);
39a509ddebSDaniel Verkamp 	}
40a509ddebSDaniel Verkamp 
41a509ddebSDaniel Verkamp 	w->buf_filled = 0;
42a509ddebSDaniel Verkamp 
43a509ddebSDaniel Verkamp 	return 0;
44a509ddebSDaniel Verkamp }
45a509ddebSDaniel Verkamp 
46f9193f4cSDaniel Verkamp struct spdk_json_write_ctx *
spdk_json_write_begin(spdk_json_write_cb write_cb,void * cb_ctx,uint32_t flags)47f9193f4cSDaniel Verkamp spdk_json_write_begin(spdk_json_write_cb write_cb, void *cb_ctx, uint32_t flags)
48f9193f4cSDaniel Verkamp {
49f9193f4cSDaniel Verkamp 	struct spdk_json_write_ctx *w;
50f9193f4cSDaniel Verkamp 
51f9193f4cSDaniel Verkamp 	w = calloc(1, sizeof(*w));
52f9193f4cSDaniel Verkamp 	if (w == NULL) {
53f9193f4cSDaniel Verkamp 		return w;
54f9193f4cSDaniel Verkamp 	}
55f9193f4cSDaniel Verkamp 
56f9193f4cSDaniel Verkamp 	w->write_cb = write_cb;
57f9193f4cSDaniel Verkamp 	w->cb_ctx = cb_ctx;
58c56b53a8SDaniel Verkamp 	w->flags = flags;
59c56b53a8SDaniel Verkamp 	w->indent = 0;
60c56b53a8SDaniel Verkamp 	w->new_indent = false;
61f9193f4cSDaniel Verkamp 	w->first_value = true;
62f9193f4cSDaniel Verkamp 	w->failed = false;
63a509ddebSDaniel Verkamp 	w->buf_filled = 0;
64f9193f4cSDaniel Verkamp 
65f9193f4cSDaniel Verkamp 	return w;
66f9193f4cSDaniel Verkamp }
67f9193f4cSDaniel Verkamp 
68f9193f4cSDaniel Verkamp int
spdk_json_write_end(struct spdk_json_write_ctx * w)69f9193f4cSDaniel Verkamp spdk_json_write_end(struct spdk_json_write_ctx *w)
70f9193f4cSDaniel Verkamp {
71f9193f4cSDaniel Verkamp 	bool failed;
72a509ddebSDaniel Verkamp 	int rc;
73f9193f4cSDaniel Verkamp 
74f9193f4cSDaniel Verkamp 	if (w == NULL) {
75f9193f4cSDaniel Verkamp 		return 0;
76f9193f4cSDaniel Verkamp 	}
77f9193f4cSDaniel Verkamp 
78f9193f4cSDaniel Verkamp 	failed = w->failed;
79f9193f4cSDaniel Verkamp 
80a509ddebSDaniel Verkamp 	rc = flush_buf(w);
81a509ddebSDaniel Verkamp 	if (rc != 0) {
82a509ddebSDaniel Verkamp 		failed = true;
83a509ddebSDaniel Verkamp 	}
84a509ddebSDaniel Verkamp 
85f9193f4cSDaniel Verkamp 	free(w);
86f9193f4cSDaniel Verkamp 
87f9193f4cSDaniel Verkamp 	return failed ? -1 : 0;
88f9193f4cSDaniel Verkamp }
89f9193f4cSDaniel Verkamp 
90a509ddebSDaniel Verkamp static inline int
emit(struct spdk_json_write_ctx * w,const void * data,size_t size)91a509ddebSDaniel Verkamp emit(struct spdk_json_write_ctx *w, const void *data, size_t size)
92f9193f4cSDaniel Verkamp {
93a509ddebSDaniel Verkamp 	size_t buf_remain = sizeof(w->buf) - w->buf_filled;
94a509ddebSDaniel Verkamp 
95a509ddebSDaniel Verkamp 	if (spdk_unlikely(size > buf_remain)) {
96a509ddebSDaniel Verkamp 		/* Not enough space in buffer for the new data. */
97a509ddebSDaniel Verkamp 		return emit_buf_full(w, data, size);
98a509ddebSDaniel Verkamp 	}
99a509ddebSDaniel Verkamp 
100a509ddebSDaniel Verkamp 	/* Copy the new data into buf. */
101a509ddebSDaniel Verkamp 	memcpy(w->buf + w->buf_filled, data, size);
102a509ddebSDaniel Verkamp 	w->buf_filled += size;
103a509ddebSDaniel Verkamp 	return 0;
104f9193f4cSDaniel Verkamp }
105f9193f4cSDaniel Verkamp 
106f9193f4cSDaniel Verkamp static int
emit_buf_full(struct spdk_json_write_ctx * w,const void * data,size_t size)107a509ddebSDaniel Verkamp emit_buf_full(struct spdk_json_write_ctx *w, const void *data, size_t size)
108f9193f4cSDaniel Verkamp {
109a509ddebSDaniel Verkamp 	size_t buf_remain = sizeof(w->buf) - w->buf_filled;
110f9193f4cSDaniel Verkamp 	int rc;
111f9193f4cSDaniel Verkamp 
112a509ddebSDaniel Verkamp 	assert(size > buf_remain);
113a509ddebSDaniel Verkamp 
114a509ddebSDaniel Verkamp 	/* Copy as much of the new data as possible into the buffer and flush it. */
115a509ddebSDaniel Verkamp 	memcpy(w->buf + w->buf_filled, data, buf_remain);
116a509ddebSDaniel Verkamp 	w->buf_filled += buf_remain;
117a509ddebSDaniel Verkamp 
118a509ddebSDaniel Verkamp 	rc = flush_buf(w);
119f9193f4cSDaniel Verkamp 	if (rc != 0) {
120f9193f4cSDaniel Verkamp 		return fail(w);
121f9193f4cSDaniel Verkamp 	}
122a509ddebSDaniel Verkamp 
123a509ddebSDaniel Verkamp 	/* Recurse to emit the rest of the data. */
124a509ddebSDaniel Verkamp 	return emit(w, data + buf_remain, size - buf_remain);
125f9193f4cSDaniel Verkamp }
126f9193f4cSDaniel Verkamp 
127f9193f4cSDaniel Verkamp static int
emit_fmt(struct spdk_json_write_ctx * w,const void * data,size_t size)128c56b53a8SDaniel Verkamp emit_fmt(struct spdk_json_write_ctx *w, const void *data, size_t size)
129c56b53a8SDaniel Verkamp {
130c56b53a8SDaniel Verkamp 	if (w->flags & SPDK_JSON_WRITE_FLAG_FORMATTED) {
131c56b53a8SDaniel Verkamp 		return emit(w, data, size);
132c56b53a8SDaniel Verkamp 	}
133c56b53a8SDaniel Verkamp 	return 0;
134c56b53a8SDaniel Verkamp }
135c56b53a8SDaniel Verkamp 
136c56b53a8SDaniel Verkamp static int
emit_indent(struct spdk_json_write_ctx * w)137c56b53a8SDaniel Verkamp emit_indent(struct spdk_json_write_ctx *w)
138c56b53a8SDaniel Verkamp {
139c56b53a8SDaniel Verkamp 	uint32_t i;
140c56b53a8SDaniel Verkamp 
141c56b53a8SDaniel Verkamp 	if (w->flags & SPDK_JSON_WRITE_FLAG_FORMATTED) {
142c56b53a8SDaniel Verkamp 		for (i = 0; i < w->indent; i++) {
14359970a89SDaniel Verkamp 			if (emit(w, "  ", 2)) { return fail(w); }
144c56b53a8SDaniel Verkamp 		}
145c56b53a8SDaniel Verkamp 	}
146c56b53a8SDaniel Verkamp 	return 0;
147c56b53a8SDaniel Verkamp }
148c56b53a8SDaniel Verkamp 
149c56b53a8SDaniel Verkamp static int
begin_value(struct spdk_json_write_ctx * w)150f9193f4cSDaniel Verkamp begin_value(struct spdk_json_write_ctx *w)
151f9193f4cSDaniel Verkamp {
152d35ee09eSShuhei Matsumoto 	/* TODO: check for value state */
153c56b53a8SDaniel Verkamp 	if (w->new_indent) {
15459970a89SDaniel Verkamp 		if (emit_fmt(w, "\n", 1)) { return fail(w); }
15559970a89SDaniel Verkamp 		if (emit_indent(w)) { return fail(w); }
156c56b53a8SDaniel Verkamp 	}
157f9193f4cSDaniel Verkamp 	if (!w->first_value) {
15859970a89SDaniel Verkamp 		if (emit(w, ",", 1)) { return fail(w); }
15959970a89SDaniel Verkamp 		if (emit_fmt(w, "\n", 1)) { return fail(w); }
16059970a89SDaniel Verkamp 		if (emit_indent(w)) { return fail(w); }
161f9193f4cSDaniel Verkamp 	}
162f9193f4cSDaniel Verkamp 	w->first_value = false;
163c56b53a8SDaniel Verkamp 	w->new_indent = false;
164f9193f4cSDaniel Verkamp 	return 0;
165f9193f4cSDaniel Verkamp }
166f9193f4cSDaniel Verkamp 
167f9193f4cSDaniel Verkamp int
spdk_json_write_val_raw(struct spdk_json_write_ctx * w,const void * data,size_t len)168f9193f4cSDaniel Verkamp spdk_json_write_val_raw(struct spdk_json_write_ctx *w, const void *data, size_t len)
169f9193f4cSDaniel Verkamp {
17059970a89SDaniel Verkamp 	if (begin_value(w)) { return fail(w); }
171f9193f4cSDaniel Verkamp 	return emit(w, data, len);
172f9193f4cSDaniel Verkamp }
173f9193f4cSDaniel Verkamp 
174f9193f4cSDaniel Verkamp int
spdk_json_write_null(struct spdk_json_write_ctx * w)175f9193f4cSDaniel Verkamp spdk_json_write_null(struct spdk_json_write_ctx *w)
176f9193f4cSDaniel Verkamp {
17759970a89SDaniel Verkamp 	if (begin_value(w)) { return fail(w); }
178f9193f4cSDaniel Verkamp 	return emit(w, "null", 4);
179f9193f4cSDaniel Verkamp }
180f9193f4cSDaniel Verkamp 
181f9193f4cSDaniel Verkamp int
spdk_json_write_bool(struct spdk_json_write_ctx * w,bool val)182f9193f4cSDaniel Verkamp spdk_json_write_bool(struct spdk_json_write_ctx *w, bool val)
183f9193f4cSDaniel Verkamp {
18459970a89SDaniel Verkamp 	if (begin_value(w)) { return fail(w); }
185f9193f4cSDaniel Verkamp 	if (val) {
186f9193f4cSDaniel Verkamp 		return emit(w, "true", 4);
187f9193f4cSDaniel Verkamp 	} else {
188f9193f4cSDaniel Verkamp 		return emit(w, "false", 5);
189f9193f4cSDaniel Verkamp 	}
190f9193f4cSDaniel Verkamp }
191f9193f4cSDaniel Verkamp 
192f9193f4cSDaniel Verkamp int
spdk_json_write_uint8(struct spdk_json_write_ctx * w,uint8_t val)1938f8f3f87SJacek Kalwas spdk_json_write_uint8(struct spdk_json_write_ctx *w, uint8_t val)
1948f8f3f87SJacek Kalwas {
1958f8f3f87SJacek Kalwas 	char buf[32];
1968f8f3f87SJacek Kalwas 	int count;
1978f8f3f87SJacek Kalwas 
1988f8f3f87SJacek Kalwas 	if (begin_value(w)) { return fail(w); }
1998f8f3f87SJacek Kalwas 	count = snprintf(buf, sizeof(buf), "%" PRIu8, val);
2008f8f3f87SJacek Kalwas 	if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
2018f8f3f87SJacek Kalwas 	return emit(w, buf, count);
2028f8f3f87SJacek Kalwas }
2038f8f3f87SJacek Kalwas 
2048f8f3f87SJacek Kalwas int
spdk_json_write_uint16(struct spdk_json_write_ctx * w,uint16_t val)2058f8f3f87SJacek Kalwas spdk_json_write_uint16(struct spdk_json_write_ctx *w, uint16_t val)
2068f8f3f87SJacek Kalwas {
2078f8f3f87SJacek Kalwas 	char buf[32];
2088f8f3f87SJacek Kalwas 	int count;
2098f8f3f87SJacek Kalwas 
2108f8f3f87SJacek Kalwas 	if (begin_value(w)) { return fail(w); }
2118f8f3f87SJacek Kalwas 	count = snprintf(buf, sizeof(buf), "%" PRIu16, val);
2128f8f3f87SJacek Kalwas 	if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
2138f8f3f87SJacek Kalwas 	return emit(w, buf, count);
2148f8f3f87SJacek Kalwas }
2158f8f3f87SJacek Kalwas 
2168f8f3f87SJacek Kalwas int
spdk_json_write_int32(struct spdk_json_write_ctx * w,int32_t val)217f9193f4cSDaniel Verkamp spdk_json_write_int32(struct spdk_json_write_ctx *w, int32_t val)
218f9193f4cSDaniel Verkamp {
219f9193f4cSDaniel Verkamp 	char buf[32];
220f9193f4cSDaniel Verkamp 	int count;
221f9193f4cSDaniel Verkamp 
22259970a89SDaniel Verkamp 	if (begin_value(w)) { return fail(w); }
223f9193f4cSDaniel Verkamp 	count = snprintf(buf, sizeof(buf), "%" PRId32, val);
22459970a89SDaniel Verkamp 	if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
225f9193f4cSDaniel Verkamp 	return emit(w, buf, count);
226f9193f4cSDaniel Verkamp }
227f9193f4cSDaniel Verkamp 
228f9193f4cSDaniel Verkamp int
spdk_json_write_uint32(struct spdk_json_write_ctx * w,uint32_t val)229f9193f4cSDaniel Verkamp spdk_json_write_uint32(struct spdk_json_write_ctx *w, uint32_t val)
230f9193f4cSDaniel Verkamp {
231f9193f4cSDaniel Verkamp 	char buf[32];
232f9193f4cSDaniel Verkamp 	int count;
233f9193f4cSDaniel Verkamp 
23459970a89SDaniel Verkamp 	if (begin_value(w)) { return fail(w); }
235f9193f4cSDaniel Verkamp 	count = snprintf(buf, sizeof(buf), "%" PRIu32, val);
23659970a89SDaniel Verkamp 	if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
237f9193f4cSDaniel Verkamp 	return emit(w, buf, count);
238f9193f4cSDaniel Verkamp }
239f9193f4cSDaniel Verkamp 
240d921d9edSDaniel Verkamp int
spdk_json_write_int64(struct spdk_json_write_ctx * w,int64_t val)241d921d9edSDaniel Verkamp spdk_json_write_int64(struct spdk_json_write_ctx *w, int64_t val)
242d921d9edSDaniel Verkamp {
243d921d9edSDaniel Verkamp 	char buf[32];
244d921d9edSDaniel Verkamp 	int count;
245d921d9edSDaniel Verkamp 
24659970a89SDaniel Verkamp 	if (begin_value(w)) { return fail(w); }
247d921d9edSDaniel Verkamp 	count = snprintf(buf, sizeof(buf), "%" PRId64, val);
24859970a89SDaniel Verkamp 	if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
249d921d9edSDaniel Verkamp 	return emit(w, buf, count);
250d921d9edSDaniel Verkamp }
251d921d9edSDaniel Verkamp 
252d921d9edSDaniel Verkamp int
spdk_json_write_uint64(struct spdk_json_write_ctx * w,uint64_t val)253d921d9edSDaniel Verkamp spdk_json_write_uint64(struct spdk_json_write_ctx *w, uint64_t val)
254d921d9edSDaniel Verkamp {
255d921d9edSDaniel Verkamp 	char buf[32];
256d921d9edSDaniel Verkamp 	int count;
257d921d9edSDaniel Verkamp 
25859970a89SDaniel Verkamp 	if (begin_value(w)) { return fail(w); }
259d921d9edSDaniel Verkamp 	count = snprintf(buf, sizeof(buf), "%" PRIu64, val);
26059970a89SDaniel Verkamp 	if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
261d921d9edSDaniel Verkamp 	return emit(w, buf, count);
262d921d9edSDaniel Verkamp }
263d921d9edSDaniel Verkamp 
2642d629511SWindYu int
spdk_json_write_uint128(struct spdk_json_write_ctx * w,uint64_t low_val,uint64_t high_val)2652d629511SWindYu spdk_json_write_uint128(struct spdk_json_write_ctx *w, uint64_t low_val, uint64_t high_val)
2662d629511SWindYu {
2672d629511SWindYu 	char buf[128] = {'\0'};
2682d629511SWindYu 	uint64_t low = low_val, high = high_val;
2692d629511SWindYu 	int count = 0;
2702d629511SWindYu 
2712d629511SWindYu 	if (begin_value(w)) { return fail(w); }
2722d629511SWindYu 
2732d629511SWindYu 	if (high != 0) {
2742d629511SWindYu 		char temp_buf[128] = {'\0'};
2752d629511SWindYu 		uint64_t seg;
2762d629511SWindYu 		unsigned __int128 total = (unsigned __int128)low +
2772d629511SWindYu 					  ((unsigned __int128)high << 64);
2782d629511SWindYu 
2792d629511SWindYu 		while (total) {
2802d629511SWindYu 			seg = total % 10000000000;
2812d629511SWindYu 			total = total / 10000000000;
2822d629511SWindYu 			if (total) {
2832d629511SWindYu 				count = snprintf(temp_buf, 128, "%010" PRIu64 "%s", seg, buf);
2842d629511SWindYu 			} else {
2852d629511SWindYu 				count = snprintf(temp_buf, 128, "%" PRIu64 "%s", seg, buf);
2862d629511SWindYu 			}
2872d629511SWindYu 
2882d629511SWindYu 			if (count <= 0 || (size_t)count >= sizeof(temp_buf)) {
2892d629511SWindYu 				return fail(w);
2902d629511SWindYu 			}
2912d629511SWindYu 
2922d629511SWindYu 			snprintf(buf, 128, "%s", temp_buf);
2932d629511SWindYu 		}
2942d629511SWindYu 	} else {
2952d629511SWindYu 		count = snprintf(buf, sizeof(buf), "%" PRIu64, low);
2962d629511SWindYu 
2972d629511SWindYu 		if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
2982d629511SWindYu 	}
2992d629511SWindYu 
3002d629511SWindYu 	return emit(w, buf, count);
3012d629511SWindYu }
3022d629511SWindYu 
3032d629511SWindYu int
spdk_json_write_named_uint128(struct spdk_json_write_ctx * w,const char * name,uint64_t low_val,uint64_t high_val)3042d629511SWindYu spdk_json_write_named_uint128(struct spdk_json_write_ctx *w, const char *name,
3052d629511SWindYu 			      uint64_t low_val, uint64_t high_val)
3062d629511SWindYu {
3072d629511SWindYu 	int rc = spdk_json_write_name(w, name);
3082d629511SWindYu 
3092d629511SWindYu 	return rc ? rc : spdk_json_write_uint128(w, low_val, high_val);
3102d629511SWindYu }
3112d629511SWindYu 
31270f185eaSThanos Makatos int
spdk_json_write_double(struct spdk_json_write_ctx * w,double val)31370f185eaSThanos Makatos spdk_json_write_double(struct spdk_json_write_ctx *w, double val)
31470f185eaSThanos Makatos {
31570f185eaSThanos Makatos 	char buf[32];
31670f185eaSThanos Makatos 	int count;
31770f185eaSThanos Makatos 
31870f185eaSThanos Makatos 	if (begin_value(w)) { return fail(w); }
31970f185eaSThanos Makatos 	count = snprintf(buf, sizeof(buf), "%.20e", val);
32070f185eaSThanos Makatos 	if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
32170f185eaSThanos Makatos 	return emit(w, buf, count);
32270f185eaSThanos Makatos }
32370f185eaSThanos Makatos 
324f9193f4cSDaniel Verkamp static void
write_hex_2(void * dest,uint8_t val)3252c9895deSKonrad Sztyber write_hex_2(void *dest, uint8_t val)
326f9193f4cSDaniel Verkamp {
3272c9895deSKonrad Sztyber 	char *p = dest;
328f9193f4cSDaniel Verkamp 	char hex[] = "0123456789ABCDEF";
329f9193f4cSDaniel Verkamp 
3302c9895deSKonrad Sztyber 	p[0] = hex[val >> 4];
3312c9895deSKonrad Sztyber 	p[1] = hex[val & 0xf];
3322c9895deSKonrad Sztyber }
3332c9895deSKonrad Sztyber 
3342c9895deSKonrad Sztyber static void
write_hex_4(void * dest,uint16_t val)3352c9895deSKonrad Sztyber write_hex_4(void *dest, uint16_t val)
3362c9895deSKonrad Sztyber {
3372c9895deSKonrad Sztyber 	write_hex_2(dest, (uint8_t)(val >> 8));
3382c9895deSKonrad Sztyber 	write_hex_2((char *)dest + 2, (uint8_t)(val & 0xff));
339f9193f4cSDaniel Verkamp }
340f9193f4cSDaniel Verkamp 
341429672d3SDaniel Verkamp static inline int
write_codepoint(struct spdk_json_write_ctx * w,uint32_t codepoint)342429672d3SDaniel Verkamp write_codepoint(struct spdk_json_write_ctx *w, uint32_t codepoint)
343f9193f4cSDaniel Verkamp {
344f9193f4cSDaniel Verkamp 	static const uint8_t escapes[] = {
345f9193f4cSDaniel Verkamp 		['\b'] = 'b',
346f9193f4cSDaniel Verkamp 		['\f'] = 'f',
347f9193f4cSDaniel Verkamp 		['\n'] = 'n',
348f9193f4cSDaniel Verkamp 		['\r'] = 'r',
349f9193f4cSDaniel Verkamp 		['\t'] = 't',
350f9193f4cSDaniel Verkamp 		['"'] = '"',
351f9193f4cSDaniel Verkamp 		['\\'] = '\\',
352f9193f4cSDaniel Verkamp 		/*
353f9193f4cSDaniel Verkamp 		 * Forward slash (/) is intentionally not converted to an escape
354f9193f4cSDaniel Verkamp 		 *  (it is valid unescaped).
355f9193f4cSDaniel Verkamp 		 */
356f9193f4cSDaniel Verkamp 	};
357f9193f4cSDaniel Verkamp 	uint16_t high, low;
358f9193f4cSDaniel Verkamp 	char out[13];
359f9193f4cSDaniel Verkamp 	size_t out_len;
360f9193f4cSDaniel Verkamp 
361f9193f4cSDaniel Verkamp 	if (codepoint < sizeof(escapes) && escapes[codepoint]) {
362f9193f4cSDaniel Verkamp 		out[0] = '\\';
363f9193f4cSDaniel Verkamp 		out[1] = escapes[codepoint];
364f9193f4cSDaniel Verkamp 		out_len = 2;
365f9193f4cSDaniel Verkamp 	} else if (codepoint >= 0x20 && codepoint < 0x7F) {
366f9193f4cSDaniel Verkamp 		/*
367f9193f4cSDaniel Verkamp 		 * Encode plain ASCII directly (except 0x7F, since it is really
368f9193f4cSDaniel Verkamp 		 *  a control character, despite the JSON spec not considering it one).
369f9193f4cSDaniel Verkamp 		 */
370f9193f4cSDaniel Verkamp 		out[0] = (uint8_t)codepoint;
371f9193f4cSDaniel Verkamp 		out_len = 1;
372f9193f4cSDaniel Verkamp 	} else if (codepoint < 0x10000) {
373f9193f4cSDaniel Verkamp 		out[0] = '\\';
374f9193f4cSDaniel Verkamp 		out[1] = 'u';
375f9193f4cSDaniel Verkamp 		write_hex_4(&out[2], (uint16_t)codepoint);
376f9193f4cSDaniel Verkamp 		out_len = 6;
377f9193f4cSDaniel Verkamp 	} else {
378f9193f4cSDaniel Verkamp 		utf16_encode_surrogate_pair(codepoint, &high, &low);
379f9193f4cSDaniel Verkamp 		out[0] = '\\';
380f9193f4cSDaniel Verkamp 		out[1] = 'u';
381f9193f4cSDaniel Verkamp 		write_hex_4(&out[2], high);
382f9193f4cSDaniel Verkamp 		out[6] = '\\';
383f9193f4cSDaniel Verkamp 		out[7] = 'u';
384f9193f4cSDaniel Verkamp 		write_hex_4(&out[8], low);
385f9193f4cSDaniel Verkamp 		out_len = 12;
386f9193f4cSDaniel Verkamp 	}
387f9193f4cSDaniel Verkamp 
388429672d3SDaniel Verkamp 	return emit(w, out, out_len);
389429672d3SDaniel Verkamp }
390429672d3SDaniel Verkamp 
391429672d3SDaniel Verkamp static int
write_string_or_name(struct spdk_json_write_ctx * w,const char * val,size_t len)392429672d3SDaniel Verkamp write_string_or_name(struct spdk_json_write_ctx *w, const char *val, size_t len)
393429672d3SDaniel Verkamp {
394429672d3SDaniel Verkamp 	const uint8_t *p = val;
395429672d3SDaniel Verkamp 	const uint8_t *end = val + len;
396429672d3SDaniel Verkamp 
39759970a89SDaniel Verkamp 	if (emit(w, "\"", 1)) { return fail(w); }
398429672d3SDaniel Verkamp 
399429672d3SDaniel Verkamp 	while (p != end) {
400429672d3SDaniel Verkamp 		int codepoint_len;
401429672d3SDaniel Verkamp 		uint32_t codepoint;
402429672d3SDaniel Verkamp 
403429672d3SDaniel Verkamp 		codepoint_len = utf8_valid(p, end);
404429672d3SDaniel Verkamp 		switch (codepoint_len) {
405429672d3SDaniel Verkamp 		case 1:
406429672d3SDaniel Verkamp 			codepoint = utf8_decode_unsafe_1(p);
407429672d3SDaniel Verkamp 			break;
408429672d3SDaniel Verkamp 		case 2:
409429672d3SDaniel Verkamp 			codepoint = utf8_decode_unsafe_2(p);
410429672d3SDaniel Verkamp 			break;
411429672d3SDaniel Verkamp 		case 3:
412429672d3SDaniel Verkamp 			codepoint = utf8_decode_unsafe_3(p);
413429672d3SDaniel Verkamp 			break;
414429672d3SDaniel Verkamp 		case 4:
415429672d3SDaniel Verkamp 			codepoint = utf8_decode_unsafe_4(p);
416429672d3SDaniel Verkamp 			break;
417429672d3SDaniel Verkamp 		default:
418429672d3SDaniel Verkamp 			return fail(w);
419429672d3SDaniel Verkamp 		}
420429672d3SDaniel Verkamp 
42159970a89SDaniel Verkamp 		if (write_codepoint(w, codepoint)) { return fail(w); }
422429672d3SDaniel Verkamp 		p += codepoint_len;
423429672d3SDaniel Verkamp 	}
424429672d3SDaniel Verkamp 
425429672d3SDaniel Verkamp 	return emit(w, "\"", 1);
426429672d3SDaniel Verkamp }
427429672d3SDaniel Verkamp 
428429672d3SDaniel Verkamp static int
write_string_or_name_utf16le(struct spdk_json_write_ctx * w,const uint16_t * val,size_t len)429429672d3SDaniel Verkamp write_string_or_name_utf16le(struct spdk_json_write_ctx *w, const uint16_t *val, size_t len)
430429672d3SDaniel Verkamp {
431429672d3SDaniel Verkamp 	const uint16_t *p = val;
432429672d3SDaniel Verkamp 	const uint16_t *end = val + len;
433429672d3SDaniel Verkamp 
43459970a89SDaniel Verkamp 	if (emit(w, "\"", 1)) { return fail(w); }
435429672d3SDaniel Verkamp 
436429672d3SDaniel Verkamp 	while (p != end) {
437429672d3SDaniel Verkamp 		int codepoint_len;
438429672d3SDaniel Verkamp 		uint32_t codepoint;
439429672d3SDaniel Verkamp 
440429672d3SDaniel Verkamp 		codepoint_len = utf16le_valid(p, end);
441429672d3SDaniel Verkamp 		switch (codepoint_len) {
442429672d3SDaniel Verkamp 		case 1:
443429672d3SDaniel Verkamp 			codepoint = from_le16(&p[0]);
444429672d3SDaniel Verkamp 			break;
445429672d3SDaniel Verkamp 		case 2:
446429672d3SDaniel Verkamp 			codepoint = utf16_decode_surrogate_pair(from_le16(&p[0]), from_le16(&p[1]));
447429672d3SDaniel Verkamp 			break;
448429672d3SDaniel Verkamp 		default:
449429672d3SDaniel Verkamp 			return fail(w);
450429672d3SDaniel Verkamp 		}
451429672d3SDaniel Verkamp 
45259970a89SDaniel Verkamp 		if (write_codepoint(w, codepoint)) { return fail(w); }
453f9193f4cSDaniel Verkamp 		p += codepoint_len;
454f9193f4cSDaniel Verkamp 	}
455f9193f4cSDaniel Verkamp 
456f9193f4cSDaniel Verkamp 	return emit(w, "\"", 1);
457f9193f4cSDaniel Verkamp }
458f9193f4cSDaniel Verkamp 
459f9193f4cSDaniel Verkamp int
spdk_json_write_string_raw(struct spdk_json_write_ctx * w,const char * val,size_t len)460f9193f4cSDaniel Verkamp spdk_json_write_string_raw(struct spdk_json_write_ctx *w, const char *val, size_t len)
461f9193f4cSDaniel Verkamp {
46259970a89SDaniel Verkamp 	if (begin_value(w)) { return fail(w); }
463f9193f4cSDaniel Verkamp 	return write_string_or_name(w, val, len);
464f9193f4cSDaniel Verkamp }
465f9193f4cSDaniel Verkamp 
466f9193f4cSDaniel Verkamp int
spdk_json_write_string(struct spdk_json_write_ctx * w,const char * val)467f9193f4cSDaniel Verkamp spdk_json_write_string(struct spdk_json_write_ctx *w, const char *val)
468f9193f4cSDaniel Verkamp {
469f9193f4cSDaniel Verkamp 	return spdk_json_write_string_raw(w, val, strlen(val));
470f9193f4cSDaniel Verkamp }
471f9193f4cSDaniel Verkamp 
472f9193f4cSDaniel Verkamp int
spdk_json_write_string_utf16le_raw(struct spdk_json_write_ctx * w,const uint16_t * val,size_t len)473429672d3SDaniel Verkamp spdk_json_write_string_utf16le_raw(struct spdk_json_write_ctx *w, const uint16_t *val, size_t len)
474429672d3SDaniel Verkamp {
47559970a89SDaniel Verkamp 	if (begin_value(w)) { return fail(w); }
476429672d3SDaniel Verkamp 	return write_string_or_name_utf16le(w, val, len);
477429672d3SDaniel Verkamp }
478429672d3SDaniel Verkamp 
479429672d3SDaniel Verkamp int
spdk_json_write_string_utf16le(struct spdk_json_write_ctx * w,const uint16_t * val)480429672d3SDaniel Verkamp spdk_json_write_string_utf16le(struct spdk_json_write_ctx *w, const uint16_t *val)
481429672d3SDaniel Verkamp {
482429672d3SDaniel Verkamp 	const uint16_t *p;
483429672d3SDaniel Verkamp 	size_t len;
484429672d3SDaniel Verkamp 
485429672d3SDaniel Verkamp 	for (len = 0, p = val; *p; p++) {
486429672d3SDaniel Verkamp 		len++;
487429672d3SDaniel Verkamp 	}
488429672d3SDaniel Verkamp 
489429672d3SDaniel Verkamp 	return spdk_json_write_string_utf16le_raw(w, val, len);
490429672d3SDaniel Verkamp }
491429672d3SDaniel Verkamp 
492429672d3SDaniel Verkamp int
spdk_json_write_string_fmt(struct spdk_json_write_ctx * w,const char * fmt,...)4931cb7e396SDaniel Verkamp spdk_json_write_string_fmt(struct spdk_json_write_ctx *w, const char *fmt, ...)
4941cb7e396SDaniel Verkamp {
4951cb7e396SDaniel Verkamp 	va_list args;
4961cb7e396SDaniel Verkamp 	int rc;
4971cb7e396SDaniel Verkamp 
4981cb7e396SDaniel Verkamp 	va_start(args, fmt);
499a5cfd430SPawel Wodkowski 	rc = spdk_json_write_string_fmt_v(w, fmt, args);
5001cb7e396SDaniel Verkamp 	va_end(args);
5011cb7e396SDaniel Verkamp 
502a5cfd430SPawel Wodkowski 	return rc;
503a5cfd430SPawel Wodkowski }
504a5cfd430SPawel Wodkowski 
505a5cfd430SPawel Wodkowski int
spdk_json_write_string_fmt_v(struct spdk_json_write_ctx * w,const char * fmt,va_list args)506a5cfd430SPawel Wodkowski spdk_json_write_string_fmt_v(struct spdk_json_write_ctx *w, const char *fmt, va_list args)
507a5cfd430SPawel Wodkowski {
508a5cfd430SPawel Wodkowski 	char *s;
509a5cfd430SPawel Wodkowski 	int rc;
510a5cfd430SPawel Wodkowski 
511a5cfd430SPawel Wodkowski 	s = spdk_vsprintf_alloc(fmt, args);
5121cb7e396SDaniel Verkamp 	if (s == NULL) {
5131cb7e396SDaniel Verkamp 		return -1;
5141cb7e396SDaniel Verkamp 	}
5151cb7e396SDaniel Verkamp 
5161cb7e396SDaniel Verkamp 	rc = spdk_json_write_string(w, s);
5171cb7e396SDaniel Verkamp 	free(s);
5181cb7e396SDaniel Verkamp 	return rc;
5191cb7e396SDaniel Verkamp }
5201cb7e396SDaniel Verkamp 
5211cb7e396SDaniel Verkamp int
spdk_json_write_bytearray(struct spdk_json_write_ctx * w,const void * val,size_t len)5222c9895deSKonrad Sztyber spdk_json_write_bytearray(struct spdk_json_write_ctx *w, const void *val, size_t len)
5232c9895deSKonrad Sztyber {
5242c9895deSKonrad Sztyber 	const uint8_t *v = val;
5252c9895deSKonrad Sztyber 	size_t i;
5262c9895deSKonrad Sztyber 	char *s;
5272c9895deSKonrad Sztyber 	int rc;
5282c9895deSKonrad Sztyber 
5292c9895deSKonrad Sztyber 	s = malloc(2 * len + 1);
5302c9895deSKonrad Sztyber 	if (s == NULL) {
5312c9895deSKonrad Sztyber 		return -1;
5322c9895deSKonrad Sztyber 	}
5332c9895deSKonrad Sztyber 
5342c9895deSKonrad Sztyber 	for (i = 0; i < len; ++i) {
5352c9895deSKonrad Sztyber 		write_hex_2(&s[2 * i], *v++);
5362c9895deSKonrad Sztyber 	}
5372c9895deSKonrad Sztyber 	s[2 * len] = '\0';
5382c9895deSKonrad Sztyber 
5392c9895deSKonrad Sztyber 	rc = spdk_json_write_string(w, s);
5402c9895deSKonrad Sztyber 	free(s);
5412c9895deSKonrad Sztyber 	return rc;
5422c9895deSKonrad Sztyber }
5432c9895deSKonrad Sztyber 
5442c9895deSKonrad Sztyber int
spdk_json_write_uuid(struct spdk_json_write_ctx * w,const struct spdk_uuid * uuid)545*5d91b074SKonrad Sztyber spdk_json_write_uuid(struct spdk_json_write_ctx *w, const struct spdk_uuid *uuid)
546*5d91b074SKonrad Sztyber {
547*5d91b074SKonrad Sztyber 	char str[SPDK_UUID_STRING_LEN];
548*5d91b074SKonrad Sztyber 
549*5d91b074SKonrad Sztyber 	spdk_uuid_fmt_lower(str, sizeof(str), uuid);
550*5d91b074SKonrad Sztyber 
551*5d91b074SKonrad Sztyber 	return spdk_json_write_string(w, str);
552*5d91b074SKonrad Sztyber }
553*5d91b074SKonrad Sztyber 
554*5d91b074SKonrad Sztyber int
spdk_json_write_array_begin(struct spdk_json_write_ctx * w)555f9193f4cSDaniel Verkamp spdk_json_write_array_begin(struct spdk_json_write_ctx *w)
556f9193f4cSDaniel Verkamp {
55759970a89SDaniel Verkamp 	if (begin_value(w)) { return fail(w); }
558f9193f4cSDaniel Verkamp 	w->first_value = true;
559c56b53a8SDaniel Verkamp 	w->new_indent = true;
560c56b53a8SDaniel Verkamp 	w->indent++;
56159970a89SDaniel Verkamp 	if (emit(w, "[", 1)) { return fail(w); }
562c56b53a8SDaniel Verkamp 	return 0;
563f9193f4cSDaniel Verkamp }
564f9193f4cSDaniel Verkamp 
565f9193f4cSDaniel Verkamp int
spdk_json_write_array_end(struct spdk_json_write_ctx * w)566f9193f4cSDaniel Verkamp spdk_json_write_array_end(struct spdk_json_write_ctx *w)
567f9193f4cSDaniel Verkamp {
568f9193f4cSDaniel Verkamp 	w->first_value = false;
56959970a89SDaniel Verkamp 	if (w->indent == 0) { return fail(w); }
570c56b53a8SDaniel Verkamp 	w->indent--;
571c56b53a8SDaniel Verkamp 	if (!w->new_indent) {
57259970a89SDaniel Verkamp 		if (emit_fmt(w, "\n", 1)) { return fail(w); }
57359970a89SDaniel Verkamp 		if (emit_indent(w)) { return fail(w); }
574c56b53a8SDaniel Verkamp 	}
575c56b53a8SDaniel Verkamp 	w->new_indent = false;
576f9193f4cSDaniel Verkamp 	return emit(w, "]", 1);
577f9193f4cSDaniel Verkamp }
578f9193f4cSDaniel Verkamp 
579f9193f4cSDaniel Verkamp int
spdk_json_write_object_begin(struct spdk_json_write_ctx * w)580f9193f4cSDaniel Verkamp spdk_json_write_object_begin(struct spdk_json_write_ctx *w)
581f9193f4cSDaniel Verkamp {
58259970a89SDaniel Verkamp 	if (begin_value(w)) { return fail(w); }
583f9193f4cSDaniel Verkamp 	w->first_value = true;
584c56b53a8SDaniel Verkamp 	w->new_indent = true;
585c56b53a8SDaniel Verkamp 	w->indent++;
58659970a89SDaniel Verkamp 	if (emit(w, "{", 1)) { return fail(w); }
587c56b53a8SDaniel Verkamp 	return 0;
588f9193f4cSDaniel Verkamp }
589f9193f4cSDaniel Verkamp 
590f9193f4cSDaniel Verkamp int
spdk_json_write_object_end(struct spdk_json_write_ctx * w)591f9193f4cSDaniel Verkamp spdk_json_write_object_end(struct spdk_json_write_ctx *w)
592f9193f4cSDaniel Verkamp {
593f9193f4cSDaniel Verkamp 	w->first_value = false;
594c56b53a8SDaniel Verkamp 	w->indent--;
595c56b53a8SDaniel Verkamp 	if (!w->new_indent) {
59659970a89SDaniel Verkamp 		if (emit_fmt(w, "\n", 1)) { return fail(w); }
59759970a89SDaniel Verkamp 		if (emit_indent(w)) { return fail(w); }
598c56b53a8SDaniel Verkamp 	}
599c56b53a8SDaniel Verkamp 	w->new_indent = false;
600f9193f4cSDaniel Verkamp 	return emit(w, "}", 1);
601f9193f4cSDaniel Verkamp }
602f9193f4cSDaniel Verkamp 
603f9193f4cSDaniel Verkamp int
spdk_json_write_name_raw(struct spdk_json_write_ctx * w,const char * name,size_t len)604f9193f4cSDaniel Verkamp spdk_json_write_name_raw(struct spdk_json_write_ctx *w, const char *name, size_t len)
605f9193f4cSDaniel Verkamp {
606f9193f4cSDaniel Verkamp 	/* TODO: check that container is an object */
60759970a89SDaniel Verkamp 	if (begin_value(w)) { return fail(w); }
60859970a89SDaniel Verkamp 	if (write_string_or_name(w, name, len)) { return fail(w); }
609f9193f4cSDaniel Verkamp 	w->first_value = true;
61059970a89SDaniel Verkamp 	if (emit(w, ":", 1)) { return fail(w); }
611c56b53a8SDaniel Verkamp 	return emit_fmt(w, " ", 1);
612f9193f4cSDaniel Verkamp }
613f9193f4cSDaniel Verkamp 
614f9193f4cSDaniel Verkamp int
spdk_json_write_name(struct spdk_json_write_ctx * w,const char * name)615f9193f4cSDaniel Verkamp spdk_json_write_name(struct spdk_json_write_ctx *w, const char *name)
616f9193f4cSDaniel Verkamp {
617f9193f4cSDaniel Verkamp 	return spdk_json_write_name_raw(w, name, strlen(name));
618f9193f4cSDaniel Verkamp }
619f9193f4cSDaniel Verkamp 
620f9193f4cSDaniel Verkamp int
spdk_json_write_val(struct spdk_json_write_ctx * w,const struct spdk_json_val * val)621f9193f4cSDaniel Verkamp spdk_json_write_val(struct spdk_json_write_ctx *w, const struct spdk_json_val *val)
622f9193f4cSDaniel Verkamp {
623f9193f4cSDaniel Verkamp 	size_t num_values, i;
624f9193f4cSDaniel Verkamp 
625f9193f4cSDaniel Verkamp 	switch (val->type) {
626f9193f4cSDaniel Verkamp 	case SPDK_JSON_VAL_NUMBER:
627f9193f4cSDaniel Verkamp 		return spdk_json_write_val_raw(w, val->start, val->len);
628f9193f4cSDaniel Verkamp 
629f9193f4cSDaniel Verkamp 	case SPDK_JSON_VAL_STRING:
630f9193f4cSDaniel Verkamp 		return spdk_json_write_string_raw(w, val->start, val->len);
631f9193f4cSDaniel Verkamp 
632f9193f4cSDaniel Verkamp 	case SPDK_JSON_VAL_NAME:
633f9193f4cSDaniel Verkamp 		return spdk_json_write_name_raw(w, val->start, val->len);
634f9193f4cSDaniel Verkamp 
635f9193f4cSDaniel Verkamp 	case SPDK_JSON_VAL_TRUE:
636f9193f4cSDaniel Verkamp 		return spdk_json_write_bool(w, true);
637f9193f4cSDaniel Verkamp 
638f9193f4cSDaniel Verkamp 	case SPDK_JSON_VAL_FALSE:
639f9193f4cSDaniel Verkamp 		return spdk_json_write_bool(w, false);
640f9193f4cSDaniel Verkamp 
641f9193f4cSDaniel Verkamp 	case SPDK_JSON_VAL_NULL:
642f9193f4cSDaniel Verkamp 		return spdk_json_write_null(w);
643f9193f4cSDaniel Verkamp 
644f9193f4cSDaniel Verkamp 	case SPDK_JSON_VAL_ARRAY_BEGIN:
645f9193f4cSDaniel Verkamp 	case SPDK_JSON_VAL_OBJECT_BEGIN:
646f9193f4cSDaniel Verkamp 		num_values = val[0].len;
647f9193f4cSDaniel Verkamp 
648f9193f4cSDaniel Verkamp 		if (val[0].type == SPDK_JSON_VAL_OBJECT_BEGIN) {
649f9193f4cSDaniel Verkamp 			if (spdk_json_write_object_begin(w)) {
650f9193f4cSDaniel Verkamp 				return fail(w);
651f9193f4cSDaniel Verkamp 			}
652f9193f4cSDaniel Verkamp 		} else {
653f9193f4cSDaniel Verkamp 			if (spdk_json_write_array_begin(w)) {
654f9193f4cSDaniel Verkamp 				return fail(w);
655f9193f4cSDaniel Verkamp 			}
656f9193f4cSDaniel Verkamp 		}
657f9193f4cSDaniel Verkamp 
658d35ee09eSShuhei Matsumoto 		/* Loop up to and including the _END value */
659ed694026SDaniel Verkamp 		for (i = 0; i < num_values + 1;) {
660f9193f4cSDaniel Verkamp 			if (spdk_json_write_val(w, &val[i + 1])) {
661f9193f4cSDaniel Verkamp 				return fail(w);
662f9193f4cSDaniel Verkamp 			}
663ed694026SDaniel Verkamp 			if (val[i + 1].type == SPDK_JSON_VAL_ARRAY_BEGIN ||
664ed694026SDaniel Verkamp 			    val[i + 1].type == SPDK_JSON_VAL_OBJECT_BEGIN) {
665ed694026SDaniel Verkamp 				i += val[i + 1].len + 2;
666ed694026SDaniel Verkamp 			} else {
667ed694026SDaniel Verkamp 				i++;
668f9193f4cSDaniel Verkamp 			}
669ed694026SDaniel Verkamp 		}
670ed694026SDaniel Verkamp 		return 0;
671f9193f4cSDaniel Verkamp 
672f9193f4cSDaniel Verkamp 	case SPDK_JSON_VAL_ARRAY_END:
673f9193f4cSDaniel Verkamp 		return spdk_json_write_array_end(w);
674f9193f4cSDaniel Verkamp 
675f9193f4cSDaniel Verkamp 	case SPDK_JSON_VAL_OBJECT_END:
676f9193f4cSDaniel Verkamp 		return spdk_json_write_object_end(w);
677f9193f4cSDaniel Verkamp 
678f9193f4cSDaniel Verkamp 	case SPDK_JSON_VAL_INVALID:
679d35ee09eSShuhei Matsumoto 		/* Handle INVALID to make the compiler happy (and catch other unhandled types) */
680f9193f4cSDaniel Verkamp 		return fail(w);
681f9193f4cSDaniel Verkamp 	}
682f9193f4cSDaniel Verkamp 
683f9193f4cSDaniel Verkamp 	return fail(w);
684f9193f4cSDaniel Verkamp }
685d6408c0dSPawel Wodkowski 
6868dd1cd21SBen Walker int
spdk_json_write_named_null(struct spdk_json_write_ctx * w,const char * name)6878dd1cd21SBen Walker spdk_json_write_named_null(struct spdk_json_write_ctx *w, const char *name)
688d6408c0dSPawel Wodkowski {
689d6408c0dSPawel Wodkowski 	int rc = spdk_json_write_name(w, name);
690d6408c0dSPawel Wodkowski 	return rc ? rc : spdk_json_write_null(w);
691d6408c0dSPawel Wodkowski }
692d6408c0dSPawel Wodkowski 
6938dd1cd21SBen Walker int
spdk_json_write_named_bool(struct spdk_json_write_ctx * w,const char * name,bool val)6948dd1cd21SBen Walker spdk_json_write_named_bool(struct spdk_json_write_ctx *w, const char *name, bool val)
695d6408c0dSPawel Wodkowski {
696d6408c0dSPawel Wodkowski 	int rc = spdk_json_write_name(w, name);
697d6408c0dSPawel Wodkowski 
698d6408c0dSPawel Wodkowski 	return rc ? rc : spdk_json_write_bool(w, val);
699d6408c0dSPawel Wodkowski }
700d6408c0dSPawel Wodkowski 
7018dd1cd21SBen Walker int
spdk_json_write_named_uint8(struct spdk_json_write_ctx * w,const char * name,uint8_t val)7028dd1cd21SBen Walker spdk_json_write_named_uint8(struct spdk_json_write_ctx *w, const char *name, uint8_t val)
7038f8f3f87SJacek Kalwas {
7048f8f3f87SJacek Kalwas 	int rc = spdk_json_write_name(w, name);
7058f8f3f87SJacek Kalwas 
7068f8f3f87SJacek Kalwas 	return rc ? rc : spdk_json_write_uint8(w, val);
7078f8f3f87SJacek Kalwas }
7088f8f3f87SJacek Kalwas 
7098dd1cd21SBen Walker int
spdk_json_write_named_uint16(struct spdk_json_write_ctx * w,const char * name,uint16_t val)7108dd1cd21SBen Walker spdk_json_write_named_uint16(struct spdk_json_write_ctx *w, const char *name, uint16_t val)
7118f8f3f87SJacek Kalwas {
7128f8f3f87SJacek Kalwas 	int rc = spdk_json_write_name(w, name);
7138f8f3f87SJacek Kalwas 
7148f8f3f87SJacek Kalwas 	return rc ? rc : spdk_json_write_uint16(w, val);
7158f8f3f87SJacek Kalwas }
7168f8f3f87SJacek Kalwas 
7178dd1cd21SBen Walker int
spdk_json_write_named_int32(struct spdk_json_write_ctx * w,const char * name,int32_t val)7188dd1cd21SBen Walker spdk_json_write_named_int32(struct spdk_json_write_ctx *w, const char *name, int32_t val)
719d6408c0dSPawel Wodkowski {
720d6408c0dSPawel Wodkowski 	int rc = spdk_json_write_name(w, name);
721d6408c0dSPawel Wodkowski 
722d6408c0dSPawel Wodkowski 	return rc ? rc : spdk_json_write_int32(w, val);
723d6408c0dSPawel Wodkowski }
724d6408c0dSPawel Wodkowski 
7258dd1cd21SBen Walker int
spdk_json_write_named_uint32(struct spdk_json_write_ctx * w,const char * name,uint32_t val)7268dd1cd21SBen Walker spdk_json_write_named_uint32(struct spdk_json_write_ctx *w, const char *name, uint32_t val)
727d6408c0dSPawel Wodkowski {
728d6408c0dSPawel Wodkowski 	int rc = spdk_json_write_name(w, name);
729d6408c0dSPawel Wodkowski 
730d6408c0dSPawel Wodkowski 	return rc ? rc : spdk_json_write_uint32(w, val);
731d6408c0dSPawel Wodkowski }
732d6408c0dSPawel Wodkowski 
7338dd1cd21SBen Walker int
spdk_json_write_named_int64(struct spdk_json_write_ctx * w,const char * name,int64_t val)7348dd1cd21SBen Walker spdk_json_write_named_int64(struct spdk_json_write_ctx *w, const char *name, int64_t val)
735d6408c0dSPawel Wodkowski {
736d6408c0dSPawel Wodkowski 	int rc = spdk_json_write_name(w, name);
737d6408c0dSPawel Wodkowski 
738d6408c0dSPawel Wodkowski 	return rc ? rc : spdk_json_write_int64(w, val);
739d6408c0dSPawel Wodkowski }
740d6408c0dSPawel Wodkowski 
7418dd1cd21SBen Walker int
spdk_json_write_named_uint64(struct spdk_json_write_ctx * w,const char * name,uint64_t val)7428dd1cd21SBen Walker spdk_json_write_named_uint64(struct spdk_json_write_ctx *w, const char *name, uint64_t val)
7438f8f3f87SJacek Kalwas {
7448f8f3f87SJacek Kalwas 	int rc = spdk_json_write_name(w, name);
7458f8f3f87SJacek Kalwas 
7468f8f3f87SJacek Kalwas 	return rc ? rc : spdk_json_write_uint64(w, val);
7478f8f3f87SJacek Kalwas }
7488f8f3f87SJacek Kalwas 
7498dd1cd21SBen Walker int
spdk_json_write_named_double(struct spdk_json_write_ctx * w,const char * name,double val)75070f185eaSThanos Makatos spdk_json_write_named_double(struct spdk_json_write_ctx *w, const char *name, double val)
75170f185eaSThanos Makatos {
75270f185eaSThanos Makatos 	int rc = spdk_json_write_name(w, name);
75370f185eaSThanos Makatos 
75470f185eaSThanos Makatos 	return rc ? rc : spdk_json_write_double(w, val);
75570f185eaSThanos Makatos }
75670f185eaSThanos Makatos 
75770f185eaSThanos Makatos int
spdk_json_write_named_string(struct spdk_json_write_ctx * w,const char * name,const char * val)7588dd1cd21SBen Walker spdk_json_write_named_string(struct spdk_json_write_ctx *w, const char *name, const char *val)
759d6408c0dSPawel Wodkowski {
760d6408c0dSPawel Wodkowski 	int rc = spdk_json_write_name(w, name);
761d6408c0dSPawel Wodkowski 
762d6408c0dSPawel Wodkowski 	return rc ? rc : spdk_json_write_string(w, val);
763d6408c0dSPawel Wodkowski }
764d6408c0dSPawel Wodkowski 
7658dd1cd21SBen Walker int
spdk_json_write_named_string_fmt(struct spdk_json_write_ctx * w,const char * name,const char * fmt,...)7668dd1cd21SBen Walker spdk_json_write_named_string_fmt(struct spdk_json_write_ctx *w, const char *name,
767d6408c0dSPawel Wodkowski 				 const char *fmt, ...)
768d6408c0dSPawel Wodkowski {
769d6408c0dSPawel Wodkowski 	va_list args;
770d6408c0dSPawel Wodkowski 	int rc;
771d6408c0dSPawel Wodkowski 
772a5cfd430SPawel Wodkowski 	va_start(args, fmt);
773a5cfd430SPawel Wodkowski 	rc = spdk_json_write_named_string_fmt_v(w, name, fmt, args);
774a5cfd430SPawel Wodkowski 	va_end(args);
775a5cfd430SPawel Wodkowski 
776a5cfd430SPawel Wodkowski 	return rc;
777a5cfd430SPawel Wodkowski }
778a5cfd430SPawel Wodkowski 
7798dd1cd21SBen Walker int
spdk_json_write_named_string_fmt_v(struct spdk_json_write_ctx * w,const char * name,const char * fmt,va_list args)7808dd1cd21SBen Walker spdk_json_write_named_string_fmt_v(struct spdk_json_write_ctx *w, const char *name,
781a5cfd430SPawel Wodkowski 				   const char *fmt, va_list args)
782a5cfd430SPawel Wodkowski {
783a5cfd430SPawel Wodkowski 	char *s;
784a5cfd430SPawel Wodkowski 	int rc;
785a5cfd430SPawel Wodkowski 
786d6408c0dSPawel Wodkowski 	rc = spdk_json_write_name(w, name);
787d6408c0dSPawel Wodkowski 	if (rc) {
788d6408c0dSPawel Wodkowski 		return rc;
789d6408c0dSPawel Wodkowski 	}
790d6408c0dSPawel Wodkowski 
791d6408c0dSPawel Wodkowski 	s = spdk_vsprintf_alloc(fmt, args);
792d6408c0dSPawel Wodkowski 
793d6408c0dSPawel Wodkowski 	if (s == NULL) {
794d6408c0dSPawel Wodkowski 		return -1;
795d6408c0dSPawel Wodkowski 	}
796d6408c0dSPawel Wodkowski 
797d6408c0dSPawel Wodkowski 	rc = spdk_json_write_string(w, s);
798d6408c0dSPawel Wodkowski 	free(s);
799d6408c0dSPawel Wodkowski 	return rc;
800d6408c0dSPawel Wodkowski }
801d6408c0dSPawel Wodkowski 
8022c9895deSKonrad Sztyber int
spdk_json_write_named_bytearray(struct spdk_json_write_ctx * w,const char * name,const void * val,size_t len)8032c9895deSKonrad Sztyber spdk_json_write_named_bytearray(struct spdk_json_write_ctx *w, const char *name, const void *val,
8042c9895deSKonrad Sztyber 				size_t len)
8052c9895deSKonrad Sztyber {
8062c9895deSKonrad Sztyber 	int rc = spdk_json_write_name(w, name);
8072c9895deSKonrad Sztyber 
8082c9895deSKonrad Sztyber 	return rc ? rc : spdk_json_write_bytearray(w, val, len);
8092c9895deSKonrad Sztyber }
8102c9895deSKonrad Sztyber 
8118dd1cd21SBen Walker int
spdk_json_write_named_array_begin(struct spdk_json_write_ctx * w,const char * name)8128dd1cd21SBen Walker spdk_json_write_named_array_begin(struct spdk_json_write_ctx *w, const char *name)
813d6408c0dSPawel Wodkowski {
814d6408c0dSPawel Wodkowski 	int rc = spdk_json_write_name(w, name);
815d6408c0dSPawel Wodkowski 
816d6408c0dSPawel Wodkowski 	return rc ? rc : spdk_json_write_array_begin(w);
817d6408c0dSPawel Wodkowski }
818d6408c0dSPawel Wodkowski 
8198dd1cd21SBen Walker int
spdk_json_write_named_object_begin(struct spdk_json_write_ctx * w,const char * name)8208dd1cd21SBen Walker spdk_json_write_named_object_begin(struct spdk_json_write_ctx *w, const char *name)
821d6408c0dSPawel Wodkowski {
822d6408c0dSPawel Wodkowski 	int rc = spdk_json_write_name(w, name);
823d6408c0dSPawel Wodkowski 
824d6408c0dSPawel Wodkowski 	return rc ? rc : spdk_json_write_object_begin(w);
825d6408c0dSPawel Wodkowski }
826*5d91b074SKonrad Sztyber 
827*5d91b074SKonrad Sztyber int
spdk_json_write_named_uuid(struct spdk_json_write_ctx * w,const char * name,const struct spdk_uuid * uuid)828*5d91b074SKonrad Sztyber spdk_json_write_named_uuid(struct spdk_json_write_ctx *w, const char *name,
829*5d91b074SKonrad Sztyber 			   const struct spdk_uuid *uuid)
830*5d91b074SKonrad Sztyber {
831*5d91b074SKonrad Sztyber 	int rc = spdk_json_write_name(w, name);
832*5d91b074SKonrad Sztyber 
833*5d91b074SKonrad Sztyber 	return rc ? rc : spdk_json_write_uuid(w, uuid);
834*5d91b074SKonrad Sztyber }
835