1 /* radare - LGPL - Copyright 2012-2020 - pancake */
2
3 #include <r_util.h>
4
r_strpool_new(int sz)5 R_API RStrpool* r_strpool_new(int sz) {
6 RStrpool *p = R_NEW (RStrpool);
7 if (!p) {
8 eprintf ("Malloc failed!\n");
9 return NULL;
10 }
11 if (sz < 1) {
12 sz = 1024;
13 }
14 p->str = malloc (sz);
15 if (!p->str) {
16 eprintf ("Malloc failed!\n");
17 free (p);
18 return NULL;
19 }
20 p->size = sz;
21 p->len = 0;
22 p->str[0] = 0;
23 return p;
24 }
25
r_strpool_empty(RStrpool * p)26 R_API char *r_strpool_empty(RStrpool *p) {
27 p->len = 0;
28 p->str[0] = 0;
29 p->str[1] = 0;
30 return p->str;
31 }
32
r_strpool_alloc(RStrpool * p,int l)33 R_API char *r_strpool_alloc(RStrpool *p, int l) {
34 char *ret = p->str + p->len;
35 if ((p->len + l) >= p->size) {
36 ut64 osize = p->size;
37 if (l >= R_STRPOOL_INC) {
38 p->size += l + R_STRPOOL_INC;
39 } else {
40 p->size += R_STRPOOL_INC;
41 }
42 if (p->size < osize) {
43 eprintf ("Underflow!\n");
44 p->size = osize;
45 return NULL;
46 }
47 ret = realloc (p->str, p->size);
48 if (!ret) {
49 eprintf ("Realloc failed!\n");
50 free (p->str);
51 p->str = NULL;
52 return NULL;
53 }
54 p->str = ret;
55 ret += p->len;
56 }
57 p->len += l;
58 return ret;
59 }
60
r_strpool_memcat(RStrpool * p,const char * s,int len)61 R_API int r_strpool_memcat(RStrpool *p, const char *s, int len) {
62 char *ptr = r_strpool_alloc (p, len);
63 if (!ptr) {
64 return -1;
65 }
66 memcpy (ptr, s, len);
67 return (size_t)(ptr - p->str);
68 }
69
r_strpool_append(RStrpool * p,const char * s)70 R_API int r_strpool_append(RStrpool *p, const char *s) {
71 int l = strlen (s) + 1;
72 return r_strpool_memcat (p, s, l);
73 }
74
r_strpool_ansi_chop(RStrpool * p,int n)75 R_API int r_strpool_ansi_chop(RStrpool *p, int n){
76 /* p->str need not be a c-string */
77 int i = r_str_ansi_trim (p->str, p->len, n);
78 p->len = i;
79 return i;
80 }
81
r_strpool_free(RStrpool * p)82 R_API void r_strpool_free(RStrpool *p) {
83 free (p->str);
84 free (p);
85 }
86
r_strpool_fit(RStrpool * p)87 R_API int r_strpool_fit(RStrpool *p) {
88 char *s;
89 if (p->len == p->size) {
90 return false;
91 }
92 s = realloc (p->str, p->len);
93 if (!s)
94 {
95 eprintf ("Realloc failed!\n");
96 free (p->str);
97 return false;
98 }
99 p->str = s;
100 p->size = p->len;
101 return true;
102 }
103
r_strpool_get(RStrpool * p,int index)104 R_API char *r_strpool_get(RStrpool *p, int index) {
105 if (!p || !p->str || index < 0 || index >= p->len) {
106 return NULL;
107 }
108 return p->str + index;
109 }
110
r_strpool_get_i(RStrpool * p,int index)111 R_API char *r_strpool_get_i(RStrpool *p, int index) {
112 int i, n = 0;
113 if (index < 0 || index >= p->len) {
114 return NULL;
115 }
116 for (i = 0; i < index; i++) {
117 char *s = r_strpool_next (p, n);
118 n = r_strpool_get_index (p, s);
119 }
120 return p->str + n;
121 }
122
r_strpool_get_index(RStrpool * p,const char * s)123 R_API int r_strpool_get_index(RStrpool *p, const char *s) {
124 int ret = (size_t)(s - p->str);
125 return (ret > 0) ? ret : 0;
126 }
127
r_strpool_next(RStrpool * p,int index)128 R_API char *r_strpool_next(RStrpool *p, int index) {
129 char *ptr = r_strpool_get (p, index);
130 if (ptr) {
131 char *q = ptr + strlen (ptr) + 1;
132 if (q >= (p->str + p->len)) {
133 return NULL;
134 }
135 ptr = q;
136 if (!*ptr) {
137 ptr = NULL;
138 }
139 }
140 return ptr;
141 }
142
r_strpool_slice(RStrpool * p,int index)143 R_API char *r_strpool_slice(RStrpool *p, int index) {
144 int idx, len;
145 char *o, *x = r_strpool_get_i (p, index + 1);
146 if (!x || !*x) {
147 return NULL;
148 }
149 idx = (size_t)(x - p->str);
150 len = p->len - idx;
151 o = malloc (len + 128);
152 if (!o) {
153 return NULL;
154 }
155 memcpy (o, x, len);
156 free (p->str);
157 p->str = o;
158 p->size = len + 128;
159 p->len = len;
160 return o;
161 }
162
163 #if TEST
main()164 int main() {
165 RStrpool *p = r_strpool_new (1024);
166 printf ("%d\n", r_strpool_append (p, "Hello World"));
167 printf ("%d\n", r_strpool_append (p, "Patata Barata"));
168 printf ("%s\n", r_strpool_get (p, 12));
169 r_strpool_fit (p);
170 r_strpool_free (p);
171 return 0;
172 }
173 #endif
174