ic_cdk/api/stable/
canister.rs

1use super::*;
2
3/// A standard implementation of [`StableMemory`].
4///
5/// Useful for creating [`StableWriter`] and [`StableReader`].
6#[derive(Default, Debug, Copy, Clone)]
7pub struct CanisterStableMemory {}
8
9impl StableMemory for CanisterStableMemory {
10    fn stable_size(&self) -> u32 {
11        // SAFETY: ic0.stable_size is always safe to call.
12        unsafe { ic0::stable_size() as u32 }
13    }
14
15    fn stable64_size(&self) -> u64 {
16        // SAFETY: ic0.stable64_size is always safe to call.
17        unsafe { ic0::stable64_size() as u64 }
18    }
19
20    fn stable_grow(&self, new_pages: u32) -> Result<u32, StableMemoryError> {
21        // SAFETY: ic0.stable_grow is always safe to call.
22        unsafe {
23            match ic0::stable_grow(new_pages as i32) {
24                -1 => Err(StableMemoryError::OutOfMemory),
25                x => Ok(x as u32),
26            }
27        }
28    }
29
30    fn stable64_grow(&self, new_pages: u64) -> Result<u64, StableMemoryError> {
31        // SAFETY: ic0.stable64_grow is always safe to call.
32        unsafe {
33            match ic0::stable64_grow(new_pages as i64) {
34                -1 => Err(StableMemoryError::OutOfMemory),
35                x => Ok(x as u64),
36            }
37        }
38    }
39
40    fn stable_write(&self, offset: u32, buf: &[u8]) {
41        // SAFETY: `buf`, being &[u8], is a readable sequence of bytes, and therefore valid to pass to ic0.stable_write.
42        unsafe {
43            ic0::stable_write(offset as i32, buf.as_ptr() as i32, buf.len() as i32);
44        }
45    }
46
47    fn stable64_write(&self, offset: u64, buf: &[u8]) {
48        // SAFETY: `buf`, being &[u8], is a readable sequence of bytes, and therefore valid to pass to ic0.stable64_write.
49        unsafe {
50            ic0::stable64_write(offset as i64, buf.as_ptr() as i64, buf.len() as i64);
51        }
52    }
53
54    fn stable_read(&self, offset: u32, buf: &mut [u8]) {
55        // SAFETY: `buf`, being &mut [u8], is a writable sequence of bytes, and therefore valid to pass to ic0.stable_read.
56        unsafe {
57            ic0::stable_read(buf.as_ptr() as i32, offset as i32, buf.len() as i32);
58        }
59    }
60
61    fn stable64_read(&self, offset: u64, buf: &mut [u8]) {
62        // SAFETY: `buf`, being &mut [u8], is a writable sequence of bytes, and therefore valid to pass to ic0.stable64_read.
63        unsafe {
64            ic0::stable64_read(buf.as_ptr() as i64, offset as i64, buf.len() as i64);
65        }
66    }
67}