aboutsummaryrefslogtreecommitdiff
path: root/sys/base/string/grow.c
blob: 39a9d2f459e4fd2678324404bbc3c3b30d9bbc0b (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
#include "internal.h"

// grow ensures that the string can encompass at least delta bytes.
// if it already can, this is a no op.
// if it can't, the string will be reallocated.
void
str·grow(string *s, vlong delta)
{
    Hdr *h, *newh;
    vlong cap = str·cap(*s);
    vlong len = str·len(*s);
    assert(cap >= len); // To prevent unsigned behavior

    if (cap - len >= delta) return;

    h = (Hdr*)(*s - sizeof(Hdr));

    vlong newCap = cap + delta;
    assert(newCap >= cap); // To prevent unsigned behavior
    if (newCap < MAX_STRING_ALLOC) {
        newCap *= 2;
    } else
        newCap += MAX_STRING_ALLOC;

    newh = (Hdr*)realloc(h, sizeof(*h) + newCap + 1);
    if (newh == nil) return;

    memset(newh->buf + len, '\0', newCap - len);
    newh->cap = newCap;
    newh->len = len;

    *s = newh->buf;
}