use super::*;
pub type MemError = mtk::Error;
pub const NULL: IPtr = 0;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Mem {
mem: Vec<Option<Box<[Byte]>>>
}
impl Mem {
pub fn new() -> Mem {
Mem {
mem: vec![Some(vec![0; 0].into_boxed_slice())]
}
}
pub fn alloc(&mut self, size: usize) -> Result<usize, MemError> {
self.mem.push(Some(vec![0x0; size].into_boxed_slice()));
Ok(self.mem.len() - 1)
}
pub fn dealloc(&mut self, addr: usize) -> Result<usize, MemError> {
match self.mem.get_mut(addr) {
Some(some) => {
let size = match some {
Some(some) => some.len(),
None => return Err(MemError::from(format!("address {} is not allocated", addr)))
};
*some = None;
Ok(size)
},
None => Err(MemError::from(format!("address {} is not allocated", addr)))
}
}
pub fn get_mut(&mut self, addr: usize) -> Result<&mut Box<[Byte]>, MemError> {
match self.mem.get_mut(addr) {
Some(some) => {
match some {
Some(some) => Ok(some),
None => Err(MemError::from(format!("address {} is not allocated", addr)))
}
},
None => Err(MemError::from(format!("address {} is not allocated", addr)))
}
}
pub fn get(&self, addr: usize) -> Result<&Box<[Byte]>, MemError> {
match self.mem.get(addr) {
Some(some) => Ok(match some {
Some(some) => some,
None => return Err(MemError::from(format!("address {} is not allocated", addr)))
}),
None => Err(MemError::from(format!("address {} is not allocated", addr)))
}
}
pub fn size(&self) -> usize {
self.mem.len()
}
}
pub mod raw {
use super::*;
pub fn malloc(mem: &mut Mem, size: usize) -> usize {
match mem.alloc(size) {
Ok(ok) => ok,
Err(_) => NULL as RPtr
}
}
pub fn calloc(mem: &mut Mem, size: usize, block_size: usize) -> usize {
match mem.alloc(size * block_size) {
Ok(ok) => ok,
Err(_) => NULL as RPtr
}
}
pub fn realloc(mem: &mut Mem, addr: usize, size: usize) -> usize {
let copy = match mem.get(addr) {
Ok(some) => some.clone(),
Err(_) => return NULL as RPtr
};
match mem.dealloc(addr) {
Ok(_) => {
let new_addr = match mem.alloc(size) {
Ok(ok) => ok,
Err(_) => return NULL as RPtr
};
match mem.get_mut(new_addr) {
Ok(some) => {
for i in 0..copy.len() {
*match some.get_mut(i) {
Some(some) => some,
None => break
} = match copy.get(i) {
Some(some) => *some,
None => return NULL as RPtr
};
}
new_addr
},
Err(_) => NULL as RPtr
}
},
Err(_) => NULL as RPtr
}
}
pub fn free(mem: &mut Mem, addr: usize) -> usize {
match mem.dealloc(addr) {
Ok(ok) => ok,
Err(_) => NULL as RPtr
}
}
}
pub use raw as c;