1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker * Simple streaming JSON writer
3*de1e4e89SAndroid Build Coastguard Worker *
4*de1e4e89SAndroid Build Coastguard Worker * This takes care of the annoying bits of JSON syntax like the commas
5*de1e4e89SAndroid Build Coastguard Worker * after elements
6*de1e4e89SAndroid Build Coastguard Worker *
7*de1e4e89SAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or
8*de1e4e89SAndroid Build Coastguard Worker * modify it under the terms of the GNU General Public License
9*de1e4e89SAndroid Build Coastguard Worker * as published by the Free Software Foundation; either version
10*de1e4e89SAndroid Build Coastguard Worker * 2 of the License, or (at your option) any later version.
11*de1e4e89SAndroid Build Coastguard Worker *
12*de1e4e89SAndroid Build Coastguard Worker * Authors: Stephen Hemminger <[email protected]>
13*de1e4e89SAndroid Build Coastguard Worker */
14*de1e4e89SAndroid Build Coastguard Worker
15*de1e4e89SAndroid Build Coastguard Worker #include <stdio.h>
16*de1e4e89SAndroid Build Coastguard Worker #include <stdbool.h>
17*de1e4e89SAndroid Build Coastguard Worker #include <stdarg.h>
18*de1e4e89SAndroid Build Coastguard Worker #include <assert.h>
19*de1e4e89SAndroid Build Coastguard Worker #include <malloc.h>
20*de1e4e89SAndroid Build Coastguard Worker #include <inttypes.h>
21*de1e4e89SAndroid Build Coastguard Worker #include <stdint.h>
22*de1e4e89SAndroid Build Coastguard Worker
23*de1e4e89SAndroid Build Coastguard Worker #include "json_writer.h"
24*de1e4e89SAndroid Build Coastguard Worker
25*de1e4e89SAndroid Build Coastguard Worker struct json_writer {
26*de1e4e89SAndroid Build Coastguard Worker FILE *out; /* output file */
27*de1e4e89SAndroid Build Coastguard Worker unsigned depth; /* nesting */
28*de1e4e89SAndroid Build Coastguard Worker bool pretty; /* optional whitepace */
29*de1e4e89SAndroid Build Coastguard Worker char sep; /* either nul or comma */
30*de1e4e89SAndroid Build Coastguard Worker };
31*de1e4e89SAndroid Build Coastguard Worker
32*de1e4e89SAndroid Build Coastguard Worker /* indentation for pretty print */
jsonw_indent(json_writer_t * self)33*de1e4e89SAndroid Build Coastguard Worker static void jsonw_indent(json_writer_t *self)
34*de1e4e89SAndroid Build Coastguard Worker {
35*de1e4e89SAndroid Build Coastguard Worker unsigned i;
36*de1e4e89SAndroid Build Coastguard Worker for (i = 0; i < self->depth; ++i)
37*de1e4e89SAndroid Build Coastguard Worker fputs(" ", self->out);
38*de1e4e89SAndroid Build Coastguard Worker }
39*de1e4e89SAndroid Build Coastguard Worker
40*de1e4e89SAndroid Build Coastguard Worker /* end current line and indent if pretty printing */
jsonw_eol(json_writer_t * self)41*de1e4e89SAndroid Build Coastguard Worker static void jsonw_eol(json_writer_t *self)
42*de1e4e89SAndroid Build Coastguard Worker {
43*de1e4e89SAndroid Build Coastguard Worker if (!self->pretty)
44*de1e4e89SAndroid Build Coastguard Worker return;
45*de1e4e89SAndroid Build Coastguard Worker
46*de1e4e89SAndroid Build Coastguard Worker putc('\n', self->out);
47*de1e4e89SAndroid Build Coastguard Worker jsonw_indent(self);
48*de1e4e89SAndroid Build Coastguard Worker }
49*de1e4e89SAndroid Build Coastguard Worker
50*de1e4e89SAndroid Build Coastguard Worker /* If current object is not empty print a comma */
jsonw_eor(json_writer_t * self)51*de1e4e89SAndroid Build Coastguard Worker static void jsonw_eor(json_writer_t *self)
52*de1e4e89SAndroid Build Coastguard Worker {
53*de1e4e89SAndroid Build Coastguard Worker if (self->sep != '\0')
54*de1e4e89SAndroid Build Coastguard Worker putc(self->sep, self->out);
55*de1e4e89SAndroid Build Coastguard Worker self->sep = ',';
56*de1e4e89SAndroid Build Coastguard Worker }
57*de1e4e89SAndroid Build Coastguard Worker
58*de1e4e89SAndroid Build Coastguard Worker
59*de1e4e89SAndroid Build Coastguard Worker /* Output JSON encoded string */
60*de1e4e89SAndroid Build Coastguard Worker /* Handles C escapes, does not do Unicode */
jsonw_puts(json_writer_t * self,const char * str)61*de1e4e89SAndroid Build Coastguard Worker static void jsonw_puts(json_writer_t *self, const char *str)
62*de1e4e89SAndroid Build Coastguard Worker {
63*de1e4e89SAndroid Build Coastguard Worker putc('"', self->out);
64*de1e4e89SAndroid Build Coastguard Worker for (; *str; ++str)
65*de1e4e89SAndroid Build Coastguard Worker switch (*str) {
66*de1e4e89SAndroid Build Coastguard Worker case '\t':
67*de1e4e89SAndroid Build Coastguard Worker fputs("\\t", self->out);
68*de1e4e89SAndroid Build Coastguard Worker break;
69*de1e4e89SAndroid Build Coastguard Worker case '\n':
70*de1e4e89SAndroid Build Coastguard Worker fputs("\\n", self->out);
71*de1e4e89SAndroid Build Coastguard Worker break;
72*de1e4e89SAndroid Build Coastguard Worker case '\r':
73*de1e4e89SAndroid Build Coastguard Worker fputs("\\r", self->out);
74*de1e4e89SAndroid Build Coastguard Worker break;
75*de1e4e89SAndroid Build Coastguard Worker case '\f':
76*de1e4e89SAndroid Build Coastguard Worker fputs("\\f", self->out);
77*de1e4e89SAndroid Build Coastguard Worker break;
78*de1e4e89SAndroid Build Coastguard Worker case '\b':
79*de1e4e89SAndroid Build Coastguard Worker fputs("\\b", self->out);
80*de1e4e89SAndroid Build Coastguard Worker break;
81*de1e4e89SAndroid Build Coastguard Worker case '\\':
82*de1e4e89SAndroid Build Coastguard Worker fputs("\\n", self->out);
83*de1e4e89SAndroid Build Coastguard Worker break;
84*de1e4e89SAndroid Build Coastguard Worker case '"':
85*de1e4e89SAndroid Build Coastguard Worker fputs("\\\"", self->out);
86*de1e4e89SAndroid Build Coastguard Worker break;
87*de1e4e89SAndroid Build Coastguard Worker case '\'':
88*de1e4e89SAndroid Build Coastguard Worker fputs("\\\'", self->out);
89*de1e4e89SAndroid Build Coastguard Worker break;
90*de1e4e89SAndroid Build Coastguard Worker default:
91*de1e4e89SAndroid Build Coastguard Worker putc(*str, self->out);
92*de1e4e89SAndroid Build Coastguard Worker }
93*de1e4e89SAndroid Build Coastguard Worker putc('"', self->out);
94*de1e4e89SAndroid Build Coastguard Worker }
95*de1e4e89SAndroid Build Coastguard Worker
96*de1e4e89SAndroid Build Coastguard Worker /* Create a new JSON stream */
jsonw_new(FILE * f)97*de1e4e89SAndroid Build Coastguard Worker json_writer_t *jsonw_new(FILE *f)
98*de1e4e89SAndroid Build Coastguard Worker {
99*de1e4e89SAndroid Build Coastguard Worker json_writer_t *self = malloc(sizeof(*self));
100*de1e4e89SAndroid Build Coastguard Worker if (self) {
101*de1e4e89SAndroid Build Coastguard Worker self->out = f;
102*de1e4e89SAndroid Build Coastguard Worker self->depth = 0;
103*de1e4e89SAndroid Build Coastguard Worker self->pretty = false;
104*de1e4e89SAndroid Build Coastguard Worker self->sep = '\0';
105*de1e4e89SAndroid Build Coastguard Worker }
106*de1e4e89SAndroid Build Coastguard Worker return self;
107*de1e4e89SAndroid Build Coastguard Worker }
108*de1e4e89SAndroid Build Coastguard Worker
109*de1e4e89SAndroid Build Coastguard Worker /* End output to JSON stream */
jsonw_destroy(json_writer_t ** self_p)110*de1e4e89SAndroid Build Coastguard Worker void jsonw_destroy(json_writer_t **self_p)
111*de1e4e89SAndroid Build Coastguard Worker {
112*de1e4e89SAndroid Build Coastguard Worker json_writer_t *self = *self_p;
113*de1e4e89SAndroid Build Coastguard Worker
114*de1e4e89SAndroid Build Coastguard Worker assert(self->depth == 0);
115*de1e4e89SAndroid Build Coastguard Worker fputs("\n", self->out);
116*de1e4e89SAndroid Build Coastguard Worker fflush(self->out);
117*de1e4e89SAndroid Build Coastguard Worker free(self);
118*de1e4e89SAndroid Build Coastguard Worker *self_p = NULL;
119*de1e4e89SAndroid Build Coastguard Worker }
120*de1e4e89SAndroid Build Coastguard Worker
jsonw_pretty(json_writer_t * self,bool on)121*de1e4e89SAndroid Build Coastguard Worker void jsonw_pretty(json_writer_t *self, bool on)
122*de1e4e89SAndroid Build Coastguard Worker {
123*de1e4e89SAndroid Build Coastguard Worker self->pretty = on;
124*de1e4e89SAndroid Build Coastguard Worker }
125*de1e4e89SAndroid Build Coastguard Worker
126*de1e4e89SAndroid Build Coastguard Worker /* Basic blocks */
jsonw_begin(json_writer_t * self,int c)127*de1e4e89SAndroid Build Coastguard Worker static void jsonw_begin(json_writer_t *self, int c)
128*de1e4e89SAndroid Build Coastguard Worker {
129*de1e4e89SAndroid Build Coastguard Worker jsonw_eor(self);
130*de1e4e89SAndroid Build Coastguard Worker putc(c, self->out);
131*de1e4e89SAndroid Build Coastguard Worker ++self->depth;
132*de1e4e89SAndroid Build Coastguard Worker self->sep = '\0';
133*de1e4e89SAndroid Build Coastguard Worker }
134*de1e4e89SAndroid Build Coastguard Worker
jsonw_end(json_writer_t * self,int c)135*de1e4e89SAndroid Build Coastguard Worker static void jsonw_end(json_writer_t *self, int c)
136*de1e4e89SAndroid Build Coastguard Worker {
137*de1e4e89SAndroid Build Coastguard Worker assert(self->depth > 0);
138*de1e4e89SAndroid Build Coastguard Worker
139*de1e4e89SAndroid Build Coastguard Worker --self->depth;
140*de1e4e89SAndroid Build Coastguard Worker if (self->sep != '\0')
141*de1e4e89SAndroid Build Coastguard Worker jsonw_eol(self);
142*de1e4e89SAndroid Build Coastguard Worker putc(c, self->out);
143*de1e4e89SAndroid Build Coastguard Worker self->sep = ',';
144*de1e4e89SAndroid Build Coastguard Worker }
145*de1e4e89SAndroid Build Coastguard Worker
146*de1e4e89SAndroid Build Coastguard Worker
147*de1e4e89SAndroid Build Coastguard Worker /* Add a JSON property name */
jsonw_name(json_writer_t * self,const char * name)148*de1e4e89SAndroid Build Coastguard Worker void jsonw_name(json_writer_t *self, const char *name)
149*de1e4e89SAndroid Build Coastguard Worker {
150*de1e4e89SAndroid Build Coastguard Worker jsonw_eor(self);
151*de1e4e89SAndroid Build Coastguard Worker jsonw_eol(self);
152*de1e4e89SAndroid Build Coastguard Worker self->sep = '\0';
153*de1e4e89SAndroid Build Coastguard Worker jsonw_puts(self, name);
154*de1e4e89SAndroid Build Coastguard Worker putc(':', self->out);
155*de1e4e89SAndroid Build Coastguard Worker if (self->pretty)
156*de1e4e89SAndroid Build Coastguard Worker putc(' ', self->out);
157*de1e4e89SAndroid Build Coastguard Worker }
158*de1e4e89SAndroid Build Coastguard Worker
jsonw_printf(json_writer_t * self,const char * fmt,...)159*de1e4e89SAndroid Build Coastguard Worker void jsonw_printf(json_writer_t *self, const char *fmt, ...)
160*de1e4e89SAndroid Build Coastguard Worker {
161*de1e4e89SAndroid Build Coastguard Worker va_list ap;
162*de1e4e89SAndroid Build Coastguard Worker
163*de1e4e89SAndroid Build Coastguard Worker va_start(ap, fmt);
164*de1e4e89SAndroid Build Coastguard Worker jsonw_eor(self);
165*de1e4e89SAndroid Build Coastguard Worker vfprintf(self->out, fmt, ap);
166*de1e4e89SAndroid Build Coastguard Worker va_end(ap);
167*de1e4e89SAndroid Build Coastguard Worker }
168*de1e4e89SAndroid Build Coastguard Worker
169*de1e4e89SAndroid Build Coastguard Worker /* Collections */
jsonw_start_object(json_writer_t * self)170*de1e4e89SAndroid Build Coastguard Worker void jsonw_start_object(json_writer_t *self)
171*de1e4e89SAndroid Build Coastguard Worker {
172*de1e4e89SAndroid Build Coastguard Worker jsonw_begin(self, '{');
173*de1e4e89SAndroid Build Coastguard Worker }
174*de1e4e89SAndroid Build Coastguard Worker
jsonw_end_object(json_writer_t * self)175*de1e4e89SAndroid Build Coastguard Worker void jsonw_end_object(json_writer_t *self)
176*de1e4e89SAndroid Build Coastguard Worker {
177*de1e4e89SAndroid Build Coastguard Worker jsonw_end(self, '}');
178*de1e4e89SAndroid Build Coastguard Worker }
179*de1e4e89SAndroid Build Coastguard Worker
jsonw_start_array(json_writer_t * self)180*de1e4e89SAndroid Build Coastguard Worker void jsonw_start_array(json_writer_t *self)
181*de1e4e89SAndroid Build Coastguard Worker {
182*de1e4e89SAndroid Build Coastguard Worker jsonw_begin(self, '[');
183*de1e4e89SAndroid Build Coastguard Worker }
184*de1e4e89SAndroid Build Coastguard Worker
jsonw_end_array(json_writer_t * self)185*de1e4e89SAndroid Build Coastguard Worker void jsonw_end_array(json_writer_t *self)
186*de1e4e89SAndroid Build Coastguard Worker {
187*de1e4e89SAndroid Build Coastguard Worker jsonw_end(self, ']');
188*de1e4e89SAndroid Build Coastguard Worker }
189*de1e4e89SAndroid Build Coastguard Worker
190*de1e4e89SAndroid Build Coastguard Worker /* JSON value types */
jsonw_string(json_writer_t * self,const char * value)191*de1e4e89SAndroid Build Coastguard Worker void jsonw_string(json_writer_t *self, const char *value)
192*de1e4e89SAndroid Build Coastguard Worker {
193*de1e4e89SAndroid Build Coastguard Worker jsonw_eor(self);
194*de1e4e89SAndroid Build Coastguard Worker jsonw_puts(self, value);
195*de1e4e89SAndroid Build Coastguard Worker }
196*de1e4e89SAndroid Build Coastguard Worker
jsonw_bool(json_writer_t * self,bool val)197*de1e4e89SAndroid Build Coastguard Worker void jsonw_bool(json_writer_t *self, bool val)
198*de1e4e89SAndroid Build Coastguard Worker {
199*de1e4e89SAndroid Build Coastguard Worker jsonw_printf(self, "%s", val ? "true" : "false");
200*de1e4e89SAndroid Build Coastguard Worker }
201*de1e4e89SAndroid Build Coastguard Worker
jsonw_null(json_writer_t * self)202*de1e4e89SAndroid Build Coastguard Worker void jsonw_null(json_writer_t *self)
203*de1e4e89SAndroid Build Coastguard Worker {
204*de1e4e89SAndroid Build Coastguard Worker jsonw_printf(self, "null");
205*de1e4e89SAndroid Build Coastguard Worker }
206*de1e4e89SAndroid Build Coastguard Worker
jsonw_float_fmt(json_writer_t * self,const char * fmt,double num)207*de1e4e89SAndroid Build Coastguard Worker void jsonw_float_fmt(json_writer_t *self, const char *fmt, double num)
208*de1e4e89SAndroid Build Coastguard Worker {
209*de1e4e89SAndroid Build Coastguard Worker jsonw_printf(self, fmt, num);
210*de1e4e89SAndroid Build Coastguard Worker }
211*de1e4e89SAndroid Build Coastguard Worker
212*de1e4e89SAndroid Build Coastguard Worker #ifdef notused
jsonw_float(json_writer_t * self,double num)213*de1e4e89SAndroid Build Coastguard Worker void jsonw_float(json_writer_t *self, double num)
214*de1e4e89SAndroid Build Coastguard Worker {
215*de1e4e89SAndroid Build Coastguard Worker jsonw_printf(self, "%g", num);
216*de1e4e89SAndroid Build Coastguard Worker }
217*de1e4e89SAndroid Build Coastguard Worker #endif
218*de1e4e89SAndroid Build Coastguard Worker
jsonw_hu(json_writer_t * self,unsigned short num)219*de1e4e89SAndroid Build Coastguard Worker void jsonw_hu(json_writer_t *self, unsigned short num)
220*de1e4e89SAndroid Build Coastguard Worker {
221*de1e4e89SAndroid Build Coastguard Worker jsonw_printf(self, "%hu", num);
222*de1e4e89SAndroid Build Coastguard Worker }
223*de1e4e89SAndroid Build Coastguard Worker
jsonw_uint(json_writer_t * self,uint64_t num)224*de1e4e89SAndroid Build Coastguard Worker void jsonw_uint(json_writer_t *self, uint64_t num)
225*de1e4e89SAndroid Build Coastguard Worker {
226*de1e4e89SAndroid Build Coastguard Worker jsonw_printf(self, "%"PRIu64, num);
227*de1e4e89SAndroid Build Coastguard Worker }
228*de1e4e89SAndroid Build Coastguard Worker
jsonw_lluint(json_writer_t * self,unsigned long long int num)229*de1e4e89SAndroid Build Coastguard Worker void jsonw_lluint(json_writer_t *self, unsigned long long int num)
230*de1e4e89SAndroid Build Coastguard Worker {
231*de1e4e89SAndroid Build Coastguard Worker jsonw_printf(self, "%llu", num);
232*de1e4e89SAndroid Build Coastguard Worker }
233*de1e4e89SAndroid Build Coastguard Worker
jsonw_int(json_writer_t * self,int64_t num)234*de1e4e89SAndroid Build Coastguard Worker void jsonw_int(json_writer_t *self, int64_t num)
235*de1e4e89SAndroid Build Coastguard Worker {
236*de1e4e89SAndroid Build Coastguard Worker jsonw_printf(self, "%"PRId64, num);
237*de1e4e89SAndroid Build Coastguard Worker }
238*de1e4e89SAndroid Build Coastguard Worker
239*de1e4e89SAndroid Build Coastguard Worker /* Basic name/value objects */
jsonw_string_field(json_writer_t * self,const char * prop,const char * val)240*de1e4e89SAndroid Build Coastguard Worker void jsonw_string_field(json_writer_t *self, const char *prop, const char *val)
241*de1e4e89SAndroid Build Coastguard Worker {
242*de1e4e89SAndroid Build Coastguard Worker jsonw_name(self, prop);
243*de1e4e89SAndroid Build Coastguard Worker jsonw_string(self, val);
244*de1e4e89SAndroid Build Coastguard Worker }
245*de1e4e89SAndroid Build Coastguard Worker
jsonw_bool_field(json_writer_t * self,const char * prop,bool val)246*de1e4e89SAndroid Build Coastguard Worker void jsonw_bool_field(json_writer_t *self, const char *prop, bool val)
247*de1e4e89SAndroid Build Coastguard Worker {
248*de1e4e89SAndroid Build Coastguard Worker jsonw_name(self, prop);
249*de1e4e89SAndroid Build Coastguard Worker jsonw_bool(self, val);
250*de1e4e89SAndroid Build Coastguard Worker }
251*de1e4e89SAndroid Build Coastguard Worker
252*de1e4e89SAndroid Build Coastguard Worker #ifdef notused
jsonw_float_field(json_writer_t * self,const char * prop,double val)253*de1e4e89SAndroid Build Coastguard Worker void jsonw_float_field(json_writer_t *self, const char *prop, double val)
254*de1e4e89SAndroid Build Coastguard Worker {
255*de1e4e89SAndroid Build Coastguard Worker jsonw_name(self, prop);
256*de1e4e89SAndroid Build Coastguard Worker jsonw_float(self, val);
257*de1e4e89SAndroid Build Coastguard Worker }
258*de1e4e89SAndroid Build Coastguard Worker #endif
259*de1e4e89SAndroid Build Coastguard Worker
jsonw_float_field_fmt(json_writer_t * self,const char * prop,const char * fmt,double val)260*de1e4e89SAndroid Build Coastguard Worker void jsonw_float_field_fmt(json_writer_t *self,
261*de1e4e89SAndroid Build Coastguard Worker const char *prop,
262*de1e4e89SAndroid Build Coastguard Worker const char *fmt,
263*de1e4e89SAndroid Build Coastguard Worker double val)
264*de1e4e89SAndroid Build Coastguard Worker {
265*de1e4e89SAndroid Build Coastguard Worker jsonw_name(self, prop);
266*de1e4e89SAndroid Build Coastguard Worker jsonw_float_fmt(self, fmt, val);
267*de1e4e89SAndroid Build Coastguard Worker }
268*de1e4e89SAndroid Build Coastguard Worker
jsonw_uint_field(json_writer_t * self,const char * prop,uint64_t num)269*de1e4e89SAndroid Build Coastguard Worker void jsonw_uint_field(json_writer_t *self, const char *prop, uint64_t num)
270*de1e4e89SAndroid Build Coastguard Worker {
271*de1e4e89SAndroid Build Coastguard Worker jsonw_name(self, prop);
272*de1e4e89SAndroid Build Coastguard Worker jsonw_uint(self, num);
273*de1e4e89SAndroid Build Coastguard Worker }
274*de1e4e89SAndroid Build Coastguard Worker
jsonw_hu_field(json_writer_t * self,const char * prop,unsigned short num)275*de1e4e89SAndroid Build Coastguard Worker void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num)
276*de1e4e89SAndroid Build Coastguard Worker {
277*de1e4e89SAndroid Build Coastguard Worker jsonw_name(self, prop);
278*de1e4e89SAndroid Build Coastguard Worker jsonw_hu(self, num);
279*de1e4e89SAndroid Build Coastguard Worker }
280*de1e4e89SAndroid Build Coastguard Worker
jsonw_lluint_field(json_writer_t * self,const char * prop,unsigned long long int num)281*de1e4e89SAndroid Build Coastguard Worker void jsonw_lluint_field(json_writer_t *self,
282*de1e4e89SAndroid Build Coastguard Worker const char *prop,
283*de1e4e89SAndroid Build Coastguard Worker unsigned long long int num)
284*de1e4e89SAndroid Build Coastguard Worker {
285*de1e4e89SAndroid Build Coastguard Worker jsonw_name(self, prop);
286*de1e4e89SAndroid Build Coastguard Worker jsonw_lluint(self, num);
287*de1e4e89SAndroid Build Coastguard Worker }
288*de1e4e89SAndroid Build Coastguard Worker
jsonw_int_field(json_writer_t * self,const char * prop,int64_t num)289*de1e4e89SAndroid Build Coastguard Worker void jsonw_int_field(json_writer_t *self, const char *prop, int64_t num)
290*de1e4e89SAndroid Build Coastguard Worker {
291*de1e4e89SAndroid Build Coastguard Worker jsonw_name(self, prop);
292*de1e4e89SAndroid Build Coastguard Worker jsonw_int(self, num);
293*de1e4e89SAndroid Build Coastguard Worker }
294*de1e4e89SAndroid Build Coastguard Worker
jsonw_null_field(json_writer_t * self,const char * prop)295*de1e4e89SAndroid Build Coastguard Worker void jsonw_null_field(json_writer_t *self, const char *prop)
296*de1e4e89SAndroid Build Coastguard Worker {
297*de1e4e89SAndroid Build Coastguard Worker jsonw_name(self, prop);
298*de1e4e89SAndroid Build Coastguard Worker jsonw_null(self);
299*de1e4e89SAndroid Build Coastguard Worker }
300*de1e4e89SAndroid Build Coastguard Worker
301*de1e4e89SAndroid Build Coastguard Worker #ifdef TEST
main(int argc,char ** argv)302*de1e4e89SAndroid Build Coastguard Worker int main(int argc, char **argv)
303*de1e4e89SAndroid Build Coastguard Worker {
304*de1e4e89SAndroid Build Coastguard Worker json_writer_t *wr = jsonw_new(stdout);
305*de1e4e89SAndroid Build Coastguard Worker
306*de1e4e89SAndroid Build Coastguard Worker jsonw_start_object(wr);
307*de1e4e89SAndroid Build Coastguard Worker jsonw_pretty(wr, true);
308*de1e4e89SAndroid Build Coastguard Worker jsonw_name(wr, "Vyatta");
309*de1e4e89SAndroid Build Coastguard Worker jsonw_start_object(wr);
310*de1e4e89SAndroid Build Coastguard Worker jsonw_string_field(wr, "url", "http://vyatta.com");
311*de1e4e89SAndroid Build Coastguard Worker jsonw_uint_field(wr, "downloads", 2000000ul);
312*de1e4e89SAndroid Build Coastguard Worker jsonw_float_field(wr, "stock", 8.16);
313*de1e4e89SAndroid Build Coastguard Worker
314*de1e4e89SAndroid Build Coastguard Worker jsonw_name(wr, "ARGV");
315*de1e4e89SAndroid Build Coastguard Worker jsonw_start_array(wr);
316*de1e4e89SAndroid Build Coastguard Worker while (--argc)
317*de1e4e89SAndroid Build Coastguard Worker jsonw_string(wr, *++argv);
318*de1e4e89SAndroid Build Coastguard Worker jsonw_end_array(wr);
319*de1e4e89SAndroid Build Coastguard Worker
320*de1e4e89SAndroid Build Coastguard Worker jsonw_name(wr, "empty");
321*de1e4e89SAndroid Build Coastguard Worker jsonw_start_array(wr);
322*de1e4e89SAndroid Build Coastguard Worker jsonw_end_array(wr);
323*de1e4e89SAndroid Build Coastguard Worker
324*de1e4e89SAndroid Build Coastguard Worker jsonw_name(wr, "NIL");
325*de1e4e89SAndroid Build Coastguard Worker jsonw_start_object(wr);
326*de1e4e89SAndroid Build Coastguard Worker jsonw_end_object(wr);
327*de1e4e89SAndroid Build Coastguard Worker
328*de1e4e89SAndroid Build Coastguard Worker jsonw_null_field(wr, "my_null");
329*de1e4e89SAndroid Build Coastguard Worker
330*de1e4e89SAndroid Build Coastguard Worker jsonw_name(wr, "special chars");
331*de1e4e89SAndroid Build Coastguard Worker jsonw_start_array(wr);
332*de1e4e89SAndroid Build Coastguard Worker jsonw_string_field(wr, "slash", "/");
333*de1e4e89SAndroid Build Coastguard Worker jsonw_string_field(wr, "newline", "\n");
334*de1e4e89SAndroid Build Coastguard Worker jsonw_string_field(wr, "tab", "\t");
335*de1e4e89SAndroid Build Coastguard Worker jsonw_string_field(wr, "ff", "\f");
336*de1e4e89SAndroid Build Coastguard Worker jsonw_string_field(wr, "quote", "\"");
337*de1e4e89SAndroid Build Coastguard Worker jsonw_string_field(wr, "tick", "\'");
338*de1e4e89SAndroid Build Coastguard Worker jsonw_string_field(wr, "backslash", "\\");
339*de1e4e89SAndroid Build Coastguard Worker jsonw_end_array(wr);
340*de1e4e89SAndroid Build Coastguard Worker
341*de1e4e89SAndroid Build Coastguard Worker jsonw_end_object(wr);
342*de1e4e89SAndroid Build Coastguard Worker
343*de1e4e89SAndroid Build Coastguard Worker jsonw_end_object(wr);
344*de1e4e89SAndroid Build Coastguard Worker jsonw_destroy(&wr);
345*de1e4e89SAndroid Build Coastguard Worker return 0;
346*de1e4e89SAndroid Build Coastguard Worker }
347*de1e4e89SAndroid Build Coastguard Worker
348*de1e4e89SAndroid Build Coastguard Worker #endif
349