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) -> u64 {
11        // SAFETY: ic0.stable64_size is always safe to call.
12        unsafe { ic0::stable64_size() as u64 }
13    }
14
15    fn stable_grow(&self, new_pages: u64) -> Result<u64, StableMemoryError> {
16        // SAFETY: ic0.stable64_grow is always safe to call.
17        unsafe {
18            match ic0::stable64_grow(new_pages as i64) {
19                -1 => Err(StableMemoryError::OutOfMemory),
20                x => Ok(x as u64),
21            }
22        }
23    }
24
25    fn stable_write(&self, offset: u64, buf: &[u8]) {
26        // SAFETY: `buf`, being &[u8], is a readable sequence of bytes, and therefore valid to pass to ic0.stable64_write.
27        unsafe {
28            ic0::stable64_write(offset as i64, buf.as_ptr() as i64, buf.len() as i64);
29        }
30    }
31
32    fn stable_read(&self, offset: u64, buf: &mut [u8]) {
33        // SAFETY: `buf`, being &mut [u8], is a writable sequence of bytes, and therefore valid to pass to ic0.stable64_read.
34        unsafe {
35            ic0::stable64_read(buf.as_ptr() as i64, offset as i64, buf.len() as i64);
36        }
37    }
38}