Landin library reference source

core/mem/blocks.ldn

1--  Byte blocks: copying, filling, comparing and searching byte slices, with
2--  their lengths checked.  Plain loops, one byte at a time; a faster copy is
3--  an optimization that keeps these contracts.
4
5--- The left bytes order before the right ones.
6public less: atom
7--- The two byte strings are the same bytes.
8public equal: atom
9--- The left bytes order after the right ones.
10public greater: atom
11--- How two byte strings order: `less`, `equal` or `greater`.
12public order: type = less | equal | greater
13
14--- Copy every byte of `source` to the start of `into`, as C's `memmove`
15--- does: the two may overlap, in either direction, and `into` then holds
16--- what `source` held before the copy.  Reports `out_of_bounds` before
17--- writing anything when `into` is shorter than `source`; bytes of `into`
18--- past the copy are untouched.
19---
20--- One rule serves every overlap: a destination that begins after its
21--- source is copied from the last byte down, any other from the first byte
22--- up, so no byte is read after it has been overwritten.
23public copy: (into: []mut u8, source: []u8) -> none ! out_of_bounds =
24    count: usize = lenof source
25    fail out_of_bounds when count > lenof into
26    return when count == 0
27    target_address: usize = usize(addr into[0])
28    source_address: usize = usize(addr source[0])
29    if target_address > source_address then
30        mut at: usize = count
31        while at > 0 do
32            dec at
33            into[at] = source[at]
34        end while
35    else
36        mut at: usize = 0
37        while at < count do
38            into[at] = source[at]
39            inc at
40        end while
41    end if
42end copy
43
44--- Set every byte of `into` to `value`.
45public fill: (into: []mut u8, value: u8) -> none =
46    mut at: usize = 0
47    while at < lenof into do
48        into[at] = value
49        inc at
50    end while
51end fill
52
53--- Order two byte strings as unsigned bytes, the first difference
54--- deciding, and a string that is a proper prefix of the other ordering
55--- first: C's `memcmp` with the lengths taken into account, and the order
56--- `ls` gives names in the C locale.
57public compare: (left: []u8, right: []u8) -> (result: order) =
58    mut at: usize = 0
59    while at < lenof left and at < lenof right do
60        if left[at] <> right[at] then
61            result = if left[at] < right[at] then less else greater end if
62            return
63        end if
64        inc at
65    end while
66    if lenof left < lenof right then
67        result = less
68    elsif lenof left > lenof right then
69        result = greater
70    else
71        result = equal
72    end if
73end compare
74
75--- The index of the first byte of `source` equal to `value`, or the length
76--- of `source` when there is none, so that `source[0..<find(source, v)]`
77--- is always the part before it.
78public find: (source: []u8, value: u8) -> (index: usize) =
79    index = 0
80    while index < lenof source do
81        return when source[index] == value
82        inc index
83    end while
84end find