lib/std/mem.rad 2.2 KiB raw
1
/// Memory error.
2
union MemoryError {
3
    /// Buffer is too small.
4
    BufferTooSmall,
5
    /// An offset is out of bounds of the given buffer.
6
    OutOfBounds,
7
}
8
9
/// Copy bytes between two slices. Returns the number of bytes copied.
10
pub fn copy(into: *mut [u8], from: *[u8]) -> u32 throws (MemoryError) {
11
    if into.len < from.len {
12
        throw MemoryError::BufferTooSmall;
13
    }
14
    for x, i in from {
15
        into[i] = x;
16
    }
17
    return from.len;
18
}
19
20
/// Strip a byte-level prefix from the input, and return the suffix.
21
/// Returns `nil` if the prefix wasn't found.
22
pub fn stripPrefix(prefix: *[u8], input: *[u8]) -> ?*[u8] {
23
    if prefix.len == 0 {
24
        return input;
25
    }
26
    if prefix.len > input.len {
27
        return nil;
28
    }
29
    for i in 0..prefix.len {
30
        if prefix[i] != input[i] {
31
            return nil;
32
        }
33
    }
34
    return &input[prefix.len..];
35
}
36
37
/// Align value up to alignment boundary.
38
pub fn alignUp(value: u32, alignment: u32) -> u32 {
39
    return (value + alignment - 1) & ~(alignment - 1);
40
}
41
42
/// Align signed value up to alignment boundary.
43
pub fn alignUpI32(value: i32, alignment: i32) -> i32 {
44
    return (value + alignment - 1) & ~(alignment - 1);
45
}
46
47
/// Count number of set bits in a 32-bit value.
48
pub fn popCount(x: u32) -> i32 {
49
    let mut n = x;
50
    let mut count: i32 = 0;
51
    while n != 0 {
52
        count += (n & 1) as i32;
53
        n >>= 1;
54
    }
55
    return count;
56
}
57
58
/// Check whether two byte slices have the same length and contents.
59
pub fn eq(a: *[u8], b: *[u8]) -> bool {
60
    if a.len != b.len {
61
        return false;
62
    }
63
    for i in 0..a.len {
64
        if a[i] != b[i] {
65
            return false;
66
        }
67
    }
68
    return true;
69
}
70
71
/// Compare two byte slices lexicographically.
72
///
73
/// Returns `-1` when `a < b`, `1` when `a > b`, and `0` when equal.
74
pub fn cmp(a: *[u8], b: *[u8]) -> i32 {
75
    let aLen = a.len;
76
    let bLen = b.len;
77
78
    let common = bLen if bLen < aLen else aLen;
79
    for i in 0..common {
80
        let aByte = a[i];
81
        let bByte = b[i];
82
        if aByte < bByte {
83
            return -1;
84
        }
85
        if aByte > bByte {
86
            return 1;
87
        }
88
    }
89
    if aLen < bLen {
90
        return -1;
91
    }
92
    if aLen > bLen {
93
        return 1;
94
    }
95
    return 0;
96
}