1 /* radare - Apache - Copyright 2014,2015 dso, pancake */
2
3 #include "dsojson.h"
4 #include "class.h"
5 #include <r_types.h>
6 #include <r_util.h>
7 #include <stdint.h>
8
9 char * dso_json_dict_entry_to_str (DsoJsonDictEntry * entry);
10 char * dso_json_list_to_str (DsoJsonList *list);
11 char * dso_json_dict_to_str (DsoJsonDict *list);
12 char * dso_json_num_to_str (DsoJsonNum * num);
13 char * dso_json_str_to_str (DsoJsonStr *str);
14
15 static int cmpDsoStr_to_str (DsoJsonStr *dsoStr1, char *dsoStr2);
16 static const DsoJsonInfo* get_type_info (unsigned int type);
17 static char * dso_json_get_str_data (DsoJsonObj *dso_obj);
18 static DsoJsonStr * dso_json_get_str (DsoJsonObj *dso_obj);
19
20 static DsoJsonInfo DSO_JSON_INFOS []= {
21 {DSO_JSON_NULL},
22 {DSO_JSON_NUM},//, dso_json_num_new, dso_json_free_num, dso_json_insert, dso_json_append, NULL, NULL, NULL, NULL},
23 {DSO_JSON_STR},//, dso_json_str_new, dso_json_str_new, dso_json_insert, dso_json_append, NULL, NULL, NULL, NULL},
24 {DSO_JSON_LIST},//, dso_json_list_new, dso_json_list_free, dso_json_insert, dso_json_list_append, NULL, NULL, NULL, NULL},
25 {DSO_JSON_DICT},//, dso_json_dict_new, dso_json_free_dict, dso_json_insert_dict, dso_json_append, NULL, NULL, NULL, NULL},
26 {DSO_JSON_DICT_ENTRY},//, dso_json_dict_entry_new, dso_json_dict_entry_free, dso_json_insert, dso_json_append, NULL, NULL, NULL, NULL},
27 {DSO_JSON_END},//, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
28 };
29
build_str_list_from_iterable(RList * the_list)30 static RList * build_str_list_from_iterable (RList *the_list) {
31 RList * res = r_list_newf (free);
32 DsoJsonObj *json_obj;
33 RListIter *iter;
34 r_list_foreach (the_list, iter, json_obj) {
35 char *str = dso_json_obj_to_str (json_obj);
36 if (str && *str) {
37 r_list_append (res, str);
38 } else {
39 free (str);
40 }
41 }
42 return res;
43 }
44
build_str_from_str_list_for_iterable(RList * the_list,int is_array)45 static char * build_str_from_str_list_for_iterable (RList *the_list, int is_array) {
46 char *res = NULL, *str;
47 int len = 3, pos = 1;
48 RListIter *iter = NULL;
49 RList *str_list = build_str_list_from_iterable (the_list);
50
51 r_list_foreach (str_list, iter, str) {
52 len += strlen (str) + 1;
53 }
54
55 res = calloc (len, 1);
56 // TODO: use [ if needed
57 if (res) {
58 strcpy (res, is_array? "[": "{");
59 r_list_foreach (str_list, iter, str) {
60 pos += snprintf (res+pos, len - pos, "%s%s",
61 str, iter->n? ",": "");
62 }
63 strcat (res, is_array?"]": "}");
64 }
65 r_list_free (str_list);
66 return res;
67 }
68
get_type(DsoJsonObj * y)69 static int get_type (DsoJsonObj *y) {
70 return (y && y->info)? y->info->type: -1;
71 }
72
dso_json_is_null(DsoJsonObj * y)73 static int dso_json_is_null (DsoJsonObj *y) {
74 return get_type (y) == DSO_JSON_NULL;
75 }
76
dso_json_is_list(DsoJsonObj * y)77 static int dso_json_is_list (DsoJsonObj *y) {
78 return get_type (y) == DSO_JSON_LIST;
79 }
80
dso_json_is_dict_entry(DsoJsonObj * y)81 static int dso_json_is_dict_entry (DsoJsonObj *y) {
82 return get_type (y) == DSO_JSON_DICT_ENTRY;
83 }
84
dso_json_char_needs_hexing(ut8 b)85 ut8 dso_json_char_needs_hexing ( ut8 b) {
86 if (b < 0x20) {
87 return 1;
88 }
89 switch (b) {
90 case 0x7f:
91 case 0x81:
92 case 0x8F:
93 case 0x90:
94 case 0x9D:
95 case 0xA0:
96 case 0xAD:
97 return 1;
98 }
99 return 0;
100 }
101
dso_json_obj_to_str(DsoJsonObj * dso_obj)102 char * dso_json_obj_to_str (DsoJsonObj * dso_obj) {
103 if (dso_obj && dso_obj->info) {
104 switch (dso_obj->info->type) {
105 case DSO_JSON_NULL: return strdup ("null");
106 case DSO_JSON_NUM: return dso_json_num_to_str (dso_obj->val._num);
107 case DSO_JSON_STR: return dso_json_str_to_str (dso_obj->val._str);
108 case DSO_JSON_LIST: return dso_json_list_to_str (dso_obj->val._list);
109 case DSO_JSON_DICT: return dso_json_dict_to_str (dso_obj->val._dict);
110 case DSO_JSON_DICT_ENTRY: return dso_json_dict_entry_to_str (dso_obj->val._dict_entry);
111 }
112 }
113 return NULL;
114 }
115
dso_json_obj_del(DsoJsonObj * dso_obj)116 void dso_json_obj_del (DsoJsonObj *dso_obj) {
117 if (!dso_obj) return;
118 switch (dso_obj->info->type) {
119 case DSO_JSON_NULL: /*do nothing */ break;
120 case DSO_JSON_NUM: dso_json_num_free (dso_obj->val._num); break;
121 case DSO_JSON_STR: dso_json_str_free (dso_obj->val._str); break;
122 case DSO_JSON_LIST: dso_json_list_free (dso_obj); break; //->val._list); break;
123 case DSO_JSON_DICT: dso_json_dict_free (dso_obj->val._dict); break;
124 case DSO_JSON_DICT_ENTRY: dso_json_dict_entry_free (dso_obj->val._dict_entry); break;
125 default: break;
126 }
127 #if 0
128 //memset (dso_obj, 0, sizeof (DsoJsonObj));
129 free (dso_obj);
130 #endif
131 }
132
get_type_info(unsigned int type)133 static const DsoJsonInfo* get_type_info (unsigned int type) {
134 unsigned int i = 0;
135 for (; DSO_JSON_INFOS[i].type != DSO_JSON_END; i++) {
136 if (DSO_JSON_INFOS[i].type == type) return &DSO_JSON_INFOS[i];
137 }
138 return NULL;
139 }
140
cmpDsoStr_to_str(DsoJsonStr * dsoStr1,char * dsoStr2)141 static int cmpDsoStr_to_str (DsoJsonStr *dsoStr1, char *dsoStr2) {
142 if (dsoStr1 && dsoStr1->data && dsoStr2)
143 return strcmp (dsoStr1->data, dsoStr2);
144 return -1;
145 }
146
allocDsoStr(DsoJsonStr * dsoStr,unsigned int sz)147 static void allocDsoStr (DsoJsonStr *dsoStr, unsigned int sz) {
148 free (dsoStr->data);
149 if (sz > 0) dsoStr->data = calloc (sz, 1);
150 else dsoStr->data = calloc (10, 1);
151 dsoStr->len = sz;
152 }
153
dso_json_get_list(DsoJsonObj * dso_obj)154 static RList * dso_json_get_list (DsoJsonObj *dso_obj) {
155 RList *the_list = NULL;
156 if (dso_obj) {
157 switch (dso_obj->info->type) {
158 case DSO_JSON_LIST: the_list = dso_obj->val._list->json_list; break;
159 case DSO_JSON_DICT: the_list = dso_obj->val._dict->json_dict; break;
160 default: break;
161 }
162 }
163 return the_list;
164 }
165
dso_json_get_str_data(DsoJsonObj * dso_obj)166 static char * dso_json_get_str_data (DsoJsonObj *dso_obj) {
167 DsoJsonStr * str = dso_json_get_str (dso_obj);
168 if (str) return str->data;
169 return NULL;
170 }
171
dso_json_get_str(DsoJsonObj * dso_obj)172 static DsoJsonStr * dso_json_get_str (DsoJsonObj *dso_obj) {
173 DsoJsonStr * str = NULL;
174 if (dso_obj) {
175 switch (dso_obj->info->type) {
176 case DSO_JSON_STR: str = dso_obj->val._str; break;
177 case DSO_JSON_DICT_ENTRY: str = dso_json_get_str (dso_obj->val._dict_entry->key); break;
178 default: break;
179 }
180 }
181 return str;
182 }
183
dso_json_null_new()184 DsoJsonObj * dso_json_null_new () {
185 DsoJsonObj *x = calloc (sizeof (DsoJsonObj), 1);
186 if (!x) return NULL;
187 x->info = get_type_info (DSO_JSON_NULL);
188 return x;
189 }
190
dso_json_null_free(void * x)191 void dso_json_null_free (void *x) {
192 free (x);
193 }
194
dso_json_str_new()195 DsoJsonObj * dso_json_str_new () {
196 DsoJsonObj *x = dso_json_null_new ();
197 if (!x) return NULL;
198 x->info = get_type_info (DSO_JSON_STR);
199 x->val._str = calloc (sizeof (DsoJsonStr), 1);
200 return x;
201 }
202
dso_json_str_free(void * y)203 void dso_json_str_free (void *y) {
204 DsoJsonStr *x = (DsoJsonStr *)y;
205 if (x) {
206 R_FREE (x->data);
207 free (x);
208 }
209 }
210
dso_json_dict_entry_new()211 DsoJsonObj * dso_json_dict_entry_new () {
212 DsoJsonObj *x = dso_json_null_new ();
213 if (!x) return NULL;
214 x->info = get_type_info (DSO_JSON_DICT_ENTRY);
215 x->val._dict_entry = calloc (sizeof (DsoJsonDictEntry), 1);
216 if (!x->val._dict_entry) {
217 dso_json_null_free (x);
218 return NULL;
219 }
220 x->val._dict_entry->key = dso_json_str_new ();
221 x->val._dict_entry->value = dso_json_null_new ();
222 return x;
223 }
224
dso_json_dict_entry_new_from_key_obj_val_obj(DsoJsonObj * key,DsoJsonObj * value)225 DsoJsonObj * dso_json_dict_entry_new_from_key_obj_val_obj (DsoJsonObj *key, DsoJsonObj *value) {
226 DsoJsonObj *x = dso_json_dict_entry_new ();
227 if (!x) return NULL;
228 dso_json_obj_del (x->val._dict_entry->key);
229 dso_json_obj_del (x->val._dict_entry->value);
230 x->val._dict_entry->key = key;
231 x->val._dict_entry->value = value;
232 return x;
233
234 }
dso_json_dict_entry_free(void * y)235 void dso_json_dict_entry_free (void *y) {
236 DsoJsonDictEntry *entry = (DsoJsonDictEntry *)y;
237 if (entry) {
238 dso_json_obj_del (entry->key);
239 dso_json_obj_del (entry->value);
240 entry->key = NULL;
241 entry->value = NULL;
242 }
243 free (entry);
244 }
245
dso_json_dict_entry_to_str(DsoJsonDictEntry * entry)246 char * dso_json_dict_entry_to_str (DsoJsonDictEntry * entry) {
247 char *res = NULL;
248 if (entry) {
249 char *key = dso_json_obj_to_str (entry->key);
250 char *value = dso_json_obj_to_str (entry->value);
251 if (key) {
252 int len = 2 + 3 + strlen (key);
253 if (value) len += strlen (value);
254 res = calloc (len, 1);
255 if (res) {
256 if (value) {
257 snprintf (res, len, "%s:%s", key, value);
258 } else {
259 snprintf (res, len, "%s:\"\"", key);
260 }
261 }
262 free (key);
263 }
264 free (value);
265 }
266 return res;
267 }
268
dso_json_dict_entry_set_key_str(DsoJsonObj * entry_obj,char * key)269 int dso_json_dict_entry_set_key_str (DsoJsonObj * entry_obj, char *key) {
270 int res = false;
271 if (dso_json_is_dict_entry (entry_obj)) {
272 DsoJsonDictEntry *entry = (DsoJsonDictEntry *)entry_obj;
273 DsoJsonObj *o_key = dso_json_str_new_from_str (key);
274 if (entry->key) {
275 dso_json_obj_del (entry->key);
276 }
277 entry->key = o_key;
278 res = true;
279 }
280 return res;
281 }
282
dso_json_dict_entry_set_key_str_len(DsoJsonObj * entry_obj,char * key,unsigned int len)283 int dso_json_dict_entry_set_key_str_len (DsoJsonObj * entry_obj, char *key, unsigned int len) {
284 int res = false;
285 if (dso_json_is_dict_entry (entry_obj)) {
286 DsoJsonDictEntry *entry = (DsoJsonDictEntry *)entry_obj;
287 DsoJsonObj *o_key = dso_json_str_new_from_str_len (key, len);
288 if (entry->key) {
289 dso_json_obj_del (entry->key);
290 }
291 entry->key = o_key;
292 res = true;
293 }
294 return res;
295 }
296
dso_json_dict_entry_set_key_num(DsoJsonObj * entry_obj,st64 num)297 int dso_json_dict_entry_set_key_num (DsoJsonObj * entry_obj, st64 num) {
298 int res = false;
299 if (dso_json_is_dict_entry (entry_obj)) {
300 DsoJsonDictEntry *entry = (DsoJsonDictEntry *)entry_obj;
301 DsoJsonObj *o_key = dso_json_num_new_from_num (num);
302 if (entry->key) {
303 dso_json_obj_del (entry->key);
304 }
305 entry->key = o_key;
306 res = true;
307 }
308 return res;
309 }
310
dso_json_dict_entry_value_append_str(DsoJsonObj * entry_obj,char * str)311 int dso_json_dict_entry_value_append_str (DsoJsonObj *entry_obj, char *str) {
312 int res = false;
313 if (dso_json_is_dict_entry (entry_obj)) {
314 DsoJsonObj *o_str = dso_json_str_new_from_str (str);
315 res = dso_json_dict_entry_value_append_obj (entry_obj, o_str);
316 if (!res) dso_json_obj_del (o_str);
317 }
318 return res;
319 }
320
dso_json_dict_entry_value_append_str_len(DsoJsonObj * entry_obj,char * str,unsigned int len)321 int dso_json_dict_entry_value_append_str_len (DsoJsonObj *entry_obj, char *str, unsigned int len) {
322 int res = false;
323 if (dso_json_is_dict_entry (entry_obj)) {
324 DsoJsonObj *o_str = dso_json_str_new_from_str_len (str, len);
325 res = dso_json_dict_entry_value_append_obj (entry_obj, o_str);
326 if (!res) dso_json_obj_del (o_str);
327 }
328 return res;
329 }
330
dso_json_dict_entry_value_append_num(DsoJsonObj * entry_obj,st64 num)331 int dso_json_dict_entry_value_append_num (DsoJsonObj *entry_obj, st64 num) {
332 int res = false;
333 if (dso_json_is_dict_entry (entry_obj)) {
334 DsoJsonObj *o_num = dso_json_num_new_from_num (num);
335 res = dso_json_dict_entry_value_append_obj (entry_obj, o_num);
336 if (!res) dso_json_obj_del (o_num);
337 }
338 return res;
339 }
340
dso_json_dict_entry_value_append_obj(DsoJsonObj * entry_obj,DsoJsonObj * obj)341 int dso_json_dict_entry_value_append_obj (DsoJsonObj *entry_obj, DsoJsonObj *obj) {
342 if (dso_json_is_dict_entry (entry_obj)) {
343 DsoJsonDictEntry *x = entry_obj->val._dict_entry;
344
345 // check to see if the object can be converted to a list
346 if (dso_json_is_null (x->value)) {
347 DsoJsonObj *new_list = dso_json_list_new ();
348 dso_json_obj_del (x->value);
349 x->value = new_list;
350 } else if (!dso_json_is_list (x->value)) {
351 DsoJsonObj *tmp = x->value;
352 x->value = dso_json_list_new ();
353 dso_json_list_append (x->value, tmp);
354 }
355
356 if (dso_json_is_list (x->value)) {
357 dso_json_list_append (x->value, obj);
358 return true;
359 }
360 }
361 return false;
362 }
363
dso_json_dict_entry_value_set_str(DsoJsonObj * entry_obj,char * str)364 int dso_json_dict_entry_value_set_str (DsoJsonObj *entry_obj, char *str) {
365 int res = false;
366 if (dso_json_is_dict_entry (entry_obj)) {
367 DsoJsonObj *o_val = dso_json_str_new_from_str (str);
368 res = dso_json_dict_entry_value_set_obj (entry_obj, o_val);
369 }
370 return res;
371 }
372
dso_json_dict_entry_value_set_str_len(DsoJsonObj * entry_obj,char * str,unsigned int len)373 int dso_json_dict_entry_value_set_str_len (DsoJsonObj *entry_obj, char *str, unsigned int len) {
374 int res = false;
375 if (dso_json_is_dict_entry (entry_obj)) {
376 DsoJsonObj *o_val = dso_json_str_new_from_str_len (str, len);
377 res = dso_json_dict_entry_value_set_obj (entry_obj, o_val);
378 }
379 return res;
380 }
381
dso_json_dict_entry_value_set_num(DsoJsonObj * entry_obj,st64 num)382 int dso_json_dict_entry_value_set_num (DsoJsonObj *entry_obj, st64 num) {
383 int res = false;
384 if (dso_json_is_dict_entry (entry_obj)) {
385 DsoJsonObj *o_val = dso_json_num_new_from_num (num);
386 res = dso_json_dict_entry_value_set_obj (entry_obj, o_val);
387 }
388 return res;
389 }
390
dso_json_dict_entry_value_set_empty_dict(DsoJsonObj * entry_obj)391 int dso_json_dict_entry_value_set_empty_dict (DsoJsonObj *entry_obj) {
392 int res = false;
393 if (dso_json_is_dict_entry (entry_obj)) {
394 DsoJsonObj *o_val = dso_json_dict_new ();
395 res = dso_json_dict_entry_value_set_obj (entry_obj, o_val);
396 }
397 return res;
398 }
399
dso_json_dict_entry_value_set_empty_list(DsoJsonObj * entry_obj)400 int dso_json_dict_entry_value_set_empty_list (DsoJsonObj *entry_obj) {
401 int res = false;
402 if (dso_json_is_dict_entry (entry_obj)) {
403 DsoJsonObj *o_val = dso_json_list_new ();
404 res = dso_json_dict_entry_value_set_obj (entry_obj, o_val);
405 }
406 return res;
407 }
408
dso_json_dict_entry_value_set_obj(DsoJsonObj * entry_obj,DsoJsonObj * obj)409 int dso_json_dict_entry_value_set_obj (DsoJsonObj *entry_obj, DsoJsonObj *obj) {
410 if (dso_json_is_dict_entry (entry_obj)) {
411 DsoJsonDictEntry *entry = entry_obj->val._dict_entry;
412 if (entry->value) dso_json_obj_del (entry->value);
413 entry->value = obj;
414 return true;
415 }
416 return false;
417 }
418
dso_json_list_new()419 DsoJsonObj * dso_json_list_new () {
420 DsoJsonObj *x = dso_json_null_new ();
421 if (x) {
422 x->info = get_type_info (DSO_JSON_LIST);
423 x->val._list = calloc (sizeof (DsoJsonList), 1);
424 if (x->val._list) {
425 x->val._list->json_list = r_list_newf ((RListFree)dso_json_obj_del);
426 } else {
427 R_FREE (x);
428 }
429 }
430 return x;
431 }
432
dso_json_list_free(DsoJsonObj * x)433 void dso_json_list_free (DsoJsonObj *x) {
434 if (!x) return;
435 if (x->val._list && x->val._list->json_list) {
436 r_list_free (x->val._list->json_list);
437 x->val._list->json_list = NULL;
438 }
439 }
440
dso_json_list_to_str(DsoJsonList * list)441 char * dso_json_list_to_str (DsoJsonList *list) {
442 if (list && list->json_list) {
443 return build_str_from_str_list_for_iterable (list->json_list, 1);
444 }
445 return strdup ("[]");
446 }
447
dso_json_list_append(DsoJsonObj * list_obj,DsoJsonObj * y)448 int dso_json_list_append (DsoJsonObj *list_obj, DsoJsonObj *y) {
449 if (get_type (list_obj) == DSO_JSON_LIST) {
450 DsoJsonList * list = list_obj->val._list;
451 r_list_append (list->json_list, y);
452 return true;
453 }
454 return false;
455 }
456
dso_json_list_append_str(DsoJsonObj * list_obj,char * y)457 int dso_json_list_append_str (DsoJsonObj *list_obj, char *y) {
458 if (get_type (list_obj) == DSO_JSON_LIST) {
459 DsoJsonObj *val = dso_json_str_new_from_str (y);
460 int res = dso_json_list_append (list_obj, val);
461 if (!res) dso_json_obj_del (val);
462 return res;
463 }
464 return false;
465 }
466
dso_json_list_append_num(DsoJsonObj * list_obj,ut64 y)467 int dso_json_list_append_num (DsoJsonObj *list_obj, ut64 y) {
468 if (get_type (list_obj) == DSO_JSON_LIST) {
469 DsoJsonObj *val = dso_json_num_new_from_num (y);
470 int res = dso_json_list_append (list_obj, val);
471 if (!res) dso_json_obj_del (val);
472 return res;
473 }
474 return false;
475 }
476
dso_json_dict_new()477 DsoJsonObj * dso_json_dict_new () {
478 DsoJsonObj *x = dso_json_null_new ();
479 if (x) {
480 x->info = get_type_info (DSO_JSON_DICT);
481 x->val._dict = calloc (sizeof (DsoJsonDict), 1);
482 if (!x->val._dict) {
483 dso_json_null_free (x);
484 return NULL;
485 }
486 x->val._dict->json_dict = r_list_newf ((RListFree)dso_json_obj_del);
487 }
488 return x;
489 }
490
dso_json_dict_free(void * y)491 void dso_json_dict_free (void *y) {
492 DsoJsonDict *x = (DsoJsonDict *)y;
493 if (x && x->json_dict) {
494 r_list_free (x->json_dict);
495 x->json_dict = NULL;
496 }
497 free (x);
498 }
499
dso_json_dict_to_str(DsoJsonDict * dict)500 char * dso_json_dict_to_str (DsoJsonDict *dict) {
501 if (dict && dict->json_dict) {
502 return build_str_from_str_list_for_iterable (dict->json_dict, 0);
503 }
504 return strdup ("{}");
505 }
506
dso_json_dict_insert_str_key_obj(DsoJsonObj * dict,char * key,DsoJsonObj * val_obj)507 int dso_json_dict_insert_str_key_obj(DsoJsonObj *dict, char *key, DsoJsonObj *val_obj) {
508 DsoJsonObj *key_obj = dso_json_str_new_from_str (key);
509 int res = dso_json_dict_insert_key_obj (dict, key_obj, val_obj);
510 if (!res) {
511 dso_json_obj_del (key_obj);
512 }
513 return res;
514 }
515
dso_json_dict_insert_str_key_num(DsoJsonObj * dict,char * key,int val)516 int dso_json_dict_insert_str_key_num(DsoJsonObj *dict, char *key, int val) {
517 DsoJsonObj *key_obj = dso_json_str_new_from_str (key);
518 DsoJsonObj *val_obj = dso_json_num_new_from_num (val);
519 int res = dso_json_dict_insert_key_obj (dict, key_obj, val_obj);
520 if (!res) {
521 dso_json_obj_del (key_obj);
522 }
523 return res;
524 }
525
dso_json_dict_insert_str_key_str(DsoJsonObj * dict,char * key,char * val)526 int dso_json_dict_insert_str_key_str (DsoJsonObj *dict, char *key, char *val) {
527 DsoJsonObj *key_obj = dso_json_str_new_from_str (key),
528 *val_obj = dso_json_str_new_from_str (val);
529 int res = dso_json_dict_insert_key_obj (dict, key_obj, val_obj);
530 if (!res) {
531 dso_json_obj_del (key_obj);
532 }
533 return res;
534 }
535
536 // create keys from num value
dso_json_dict_insert_num_key_obj(DsoJsonObj * dict,int key,DsoJsonObj * val_obj)537 int dso_json_dict_insert_num_key_obj (DsoJsonObj *dict, int key, DsoJsonObj *val_obj) {
538 DsoJsonObj *key_obj = dso_json_str_new_from_num (key);
539 int res = dso_json_dict_insert_key_obj (dict, key_obj, val_obj);
540 if (!res) {
541 dso_json_obj_del (key_obj);
542 }
543 return res;
544 }
545
546
dso_json_dict_insert_num_key_num(DsoJsonObj * dict,int key,int val)547 int dso_json_dict_insert_num_key_num (DsoJsonObj *dict, int key, int val) {
548 DsoJsonObj *key_obj = dso_json_str_new_from_num (key),
549 *val_obj = dso_json_num_new_from_num (val);
550 int res = dso_json_dict_insert_key_obj (dict, key_obj, val_obj);
551 if (!res) {
552 dso_json_obj_del (key_obj);
553 }
554 return res;
555 }
556
dso_json_dict_insert_num_key_str(DsoJsonObj * dict,int key,char * val)557 int dso_json_dict_insert_num_key_str (DsoJsonObj *dict, int key, char *val) {
558 DsoJsonObj *key_obj = dso_json_str_new_from_num (key),
559 *val_obj = dso_json_str_new_from_str (val);
560 int res = dso_json_dict_insert_key_obj (dict, key_obj, val_obj);
561 if (!res) {
562 dso_json_obj_del (key_obj);
563 }
564 return res;
565 }
566
567 // TODO inserting the dicts.
dso_json_dict_insert_key_obj(DsoJsonObj * dict,DsoJsonObj * key,DsoJsonObj * value)568 int dso_json_dict_insert_key_obj (DsoJsonObj *dict, DsoJsonObj *key, DsoJsonObj *value) {
569 int res = false;
570 RList* the_list = dso_json_get_list (dict);
571 if (!the_list) return false;
572 if (get_type (key) != DSO_JSON_STR) return false;
573 if (!value) value = dso_json_null_new ();
574 if (value && key && !dso_json_dict_contains_key_obj (dict, key)) {
575 DsoJsonObj *entry = dso_json_dict_entry_new_from_key_obj_val_obj (key, value);
576 r_list_append (the_list, entry);
577 res = true;
578 //TODO implement the remove key
579 } else if (value && key && !dso_json_dict_remove_key_obj (dict, key)) {
580 DsoJsonObj *entry = dso_json_dict_entry_new_from_key_obj_val_obj (key, value);
581 r_list_append (the_list, entry);
582 res = true;
583 } else {
584 dso_json_obj_del (value);
585 dso_json_dict_free (value);
586 }
587 return res;
588 }
589
dso_json_dict_remove_key_obj(DsoJsonObj * dict,DsoJsonObj * key)590 int dso_json_dict_remove_key_obj (DsoJsonObj *dict, DsoJsonObj *key) {
591 return dso_json_dict_remove_key_str (dict, dso_json_get_str_data (key));
592 }
593
dso_json_dict_remove_key_str(DsoJsonObj * dict,char * key)594 int dso_json_dict_remove_key_str (DsoJsonObj *dict, char *key) {
595 RListIter *iter;
596 DsoJsonObj *dso_obj;
597 int res = false;
598 RList* the_list = dso_json_get_list (dict);
599 if (the_list) {
600 r_list_foreach (the_list, iter, dso_obj) {
601 if (get_type (dso_obj) == DSO_JSON_DICT_ENTRY &&
602 get_type (dso_obj->val._dict_entry->key) == DSO_JSON_STR) {
603 if (!cmpDsoStr_to_str (dso_json_get_str (dso_obj), key)) {
604 res = true;
605 r_list_delete (the_list, iter);
606 break;
607 }
608 }
609 }
610 }
611 return res;
612 }
613
dso_json_dict_contains_key_obj(DsoJsonObj * dict,DsoJsonObj * key)614 int dso_json_dict_contains_key_obj (DsoJsonObj *dict, DsoJsonObj *key) {
615 return dso_json_dict_contains_key_str (dict, dso_json_get_str_data (key));
616 }
617
dso_json_dict_contains_key_str(DsoJsonObj * dict,char * key)618 int dso_json_dict_contains_key_str (DsoJsonObj *dict, char *key) {
619 RListIter *iter;
620 DsoJsonObj *dso_obj;
621 RList* the_list = dso_json_get_list (dict);
622 if (the_list) {
623 r_list_foreach (the_list, iter, dso_obj) {
624 if (get_type (dso_obj) == DSO_JSON_DICT_ENTRY &&
625 get_type (dso_obj->val._dict_entry->key) == DSO_JSON_STR) {
626 if (!cmpDsoStr_to_str (dso_json_get_str (dso_obj), key)) {
627 return true;
628 }
629 }
630 }
631 }
632 return false;
633 }
634
635 // TODO append value to key 1) check that key is valid, 2) if not create new entry and append it
636
dso_json_num_new()637 DsoJsonObj * dso_json_num_new () {
638 DsoJsonObj *x = dso_json_null_new ();
639 if (!x) return NULL;
640 x->info = get_type_info (DSO_JSON_NUM);
641 x->val._num = calloc (sizeof (DsoJsonNum), 1);
642 return x;
643 }
644
dso_json_num_free(void * y)645 void dso_json_num_free (void *y) {
646 DsoJsonNum *x = (DsoJsonNum *)y;
647 free (x);
648 }
649
dso_json_num_to_str(DsoJsonNum * num)650 char * dso_json_num_to_str (DsoJsonNum * num) {
651 return r_str_newf ("%"PFMT64d, num->value);
652 }
653
dso_json_num_new_from_num(ut64 num)654 DsoJsonObj * dso_json_num_new_from_num (ut64 num) {
655 DsoJsonObj *x = dso_json_num_new ();
656 if (x) x->val._num->value = num;
657 return x;
658 }
659
dso_json_convert_string(const char * bytes,ut32 len)660 char * dso_json_convert_string (const char * bytes, ut32 len) {
661 ut32 idx = 0, pos = 1;
662 ut32 str_sz = 4*len+1+2;
663 char *cpy_buffer = len > 0 ? calloc (1, str_sz): NULL;
664 if (!cpy_buffer) return cpy_buffer;
665 // 4x is the increase from byte to \xHH where HH represents hexed byte
666 cpy_buffer[0] = '"';
667 while (idx < len) {
668 if (bytes[idx] == '"') {
669 sprintf (cpy_buffer+pos, "\\%c", bytes[idx]);
670 pos += 2;
671 } else if (dso_json_char_needs_hexing (bytes[idx])) {
672 sprintf (cpy_buffer+pos, "\\x%02x", bytes[idx]);
673 pos += 4;
674 } else {
675 cpy_buffer[pos] = bytes[idx];
676 pos++;
677 }
678 idx ++;
679 }
680 strcat (cpy_buffer, "\"");
681 return cpy_buffer;
682 }
683
dso_json_str_to_str(DsoJsonStr * str)684 char * dso_json_str_to_str (DsoJsonStr *str) {
685 if (str && str->data && str->len> 0) {
686 return dso_json_convert_string (str->data, str->len);
687 }
688 return NULL;
689 }
690
dso_json_str_new_from_str(const char * str)691 DsoJsonObj * dso_json_str_new_from_str (const char *str) {
692 DsoJsonObj *x = dso_json_str_new ();
693 if (!x) return NULL;
694 DsoJsonStr * dsoStr = x->val._str;
695 allocDsoStr (dsoStr, strlen (str));
696 if (dsoStr->data) memcpy (dsoStr->data, str, dsoStr->len);
697 return x;
698 }
699
dso_json_str_new_from_str_len(const char * str,unsigned int len)700 DsoJsonObj * dso_json_str_new_from_str_len (const char *str, unsigned int len) {
701 DsoJsonObj *x = dso_json_str_new ();
702 if (!x) return NULL;
703 DsoJsonStr * dsoStr = x->val._str;
704 allocDsoStr (dsoStr, len);
705 memcpy (dsoStr->data, str, dsoStr->len);
706 return x;
707 }
708
dso_json_str_new_from_num(long num)709 DsoJsonObj * dso_json_str_new_from_num (long num) {
710 DsoJsonObj *x = dso_json_str_new ();
711 if (!x) return NULL;
712 DsoJsonStr * dsoStr = x->val._str;
713 int len = snprintf (NULL, 0, "%lu", num);
714 allocDsoStr (dsoStr, len-1);
715 snprintf (dsoStr->data, dsoStr->len, "%lu", num);
716 return x;
717 }
718