diff options
| author | 0x221E | 2026-05-11 00:52:53 +0200 |
|---|---|---|
| committer | 0x221E | 2026-05-11 00:52:53 +0200 |
| commit | 223d46a51f74bb0333cce2957352dc9ecbe896fa (patch) | |
| tree | 31642604e773e6e3b674c7248e6112d4eb0bfd37 | |
| parent | b4cd16236d97c0074a927159bb7df8620273f263 (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.h | 6 | ||||
| -rw-r--r-- | src/lib/sv.c | 61 |
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; +} |
