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
131
132
133
134
135
136
137
138
139
140
use crate::ic::{stable_bytes, stable_grow, stable_read, stable_size, stable_write, StableSize};
use candid::utils::{ArgumentDecoder, ArgumentEncoder};
use std::io;
pub use ic_kit_sys::types::StableMemoryError;
pub struct StableWriter {
offset: StableSize,
capacity: StableSize,
}
impl Default for StableWriter {
fn default() -> Self {
let capacity = stable_size();
Self {
offset: 0,
capacity,
}
}
}
impl StableWriter {
pub fn new(offset: StableSize) -> Self {
StableWriter {
offset,
capacity: stable_size(),
}
}
pub fn offset(&self) -> StableSize {
self.offset
}
pub fn grow(&mut self, added_pages: StableSize) -> 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() as StableSize) > (self.capacity << 16) {
self.grow((buf.len() >> 16) as StableSize + 1)?;
}
stable_write(self.offset, buf);
self.offset += buf.len() as StableSize;
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: StableSize,
}
impl Default for StableReader {
fn default() -> Self {
Self { offset: 0 }
}
}
impl StableReader {
pub fn new(offset: StableSize) -> Self {
StableReader { offset }
}
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, StableMemoryError> {
stable_read(self.offset, buf);
self.offset += buf.len() as StableSize;
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."))
}
}
#[deprecated(
since = "0.5.0",
note = "This is a non-performant legacy from IC-CDK for us to deal with."
)]
pub fn stable_store<T>(data: T) -> Result<(), candid::Error>
where
T: ArgumentEncoder,
{
candid::write_args(&mut StableWriter::default(), data)
}
#[deprecated(
since = "0.5.0",
note = "This is a non-performant legacy from IC-CDK for us to deal with."
)]
pub fn stable_restore<T>() -> Result<T, String>
where
T: for<'de> ArgumentDecoder<'de>,
{
let bytes = stable_bytes();
let mut de =
candid::de::IDLDeserialize::new(bytes.as_slice()).map_err(|e| format!("{:?}", e))?;
let res = ArgumentDecoder::decode(&mut de).map_err(|e| format!("{:?}", e))?;
Ok(res)
}