summaryrefslogtreecommitdiff
path: root/src/dynstr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dynstr.c')
-rw-r--r--src/dynstr.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/dynstr.c b/src/dynstr.c
new file mode 100644
index 0000000..fa9e9e0
--- /dev/null
+++ b/src/dynstr.c
@@ -0,0 +1,95 @@
+#include "common.h"
+
+#include "dynstr.h"
+
+dynstr_t* dynstr_new(void)
+{
+ dynstr_t* str = calloc(1, sizeof(dynstr_t));
+ if (str)
+ {
+ str->size = 64;
+ str->data = malloc(str->size);
+ if (!str->data)
+ {
+ free(str);
+ return NULL;
+ }
+ }
+ return str;
+}
+
+dynstr_t* dynstr_new_strn(const char* cstr, size_t len)
+{
+ dynstr_t* str = calloc(1, sizeof(dynstr_t));
+ assert(cstr);
+ if (str)
+ {
+ str->len = len;
+ str->size = len + 1;
+ str->data = malloc(str->size);
+ if (!str->data)
+ {
+ free(str);
+ return NULL;
+ }
+ memcpy(str->data, cstr, len);
+ }
+ return str;
+}
+
+void dynstr_free(dynstr_t* str)
+{
+ if (str)
+ {
+ free(str->data);
+ free(str);
+ }
+}
+
+char* dynstr_done(dynstr_t* str)
+{
+ char* ret;
+ assert(str);
+ assert(str->len < str->size);
+ str->data[str->len] = '\0';
+ ret = str->data;
+ free(str);
+ return ret;
+}
+
+const char* dynstr_peek(dynstr_t* str)
+{
+ assert(str);
+ assert(str->len < str->size);
+ str->data[str->len] = '\0';
+ return str->data;
+}
+
+bool dynstr_nappend(dynstr_t* str, const char* add, size_t len)
+{
+ assert(str && add);
+ if (str->len + len >= str->size)
+ {
+ size_t ns = MAX(str->size * 2, str->len + len + 1);
+ char* tmp = realloc(str->data, ns);
+ if (!tmp)
+ {
+ return false;
+ }
+ str->data = tmp;
+ str->size = ns;
+ }
+ memcpy(str->data + str->len, add, len);
+ str->len += len;
+ return true;
+}
+
+void dynstr_cut(dynstr_t* str, size_t newlen)
+{
+ assert(str);
+ assert(newlen <= str->len);
+ if (newlen < str->len)
+ {
+ str->len = newlen;
+ }
+}