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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use std::io;
pub fn stable_size() -> u32 {
unsafe { super::ic0::stable_size() as u32 }
}
pub struct StableMemoryError();
pub fn stable_grow(new_pages: u32) -> Result<u32, StableMemoryError> {
unsafe {
match super::ic0::stable_grow(new_pages as i32) {
-1 => Err(StableMemoryError()),
x => Ok(x as u32),
}
}
}
pub fn stable_write(offset: u32, buf: &[u8]) {
unsafe {
super::ic0::stable_write(offset as i32, buf.as_ptr() as i32, buf.len() as i32);
}
}
pub fn stable_read(offset: u32, buf: &mut [u8]) {
unsafe {
super::ic0::stable_read(buf.as_ptr() as i32, offset as i32, buf.len() as i32);
}
}
pub fn stable_bytes() -> Vec<u8> {
let size = (stable_size() as usize) << 16;
let mut vec = Vec::with_capacity(size);
unsafe {
vec.set_len(size);
}
stable_read(0, vec.as_mut_slice());
vec
}
pub struct StableWriter {
offset: usize,
capacity: u32,
}
impl Default for StableWriter {
fn default() -> Self {
let capacity = stable_size();
Self {
offset: 0,
capacity,
}
}
}
impl StableWriter {
pub fn grow(&mut self, added_pages: u32) -> Result<(), StableMemoryError> {
let old_page_count = stable_grow(added_pages)?;
self.capacity = old_page_count + added_pages;
Ok(())
}
pub fn write(&mut self, buf: &[u8]) -> Result<usize, StableMemoryError> {
if self.offset + buf.len() > ((self.capacity as usize) << 16) {
self.grow((buf.len() >> 16) as u32 + 1)?;
}
stable_write(self.offset as u32, buf);
self.offset += buf.len();
Ok(buf.len())
}
}
impl io::Write for StableWriter {
fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
self.write(buf)
.map_err(|_| io::Error::new(io::ErrorKind::Other, "Out Of Memory"))
}
fn flush(&mut self) -> Result<(), io::Error> {
Ok(())
}
}
pub struct StableReader {
offset: usize,
}
impl Default for StableReader {
fn default() -> Self {
Self { offset: 0 }
}
}
impl StableReader {
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, StableMemoryError> {
stable_read(self.offset as u32, buf);
self.offset += buf.len();
Ok(buf.len())
}
}
impl io::Read for StableReader {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
self.read(buf)
.map_err(|_| io::Error::new(io::ErrorKind::Other, "Unexpected error."))
}
}