blob: 9d7f6eb9ebab6c03404dd812d216c530a193b451 [file] [log] [blame]
Alexander Graf190c8822015-01-22 15:01:37 +01001/*
Markus Armbruster17b74b92016-05-04 18:49:17 +02002 * A simple JSON writer
Alexander Graf190c8822015-01-22 15:01:37 +01003 *
4 * Copyright Alexander Graf
5 *
6 * Authors:
Greg Kurz559782c2015-02-07 11:25:50 +01007 * Alexander Graf <agraf@suse.de>
Alexander Graf190c8822015-01-22 15:01:37 +01008 *
9 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
10 * See the COPYING.LIB file in the top-level directory.
11 *
12 */
13
Markus Armbruster17b74b92016-05-04 18:49:17 +020014/*
15 * Type QJSON lets you build JSON text. Its interface mirrors (a
16 * subset of) abstract JSON syntax.
17 *
18 * It does *not* detect incorrect use. It happily produces invalid
19 * JSON then. This is what migration wants.
20 *
21 * QAPI output visitors also produce JSON text. However, they do
22 * assert their preconditions and invariants, and therefore abort on
23 * incorrect use.
24 */
25
Peter Maydelld38ea872016-01-29 17:50:05 +000026#include "qemu/osdep.h"
Markus Armbruster17b74b92016-05-04 18:49:17 +020027#include "qapi/qmp/qstring.h"
Juan Quintela05b98c22017-04-20 13:10:28 +020028#include "qjson.h"
Alexander Graf190c8822015-01-22 15:01:37 +010029
30struct QJSON {
Alexander Graf190c8822015-01-22 15:01:37 +010031 QString *str;
32 bool omit_comma;
33};
34
35static void json_emit_element(QJSON *json, const char *name)
36{
37 /* Check whether we need to print a , before an element */
38 if (json->omit_comma) {
39 json->omit_comma = false;
40 } else {
41 qstring_append(json->str, ", ");
42 }
43
44 if (name) {
45 qstring_append(json->str, "\"");
46 qstring_append(json->str, name);
47 qstring_append(json->str, "\" : ");
48 }
49}
50
51void json_start_object(QJSON *json, const char *name)
52{
53 json_emit_element(json, name);
54 qstring_append(json->str, "{ ");
55 json->omit_comma = true;
56}
57
58void json_end_object(QJSON *json)
59{
60 qstring_append(json->str, " }");
61 json->omit_comma = false;
62}
63
64void json_start_array(QJSON *json, const char *name)
65{
66 json_emit_element(json, name);
67 qstring_append(json->str, "[ ");
68 json->omit_comma = true;
69}
70
71void json_end_array(QJSON *json)
72{
73 qstring_append(json->str, " ]");
74 json->omit_comma = false;
75}
76
77void json_prop_int(QJSON *json, const char *name, int64_t val)
78{
79 json_emit_element(json, name);
80 qstring_append_int(json->str, val);
81}
82
83void json_prop_str(QJSON *json, const char *name, const char *str)
84{
85 json_emit_element(json, name);
86 qstring_append_chr(json->str, '"');
87 qstring_append(json->str, str);
88 qstring_append_chr(json->str, '"');
89}
90
91const char *qjson_get_str(QJSON *json)
92{
93 return qstring_get_str(json->str);
94}
95
96QJSON *qjson_new(void)
97{
Markus Armbrusterb72fe9e2016-05-04 18:49:18 +020098 QJSON *json = g_new0(QJSON, 1);
99
100 json->str = qstring_from_str("{ ");
101 json->omit_comma = true;
Alexander Graf190c8822015-01-22 15:01:37 +0100102 return json;
103}
104
105void qjson_finish(QJSON *json)
106{
107 json_end_object(json);
108}
109
Markus Armbrusterb72fe9e2016-05-04 18:49:18 +0200110void qjson_destroy(QJSON *json)
Alexander Graf190c8822015-01-22 15:01:37 +0100111{
Marc-André Lureaudf37dd62016-07-15 10:41:03 +0200112 QDECREF(json->str);
Markus Armbrusterb72fe9e2016-05-04 18:49:18 +0200113 g_free(json);
Alexander Graf190c8822015-01-22 15:01:37 +0100114}