Rizin
unix-like reverse engineering framework and cli tools
pj.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2018-2019 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_util.h>
5 #include <rz_util/rz_print.h>
6 
7 RZ_API void pj_raw(PJ *j, const char *msg) {
9  if (*msg) {
10  rz_strbuf_append(&j->sb, msg);
11  }
12 }
13 
14 static void pj_comma(PJ *j) {
16  if (!j->is_key) {
17  if (!j->is_first) {
18  pj_raw(j, ",");
19  }
20  }
21  j->is_first = false;
22  j->is_key = false;
23 }
24 
25 RZ_API PJ *pj_new(void) {
26  PJ *j = RZ_NEW0(PJ);
27  if (j) {
28  rz_strbuf_init(&j->sb);
29  j->is_first = true;
30  }
31  return j;
32 }
33 
34 RZ_API void pj_free(PJ *pj) {
35  if (!pj) {
36  return;
37  }
38  rz_strbuf_fini(&pj->sb);
39  free(pj);
40 }
41 
42 RZ_API void pj_reset(PJ *j) {
44  rz_strbuf_set(&j->sb, "");
45  j->level = 0;
46  j->is_first = true;
47  j->is_key = false;
48 }
49 
50 RZ_API char *pj_drain(PJ *pj) {
51  rz_return_val_if_fail(pj && pj->level == 0, NULL);
52  char *res = rz_strbuf_drain_nofree(&pj->sb);
53  free(pj);
54  return res;
55 }
56 
57 RZ_API const char *pj_string(PJ *j) {
58  return j ? rz_strbuf_get(&j->sb) : NULL;
59 }
60 
61 static PJ *pj_begin(PJ *j, char type) {
62  if (j) {
63  if (!j || j->level >= RZ_PRINT_JSON_DEPTH_LIMIT) {
64  return NULL;
65  }
66  char msg[2] = { type, 0 };
67  pj_raw(j, msg);
68  j->braces[j->level] = (type == '{') ? '}' : ']';
69  j->level++;
70  j->is_first = true;
71  }
72  return j;
73 }
74 
75 RZ_API PJ *pj_o(PJ *j) {
77  pj_comma(j);
78  return pj_begin(j, '{');
79 }
80 
81 RZ_API PJ *pj_a(PJ *j) {
83  pj_comma(j);
84  return pj_begin(j, '[');
85 }
86 
89  if (j->level < 1) {
90  return j;
91  }
92  if (--j->level < 1) {
93  char msg[2] = { j->braces[j->level], 0 };
94  pj_raw(j, msg);
95  j->level = 0;
96  return j;
97  }
98  j->is_first = false;
99  char msg[2] = { j->braces[j->level], 0 };
100  pj_raw(j, msg);
101  return j;
102 }
103 
104 RZ_API PJ *pj_k(PJ *j, const char *k) {
105  rz_return_val_if_fail(j && k, j);
106  j->is_key = false;
107  pj_s(j, k);
108  pj_raw(j, ":");
109  j->is_first = false;
110  j->is_key = true;
111  return j;
112 }
113 
114 RZ_API PJ *pj_knull(PJ *j, const char *k) {
115  rz_return_val_if_fail(j && k, j);
116  pj_k(j, k);
117  pj_null(j);
118  return j;
119 }
120 
121 RZ_API PJ *pj_kn(PJ *j, const char *k, ut64 n) {
122  rz_return_val_if_fail(j && k, j);
123  pj_k(j, k);
124  pj_n(j, n);
125  return j;
126 }
127 
128 RZ_API PJ *pj_kN(PJ *j, const char *k, st64 n) {
129  if (j && k) {
130  pj_k(j, k);
131  pj_N(j, n);
132  }
133  return j;
134 }
135 
136 RZ_API PJ *pj_kd(PJ *j, const char *k, double d) {
137  rz_return_val_if_fail(j && k, j);
138  pj_k(j, k);
139  pj_d(j, d);
140  return j;
141 }
142 
143 RZ_API PJ *pj_kf(PJ *j, const char *k, float d) {
144  rz_return_val_if_fail(j && k, j);
145  pj_k(j, k);
146  pj_f(j, d);
147  return j;
148 }
149 RZ_API PJ *pj_ki(PJ *j, const char *k, int i) {
150  rz_return_val_if_fail(j && k, j);
151  pj_k(j, k);
152  pj_i(j, i);
153  return j;
154 }
155 
156 RZ_API PJ *pj_ko(PJ *j, const char *k) {
157  rz_return_val_if_fail(j && k, j);
158  pj_k(j, k);
159  pj_o(j);
160  return j;
161 }
162 
163 RZ_API PJ *pj_ka(PJ *j, const char *k) {
164  rz_return_val_if_fail(j && k, j);
165  pj_k(j, k);
166  pj_a(j);
167  return j;
168 }
169 
170 RZ_API PJ *pj_ks(PJ *j, const char *k, const char *v) {
171  rz_return_val_if_fail(j && k && v, j);
172  pj_k(j, k);
173  pj_s(j, v);
174  return j;
175 }
176 
177 RZ_API PJ *pj_kb(PJ *j, const char *k, bool v) {
178  rz_return_val_if_fail(j && k, j);
179  pj_k(j, k);
180  pj_b(j, v);
181  return j;
182 }
183 
185  rz_return_val_if_fail(j, j);
186  pj_raw(j, "null");
187  return j;
188 }
189 
190 RZ_API PJ *pj_b(PJ *j, bool v) {
191  rz_return_val_if_fail(j, j);
192  pj_comma(j);
193  pj_raw(j, rz_str_bool(v));
194  return j;
195 }
196 
197 RZ_API PJ *pj_s(PJ *j, const char *k) {
198  rz_return_val_if_fail(j && k, j);
199  pj_comma(j);
200  pj_raw(j, "\"");
201  char *ek = rz_str_escape_utf8_for_json(k, -1);
202  if (ek) {
203  pj_raw(j, ek);
204  free(ek);
205  } else {
206  eprintf("cannot escape string\n");
207  }
208  pj_raw(j, "\"");
209  return j;
210 }
211 
212 RZ_API PJ *pj_S(PJ *j, const char *k) {
213  rz_return_val_if_fail(j && k, j);
214  pj_comma(j);
215  char *ek = rz_str_escape_utf8_for_json(k, -1);
216  if (ek) {
217  pj_raw(j, ek);
218  free(ek);
219  } else {
220  eprintf("cannot escape string\n");
221  }
222  return j;
223 }
224 
225 RZ_API PJ *pj_r(PJ *j, const ut8 *v, size_t v_len) {
226  rz_return_val_if_fail(j && v, j);
227  size_t i;
228  pj_a(j);
229  for (i = 0; i < v_len; i++) {
230  pj_i(j, v[i]);
231  }
232  pj_end(j);
233  return j;
234 }
235 
236 RZ_API PJ *pj_kr(PJ *j, const char *k, const ut8 *v, size_t v_len) {
237  rz_return_val_if_fail(j && k && v, j);
238  pj_k(j, k);
239  pj_r(j, v, v_len);
240  return j;
241 }
242 
243 RZ_API PJ *pj_j(PJ *j, const char *k) {
244  rz_return_val_if_fail(j && k, j);
245  if (*k) {
246  pj_comma(j);
247  pj_raw(j, k);
248  }
249  return j;
250 }
251 
253  rz_return_val_if_fail(j, j);
254  pj_comma(j);
255  char s[64] = { 0 };
256  pj_raw(j, rz_strf(s, "%" PFMT64u, n));
257  return j;
258 }
259 
262  pj_comma(j);
263  char s[64] = { 0 };
264  pj_raw(j, rz_strf(s, "%" PFMT64d, n));
265  return j;
266 }
267 
268 RZ_API PJ *pj_f(PJ *j, float f) {
270  pj_comma(j);
271  char s[64] = { 0 };
272  pj_raw(j, rz_strf(s, "%f", f));
273  return j;
274 }
275 
276 RZ_API PJ *pj_d(PJ *j, double d) {
278  pj_comma(j);
279  char s[64] = { 0 };
280  pj_raw(j, rz_strf(s, "%lf", d));
281  return j;
282 }
283 
284 RZ_API PJ *pj_i(PJ *j, int i) {
285  if (j) {
286  pj_comma(j);
287  char s[64] = { 0 };
288  pj_raw(j, rz_strf(s, "%d", i));
289  }
290  return j;
291 }
lzma_index ** i
Definition: index.h:629
#define RZ_API
#define NULL
Definition: cris-opc.c:27
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
uint8_t ut8
Definition: lh5801.h:11
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
static void pj_comma(PJ *j)
Definition: pj.c:14
RZ_API PJ * pj_S(PJ *j, const char *k)
Definition: pj.c:212
RZ_API PJ * pj_j(PJ *j, const char *k)
Definition: pj.c:243
RZ_API void pj_free(PJ *pj)
Definition: pj.c:34
RZ_API PJ * pj_i(PJ *j, int i)
Definition: pj.c:284
RZ_API PJ * pj_ko(PJ *j, const char *k)
Definition: pj.c:156
RZ_API const char * pj_string(PJ *j)
Definition: pj.c:57
RZ_API PJ * pj_ka(PJ *j, const char *k)
Definition: pj.c:163
static PJ * pj_begin(PJ *j, char type)
Definition: pj.c:61
RZ_API PJ * pj_r(PJ *j, const ut8 *v, size_t v_len)
Definition: pj.c:225
RZ_API PJ * pj_new(void)
Definition: pj.c:25
RZ_API PJ * pj_kb(PJ *j, const char *k, bool v)
Definition: pj.c:177
RZ_API PJ * pj_b(PJ *j, bool v)
Definition: pj.c:190
RZ_API PJ * pj_ki(PJ *j, const char *k, int i)
Definition: pj.c:149
RZ_API PJ * pj_f(PJ *j, float f)
Definition: pj.c:268
RZ_API PJ * pj_k(PJ *j, const char *k)
Definition: pj.c:104
RZ_API PJ * pj_end(PJ *j)
Definition: pj.c:87
RZ_API PJ * pj_knull(PJ *j, const char *k)
Definition: pj.c:114
RZ_API char * pj_drain(PJ *pj)
Definition: pj.c:50
RZ_API PJ * pj_o(PJ *j)
Definition: pj.c:75
RZ_API PJ * pj_d(PJ *j, double d)
Definition: pj.c:276
RZ_API PJ * pj_null(PJ *j)
Definition: pj.c:184
RZ_API PJ * pj_kf(PJ *j, const char *k, float d)
Definition: pj.c:143
RZ_API PJ * pj_s(PJ *j, const char *k)
Definition: pj.c:197
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
Definition: pj.c:170
RZ_API PJ * pj_n(PJ *j, ut64 n)
Definition: pj.c:252
RZ_API PJ * pj_N(PJ *j, st64 n)
Definition: pj.c:260
RZ_API PJ * pj_kr(PJ *j, const char *k, const ut8 *v, size_t v_len)
Definition: pj.c:236
RZ_API PJ * pj_kn(PJ *j, const char *k, ut64 n)
Definition: pj.c:121
RZ_API PJ * pj_kd(PJ *j, const char *k, double d)
Definition: pj.c:136
RZ_API PJ * pj_a(PJ *j)
Definition: pj.c:81
RZ_API void pj_reset(PJ *j)
Definition: pj.c:42
RZ_API PJ * pj_kN(PJ *j, const char *k, st64 n)
Definition: pj.c:128
RZ_API void pj_raw(PJ *j, const char *msg)
Definition: pj.c:7
#define eprintf(x, y...)
Definition: rlcc.c:7
static RzSocket * s
Definition: rtr.c:28
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define RZ_PRINT_JSON_DEPTH_LIMIT
Definition: rz_pj.h:4
RZ_API const char * rz_str_bool(int b)
Definition: str.c:3896
RZ_API char * rz_str_escape_utf8_for_json(const char *s, int len)
Definition: str.c:1834
#define rz_strf(buf,...)
Convenience macro for local temporary strings.
Definition: rz_str.h:59
RZ_API RZ_OWN char * rz_strbuf_drain_nofree(RzStrBuf *sb)
Definition: strbuf.c:349
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API void rz_strbuf_fini(RzStrBuf *sb)
Definition: strbuf.c:365
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
#define PFMT64d
Definition: rz_types.h:394
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define PFMT64u
Definition: rz_types.h:395
#define st64
Definition: rz_types_base.h:10
static struct sockaddr static addrlen static backlog const void msg
Definition: sfsocketcall.h:119
#define d(i)
Definition: sha256.c:44
#define f(i)
Definition: sha256.c:46
Definition: rz_pj.h:12
char braces[RZ_PRINT_JSON_DEPTH_LIMIT]
Definition: rz_pj.h:16
bool is_first
Definition: rz_pj.h:14
int level
Definition: rz_pj.h:17
bool is_key
Definition: rz_pj.h:15
RzStrBuf sb
Definition: rz_pj.h:13
ut64(WINAPI *w32_GetEnabledXStateFeatures)()