Landin library reference discuss source

core/io/fake/entropy.ldn

1--  Entropy whose bytes a test gives, the fake of `io.entropy`.
2
3import core/io
4import core/mem
5
6--- Caller-owned state of scripted entropy: how many of its bytes it has
7--- given and how often it was asked.  Declare it `zeroed` and give it to
8--- `entropy_over`; it must outlive the handle, and may be read while the
9--- handle is in use.
10public entropy_space: type = struct
11    used: usize
12    requests: usize
13end entropy_space
14
15scripted_entropy_value: type = struct
16    state: ptr mut entropy_space
17    bytes: []u8
18end scripted_entropy_value
19
20--- Entropy whose bytes are the caller's, given in order, so a program
21--- that seeds itself from entropy runs the same way in every test: a
22--- provider of `entropy`.  A request for more than what is left of them
23--- fails `io_failed` and gives nothing, so a test can make the source run
24--- dry.  Copies share the state.
25public entropy: type = scripted_entropy_value
26
27--- Fill `state` for scripted entropy over `bytes`, which the handle lends;
28--- keep them alive while it is used.
29public entropy_over: (inout state: entropy_space, bytes: []u8)
30                     -> (host: entropy from state, bytes) =
31    state = (used: 0, requests: 0)
32    host = (state: addr state, bytes: bytes)
33end entropy_over
34
35scripted_fill: (self: entropy, into: []mut u8) -> none ! io.io_failed =
36    state: ptr mut entropy_space = self.state
37    inc state.val.requests
38    used: usize = state.val.used
39    given: []u8 = self.bytes
40    fail io.io_failed when used > lenof given or lenof into > lenof given - used
41    mem.copy(into, given[used..<used + lenof into]) else (problem)
42        _ = problem
43        fail io.io_failed
44    end
45    state.val.used = used + lenof into
46end scripted_fill
47
48entropy is io.entropy (fill_random: scripted_fill)