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