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