]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - lib/jsonwrt.c
2 * JSON output formatting functions.
4 * No copyright is claimed. This code is in the public domain; do with
7 * Written by Karel Zak <kzak@redhat.com>
18 * Requirements enumerated via testing (V8, Firefox, IE11):
20 * var charsToEscape = [];
21 * for (var i = 0; i < 65535; i += 1) {
23 * JSON.parse('{"sample": "' + String.fromCodePoint(i) + '"}');
25 * charsToEscape.push(i);
29 static void fputs_quoted_case_json(const char *data
, FILE *out
, int dir
)
34 for (p
= data
; p
&& *p
; p
++) {
36 const unsigned int c
= (unsigned int) *p
;
38 /* From http://www.json.org
40 * The double-quote and backslashes would break out a string or
41 * init an escape sequence if not escaped.
43 * Note that single-quotes and forward slashes, while they're
44 * in the JSON spec, don't break double-quoted strings.
46 if (c
== '"' || c
== '\\') {
52 /* All non-control characters OK; do the case swap as required. */
55 * Don't use locale sensitive ctype.h functions for regular
56 * ASCII chars, because for example with Turkish locale
57 * (aka LANG=tr_TR.UTF-8) toupper('I') returns 'I'.
60 fputc(dir
== 1 ? c_toupper(c
) :
61 dir
== -1 ? c_tolower(c
) : *p
, out
);
63 fputc(dir
== 1 ? toupper(c
) :
64 dir
== -1 ? tolower(c
) : *p
, out
);
68 /* In addition, all chars under ' ' break Node's/V8/Chrome's, and
69 * Firefox's JSON.parse function
72 /* Handle short-hand cases to reduce output size. C
73 * has most of the same stuff here, so if there's an
74 * "Escape for C" function somewhere in the STL, we
75 * should probably be using it.
93 /* Other assorted control characters */
94 fprintf(out
, "\\u00%02x", c
);
101 #define fputs_quoted_json(_d, _o) fputs_quoted_case_json(_d, _o, 0)
102 #define fputs_quoted_json_upper(_d, _o) fputs_quoted_case_json(_d, _o, 1)
103 #define fputs_quoted_json_lower(_d, _o) fputs_quoted_case_json(_d, _o, -1)
105 void ul_jsonwrt_init(struct ul_jsonwrt
*fmt
, FILE *out
, int indent
)
108 fmt
->indent
= indent
;
109 fmt
->after_close
= 0;
112 int ul_jsonwrt_is_ready(struct ul_jsonwrt
*fmt
)
114 return fmt
->out
== NULL
? 0 : 1;
117 void ul_jsonwrt_indent(struct ul_jsonwrt
*fmt
)
121 for (i
= 0; i
< fmt
->indent
; i
++)
122 fputs(" ", fmt
->out
);
125 void ul_jsonwrt_open(struct ul_jsonwrt
*fmt
, const char *name
, int type
)
128 if (fmt
->after_close
)
129 fputs(",\n", fmt
->out
);
130 ul_jsonwrt_indent(fmt
);
131 fputs_quoted_json_lower(name
, fmt
->out
);
133 if (fmt
->after_close
)
134 fputs(",", fmt
->out
);
136 ul_jsonwrt_indent(fmt
);
141 fputs(name
? ": {\n" : "{\n", fmt
->out
);
145 fputs(name
? ": [\n" : "[\n", fmt
->out
);
149 fputs(name
? ": " : " ", fmt
->out
);
152 fmt
->after_close
= 0;
155 void ul_jsonwrt_close(struct ul_jsonwrt
*fmt
, int type
)
157 if (fmt
->indent
== 1) {
158 fputs("\n}\n", fmt
->out
);
160 fmt
->after_close
= 1;
163 assert(fmt
->indent
> 0);
168 fputc('\n', fmt
->out
);
169 ul_jsonwrt_indent(fmt
);
170 fputs("}", fmt
->out
);
174 fputc('\n', fmt
->out
);
175 ul_jsonwrt_indent(fmt
);
176 fputs("]", fmt
->out
);
182 fmt
->after_close
= 1;
185 void ul_jsonwrt_value_raw(struct ul_jsonwrt
*fmt
,
186 const char *name
, const char *data
)
188 ul_jsonwrt_value_open(fmt
, name
);
190 fputs(data
, fmt
->out
);
192 fputs("null", fmt
->out
);
193 ul_jsonwrt_value_close(fmt
);
196 void ul_jsonwrt_value_s(struct ul_jsonwrt
*fmt
,
197 const char *name
, const char *data
)
199 ul_jsonwrt_value_open(fmt
, name
);
201 fputs_quoted_json(data
, fmt
->out
);
203 fputs("null", fmt
->out
);
204 ul_jsonwrt_value_close(fmt
);
207 void ul_jsonwrt_value_u64(struct ul_jsonwrt
*fmt
,
208 const char *name
, uint64_t data
)
210 ul_jsonwrt_value_open(fmt
, name
);
211 fprintf(fmt
->out
, "%"PRIu64
, data
);
212 ul_jsonwrt_value_close(fmt
);
215 void ul_jsonwrt_value_boolean(struct ul_jsonwrt
*fmt
,
216 const char *name
, int data
)
218 ul_jsonwrt_value_open(fmt
, name
);
219 fputs(data
? "true" : "false", fmt
->out
);
220 ul_jsonwrt_value_close(fmt
);
223 void ul_jsonwrt_value_null(struct ul_jsonwrt
*fmt
,
226 ul_jsonwrt_value_open(fmt
, name
);
227 fputs("null", fmt
->out
);
228 ul_jsonwrt_value_close(fmt
);