1 /* radare - LGPL - Copyright 2020 - gogo, pancake */
2 
3 #include <r_util.h>
4 
5 #define USE_RUNES 0
6 
r_charset_new(void)7 R_API RCharset *r_charset_new(void) {
8 	RCharset* c = R_NEW0 (RCharset);
9 	if (!c) {
10 		return NULL;
11 	}
12 	c->db = NULL; // must be set after calling new by the caller
13 	return c;
14 }
15 
r_charset_free(RCharset * c)16 R_API void r_charset_free(RCharset *c) {
17 	sdb_free (c->db);
18 	free (c);
19 }
20 
r_charset_open(RCharset * c,const char * cs)21 R_API bool r_charset_open(RCharset *c, const char *cs) {
22 	r_return_val_if_fail (c && cs, false);
23 	sdb_reset (c->db);
24 	sdb_open (c->db, cs);
25 	sdb_reset (c->db_char_to_hex);
26 	sdb_open (c->db_char_to_hex, cs);
27 
28 	c->db_char_to_hex = sdb_new0 ();
29 
30 	SdbListIter *iter;
31 	SdbKv *kv;
32 	SdbList *sdbls = sdb_foreach_list (c->db, true);
33 
34 	ls_foreach (sdbls, iter, kv) {
35 		const char *new_key = kv->base.value;
36 		const char *new_value = kv->base.key;
37 		sdb_add (c->db_char_to_hex, new_key, new_value, 0);
38 	}
39 	ls_free (sdbls);
40 
41 	return true;
42 }
43 
44 // rune
r_charset_rune_new(const ut8 * ch,const ut8 * hx)45 R_API RCharsetRune *r_charset_rune_new(const ut8 *ch, const ut8 *hx) {
46 	RCharsetRune* c = R_NEW0 (RCharsetRune);
47 	if (!c) {
48 		return NULL;
49 	}
50 	c->ch = (ut8 *) strdup ((char *) ch);
51 	c->hx = (ut8 *) strdup ((char *) hx);
52 	c->left = NULL;
53 	c->right = NULL;
54 	return c;
55 }
56 
r_charset_rune_free(RCharsetRune * c)57 R_API void r_charset_rune_free(RCharsetRune *c) {
58 	free (c->ch);
59 	free (c->hx);
60 	free (c);
61 }
62 
add_rune(RCharsetRune * r,const ut8 * ch,const ut8 * hx)63 R_API RCharsetRune *add_rune(RCharsetRune *r, const ut8 *ch, const ut8 *hx) {
64 	if (!r) {
65 		r = r_charset_rune_new (ch, hx);
66 	}
67 	int cmp = strcmp ((char *)hx, (char *)r->hx);
68 	if (cmp < 0) {
69 		r->left = add_rune (r->left, ch, hx);
70 	} else if (cmp > 0) {
71 		r->right = add_rune (r->right, ch, hx);
72 	} else {
73 		int cmp = strcmp ((char *)ch, (char *)r->ch);
74 		if (cmp > 0) {
75 			r->left = add_rune (r->left, ch, hx);
76 		} else if (cmp < 0) {
77 			r->right = add_rune (r->right, ch, hx);
78 		}
79 	}
80 	return r;
81 }
82 
search_from_hex(RCharsetRune * r,const ut8 * hx)83 R_API RCharsetRune *search_from_hex(RCharsetRune *r, const ut8 *hx) {
84 	if (!r) {
85 		return NULL;
86 	}
87 	if (!strcmp ((char *)r->hx, (char *)hx)) {
88 		return r;
89 	}
90 	RCharsetRune *left = search_from_hex (r->left, hx);
91 	return left? left: search_from_hex (r->right, hx);
92 }
93 
94 // assumes out is as big as in_len
r_charset_encode_str(RCharset * rc,ut8 * out,size_t out_len,const ut8 * in,size_t in_len)95 R_API size_t r_charset_encode_str(RCharset *rc, ut8 *out, size_t out_len, const ut8 *in, size_t in_len) {
96 	char k[32];
97 	char *o = (char*)out;
98 	int i;
99 	for (i = 0; i < in_len; i++) {
100 		ut8 ch_in = in[i];
101 
102 		snprintf (k, sizeof (k), "0x%02x", ch_in);
103 		const char *v = sdb_const_get (rc->db, k, 0);
104 		const char *ret = r_str_get_fail (v, "?");
105 
106 		strcpy (o, ret);
107 
108 		o += strlen (o);
109 	}
110 
111 	return o - (char*)out;
112 }
113 
114 // assumes out is as big as in_len
r_charset_decode_str(RCharset * rc,ut8 * out,size_t out_len,const ut8 * in,size_t in_len)115 R_API size_t r_charset_decode_str(RCharset *rc, ut8 *out, size_t out_len, const ut8 *in, size_t in_len) {
116 	char k[32];
117 	char *o = (char*)out;
118 	int i;
119 	for (i = 0; i < in_len; i++) {
120 		ut8 ch_in = in[i];
121 
122 		//zero terminate the string
123 		snprintf (k, sizeof (k), "%c", ch_in);//snprintf (k, sizeof (k), "0x%02x", ch_in);
124 		char *v = sdb_get (rc->db_char_to_hex, k, 0);
125 		memmove(v, v+2, strlen (v));
126 
127 		//convert to ascii
128 		char str_hx[32];
129 		snprintf (str_hx, sizeof (str_hx), "%c", (char) strtol( v, 0, 16));
130 		const char *ret = r_str_get_fail (str_hx, "?");
131 		strcpy (o, ret);
132 
133 		o += strlen (o);
134 	}
135 	return o - (char*)out;
136 }
137