use crate::runtime::{ Reference, acquire, release, type_inner, type_key, block_length, block_set, block_get, }; use crate::tag; use super::block; pub struct Block { managed:bool, addr:Reference, } impl Block { pub fn new(size:usize) -> Self { Self { managed:true, addr:unsafe {acquire(block(size))}, } } pub fn from(addr:Reference) -> Result { return if(unsafe {type_key(addr.class)} == tag::BLOCK) { Ok(Self { managed:false, addr:addr }) } else { Err(()) } } pub fn length(&self) -> usize { unsafe {block_length(self.addr)} } pub fn set(&mut self, data:Vec) { let length = unsafe {type_key(type_inner(self.addr.class))}; for index in 0..usize::min(data.len(), length) { unsafe {block_set(self.addr, index, data[index])}; } } pub fn get(&self) -> Vec { let mut result = Vec::::new(); let length = unsafe {type_key(type_inner(self.addr.class))}; if length > 0 { result.resize(length, 0); for index in 0..length { result[index] = unsafe {block_get(self.addr, index)}; } } return result; } } impl std::ops::Deref for Block { type Target = Reference; fn deref(&self) -> &Self::Target { return &self.addr; } } impl Drop for Block { fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } } }