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