xref: /aosp_15_r20/external/iproute2/lib/json_writer.c (revision de1e4e894b0c224df933550f0afdecc354b238c4)
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