summaryrefslogtreecommitdiff
path: root/src/runtime/value/bytes.c
blob: 6a6edb623941f7143a40b60b5757468c0960fc50 (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
#include <lcq/pit/runtime/value/bytes.h>

bool pit_value_is_bytes(pit_runtime *rt, pit_value a) {
    return pit_value_is_ref_heavy_sort(rt, a, PIT_VALUE_HEAVY_SORT_BYTES);
}
pit_value pit_value_bytes_new(pit_runtime *rt, u8 *buf, i64 len) {
    u8 *dest = pit_arena_alloc_back(rt->heap, len);
    if (!dest) { pit_error(rt, "failed to allocate bytes"); return PIT_NIL; }
    pit_libc_string_memcpy(dest, buf, (size_t) len);
    pit_value ret = pit_value_ref_heavy_new(rt);
    pit_value_heavy *h = pit_value_ref_deref(rt, pit_value_as_ref(rt, ret));
    if (!h) { pit_error(rt, "failed to create new heavy value for bytes"); return PIT_NIL; }
    h->hsort = PIT_VALUE_HEAVY_SORT_BYTES;
    h->in.bytes.data = dest;
    h->in.bytes.len = len;
    return ret;
}
pit_value pit_value_bytes_new_cstr(pit_runtime *rt, char *s) {
    return pit_value_bytes_new(rt, (u8 *) s, (i64) pit_libc_string_strlen(s));
}
/* return true if v is a reference to bytes that are the same as those in buf */
bool pit_value_bytes_match(pit_runtime *rt, pit_value v, u8 *buf, i64 len) {
    if (pit_value_sort(v) != PIT_VALUE_SORT_REF) return false;
    pit_value_heavy *h = pit_value_ref_deref(rt, pit_value_as_ref(rt, v));
    if (!h) { pit_error(rt, "bad ref"); return false; }
    if (h->hsort != PIT_VALUE_HEAVY_SORT_BYTES) return false;
    if (h->in.bytes.len != len) return false;
    for (i64 i = 0; i < len; ++i)
        if (h->in.bytes.data[i] != buf[i]) {
            return false;
        }
    return true;
}
i64 pit_value_bytes_copy(pit_runtime *rt, pit_value v, u8 *buf, i64 maxlen) {
    if (pit_value_sort(v) != PIT_VALUE_SORT_REF) { pit_error(rt, "not a ref"); return -1; }
    pit_value_heavy *h = pit_value_ref_deref(rt, pit_value_as_ref(rt, v));
    if (!h) { pit_error(rt, "bad ref"); return -1; }
    if (h->hsort != PIT_VALUE_HEAVY_SORT_BYTES) {
        pit_error(rt, "invalid use of value as bytes");
        return -1;
    }
    i64 len = maxlen < h->in.bytes.len ? maxlen : h->in.bytes.len;
    for (i64 i = 0; i < len; ++i) {
        buf[i] = h->in.bytes.data[i];
    }
    return len;
}