summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author0x221E2026-05-11 00:52:53 +0200
committer0x221E2026-05-11 00:52:53 +0200
commit223d46a51f74bb0333cce2957352dc9ecbe896fa (patch)
tree31642604e773e6e3b674c7248e6112d4eb0bfd37
parentb4cd16236d97c0074a927159bb7df8620273f263 (diff)
lib: sv: add sv_concat_cstr(), sv_init() and sv_free()
Creates an default option to heap-init string view to be used by complex operation where memory needs to be fine-grained.
-rw-r--r--include/lib/sv.h6
-rw-r--r--src/lib/sv.c61
2 files changed, 64 insertions, 3 deletions
diff --git a/include/lib/sv.h b/include/lib/sv.h
index f5169d0..125939a 100644
--- a/include/lib/sv.h
+++ b/include/lib/sv.h
@@ -8,9 +8,13 @@ struct string_view {
size_t len;
};
-struct string_view sv_create(char *buf, size_t len);
+struct string_view sv_create(const char *buf, const size_t len);
+int sv_init(struct string_view *sv, const char *buf);
+void sv_free(struct string_view *sv);
struct string_view sv_copy(struct string_view *sv);
int sv_equal(struct string_view *a, struct string_view *b);
+struct string_view sv_concat(struct string_view *a, struct string_view *b);
+int sv_concat_cstr(struct string_view *sv, const char *cstr);
#define SV(x) (struct string_view){(x), sizeof(x) - 1}
diff --git a/src/lib/sv.c b/src/lib/sv.c
index 34d214f..33881d2 100644
--- a/src/lib/sv.c
+++ b/src/lib/sv.c
@@ -4,9 +4,30 @@
#include <string.h>
#include <assert.h>
-struct string_view sv_create(char *buf, size_t len)
+struct string_view sv_create(const char *buf, const size_t len)
{
- return (struct string_view){.buf = buf, .len = len};
+ return (struct string_view){.buf = buf, .len = len};
+}
+
+int sv_init(struct string_view *sv, const char *b)
+{
+ assert(sv != NULL);
+
+ size_t len = strlen(b);
+ void *ptr = malloc(len);
+
+ memcpy(ptr, b, len);
+
+ sv->buf = ptr;
+ sv->len = len;
+
+ return 0;
+}
+
+void sv_free(struct string_view *sv)
+{
+ assert(sv != NULL);
+ free(sv->buf);
}
/**
@@ -38,3 +59,39 @@ int sv_equal(struct string_view *a, struct string_view *b)
return 1;
}
+
+/**
+ * @warning User's responsibility to cleanup memory.
+ */
+struct string_view sv_concat(struct string_view *a, struct string_view *b)
+{
+ assert(a != NULL);
+ assert(b != NULL);
+ size_t nlen = a->len + b->len;
+ char *ptr = malloc(nlen);
+ return (struct string_view){.buf = ptr, .len = nlen};
+}
+
+int sv_concat_cstr(struct string_view *a, const char *cstr)
+{
+ assert(a != NULL);
+
+ if (a->len > 0 && a->buf[a->len - 1] == '\0')
+ a->len--;
+
+ size_t lenb = strlen(cstr);
+ size_t nlen = lenb + a->len + 1;
+
+ char *tmp = realloc(a->buf, nlen);
+
+ if (tmp == NULL)
+ return -1;
+
+ a->buf = tmp;
+
+ memcpy(a->buf + a->len, cstr, lenb);
+ a->len = nlen - 1;
+ a->buf[a->len] = '\0';
+
+ return 0;
+}