1use crate::Sandbox;
2use inkpad_executor::{Error, Result};
3use inkpad_std::{vec, Vec};
4use inkpad_support::traits::Ext;
5use parity_scale_codec::{Decode, DecodeAll, Encode};
6
7impl Sandbox {
8 pub fn read_sandbox_memory(&self, ptr: u32, len: u32) -> Result<Vec<u8>> {
10 let mut buf = vec![0u8; len as usize];
11 self.read_sandbox_memory_into_buf(ptr, &mut buf)?;
12 Ok(buf.to_vec())
13 }
14
15 pub fn read_sandbox_memory_into_buf(&self, ptr: u32, buf: &mut [u8]) -> Result<()> {
17 self.memory()
18 .ok_or(Error::CodeNotFound)?
19 .get(ptr, buf)
20 .map_err(|_| Error::OutOfBounds)?;
21 Ok(())
22 }
23
24 pub fn read_sandbox_memory_as<D: Decode>(&mut self, ptr: u32, len: u32) -> Result<D> {
26 let buf = self.read_sandbox_memory(ptr, len)?;
27 let decoded = D::decode_all(&buf[..]).map_err(|_| Error::DecodeRuntimeValueFailed)?;
28 Ok(decoded)
29 }
30
31 pub fn write_sandbox_memory(&mut self, ptr: u32, buf: &[u8]) -> Result<()> {
33 self.memory()
34 .ok_or(Error::CodeNotFound)?
35 .set(ptr, buf)
36 .map_err(|_| Error::OutOfBounds)
37 }
38
39 pub fn write_sandbox_output(
43 &mut self,
44 out_ptr: u32,
45 out_len_ptr: u32,
46 buf: &[u8],
47 ) -> Result<()> {
48 let buf_len = buf.len() as u32;
49 let len: u32 = self.read_sandbox_memory_as(out_len_ptr, 4)?;
50
51 if len < buf_len {
52 return Err(Error::OutputBufferTooSmall);
53 }
54
55 let memory = self.memory().ok_or(Error::CodeNotFound)?;
56 memory
57 .set(out_ptr, buf)
58 .and_then(|_| memory.set(out_len_ptr, &buf_len.encode()))
59 .map_err(|_| Error::OutOfBounds)?;
60
61 Ok(())
62 }
63}