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