[−][src]Crate memory_slice
Structures and traits to represent and safely manipulate any data as raw memory
Examples
Any kind of data can be viewed as constant memory slice:
use memory_slice::AsMemory; let v: [u8;4] = [1,1,1,1]; //as_memory return a &memory_slice assert_eq!(unsafe{v.as_memory().read::<i32>()},1 + (1<<8) + (1<<16) + (1<<24));
But only types that does not preserve any invariants are accessible as mutable memory slice:
This will compile:
use memory_slice::AsMutMemory; let mut v: [u8;4] = [1,1,1,1]; //as_memory return a &memory_slice v.as_mut_memory().write(16 as u16);
This will not compile:
use memory_slice::AsMutMemory; use std::string::String; let mut v = String::new(); //as_memory return a &memory_slice v.as_mut_memory().write(16 as u16);
Mutable memory slices can be used to write information of any type while preserving borrow rules. The API provide also a smart pointer that will drop value created on the memory slice:
use memory_slice::{align,AsMutMemory,AsMemory}; // creates an array of 64 u8 aligned as 8: let mut buff = align!(8,[0 as u8;64]); //the create an int inside the buffer and get a reference to it let (padding, v1, remaining_buffer) = buff.as_mut_memory().write(42 as i32); assert!(padding.is_empty()); //unsafe{buff[0]}; //error => cannot borrow buff as immutable //use the remaining unitialized buffer to write an u64 in it: let (padding, v2, remaining_buffer2) = remaining_buffer.write(42 as u64); assert_eq!(padding.len(), 4); //unsafe{remaing_buffer.read::<u8>()}; //error => cannot borrow remaining_buffer //v1 and v2 are reference to the i32 and u64 created inside buff assert_eq!(*v1 as u64, *v2); { extern crate alloc; use alloc::borrow::ToOwned; //In what remains of the buffer, let's create a value that needs to be dropped: let (_padding, v3, _remaining) = remaining_buffer2.emplace("42".to_owned()); //v3 is a smart pointer to the String created in the buffer that will drop //this string when it goes out of scope assert_eq!(*v1, v3.parse::<i32>().unwrap()); } //string refered by v3 is dropped //buff is not anymore borrowed, so it is accessible: assert_eq!(unsafe { buff.as_memory().read::<i32>() }, 42); //memory slice can be indexed (!!less inoffensive than it looks) unsafe{*buff.as_mut_memory()[2..4].as_mut_unchecked()=16 as u16}; assert_ne!(unsafe { buff.as_memory().read::<i32>() }, 42);
A macro named buffer
is provided to create un initialized
buffer:
use memory_slice::buffer; // create an uninitialized buffer of 64 bytes aligned as 8. let mut buff = buffer!(64,8); // buffer are dereferencable as memory_slice //the create an int inside the buffer and get a reference to it buff.write(42 as i32);
Macros
align | Returns an overaligned value. |
buffer | Creates a statically sized buffer on the stack. |
Structs
BufferAs | A buffer of uninitialized memory with same size and alignement as T. |
Memory | Represents a raw memory range |
OwnedRef | A reference that drops its pointee when it is dropped |
OwnedSlice | A reference to a slice that drops its pointee when it is dropped |
Traits
AsMemory | Enable conversion of any type to a constant memory slice |
AsMutMemory | Enable conversion to a mutable memory. |