aboutsummaryrefslogtreecommitdiff
path: root/src/base/string/make.c
blob: ca38984c524f2dfa1c92c4576eac446b2fae8171 (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
string·nnmake(byte *s, vlong len, vlong cap)
{
    struct Hdr* h;

    h = malloc(sizeof(*h) + cap + 1);
    if(s == nil) mem·set(h, sizeof(*h), 0);

    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){
        mem·copy(h->buf, h->len, s);
        mem·set(h->buf + h->len, h->cap - h->len + 1, '\0');
    }

    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
string·nmake(byte *s, vlong len)
{
    vlong sl = (!s) ? 0 : str·len(s);
    if(sl < len) panicf("attempted to take a bigger substring than string length");

    vlong cap = (len == 0) ? 1 : len;
    return string·nnmake(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
string·make(byte *s)
{
    vlong len = (!s) ? 0 : str·len(s);
    return string·nmake(s, len);
}