radare2/libr/util/strbuf.c

144 lines
2.7 KiB
C
Raw Normal View History

/* radare - LGPL - Copyright 2013-2014 - pancake */
2013-12-03 04:46:53 +01:00
#include "r_types.h"
#include "r_util.h"
#include <stdio.h>
2013-12-14 01:16:09 +01:00
R_API RStrBuf *r_strbuf_new(const char *str) {
RStrBuf *s = R_NEW0 (RStrBuf);
if (str) r_strbuf_set (s, str);
return s;
2013-12-03 04:46:53 +01:00
}
2013-12-03 17:27:47 +01:00
R_API void r_strbuf_init(RStrBuf *sb) {
memset (sb, 0, sizeof (RStrBuf));
}
R_API bool r_strbuf_set(RStrBuf *sb, const char *s) {
int l;
if (!sb) return false;
if (!s) {
r_strbuf_init (sb);
return true;
}
l = strlen (s);
2015-09-30 17:06:59 +02:00
if (l >= sizeof (sb->buf)) {
char *ptr = sb->ptr;
2016-02-16 00:28:57 +01:00
if (!ptr || l+1 > sb->ptrlen) {
ptr = malloc (l + 1);
if (!ptr) return false;
sb->ptrlen = l + 1;
sb->ptr = ptr;
}
memcpy (ptr, s, l+1);
2013-12-03 04:46:53 +01:00
} else {
sb->ptr = NULL;
memcpy (sb->buf, s, l+1);
}
sb->len = l;
return true;
2013-12-03 04:46:53 +01:00
}
R_API bool r_strbuf_setf(RStrBuf *sb, const char *fmt, ...) {
int rc;
bool ret;
char string[1024];
va_list ap;
2015-10-29 23:41:29 +01:00
if (!sb || !fmt)
return false;
va_start (ap, fmt);
rc = vsnprintf (string, sizeof (string), fmt, ap);
if (rc >= sizeof (string)) {
char *p = malloc (rc + 2);
2014-03-08 10:41:22 +04:00
if (!p) {
va_end (ap);
return false;
2014-03-08 10:41:22 +04:00
}
vsnprintf (p, rc + 1, fmt, ap);
ret = r_strbuf_set (sb, p);
free (p);
} else {
ret = r_strbuf_set (sb, string);
}
va_end (ap);
return ret;
}
R_API int r_strbuf_append(RStrBuf *sb, const char *s) {
int l = strlen (s);
2016-02-16 00:57:17 +01:00
if (l<1) return false;
if ((sb->len + l + 1) < sizeof (sb->buf)) {
memcpy (sb->buf + sb->len, s, l + 1);
2016-02-16 00:57:17 +01:00
R_FREE (sb->ptr);
2013-12-03 04:46:53 +01:00
} else {
int newlen = sb->len + l + 128;
2016-02-16 00:28:57 +01:00
char *p = sb->ptr;
2016-02-16 00:57:17 +01:00
bool allocated = true;
if (!sb->ptr) {
p = malloc (newlen);
2016-02-16 00:57:17 +01:00
if (p && sb->len > 0) {
memcpy (p, sb->buf, sb->len);
}
} else if (sb->len + l + 1 > sb->ptrlen) {
p = realloc (sb->ptr, newlen);
2016-02-16 00:57:17 +01:00
} else {
allocated = false;
}
if (allocated) {
if (!p) return false;
sb->ptr = p;
sb->ptrlen = newlen;
}
memcpy (p + sb->len, s, l + 1);
2013-12-03 04:46:53 +01:00
}
sb->len += l;
2015-09-28 03:20:53 +02:00
return true;
2013-12-03 04:46:53 +01:00
}
2014-06-19 04:03:11 +02:00
R_API int r_strbuf_appendf(RStrBuf *sb, const char *fmt, ...) {
int ret;
char string[4096];
va_list ap;
va_start (ap, fmt);
ret = vsnprintf (string, sizeof (string), fmt, ap);
2015-09-28 03:20:53 +02:00
if (ret >= sizeof (string)) {
2014-06-19 04:03:11 +02:00
char *p = malloc (ret+2);
if (!p) {
va_end (ap);
2015-09-28 03:20:53 +02:00
return false;
2014-06-19 04:03:11 +02:00
}
vsnprintf (p, ret + 1, fmt, ap);
2014-06-19 04:03:11 +02:00
ret = r_strbuf_append (sb, p);
free (p);
} else {
ret = r_strbuf_append (sb, string);
}
2014-06-19 04:03:11 +02:00
va_end (ap);
return ret;
}
2013-12-03 04:46:53 +01:00
R_API char *r_strbuf_get(RStrBuf *sb) {
2016-02-16 00:28:57 +01:00
return sb? (sb->ptr? sb->ptr: sb->buf) : NULL;
2013-12-03 04:46:53 +01:00
}
R_API char *r_strbuf_drain(RStrBuf *sb) {
char *ret = NULL;
if (sb) {
ret = sb->ptr? sb->ptr: strdup (sb->buf);
free (sb);
}
return ret;
}
2013-12-03 04:46:53 +01:00
R_API void r_strbuf_free(RStrBuf *sb) {
2013-12-03 17:27:47 +01:00
r_strbuf_fini (sb);
free (sb);
}
R_API void r_strbuf_fini(RStrBuf *sb) {
2013-12-03 04:46:53 +01:00
if (sb && sb->ptr)
2016-04-04 21:25:03 +02:00
R_FREE (sb->ptr);
2013-12-03 04:46:53 +01:00
}