aboutsummaryrefslogtreecommitdiff
path: root/src/base/string/make.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/string/make.c')
-rw-r--r--src/base/string/make.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/base/string/make.c b/src/base/string/make.c
new file mode 100644
index 0000000..eb71543
--- /dev/null
+++ b/src/base/string/make.c
@@ -0,0 +1,53 @@
+#include "internal.h"
+
+// new returns a new dynamic string object, initialized from the given c string.
+// len defines the length of the c substring that we will copy into our buffer.
+// the backing buffer will have capacity cap.
+string
+str·makecap(const byte *s, vlong len, vlong cap)
+{
+ struct Hdr* h;
+
+ h = malloc(sizeof(*h) + cap + 1);
+ if (s == nil) memset(h, 0, sizeof(*h));
+
+ if (h == nil) return nil; // Allocation failed.
+
+ h->len = (s == nil) ? 0 : len;
+ h->cap = cap;
+
+ if (cap < h->len) goto cleanup;
+
+ if (s != nil && cap > 0) {
+ memcpy(h->buf, s, h->len);
+ memset(h->buf + h->len, '\0', h->cap - h->len + 1);
+ }
+
+ return h->buf;
+
+cleanup:
+ free(h);
+ panicf("Attempted to create a string with less capacity than length");
+ return nil;
+}
+
+// new returns a new dynamic string object, initialized from the given c string.
+// the backing buffer capacity is equivalent to the string length.
+string
+str·makelen(const byte *s, vlong len)
+{
+ vlong sl = (!s) ? 0 : strlen(s);
+ if (sl < len) panicf("attempted to take a bigger substring than string length");
+
+ vlong cap = (len == 0) ? 1 : len;
+ return str·makecap(s, len, cap);
+}
+
+// new returns a new dynamic string object, initialized from the given c string.
+// the backing buffer capacity is equivalent to the string length.
+string
+str·make(const byte *s)
+{
+ vlong len = (!s) ? 0 : strlen(s);
+ return str·makelen(s, len);
+}