xref: /spdk/lib/json/json_write.c (revision b30d57cdad6d2bc75cc1e4e2ebbcebcb0d98dcfa)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk/json.h"
35 
36 #include "spdk_internal/utf.h"
37 
38 struct spdk_json_write_ctx {
39 	spdk_json_write_cb write_cb;
40 	void *cb_ctx;
41 	uint32_t flags;
42 	uint32_t indent;
43 	bool new_indent;
44 	bool first_value;
45 	bool failed;
46 	size_t buf_filled;
47 	uint8_t buf[4096];
48 };
49 
50 static int emit_buf_full(struct spdk_json_write_ctx *w, const void *data, size_t size);
51 
52 static int
53 fail(struct spdk_json_write_ctx *w)
54 {
55 	w->failed = true;
56 	return -1;
57 }
58 
59 static int
60 flush_buf(struct spdk_json_write_ctx *w)
61 {
62 	int rc;
63 
64 	rc = w->write_cb(w->cb_ctx, w->buf, w->buf_filled);
65 	if (rc != 0) {
66 		return fail(w);
67 	}
68 
69 	w->buf_filled = 0;
70 
71 	return 0;
72 }
73 
74 struct spdk_json_write_ctx *
75 spdk_json_write_begin(spdk_json_write_cb write_cb, void *cb_ctx, uint32_t flags)
76 {
77 	struct spdk_json_write_ctx *w;
78 
79 	w = calloc(1, sizeof(*w));
80 	if (w == NULL) {
81 		return w;
82 	}
83 
84 	w->write_cb = write_cb;
85 	w->cb_ctx = cb_ctx;
86 	w->flags = flags;
87 	w->indent = 0;
88 	w->new_indent = false;
89 	w->first_value = true;
90 	w->failed = false;
91 	w->buf_filled = 0;
92 
93 	return w;
94 }
95 
96 int
97 spdk_json_write_end(struct spdk_json_write_ctx *w)
98 {
99 	bool failed;
100 	int rc;
101 
102 	if (w == NULL) {
103 		return 0;
104 	}
105 
106 	failed = w->failed;
107 
108 	rc = flush_buf(w);
109 	if (rc != 0) {
110 		failed = true;
111 	}
112 
113 	free(w);
114 
115 	return failed ? -1 : 0;
116 }
117 
118 static inline int
119 emit(struct spdk_json_write_ctx *w, const void *data, size_t size)
120 {
121 	size_t buf_remain = sizeof(w->buf) - w->buf_filled;
122 
123 	if (spdk_unlikely(size > buf_remain)) {
124 		/* Not enough space in buffer for the new data. */
125 		return emit_buf_full(w, data, size);
126 	}
127 
128 	/* Copy the new data into buf. */
129 	memcpy(w->buf + w->buf_filled, data, size);
130 	w->buf_filled += size;
131 	return 0;
132 }
133 
134 static int
135 emit_buf_full(struct spdk_json_write_ctx *w, const void *data, size_t size)
136 {
137 	size_t buf_remain = sizeof(w->buf) - w->buf_filled;
138 	int rc;
139 
140 	assert(size > buf_remain);
141 
142 	/* Copy as much of the new data as possible into the buffer and flush it. */
143 	memcpy(w->buf + w->buf_filled, data, buf_remain);
144 	w->buf_filled += buf_remain;
145 
146 	rc = flush_buf(w);
147 	if (rc != 0) {
148 		return fail(w);
149 	}
150 
151 	/* Recurse to emit the rest of the data. */
152 	return emit(w, data + buf_remain, size - buf_remain);
153 }
154 
155 static int
156 emit_fmt(struct spdk_json_write_ctx *w, const void *data, size_t size)
157 {
158 	if (w->flags & SPDK_JSON_WRITE_FLAG_FORMATTED) {
159 		return emit(w, data, size);
160 	}
161 	return 0;
162 }
163 
164 static int
165 emit_indent(struct spdk_json_write_ctx *w)
166 {
167 	uint32_t i;
168 
169 	if (w->flags & SPDK_JSON_WRITE_FLAG_FORMATTED) {
170 		for (i = 0; i < w->indent; i++) {
171 			if (emit(w, "  ", 2)) { return fail(w); }
172 		}
173 	}
174 	return 0;
175 }
176 
177 static int
178 begin_value(struct spdk_json_write_ctx *w)
179 {
180 	/* TODO: check for value state */
181 	if (w->new_indent) {
182 		if (emit_fmt(w, "\n", 1)) { return fail(w); }
183 		if (emit_indent(w)) { return fail(w); }
184 	}
185 	if (!w->first_value) {
186 		if (emit(w, ",", 1)) { return fail(w); }
187 		if (emit_fmt(w, "\n", 1)) { return fail(w); }
188 		if (emit_indent(w)) { return fail(w); }
189 	}
190 	w->first_value = false;
191 	w->new_indent = false;
192 	return 0;
193 }
194 
195 int
196 spdk_json_write_val_raw(struct spdk_json_write_ctx *w, const void *data, size_t len)
197 {
198 	if (begin_value(w)) { return fail(w); }
199 	return emit(w, data, len);
200 }
201 
202 int
203 spdk_json_write_null(struct spdk_json_write_ctx *w)
204 {
205 	if (begin_value(w)) { return fail(w); }
206 	return emit(w, "null", 4);
207 }
208 
209 int
210 spdk_json_write_bool(struct spdk_json_write_ctx *w, bool val)
211 {
212 	if (begin_value(w)) { return fail(w); }
213 	if (val) {
214 		return emit(w, "true", 4);
215 	} else {
216 		return emit(w, "false", 5);
217 	}
218 }
219 
220 int
221 spdk_json_write_int32(struct spdk_json_write_ctx *w, int32_t val)
222 {
223 	char buf[32];
224 	int count;
225 
226 	if (begin_value(w)) { return fail(w); }
227 	count = snprintf(buf, sizeof(buf), "%" PRId32, val);
228 	if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
229 	return emit(w, buf, count);
230 }
231 
232 int
233 spdk_json_write_uint32(struct spdk_json_write_ctx *w, uint32_t val)
234 {
235 	char buf[32];
236 	int count;
237 
238 	if (begin_value(w)) { return fail(w); }
239 	count = snprintf(buf, sizeof(buf), "%" PRIu32, val);
240 	if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
241 	return emit(w, buf, count);
242 }
243 
244 int
245 spdk_json_write_int64(struct spdk_json_write_ctx *w, int64_t val)
246 {
247 	char buf[32];
248 	int count;
249 
250 	if (begin_value(w)) { return fail(w); }
251 	count = snprintf(buf, sizeof(buf), "%" PRId64, val);
252 	if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
253 	return emit(w, buf, count);
254 }
255 
256 int
257 spdk_json_write_uint64(struct spdk_json_write_ctx *w, uint64_t val)
258 {
259 	char buf[32];
260 	int count;
261 
262 	if (begin_value(w)) { return fail(w); }
263 	count = snprintf(buf, sizeof(buf), "%" PRIu64, val);
264 	if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
265 	return emit(w, buf, count);
266 }
267 
268 static void
269 write_hex_4(void *dest, uint16_t val)
270 {
271 	uint8_t *p = dest;
272 	char hex[] = "0123456789ABCDEF";
273 
274 	p[0] = hex[(val >> 12)];
275 	p[1] = hex[(val >> 8) & 0xF];
276 	p[2] = hex[(val >> 4) & 0xF];
277 	p[3] = hex[val & 0xF];
278 }
279 
280 static inline int
281 write_codepoint(struct spdk_json_write_ctx *w, uint32_t codepoint)
282 {
283 	static const uint8_t escapes[] = {
284 		['\b'] = 'b',
285 		['\f'] = 'f',
286 		['\n'] = 'n',
287 		['\r'] = 'r',
288 		['\t'] = 't',
289 		['"'] = '"',
290 		['\\'] = '\\',
291 		/*
292 		 * Forward slash (/) is intentionally not converted to an escape
293 		 *  (it is valid unescaped).
294 		 */
295 	};
296 	uint16_t high, low;
297 	char out[13];
298 	size_t out_len;
299 
300 	if (codepoint < sizeof(escapes) && escapes[codepoint]) {
301 		out[0] = '\\';
302 		out[1] = escapes[codepoint];
303 		out_len = 2;
304 	} else if (codepoint >= 0x20 && codepoint < 0x7F) {
305 		/*
306 		 * Encode plain ASCII directly (except 0x7F, since it is really
307 		 *  a control character, despite the JSON spec not considering it one).
308 		 */
309 		out[0] = (uint8_t)codepoint;
310 		out_len = 1;
311 	} else if (codepoint < 0x10000) {
312 		out[0] = '\\';
313 		out[1] = 'u';
314 		write_hex_4(&out[2], (uint16_t)codepoint);
315 		out_len = 6;
316 	} else {
317 		utf16_encode_surrogate_pair(codepoint, &high, &low);
318 		out[0] = '\\';
319 		out[1] = 'u';
320 		write_hex_4(&out[2], high);
321 		out[6] = '\\';
322 		out[7] = 'u';
323 		write_hex_4(&out[8], low);
324 		out_len = 12;
325 	}
326 
327 	return emit(w, out, out_len);
328 }
329 
330 static int
331 write_string_or_name(struct spdk_json_write_ctx *w, const char *val, size_t len)
332 {
333 	const uint8_t *p = val;
334 	const uint8_t *end = val + len;
335 
336 	if (emit(w, "\"", 1)) { return fail(w); }
337 
338 	while (p != end) {
339 		int codepoint_len;
340 		uint32_t codepoint;
341 
342 		codepoint_len = utf8_valid(p, end);
343 		switch (codepoint_len) {
344 		case 1:
345 			codepoint = utf8_decode_unsafe_1(p);
346 			break;
347 		case 2:
348 			codepoint = utf8_decode_unsafe_2(p);
349 			break;
350 		case 3:
351 			codepoint = utf8_decode_unsafe_3(p);
352 			break;
353 		case 4:
354 			codepoint = utf8_decode_unsafe_4(p);
355 			break;
356 		default:
357 			return fail(w);
358 		}
359 
360 		if (write_codepoint(w, codepoint)) { return fail(w); }
361 		p += codepoint_len;
362 	}
363 
364 	return emit(w, "\"", 1);
365 }
366 
367 static int
368 write_string_or_name_utf16le(struct spdk_json_write_ctx *w, const uint16_t *val, size_t len)
369 {
370 	const uint16_t *p = val;
371 	const uint16_t *end = val + len;
372 
373 	if (emit(w, "\"", 1)) { return fail(w); }
374 
375 	while (p != end) {
376 		int codepoint_len;
377 		uint32_t codepoint;
378 
379 		codepoint_len = utf16le_valid(p, end);
380 		switch (codepoint_len) {
381 		case 1:
382 			codepoint = from_le16(&p[0]);
383 			break;
384 		case 2:
385 			codepoint = utf16_decode_surrogate_pair(from_le16(&p[0]), from_le16(&p[1]));
386 			break;
387 		default:
388 			return fail(w);
389 		}
390 
391 		if (write_codepoint(w, codepoint)) { return fail(w); }
392 		p += codepoint_len;
393 	}
394 
395 	return emit(w, "\"", 1);
396 }
397 
398 int
399 spdk_json_write_string_raw(struct spdk_json_write_ctx *w, const char *val, size_t len)
400 {
401 	if (begin_value(w)) { return fail(w); }
402 	return write_string_or_name(w, val, len);
403 }
404 
405 int
406 spdk_json_write_string(struct spdk_json_write_ctx *w, const char *val)
407 {
408 	return spdk_json_write_string_raw(w, val, strlen(val));
409 }
410 
411 int
412 spdk_json_write_string_utf16le_raw(struct spdk_json_write_ctx *w, const uint16_t *val, size_t len)
413 {
414 	if (begin_value(w)) { return fail(w); }
415 	return write_string_or_name_utf16le(w, val, len);
416 }
417 
418 int
419 spdk_json_write_string_utf16le(struct spdk_json_write_ctx *w, const uint16_t *val)
420 {
421 	const uint16_t *p;
422 	size_t len;
423 
424 	for (len = 0, p = val; *p; p++) {
425 		len++;
426 	}
427 
428 	return spdk_json_write_string_utf16le_raw(w, val, len);
429 }
430 
431 int
432 spdk_json_write_string_fmt(struct spdk_json_write_ctx *w, const char *fmt, ...)
433 {
434 	va_list args;
435 	int rc;
436 
437 	va_start(args, fmt);
438 	rc = spdk_json_write_string_fmt_v(w, fmt, args);
439 	va_end(args);
440 
441 	return rc;
442 }
443 
444 int
445 spdk_json_write_string_fmt_v(struct spdk_json_write_ctx *w, const char *fmt, va_list args)
446 {
447 	char *s;
448 	int rc;
449 
450 	s = spdk_vsprintf_alloc(fmt, args);
451 	if (s == NULL) {
452 		return -1;
453 	}
454 
455 	rc = spdk_json_write_string(w, s);
456 	free(s);
457 	return rc;
458 }
459 
460 int
461 spdk_json_write_array_begin(struct spdk_json_write_ctx *w)
462 {
463 	if (begin_value(w)) { return fail(w); }
464 	w->first_value = true;
465 	w->new_indent = true;
466 	w->indent++;
467 	if (emit(w, "[", 1)) { return fail(w); }
468 	return 0;
469 }
470 
471 int
472 spdk_json_write_array_end(struct spdk_json_write_ctx *w)
473 {
474 	w->first_value = false;
475 	if (w->indent == 0) { return fail(w); }
476 	w->indent--;
477 	if (!w->new_indent) {
478 		if (emit_fmt(w, "\n", 1)) { return fail(w); }
479 		if (emit_indent(w)) { return fail(w); }
480 	}
481 	w->new_indent = false;
482 	return emit(w, "]", 1);
483 }
484 
485 int
486 spdk_json_write_object_begin(struct spdk_json_write_ctx *w)
487 {
488 	if (begin_value(w)) { return fail(w); }
489 	w->first_value = true;
490 	w->new_indent = true;
491 	w->indent++;
492 	if (emit(w, "{", 1)) { return fail(w); }
493 	return 0;
494 }
495 
496 int
497 spdk_json_write_object_end(struct spdk_json_write_ctx *w)
498 {
499 	w->first_value = false;
500 	w->indent--;
501 	if (!w->new_indent) {
502 		if (emit_fmt(w, "\n", 1)) { return fail(w); }
503 		if (emit_indent(w)) { return fail(w); }
504 	}
505 	w->new_indent = false;
506 	return emit(w, "}", 1);
507 }
508 
509 int
510 spdk_json_write_name_raw(struct spdk_json_write_ctx *w, const char *name, size_t len)
511 {
512 	/* TODO: check that container is an object */
513 	if (begin_value(w)) { return fail(w); }
514 	if (write_string_or_name(w, name, len)) { return fail(w); }
515 	w->first_value = true;
516 	if (emit(w, ":", 1)) { return fail(w); }
517 	return emit_fmt(w, " ", 1);
518 }
519 
520 int
521 spdk_json_write_name(struct spdk_json_write_ctx *w, const char *name)
522 {
523 	return spdk_json_write_name_raw(w, name, strlen(name));
524 }
525 
526 int
527 spdk_json_write_val(struct spdk_json_write_ctx *w, const struct spdk_json_val *val)
528 {
529 	size_t num_values, i;
530 
531 	switch (val->type) {
532 	case SPDK_JSON_VAL_NUMBER:
533 		return spdk_json_write_val_raw(w, val->start, val->len);
534 
535 	case SPDK_JSON_VAL_STRING:
536 		return spdk_json_write_string_raw(w, val->start, val->len);
537 
538 	case SPDK_JSON_VAL_NAME:
539 		return spdk_json_write_name_raw(w, val->start, val->len);
540 
541 	case SPDK_JSON_VAL_TRUE:
542 		return spdk_json_write_bool(w, true);
543 
544 	case SPDK_JSON_VAL_FALSE:
545 		return spdk_json_write_bool(w, false);
546 
547 	case SPDK_JSON_VAL_NULL:
548 		return spdk_json_write_null(w);
549 
550 	case SPDK_JSON_VAL_ARRAY_BEGIN:
551 	case SPDK_JSON_VAL_OBJECT_BEGIN:
552 		num_values = val[0].len;
553 
554 		if (val[0].type == SPDK_JSON_VAL_OBJECT_BEGIN) {
555 			if (spdk_json_write_object_begin(w)) {
556 				return fail(w);
557 			}
558 		} else {
559 			if (spdk_json_write_array_begin(w)) {
560 				return fail(w);
561 			}
562 		}
563 
564 		/* Loop up to and including the _END value */
565 		for (i = 0; i < num_values + 1;) {
566 			if (spdk_json_write_val(w, &val[i + 1])) {
567 				return fail(w);
568 			}
569 			if (val[i + 1].type == SPDK_JSON_VAL_ARRAY_BEGIN ||
570 			    val[i + 1].type == SPDK_JSON_VAL_OBJECT_BEGIN) {
571 				i += val[i + 1].len + 2;
572 			} else {
573 				i++;
574 			}
575 		}
576 		return 0;
577 
578 	case SPDK_JSON_VAL_ARRAY_END:
579 		return spdk_json_write_array_end(w);
580 
581 	case SPDK_JSON_VAL_OBJECT_END:
582 		return spdk_json_write_object_end(w);
583 
584 	case SPDK_JSON_VAL_INVALID:
585 		/* Handle INVALID to make the compiler happy (and catch other unhandled types) */
586 		return fail(w);
587 	}
588 
589 	return fail(w);
590 }
591 
592 int spdk_json_write_named_null(struct spdk_json_write_ctx *w, const char *name)
593 {
594 	int rc = spdk_json_write_name(w, name);
595 	return rc ? rc : spdk_json_write_null(w);
596 }
597 
598 int spdk_json_write_named_bool(struct spdk_json_write_ctx *w, const char *name, bool val)
599 {
600 	int rc = spdk_json_write_name(w, name);
601 
602 	return rc ? rc : spdk_json_write_bool(w, val);
603 }
604 
605 int spdk_json_write_named_int32(struct spdk_json_write_ctx *w, const char *name, int32_t val)
606 {
607 	int rc = spdk_json_write_name(w, name);
608 
609 	return rc ? rc : spdk_json_write_int32(w, val);
610 }
611 
612 int spdk_json_write_named_uint32(struct spdk_json_write_ctx *w, const char *name, uint32_t val)
613 {
614 	int rc = spdk_json_write_name(w, name);
615 
616 	return rc ? rc : spdk_json_write_uint32(w, val);
617 }
618 
619 int spdk_json_write_named_uint64(struct spdk_json_write_ctx *w, const char *name, uint64_t val)
620 {
621 	int rc = spdk_json_write_name(w, name);
622 
623 	return rc ? rc : spdk_json_write_uint64(w, val);
624 }
625 
626 int spdk_json_write_named_int64(struct spdk_json_write_ctx *w, const char *name, int64_t val)
627 {
628 	int rc = spdk_json_write_name(w, name);
629 
630 	return rc ? rc : spdk_json_write_int64(w, val);
631 }
632 
633 int spdk_json_write_named_string(struct spdk_json_write_ctx *w, const char *name, const char *val)
634 {
635 	int rc = spdk_json_write_name(w, name);
636 
637 	return rc ? rc : spdk_json_write_string(w, val);
638 }
639 
640 int spdk_json_write_named_string_fmt(struct spdk_json_write_ctx *w, const char *name,
641 				     const char *fmt, ...)
642 {
643 	va_list args;
644 	int rc;
645 
646 	va_start(args, fmt);
647 	rc = spdk_json_write_named_string_fmt_v(w, name, fmt, args);
648 	va_end(args);
649 
650 	return rc;
651 }
652 
653 int spdk_json_write_named_string_fmt_v(struct spdk_json_write_ctx *w, const char *name,
654 				       const char *fmt, va_list args)
655 {
656 	char *s;
657 	int rc;
658 
659 	rc = spdk_json_write_name(w, name);
660 	if (rc) {
661 		return rc;
662 	}
663 
664 	s = spdk_vsprintf_alloc(fmt, args);
665 
666 	if (s == NULL) {
667 		return -1;
668 	}
669 
670 	rc = spdk_json_write_string(w, s);
671 	free(s);
672 	return rc;
673 }
674 
675 int spdk_json_write_named_array_begin(struct spdk_json_write_ctx *w, const char *name)
676 {
677 	int rc = spdk_json_write_name(w, name);
678 
679 	return rc ? rc : spdk_json_write_array_begin(w);
680 }
681 
682 int spdk_json_write_named_object_begin(struct spdk_json_write_ctx *w, const char *name)
683 {
684 	int rc = spdk_json_write_name(w, name);
685 
686 	return rc ? rc : spdk_json_write_object_begin(w);
687 }
688