1 /* radare - LGPL - Copyright 2018-2019 - pancake */
2 
3 #include <r_util.h>
4 #include <r_util/r_print.h>
5 
pj_raw(PJ * j,const char * msg)6 R_API void pj_raw(PJ *j, const char *msg) {
7 	r_return_if_fail (j && msg);
8 	if (*msg) {
9 		r_strbuf_append (&j->sb, msg);
10 	}
11 }
12 
pj_comma(PJ * j)13 static void pj_comma(PJ *j) {
14 	r_return_if_fail (j);
15 	if (!j->is_key) {
16 		if (!j->is_first) {
17 			pj_raw (j, ",");
18 		}
19 	}
20 	j->is_first = false;
21 	j->is_key = false;
22 }
23 
pj_new(void)24 R_API PJ *pj_new(void) {
25 	PJ *j = R_NEW0 (PJ);
26 	if (j) {
27 		r_strbuf_init (&j->sb);
28 		j->is_first = true;
29 		j->str_encoding = PJ_ENCODING_STR_DEFAULT;
30 		j->num_encoding = PJ_ENCODING_NUM_DEFAULT;
31 	}
32 	return j;
33 }
34 
pj_new_with_encoding(PJEncodingStr str_encoding,PJEncodingNum num_encoding)35 R_API PJ *pj_new_with_encoding(PJEncodingStr str_encoding, PJEncodingNum num_encoding) {
36 	PJ *j = pj_new ();
37 	if (j) {
38 		j->str_encoding = str_encoding;
39 		j->num_encoding = num_encoding;
40 	}
41 	return j;
42 }
43 
pj_free(PJ * pj)44 R_API void pj_free(PJ *pj) {
45 	if (pj) {
46 		r_strbuf_fini (&pj->sb);
47 		free (pj);
48 	}
49 }
50 
pj_reset(PJ * j)51 R_API void pj_reset(PJ *j) {
52 	r_return_if_fail (j);
53 	r_strbuf_set (&j->sb, "");
54 	j->level = 0;
55 	j->is_first = true;
56 	j->is_key = false;
57 }
58 
pj_drain(PJ * pj)59 R_API char *pj_drain(PJ *pj) {
60 	r_return_val_if_fail (pj && pj->level == 0, NULL);
61 	char *res = r_strbuf_drain_nofree (&pj->sb);
62 	free (pj);
63 	return res;
64 }
65 
pj_string(PJ * j)66 R_API const char *pj_string(PJ *j) {
67 	return j? r_strbuf_get (&j->sb): NULL;
68 }
69 
pj_begin(PJ * j,char type)70 static PJ *pj_begin(PJ *j, char type) {
71 	if (j) {
72 		if (!j || j->level >= R_PRINT_JSON_DEPTH_LIMIT) {
73 			return NULL;
74 		}
75 		char msg[2] = { type, 0 };
76 		pj_raw (j, msg);
77 		j->braces[j->level] = (type == '{') ? '}' : ']';
78 		j->level++;
79 		j->is_first = true;
80 	}
81 	return j;
82 }
83 
pj_o(PJ * j)84 R_API PJ *pj_o(PJ *j) {
85 	r_return_val_if_fail (j, j);
86 	pj_comma (j);
87 	return pj_begin (j, '{');
88 }
89 
pj_a(PJ * j)90 R_API PJ *pj_a(PJ *j) {
91 	r_return_val_if_fail (j, j);
92 	pj_comma (j);
93 	return pj_begin (j, '[');
94 }
95 
pj_end(PJ * j)96 R_API PJ *pj_end(PJ *j) {
97 	r_return_val_if_fail (j, j);
98 	if (j->level < 1) {
99 		return j;
100 	}
101 	if (--j->level < 1) {
102 		char msg[2] = { j->braces[j->level], 0 };
103 		pj_raw (j, msg);
104 		j->level = 0;
105 		return j;
106 	}
107 	j->is_first = false;
108 	char msg[2] = { j->braces[j->level], 0 };
109 	pj_raw (j, msg);
110 	return j;
111 }
112 
pj_k(PJ * j,const char * k)113 R_API PJ *pj_k(PJ *j, const char *k) {
114 	r_return_val_if_fail (j && k, j);
115 	j->is_key = false;
116 	pj_s (j, k);
117 	pj_raw (j, ":");
118 	j->is_first = false;
119 	j->is_key = true;
120 	return j;
121 }
122 
pj_knull(PJ * j,const char * k)123 R_API PJ *pj_knull(PJ *j, const char *k) {
124 	r_return_val_if_fail (j && k, j);
125 	pj_k (j, k);
126 	pj_null (j);
127 	return j;
128 }
129 
pj_kn(PJ * j,const char * k,ut64 n)130 R_API PJ *pj_kn(PJ *j, const char *k, ut64 n) {
131 	r_return_val_if_fail (j && k, j);
132 	pj_k (j, k);
133 	if (j->num_encoding != PJ_ENCODING_NUM_DEFAULT) {
134 		pj_ne (j, n);
135 	} else {
136 		pj_n (j, n);
137 	}
138 	return j;
139 }
140 
pj_kN(PJ * j,const char * k,st64 n)141 R_API PJ *pj_kN(PJ *j, const char *k, st64 n) {
142 	if (j && k) {
143 		pj_k (j, k);
144 		pj_N (j, n);
145 	}
146 	return j;
147 }
148 
pj_kd(PJ * j,const char * k,double d)149 R_API PJ *pj_kd(PJ *j, const char *k, double d) {
150 	r_return_val_if_fail (j && k, j);
151 	pj_k (j, k);
152 	pj_d (j, d);
153 	return j;
154 }
155 
pj_kf(PJ * j,const char * k,float d)156 R_API PJ *pj_kf(PJ *j, const char *k, float d) {
157 	r_return_val_if_fail (j && k, j);
158 	pj_k (j, k);
159 	pj_f (j, d);
160 	return j;
161 }
pj_ki(PJ * j,const char * k,int i)162 R_API PJ *pj_ki(PJ *j, const char *k, int i) {
163 	r_return_val_if_fail (j && k, j);
164 	pj_k (j, k);
165 	pj_i (j, i);
166 	return j;
167 }
168 
pj_ko(PJ * j,const char * k)169 R_API PJ *pj_ko(PJ *j, const char *k) {
170 	r_return_val_if_fail (j && k, j);
171 	pj_k (j, k);
172 	pj_o (j);
173 	return j;
174 }
175 
pj_ka(PJ * j,const char * k)176 R_API PJ *pj_ka(PJ *j, const char *k) {
177 	r_return_val_if_fail (j && k, j);
178 	pj_k (j, k);
179 	pj_a (j);
180 	return j;
181 }
182 
pj_ks(PJ * j,const char * k,const char * v)183 R_API PJ *pj_ks(PJ *j, const char *k, const char *v) {
184 	r_return_val_if_fail (j && k && v, j);
185 	pj_k (j, k);
186 	if (j->str_encoding != PJ_ENCODING_STR_DEFAULT) {
187 		pj_se (j, v);
188 	} else {
189 		pj_s (j, v);
190 	}
191 	return j;
192 }
193 
pj_kb(PJ * j,const char * k,bool v)194 R_API PJ *pj_kb(PJ *j, const char *k, bool v) {
195 	r_return_val_if_fail (j && k, j);
196 	pj_k (j, k);
197 	pj_b (j, v);
198 	return j;
199 }
200 
pj_null(PJ * j)201 R_API PJ *pj_null(PJ *j) {
202 	r_return_val_if_fail (j, j);
203 	pj_comma (j);
204 	pj_raw (j, "null");
205 	return j;
206 }
207 
pj_b(PJ * j,bool v)208 R_API PJ *pj_b(PJ *j, bool v) {
209 	r_return_val_if_fail (j, j);
210 	pj_comma (j);
211 	pj_raw (j, r_str_bool (v));
212 	return j;
213 }
214 
pj_s(PJ * j,const char * k)215 R_API PJ *pj_s(PJ *j, const char *k) {
216 	r_return_val_if_fail (j && k, j);
217 	pj_comma (j);
218 	pj_raw (j, "\"");
219 	char *ek = r_str_escape_utf8_for_json (k, -1);
220 	if (ek) {
221 		pj_raw (j, ek);
222 		free (ek);
223 	} else {
224 		eprintf ("cannot escape string\n");
225 	}
226 	pj_raw (j, "\"");
227 	return j;
228 }
229 
pj_se(PJ * j,const char * k)230 R_API PJ *pj_se(PJ *j, const char *k) {
231 	r_return_val_if_fail (j && k, j);
232 	pj_comma (j);
233 	if (j->str_encoding == PJ_ENCODING_STR_ARRAY) {
234 		pj_raw (j, "[");
235 	} else {
236 		pj_raw (j, "\"");
237 	}
238 	char *en = r_str_encoded_json (k, -1, j->str_encoding);
239 	if (en) {
240 		pj_raw (j, en);
241 		free (en);
242 	}
243 	if (j->str_encoding == PJ_ENCODING_STR_ARRAY) {
244 		pj_raw (j, "]");
245 	} else {
246 		pj_raw (j, "\"");
247 	}
248 	return j;
249 }
250 
pj_r(PJ * j,const unsigned char * v,size_t v_len)251 R_API PJ *pj_r(PJ *j, const unsigned char *v, size_t v_len) {
252 	r_return_val_if_fail (j && v, j);
253 	size_t i;
254 	pj_a (j);
255 	for (i = 0; i < v_len; i++) {
256 		pj_i (j, v[i]);
257 	}
258 	pj_end (j);
259 	return j;
260 }
261 
pj_kr(PJ * j,const char * k,const unsigned char * v,size_t v_len)262 R_API PJ *pj_kr(PJ *j, const char *k, const unsigned char *v, size_t v_len) {
263 	r_return_val_if_fail (j && k && v, j);
264 	pj_k (j, k);
265 	pj_r (j, v, v_len);
266 	return j;
267 }
268 
pj_j(PJ * j,const char * k)269 R_API PJ *pj_j(PJ *j, const char *k) {
270 	r_return_val_if_fail (j && k, j);
271 	if (*k) {
272 		pj_comma (j);
273 		pj_raw (j, k);
274 	}
275 	return j;
276 }
277 
pj_n(PJ * j,ut64 n)278 R_API PJ *pj_n(PJ *j, ut64 n) {
279 	r_return_val_if_fail (j, j);
280 	pj_comma (j);
281 	pj_raw (j, sdb_fmt ("%" PFMT64u, n));
282 	return j;
283 }
284 
pj_ne(PJ * j,ut64 n)285 R_API PJ *pj_ne(PJ *j, ut64 n) {
286 	r_return_val_if_fail (j, j);
287 	pj_comma (j);
288 	if (j->num_encoding == PJ_ENCODING_NUM_STR) {
289 		pj_raw (j, sdb_fmt ("\"%" PFMT64u "\"", n));
290 	} else if (j->num_encoding == PJ_ENCODING_NUM_HEX) {
291 		pj_raw (j, sdb_fmt ("\"0x%" PFMT64x "\"", n));
292 	} else {
293 		pj_n(j, n);
294 	}
295 	return j;
296 }
297 
pj_N(PJ * j,st64 n)298 R_API PJ *pj_N(PJ *j, st64 n) {
299 	r_return_val_if_fail (j, NULL);
300 	pj_comma (j);
301 	pj_raw (j, sdb_fmt ("%"PFMT64d, n));
302 	return j;
303 }
304 
pj_f(PJ * j,float f)305 R_API PJ *pj_f(PJ *j, float f) {
306 	r_return_val_if_fail (j, NULL);
307 	pj_comma (j);
308 	pj_raw (j, sdb_fmt ("%f", f));
309 	return j;
310 }
311 
pj_d(PJ * j,double d)312 R_API PJ *pj_d(PJ *j, double d) {
313 	r_return_val_if_fail (j, NULL);
314 	pj_comma (j);
315 	pj_raw (j, sdb_fmt ("%lf", d));
316 	return j;
317 }
318 
pj_i(PJ * j,int i)319 R_API PJ *pj_i(PJ *j, int i) {
320 	if (j) {
321 		pj_comma (j);
322 		pj_raw (j, sdb_fmt ("%d", i));
323 	}
324 	return j;
325 }
326