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