xref: /spdk/lib/json/json_write.c (revision 2f5c602574a98ede645991abe279a96e19c50196)
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 int
269 spdk_json_write_uint128(struct spdk_json_write_ctx *w, uint64_t low_val, uint64_t high_val)
270 {
271 	char buf[128] = {'\0'};
272 	uint64_t low = low_val, high = high_val;
273 	int count = 0;
274 
275 	if (begin_value(w)) { return fail(w); }
276 
277 	if (high != 0) {
278 		char temp_buf[128] = {'\0'};
279 		uint64_t seg;
280 		unsigned __int128 total = (unsigned __int128)low +
281 					  ((unsigned __int128)high << 64);
282 
283 		while (total) {
284 			seg = total % 10000000000;
285 			total = total / 10000000000;
286 			if (total) {
287 				count = snprintf(temp_buf, 128, "%010" PRIu64 "%s", seg, buf);
288 			} else {
289 				count = snprintf(temp_buf, 128, "%" PRIu64 "%s", seg, buf);
290 			}
291 
292 			if (count <= 0 || (size_t)count >= sizeof(temp_buf)) {
293 				return fail(w);
294 			}
295 
296 			snprintf(buf, 128, "%s", temp_buf);
297 		}
298 	} else {
299 		count = snprintf(buf, sizeof(buf), "%" PRIu64, low);
300 
301 		if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
302 	}
303 
304 	return emit(w, buf, count);
305 }
306 
307 int
308 spdk_json_write_named_uint128(struct spdk_json_write_ctx *w, const char *name,
309 			      uint64_t low_val, uint64_t high_val)
310 {
311 	int rc = spdk_json_write_name(w, name);
312 
313 	return rc ? rc : spdk_json_write_uint128(w, low_val, high_val);
314 }
315 
316 static void
317 write_hex_4(void *dest, uint16_t val)
318 {
319 	uint8_t *p = dest;
320 	char hex[] = "0123456789ABCDEF";
321 
322 	p[0] = hex[(val >> 12)];
323 	p[1] = hex[(val >> 8) & 0xF];
324 	p[2] = hex[(val >> 4) & 0xF];
325 	p[3] = hex[val & 0xF];
326 }
327 
328 static inline int
329 write_codepoint(struct spdk_json_write_ctx *w, uint32_t codepoint)
330 {
331 	static const uint8_t escapes[] = {
332 		['\b'] = 'b',
333 		['\f'] = 'f',
334 		['\n'] = 'n',
335 		['\r'] = 'r',
336 		['\t'] = 't',
337 		['"'] = '"',
338 		['\\'] = '\\',
339 		/*
340 		 * Forward slash (/) is intentionally not converted to an escape
341 		 *  (it is valid unescaped).
342 		 */
343 	};
344 	uint16_t high, low;
345 	char out[13];
346 	size_t out_len;
347 
348 	if (codepoint < sizeof(escapes) && escapes[codepoint]) {
349 		out[0] = '\\';
350 		out[1] = escapes[codepoint];
351 		out_len = 2;
352 	} else if (codepoint >= 0x20 && codepoint < 0x7F) {
353 		/*
354 		 * Encode plain ASCII directly (except 0x7F, since it is really
355 		 *  a control character, despite the JSON spec not considering it one).
356 		 */
357 		out[0] = (uint8_t)codepoint;
358 		out_len = 1;
359 	} else if (codepoint < 0x10000) {
360 		out[0] = '\\';
361 		out[1] = 'u';
362 		write_hex_4(&out[2], (uint16_t)codepoint);
363 		out_len = 6;
364 	} else {
365 		utf16_encode_surrogate_pair(codepoint, &high, &low);
366 		out[0] = '\\';
367 		out[1] = 'u';
368 		write_hex_4(&out[2], high);
369 		out[6] = '\\';
370 		out[7] = 'u';
371 		write_hex_4(&out[8], low);
372 		out_len = 12;
373 	}
374 
375 	return emit(w, out, out_len);
376 }
377 
378 static int
379 write_string_or_name(struct spdk_json_write_ctx *w, const char *val, size_t len)
380 {
381 	const uint8_t *p = val;
382 	const uint8_t *end = val + len;
383 
384 	if (emit(w, "\"", 1)) { return fail(w); }
385 
386 	while (p != end) {
387 		int codepoint_len;
388 		uint32_t codepoint;
389 
390 		codepoint_len = utf8_valid(p, end);
391 		switch (codepoint_len) {
392 		case 1:
393 			codepoint = utf8_decode_unsafe_1(p);
394 			break;
395 		case 2:
396 			codepoint = utf8_decode_unsafe_2(p);
397 			break;
398 		case 3:
399 			codepoint = utf8_decode_unsafe_3(p);
400 			break;
401 		case 4:
402 			codepoint = utf8_decode_unsafe_4(p);
403 			break;
404 		default:
405 			return fail(w);
406 		}
407 
408 		if (write_codepoint(w, codepoint)) { return fail(w); }
409 		p += codepoint_len;
410 	}
411 
412 	return emit(w, "\"", 1);
413 }
414 
415 static int
416 write_string_or_name_utf16le(struct spdk_json_write_ctx *w, const uint16_t *val, size_t len)
417 {
418 	const uint16_t *p = val;
419 	const uint16_t *end = val + len;
420 
421 	if (emit(w, "\"", 1)) { return fail(w); }
422 
423 	while (p != end) {
424 		int codepoint_len;
425 		uint32_t codepoint;
426 
427 		codepoint_len = utf16le_valid(p, end);
428 		switch (codepoint_len) {
429 		case 1:
430 			codepoint = from_le16(&p[0]);
431 			break;
432 		case 2:
433 			codepoint = utf16_decode_surrogate_pair(from_le16(&p[0]), from_le16(&p[1]));
434 			break;
435 		default:
436 			return fail(w);
437 		}
438 
439 		if (write_codepoint(w, codepoint)) { return fail(w); }
440 		p += codepoint_len;
441 	}
442 
443 	return emit(w, "\"", 1);
444 }
445 
446 int
447 spdk_json_write_string_raw(struct spdk_json_write_ctx *w, const char *val, size_t len)
448 {
449 	if (begin_value(w)) { return fail(w); }
450 	return write_string_or_name(w, val, len);
451 }
452 
453 int
454 spdk_json_write_string(struct spdk_json_write_ctx *w, const char *val)
455 {
456 	return spdk_json_write_string_raw(w, val, strlen(val));
457 }
458 
459 int
460 spdk_json_write_string_utf16le_raw(struct spdk_json_write_ctx *w, const uint16_t *val, size_t len)
461 {
462 	if (begin_value(w)) { return fail(w); }
463 	return write_string_or_name_utf16le(w, val, len);
464 }
465 
466 int
467 spdk_json_write_string_utf16le(struct spdk_json_write_ctx *w, const uint16_t *val)
468 {
469 	const uint16_t *p;
470 	size_t len;
471 
472 	for (len = 0, p = val; *p; p++) {
473 		len++;
474 	}
475 
476 	return spdk_json_write_string_utf16le_raw(w, val, len);
477 }
478 
479 int
480 spdk_json_write_string_fmt(struct spdk_json_write_ctx *w, const char *fmt, ...)
481 {
482 	va_list args;
483 	int rc;
484 
485 	va_start(args, fmt);
486 	rc = spdk_json_write_string_fmt_v(w, fmt, args);
487 	va_end(args);
488 
489 	return rc;
490 }
491 
492 int
493 spdk_json_write_string_fmt_v(struct spdk_json_write_ctx *w, const char *fmt, va_list args)
494 {
495 	char *s;
496 	int rc;
497 
498 	s = spdk_vsprintf_alloc(fmt, args);
499 	if (s == NULL) {
500 		return -1;
501 	}
502 
503 	rc = spdk_json_write_string(w, s);
504 	free(s);
505 	return rc;
506 }
507 
508 int
509 spdk_json_write_array_begin(struct spdk_json_write_ctx *w)
510 {
511 	if (begin_value(w)) { return fail(w); }
512 	w->first_value = true;
513 	w->new_indent = true;
514 	w->indent++;
515 	if (emit(w, "[", 1)) { return fail(w); }
516 	return 0;
517 }
518 
519 int
520 spdk_json_write_array_end(struct spdk_json_write_ctx *w)
521 {
522 	w->first_value = false;
523 	if (w->indent == 0) { return fail(w); }
524 	w->indent--;
525 	if (!w->new_indent) {
526 		if (emit_fmt(w, "\n", 1)) { return fail(w); }
527 		if (emit_indent(w)) { return fail(w); }
528 	}
529 	w->new_indent = false;
530 	return emit(w, "]", 1);
531 }
532 
533 int
534 spdk_json_write_object_begin(struct spdk_json_write_ctx *w)
535 {
536 	if (begin_value(w)) { return fail(w); }
537 	w->first_value = true;
538 	w->new_indent = true;
539 	w->indent++;
540 	if (emit(w, "{", 1)) { return fail(w); }
541 	return 0;
542 }
543 
544 int
545 spdk_json_write_object_end(struct spdk_json_write_ctx *w)
546 {
547 	w->first_value = false;
548 	w->indent--;
549 	if (!w->new_indent) {
550 		if (emit_fmt(w, "\n", 1)) { return fail(w); }
551 		if (emit_indent(w)) { return fail(w); }
552 	}
553 	w->new_indent = false;
554 	return emit(w, "}", 1);
555 }
556 
557 int
558 spdk_json_write_name_raw(struct spdk_json_write_ctx *w, const char *name, size_t len)
559 {
560 	/* TODO: check that container is an object */
561 	if (begin_value(w)) { return fail(w); }
562 	if (write_string_or_name(w, name, len)) { return fail(w); }
563 	w->first_value = true;
564 	if (emit(w, ":", 1)) { return fail(w); }
565 	return emit_fmt(w, " ", 1);
566 }
567 
568 int
569 spdk_json_write_name(struct spdk_json_write_ctx *w, const char *name)
570 {
571 	return spdk_json_write_name_raw(w, name, strlen(name));
572 }
573 
574 int
575 spdk_json_write_val(struct spdk_json_write_ctx *w, const struct spdk_json_val *val)
576 {
577 	size_t num_values, i;
578 
579 	switch (val->type) {
580 	case SPDK_JSON_VAL_NUMBER:
581 		return spdk_json_write_val_raw(w, val->start, val->len);
582 
583 	case SPDK_JSON_VAL_STRING:
584 		return spdk_json_write_string_raw(w, val->start, val->len);
585 
586 	case SPDK_JSON_VAL_NAME:
587 		return spdk_json_write_name_raw(w, val->start, val->len);
588 
589 	case SPDK_JSON_VAL_TRUE:
590 		return spdk_json_write_bool(w, true);
591 
592 	case SPDK_JSON_VAL_FALSE:
593 		return spdk_json_write_bool(w, false);
594 
595 	case SPDK_JSON_VAL_NULL:
596 		return spdk_json_write_null(w);
597 
598 	case SPDK_JSON_VAL_ARRAY_BEGIN:
599 	case SPDK_JSON_VAL_OBJECT_BEGIN:
600 		num_values = val[0].len;
601 
602 		if (val[0].type == SPDK_JSON_VAL_OBJECT_BEGIN) {
603 			if (spdk_json_write_object_begin(w)) {
604 				return fail(w);
605 			}
606 		} else {
607 			if (spdk_json_write_array_begin(w)) {
608 				return fail(w);
609 			}
610 		}
611 
612 		/* Loop up to and including the _END value */
613 		for (i = 0; i < num_values + 1;) {
614 			if (spdk_json_write_val(w, &val[i + 1])) {
615 				return fail(w);
616 			}
617 			if (val[i + 1].type == SPDK_JSON_VAL_ARRAY_BEGIN ||
618 			    val[i + 1].type == SPDK_JSON_VAL_OBJECT_BEGIN) {
619 				i += val[i + 1].len + 2;
620 			} else {
621 				i++;
622 			}
623 		}
624 		return 0;
625 
626 	case SPDK_JSON_VAL_ARRAY_END:
627 		return spdk_json_write_array_end(w);
628 
629 	case SPDK_JSON_VAL_OBJECT_END:
630 		return spdk_json_write_object_end(w);
631 
632 	case SPDK_JSON_VAL_INVALID:
633 		/* Handle INVALID to make the compiler happy (and catch other unhandled types) */
634 		return fail(w);
635 	}
636 
637 	return fail(w);
638 }
639 
640 int spdk_json_write_named_null(struct spdk_json_write_ctx *w, const char *name)
641 {
642 	int rc = spdk_json_write_name(w, name);
643 	return rc ? rc : spdk_json_write_null(w);
644 }
645 
646 int spdk_json_write_named_bool(struct spdk_json_write_ctx *w, const char *name, bool val)
647 {
648 	int rc = spdk_json_write_name(w, name);
649 
650 	return rc ? rc : spdk_json_write_bool(w, val);
651 }
652 
653 int spdk_json_write_named_int32(struct spdk_json_write_ctx *w, const char *name, int32_t val)
654 {
655 	int rc = spdk_json_write_name(w, name);
656 
657 	return rc ? rc : spdk_json_write_int32(w, val);
658 }
659 
660 int spdk_json_write_named_uint32(struct spdk_json_write_ctx *w, const char *name, uint32_t val)
661 {
662 	int rc = spdk_json_write_name(w, name);
663 
664 	return rc ? rc : spdk_json_write_uint32(w, val);
665 }
666 
667 int spdk_json_write_named_uint64(struct spdk_json_write_ctx *w, const char *name, uint64_t val)
668 {
669 	int rc = spdk_json_write_name(w, name);
670 
671 	return rc ? rc : spdk_json_write_uint64(w, val);
672 }
673 
674 int spdk_json_write_named_int64(struct spdk_json_write_ctx *w, const char *name, int64_t val)
675 {
676 	int rc = spdk_json_write_name(w, name);
677 
678 	return rc ? rc : spdk_json_write_int64(w, val);
679 }
680 
681 int spdk_json_write_named_string(struct spdk_json_write_ctx *w, const char *name, const char *val)
682 {
683 	int rc = spdk_json_write_name(w, name);
684 
685 	return rc ? rc : spdk_json_write_string(w, val);
686 }
687 
688 int spdk_json_write_named_string_fmt(struct spdk_json_write_ctx *w, const char *name,
689 				     const char *fmt, ...)
690 {
691 	va_list args;
692 	int rc;
693 
694 	va_start(args, fmt);
695 	rc = spdk_json_write_named_string_fmt_v(w, name, fmt, args);
696 	va_end(args);
697 
698 	return rc;
699 }
700 
701 int spdk_json_write_named_string_fmt_v(struct spdk_json_write_ctx *w, const char *name,
702 				       const char *fmt, va_list args)
703 {
704 	char *s;
705 	int rc;
706 
707 	rc = spdk_json_write_name(w, name);
708 	if (rc) {
709 		return rc;
710 	}
711 
712 	s = spdk_vsprintf_alloc(fmt, args);
713 
714 	if (s == NULL) {
715 		return -1;
716 	}
717 
718 	rc = spdk_json_write_string(w, s);
719 	free(s);
720 	return rc;
721 }
722 
723 int spdk_json_write_named_array_begin(struct spdk_json_write_ctx *w, const char *name)
724 {
725 	int rc = spdk_json_write_name(w, name);
726 
727 	return rc ? rc : spdk_json_write_array_begin(w);
728 }
729 
730 int spdk_json_write_named_object_begin(struct spdk_json_write_ctx *w, const char *name)
731 {
732 	int rc = spdk_json_write_name(w, name);
733 
734 	return rc ? rc : spdk_json_write_object_begin(w);
735 }
736