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
use crate::memory::{
allocation::{AllocationError, WasmAllocation},
stack::WasmStack,
MemoryBits, MemoryInt,
};
use holochain_json_api::json::JsonString;
use memory::allocation::{AllocationResult, Length};
use std::{cmp::max, convert::TryInto, os::raw::c_char, slice};
impl WasmStack {
fn write_in_wasm_memory(&mut self, bytes: &[u8], length: Length) -> AllocationResult {
let next_allocation = self.next_allocation(length)?;
let ptr = MemoryInt::from(self.allocate(next_allocation)?) as *mut c_char;
let ptr_safe = unsafe { slice::from_raw_parts_mut(ptr, usize::from(length)) };
for (i, byte) in bytes.iter().enumerate() {
ptr_safe[i] = *byte as c_char;
}
WasmAllocation::new((ptr as MemoryInt).into(), length)
}
pub fn write_string(&mut self, s: &str) -> AllocationResult {
let bytes = s.as_bytes();
let length = max(bytes.len(), 1) as MemoryInt;
if MemoryBits::from(length) > WasmStack::max() {
return Err(AllocationError::OutOfBounds);
}
self.write_in_wasm_memory(bytes, Length::from(length))
}
pub fn write_json<J: TryInto<JsonString>>(&mut self, jsonable: J) -> AllocationResult {
let j: JsonString = jsonable
.try_into()
.map_err(|_| AllocationError::Serialization)?;
let json_bytes = j.to_bytes();
let json_bytes_len = max(json_bytes.len(), 1) as MemoryInt;
if MemoryBits::from(json_bytes_len) > WasmStack::max() {
return Err(AllocationError::OutOfBounds);
}
self.write_in_wasm_memory(&json_bytes, Length::from(json_bytes_len))
}
}