mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-30 16:40:57 +00:00
195 lines
3.6 KiB
C
195 lines
3.6 KiB
C
/* radare2 - LGPL - Copyright 2022 - pancake */
|
|
|
|
// radare-stack-string-implementation
|
|
#include <r_util.h>
|
|
|
|
// #define r_string_get(x) ((char *)((x).ptr?(x).ptr:(char *)&(x).buf))
|
|
// #define r_string_free(x) if (!(x).weak) {free ((x).ptr);}
|
|
|
|
R_API char *r_string_get(const RString *s, int *len) {
|
|
if (len) {
|
|
*len = s->len;
|
|
}
|
|
if (s->len < 1) {
|
|
if (len) {
|
|
*len = 0;
|
|
}
|
|
return strdup ("");
|
|
}
|
|
if (s->weak) {
|
|
return r_str_ndup (s->str, s->len);
|
|
}
|
|
if (len) {
|
|
*len = s->len;
|
|
}
|
|
return strdup (s->str);
|
|
}
|
|
|
|
R_API RString r_string_new(const char *is, int len) {
|
|
RString s = {0};
|
|
if (is) {
|
|
size_t sl = len < 0 ? strlen (is): len;
|
|
if (sl >= sizeof (s.buf)) {
|
|
s.ptr = strdup (is);
|
|
s.str = s.ptr;
|
|
} else {
|
|
memcpy (s.buf, is, sl + 1);
|
|
s.str = s.buf;
|
|
}
|
|
s.len = sl;
|
|
}
|
|
return s;
|
|
}
|
|
|
|
R_API void r_string_free(RString *s) {
|
|
if (s->weak) {
|
|
return;
|
|
}
|
|
s->len = 0;
|
|
s->str = (char *)&s->buf;
|
|
R_FREE (s->ptr);
|
|
}
|
|
|
|
R_API RString r_string_from(const char *is, int len) {
|
|
RString s = {0};
|
|
if (is) {
|
|
s.weak = true;
|
|
s.ptr = (char *)is;
|
|
s.str = s.ptr;
|
|
s.len = len;
|
|
}
|
|
return s;
|
|
}
|
|
|
|
R_API void r_string_unweak(RString *a) {
|
|
a->weak = false;
|
|
a->ptr = r_str_ndup (a->ptr, a->len);
|
|
a->str = a->ptr;
|
|
}
|
|
|
|
R_API void r_string_trim(RString *s) {
|
|
if (s->weak) {
|
|
const char *trimmed = r_str_trim_head_ro (s->str);
|
|
s->str = (char *)trimmed;
|
|
if (s->ptr) {
|
|
s->ptr = s->str;
|
|
}
|
|
return;
|
|
}
|
|
s->len = r_str_ntrim (s->str, s->len);
|
|
}
|
|
|
|
R_API R_WIP RString r_string_newf(const char *fmt, ...) {
|
|
va_list ap, ap2;
|
|
|
|
va_start (ap, fmt);
|
|
if (!strchr (fmt, '%')) {
|
|
va_end (ap);
|
|
return r_string_new (fmt, strlen (fmt));
|
|
}
|
|
va_copy (ap2, ap);
|
|
int ret = vsnprintf (NULL, 0, fmt, ap2);
|
|
ret++;
|
|
RString s = {0};
|
|
char *p = NULL;
|
|
if (ret + 2 >= sizeof (s.buf)) {
|
|
p = calloc (1, ret);
|
|
s.ptr = p;
|
|
} else {
|
|
p = (char *)&s.buf;
|
|
R_FREE (s.ptr);
|
|
}
|
|
s.str = (char *)p;
|
|
s.len = ret;
|
|
if (p) {
|
|
(void)vsnprintf (p, ret, fmt, ap);
|
|
}
|
|
va_end (ap2);
|
|
va_end (ap);
|
|
return s;
|
|
}
|
|
|
|
R_API bool r_string_append(RString *a, const char *s) {
|
|
if (a->weak) {
|
|
// error. weak strings cannot be modified.. unless well you unweak them
|
|
return false;
|
|
}
|
|
size_t olen = a->len;
|
|
size_t slen = strlen (s);
|
|
size_t tlen = olen + slen;
|
|
if (tlen >= sizeof (a->buf)) {
|
|
char *aptr = a->ptr;
|
|
a->ptr = r_str_newf ("%s%s", a->str, s);
|
|
a->str = a->ptr;
|
|
a->len = tlen;
|
|
free (aptr);
|
|
} else {
|
|
memcpy (a->buf + olen, s, slen + 1);
|
|
a->len = tlen;
|
|
a->str = a->buf;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
R_API void r_string_appendf(RString *a, const char *fmt, ...) {
|
|
RString s = {0};
|
|
va_list ap, ap2;
|
|
|
|
va_start (ap, fmt);
|
|
if (!strchr (fmt, '%')) {
|
|
va_end (ap);
|
|
r_string_append (a, fmt);
|
|
return;
|
|
}
|
|
va_copy (ap2, ap);
|
|
int ret = vsnprintf (NULL, 0, fmt, ap2);
|
|
ret++;
|
|
char *p = NULL;
|
|
bool myp = false;
|
|
if (ret >= sizeof (s.buf)) {
|
|
myp = true;
|
|
p = calloc (1, ret);
|
|
} else {
|
|
p = (char *)&s.buf;
|
|
}
|
|
if (p) {
|
|
(void)vsnprintf (p, ret, fmt, ap);
|
|
r_string_append (a, p);
|
|
if (myp) {
|
|
free (p);
|
|
}
|
|
}
|
|
va_end (ap2);
|
|
va_end (ap);
|
|
}
|
|
|
|
#if 0
|
|
int main() {
|
|
int i;
|
|
#if 1
|
|
// 10.4s
|
|
for (i = 0; i < 10000000; i++) {
|
|
RString s = r_string_new (" hello world", -1);
|
|
r_string_appendf (&s, " [PATATA %s:%d] ", "jeje", 23);
|
|
r_string_trim (&s);
|
|
printf ("%s\n", s.str);
|
|
printf ("%s\n", r_string_newf ("rstring %s", "rulez").str);
|
|
r_string_free (s);
|
|
}
|
|
#else
|
|
// 13.8s
|
|
for (i = 0; i < 10000000; i++) {
|
|
RStrBuf *sb = r_strbuf_new (" hello world");
|
|
r_strbuf_appendf (sb, " [PATATA %s:%d] ", "jeje", 23);
|
|
char *ss = r_strbuf_drain (sb);
|
|
r_str_trim (ss);
|
|
printf ("%s\n", ss);
|
|
char *lala = r_str_newf ("rstring %s", "rulez");
|
|
printf ("%s\n", lala);
|
|
free (lala);
|
|
free (ss);
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|