Rizin
unix-like reverse engineering framework and cli tools
strbuf.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2013-2020 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include "rz_types.h"
5 #include "rz_util.h"
6 #include <stdio.h>
7 
10  if (str) {
12  }
13  return s;
14 }
15 
17  rz_return_val_if_fail(sa && sb, false);
18  if (sa->len != sb->len) {
19  return false;
20  }
21  return strcmp(rz_strbuf_get(sa), rz_strbuf_get(sb)) == 0;
22 }
23 
25  return sb->len == 0;
26 }
27 
30  return sb->len;
31 }
32 
35  memset(sb, 0, sizeof(RzStrBuf));
36 }
37 
38 RZ_API const char *rz_strbuf_initf(RzStrBuf *sb, const char *fmt, ...) {
39  rz_return_val_if_fail(sb && fmt, NULL);
41  va_list ap;
42  va_start(ap, fmt);
43  const char *r = rz_strbuf_vsetf(sb, fmt, ap);
44  va_end(ap);
45  return r;
46 }
47 
49  rz_return_val_if_fail(dst && src, false);
50  if (src->ptr) {
51  char *p = malloc(src->ptrlen);
52  if (!p) {
53  return false;
54  }
55  memcpy(p, src->ptr, src->ptrlen);
56  free(dst->ptr);
57  dst->ptr = p;
58  dst->ptrlen = src->ptrlen;
59  } else {
60  RZ_FREE(dst->ptr);
61  memcpy(dst->buf, src->buf, sizeof(dst->buf));
62  }
63  dst->len = src->len;
64  return true;
65 }
66 
68  rz_return_val_if_fail(sb, false);
69 
70  if ((sb->ptr && len < sb->ptrlen) || (!sb->ptr && len < sizeof(sb->buf))) {
71  return true;
72  }
73  char *newptr = realloc(sb->ptr, len + 1);
74  if (!newptr) {
75  return false;
76  }
77  if (!sb->ptr) {
78  memcpy(newptr, sb->buf, sizeof(sb->buf));
79  }
80  sb->ptr = newptr;
81  sb->ptrlen = len + 1;
82  return true;
83 }
84 
85 RZ_API bool rz_strbuf_setbin(RzStrBuf *sb, const ut8 *s, size_t l) {
86  rz_return_val_if_fail(sb && s, false);
87  if (l >= sizeof(sb->buf)) {
88  char *ptr = sb->ptr;
89  if (!ptr || l + 1 > sb->ptrlen) {
90  ptr = malloc(l + 1);
91  if (!ptr) {
92  return false;
93  }
94  RZ_FREE(sb->ptr);
95  sb->ptrlen = l + 1;
96  sb->ptr = ptr;
97  }
98  memcpy(ptr, s, l);
99  ptr[l] = 0;
100  } else {
101  RZ_FREE(sb->ptr);
102  memcpy(sb->buf, s, l);
103  sb->buf[l] = 0;
104  }
105  sb->len = l;
106  sb->weakref = false;
107  return true;
108 }
109 
123  rz_return_val_if_fail(sb && from >= 0 && len >= 0, false);
124  if (from >= sb->len) {
125  // trying to cut outside the buf
126  return !sb->len && !from; // but it's fine if both are 0
127  }
128  char *s = rz_strbuf_get(sb);
129  len = RZ_MIN(sb->len - from, len);
130  if (from) {
131  memmove(s, s + from, len);
132  }
133  sb->len = len;
134  sb->ptrlen = len + 1;
135  s[len] = 0;
136  return true;
137 }
138 
139 RZ_API bool rz_strbuf_setptr(RzStrBuf *sb, char *s, int len) {
140  rz_return_val_if_fail(sb, false);
141  if (len < 0) {
142  sb->len = strlen(s);
143  sb->ptrlen = sb->len + 1;
144  } else {
145  sb->ptrlen = len;
146  sb->len = len;
147  }
148  sb->ptr = s;
149  sb->weakref = true;
150  return true;
151 }
152 
153 RZ_API const char *rz_strbuf_set(RzStrBuf *sb, const char *s) {
155  if (!s) {
157  return rz_strbuf_get(sb);
158  }
159  size_t len = strlen(s);
160  if (!rz_strbuf_setbin(sb, (const ut8 *)s, len)) {
161  return NULL;
162  }
163  sb->len = len;
164  return rz_strbuf_get(sb);
165 }
166 
167 RZ_API const char *rz_strbuf_setf(RzStrBuf *sb, const char *fmt, ...) {
168  rz_return_val_if_fail(sb && fmt, false);
169 
170  va_list ap;
171  va_start(ap, fmt);
172  const char *ret = rz_strbuf_vsetf(sb, fmt, ap);
173  va_end(ap);
174  return ret;
175 }
176 
177 RZ_API const char *rz_strbuf_vsetf(RzStrBuf *sb, const char *fmt, va_list ap) {
178  rz_return_val_if_fail(sb && fmt, false);
179 
180  const char *ret = NULL;
181  va_list ap2;
182  va_copy(ap2, ap);
183  char string[1024];
184  int rc = vsnprintf(string, sizeof(string), fmt, ap);
185  if (rc >= sizeof(string)) {
186  char *p = malloc(rc + 1);
187  if (!p) {
188  goto done;
189  }
190  vsnprintf(p, rc + 1, fmt, ap2);
191  ret = rz_strbuf_set(sb, p);
192  free(p);
193  } else if (rc >= 0) {
194  ret = rz_strbuf_set(sb, string);
195  }
196 done:
197  va_end(ap2);
198  return ret;
199 }
200 
201 RZ_API bool rz_strbuf_prepend(RzStrBuf *sb, const char *s) {
202  rz_return_val_if_fail(sb && s, false);
203  int l = strlen(s);
204  // fast path if no chars to append
205  if (l == 0) {
206  return true;
207  }
208  int newlen = l + sb->len;
209  char *ns = malloc(newlen + 1);
210  bool ret = false;
211  if (ns) {
212  memcpy(ns, s, l);
213  char *s = sb->ptr ? sb->ptr : sb->buf;
214  memcpy(ns + l, s, sb->len);
215  ns[newlen] = 0;
216  ret = rz_strbuf_set(sb, ns);
217  free(ns);
218  }
219  return ret;
220 }
221 
222 RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s) {
223  rz_return_val_if_fail(sb && s, false);
224 
225  int l = strlen(s);
226  return rz_strbuf_append_n(sb, s, l);
227 }
228 
229 RZ_API bool rz_strbuf_append_n(RzStrBuf *sb, const char *s, size_t l) {
230  rz_return_val_if_fail(sb && s, false);
231 
232  if (sb->weakref) {
233  return false;
234  }
235 
236  // fast path if no chars to append
237  if (l == 0) {
238  return true;
239  }
240 
241  if ((sb->len + l + 1) <= sizeof(sb->buf)) {
242  memcpy(sb->buf + sb->len, s, l);
243  sb->buf[sb->len + l] = 0;
244  RZ_FREE(sb->ptr);
245  } else {
246  size_t newlen = sb->len + l + 128;
247  char *p = sb->ptr;
248  bool allocated = true;
249  if (!sb->ptr) {
250  p = malloc(newlen);
251  if (p && sb->len > 0) {
252  memcpy(p, sb->buf, sb->len);
253  }
254  } else if (sb->len + l + 1 > sb->ptrlen) {
255  if (SZT_MUL_OVFCHK(newlen, 2)) {
256  return false;
257  }
258  newlen *= 2;
259  p = realloc(sb->ptr, newlen);
260  } else {
261  allocated = false;
262  }
263  if (allocated) {
264  if (!p) {
265  return false;
266  }
267  sb->ptr = p;
268  sb->ptrlen = newlen;
269  }
270  if (p) {
271  memcpy(p + sb->len, s, l);
272  *(p + sb->len + l) = 0;
273  }
274  }
275  sb->len += l;
276  return true;
277 }
278 
279 RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt, ...) {
280  va_list ap;
281 
282  rz_return_val_if_fail(sb && fmt, -1);
283 
284  va_start(ap, fmt);
285  bool ret = rz_strbuf_vappendf(sb, fmt, ap);
286  va_end(ap);
287  return ret;
288 }
289 
290 RZ_API bool rz_strbuf_vappendf(RzStrBuf *sb, const char *fmt, va_list ap) {
291  int ret;
292  va_list ap2;
293  char string[1024];
294 
295  rz_return_val_if_fail(sb && fmt, -1);
296 
297  if (sb->weakref) {
298  return false;
299  }
300  va_copy(ap2, ap);
301  ret = vsnprintf(string, sizeof(string), fmt, ap);
302  if (ret >= sizeof(string)) {
303  char *p = malloc(ret + 1);
304  if (!p) {
305  va_end(ap2);
306  return false;
307  }
308  *p = 0;
309  vsnprintf(p, ret + 1, fmt, ap2);
310  ret = rz_strbuf_append(sb, p);
311  free(p);
312  } else if (ret >= 0) {
313  ret = rz_strbuf_append(sb, string);
314  } else {
315  ret = false;
316  }
317  va_end(ap2);
318  return ret;
319 }
320 
323  return sb->ptr ? sb->ptr : sb->buf;
324 }
325 
328  if (len) {
329  *len = sb->len;
330  }
331  return (ut8 *)(sb->ptr ? sb->ptr : sb->buf);
332 }
333 
334 static inline char *drain(RzStrBuf *sb) {
335  return sb->ptr
336  ? sb->weakref
337  ? rz_mem_dup(sb->ptr, sb->ptrlen)
338  : sb->ptr
339  : strdup(sb->buf);
340 }
341 
344  char *ret = drain(sb);
345  free(sb);
346  return ret;
347 }
348 
351  char *ret = drain(sb);
352  sb->ptr = NULL;
353  sb->len = 0;
354  sb->buf[0] = '\0';
355  return ret;
356 }
357 
359  if (sb) {
361  free(sb);
362  }
363 }
364 
366  if (sb && !sb->weakref) {
367  RZ_FREE(sb->ptr);
368  sb->ptr = NULL;
369  sb->len = 0;
370  sb->buf[0] = '\0';
371  }
372 }
size_t len
Definition: 6502dis.c:15
lzma_index * src
Definition: index.h:567
static SblHeader sb
Definition: bin_mbn.c:26
#define RZ_API
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
struct tab * done
Definition: enough.c:233
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
vsnprintf
Definition: kernel.h:366
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
char * dst
Definition: lz4.h:724
static RzSocket * s
Definition: rtr.c:28
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API void * rz_mem_dup(const void *s, int l)
Definition: mem.c:319
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_FREE(x)
Definition: rz_types.h:369
#define RZ_MIN(x, y)
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr from
Definition: sfsocketcall.h:123
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
Definition: strbuf.c:342
RZ_API RZ_OWN char * rz_strbuf_drain_nofree(RzStrBuf *sb)
Definition: strbuf.c:349
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
RZ_API bool rz_strbuf_prepend(RzStrBuf *sb, const char *s)
Definition: strbuf.c:201
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
RZ_API bool rz_strbuf_copy(RzStrBuf *dst, RzStrBuf *src)
Definition: strbuf.c:48
RZ_API bool rz_strbuf_reserve(RzStrBuf *sb, size_t len)
Definition: strbuf.c:67
RZ_API bool rz_strbuf_slice(RZ_NONNULL RzStrBuf *sb, size_t from, size_t len)
Cuts the current string into a substring.
Definition: strbuf.c:122
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API const char * rz_strbuf_initf(RzStrBuf *sb, const char *fmt,...)
Definition: strbuf.c:38
RZ_API void rz_strbuf_fini(RzStrBuf *sb)
Definition: strbuf.c:365
RZ_API void rz_strbuf_free(RzStrBuf *sb)
Definition: strbuf.c:358
RZ_API bool rz_strbuf_equals(RzStrBuf *sa, RzStrBuf *sb)
Definition: strbuf.c:16
RZ_API bool rz_strbuf_setbin(RzStrBuf *sb, const ut8 *s, size_t l)
Definition: strbuf.c:85
RZ_API ut8 * rz_strbuf_getbin(RzStrBuf *sb, int *len)
Definition: strbuf.c:326
static char * drain(RzStrBuf *sb)
Definition: strbuf.c:334
RZ_API const char * rz_strbuf_setf(RzStrBuf *sb, const char *fmt,...)
Definition: strbuf.c:167
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
RZ_API bool rz_strbuf_is_empty(RzStrBuf *sb)
Definition: strbuf.c:24
RZ_API int rz_strbuf_length(RzStrBuf *sb)
Definition: strbuf.c:28
RZ_API RzStrBuf * rz_strbuf_new(const char *str)
Definition: strbuf.c:8
RZ_API bool rz_strbuf_vappendf(RzStrBuf *sb, const char *fmt, va_list ap)
Definition: strbuf.c:290
RZ_API bool rz_strbuf_append_n(RzStrBuf *sb, const char *s, size_t l)
Definition: strbuf.c:229
RZ_API bool rz_strbuf_setptr(RzStrBuf *sb, char *s, int len)
Definition: strbuf.c:139
RZ_API const char * rz_strbuf_vsetf(RzStrBuf *sb, const char *fmt, va_list ap)
Definition: strbuf.c:177
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...)
Definition: strbuf.c:279
size_t len
Definition: rz_strbuf.h:12