1 /*
2  * A simple JSON writer
3  *
4  * Copyright Alexander Graf
5  *
6  * Authors:
7  *  Alexander Graf <agraf@suse.de>
8  *
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 
14 /*
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 
26 #include "qemu/osdep.h"
27 #include "qapi/qmp/qstring.h"
28 #include "qjson.h"
29 
30 struct QJSON {
31     QString *str;
32     bool omit_comma;
33 };
34 
json_emit_element(QJSON * json,const char * name)35 static 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 
json_start_object(QJSON * json,const char * name)51 void 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 
json_end_object(QJSON * json)58 void json_end_object(QJSON *json)
59 {
60     qstring_append(json->str, " }");
61     json->omit_comma = false;
62 }
63 
json_start_array(QJSON * json,const char * name)64 void 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 
json_end_array(QJSON * json)71 void json_end_array(QJSON *json)
72 {
73     qstring_append(json->str, " ]");
74     json->omit_comma = false;
75 }
76 
json_prop_int(QJSON * json,const char * name,int64_t val)77 void 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 
json_prop_str(QJSON * json,const char * name,const char * str)83 void 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 
qjson_get_str(QJSON * json)91 const char *qjson_get_str(QJSON *json)
92 {
93     return qstring_get_str(json->str);
94 }
95 
qjson_new(void)96 QJSON *qjson_new(void)
97 {
98     QJSON *json = g_new0(QJSON, 1);
99 
100     json->str = qstring_from_str("{ ");
101     json->omit_comma = true;
102     return json;
103 }
104 
qjson_finish(QJSON * json)105 void qjson_finish(QJSON *json)
106 {
107     json_end_object(json);
108 }
109 
qjson_destroy(QJSON * json)110 void qjson_destroy(QJSON *json)
111 {
112     qobject_unref(json->str);
113     g_free(json);
114 }
115