aboutsummaryrefslogtreecommitdiff
path: root/src/base/string/make.c
blob: eb715433896500d4722a9d10853e251226ff4d33 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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);
}