1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use crate::{Memory, WASM_PAGE_SIZE};
use std::io;
#[cfg(test)]
mod tests;
pub struct Reader<'a, M> {
offset: u64,
memory: &'a M,
}
#[derive(Debug)]
pub struct OutOfBounds {
pub max_address: u64,
pub attempted_read_address: u64,
}
impl<'a, M: Memory> Reader<'a, M> {
pub fn new(memory: &'a M, offset: u64) -> Self {
Self { offset, memory }
}
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, OutOfBounds> {
let memory_end_addr = self.memory.size() * WASM_PAGE_SIZE;
let read_buf = if buf.len() as u64 + self.offset > memory_end_addr {
if self.offset < memory_end_addr {
let available_bytes = (memory_end_addr - self.offset) as usize;
&mut buf[..available_bytes]
} else {
return Err(OutOfBounds {
max_address: memory_end_addr,
attempted_read_address: self.offset,
});
}
} else {
buf
};
self.memory.read(self.offset, read_buf);
self.offset += read_buf.len() as u64;
Ok(read_buf.len())
}
}
impl<'a, M: Memory> io::Read for Reader<'a, M> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
self.read(buf).or(Ok(0)) }
}
pub struct BufferedReader<'a, M> {
inner: io::BufReader<Reader<'a, M>>,
}
impl<'a, M: Memory> BufferedReader<'a, M> {
pub fn new(buffer_size: usize, reader: Reader<M>) -> BufferedReader<M> {
BufferedReader {
inner: io::BufReader::with_capacity(buffer_size, reader),
}
}
}
impl<'a, M: Memory> io::Read for BufferedReader<'a, M> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}