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