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