aboutsummaryrefslogtreecommitdiff
path: root/sys/base/mem/buffer.c
blob: b684d35d32596d10dd16134ca80671a6d0cc4383 (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
#include "internal.h"

/* Grow to particular size */
void*
·bufgrow(void* buf, vlong newLen, vlong eltsize)
{
    assert(bufcap(buf) <= (SIZE_MAX - 1) / 2);

    vlong newCap = MAX(16, MAX(1 + 2 * bufcap(buf), newLen));

    assert(newLen <= newCap);
    assert(newCap <= (SIZE_MAX - offsetof(BufHdr, buf)) / eltsize);

    vlong newSize = offsetof(BufHdr, buf) + newCap * eltsize;

    BufHdr* newHdr;
    if (buf) {
        newHdr = bufhdr(buf);
        newHdr = (BufHdr*)realloc((void*)newHdr, newSize);
    } else {
        newHdr      = (BufHdr*)malloc(newSize);
        newHdr->len = 0;
    }

    newHdr->cap = newCap;
    return (void*)newHdr->buf;
}

/* Pop out a value */
void
·bufdel(void *buf, int i, vlong eltsize)
{
    int n;
    byte *b;
    byte stk[1024];
    assert(eltsize < sizeof(stk));

    b = (byte*)buf;
    if(n = buflen(buf), i < n) {
        memcpy(stk, b+eltsize*i, eltsize);
        memcpy(b+eltsize*i, b+eltsize*(i+1), eltsize*(n-i-1));
        memcpy(b+eltsize*(n-1), stk, eltsize);
    } 
    bufhdr(buf)->len--;
}