extern crate alloc;
use core::cmp;
use crate::heap::*;
use crate::sharedmutex::*;
static mut BH:SharedMutex<Heap<DataStream>> = SharedMutex::new();
static mut BD:SharedMutex<Vec<usize>> = SharedMutex::new();
#[derive(Debug, Default)]
pub struct DataStream {
data: Vec<u8>,
len: usize,
read_open: bool,
write_open: bool,
mime_type: Option<String>,
}
impl DataStream {
pub fn new() -> Self {
DataStream {
data: Vec::new(),
len: 0,
read_open: true,
write_open: true,
mime_type: None,
}
}
pub fn from_bytes(buf:Vec<u8>) -> DataStream {
let len = buf.len();
DataStream {
data: buf,
len: len,
read_open: true,
write_open: false,
mime_type: None,
}
}
pub fn deep_copy(&self) -> DataStream {
DataStream {
data: self.data.to_owned(),
len: self.len,
read_open: self.read_open,
write_open: self.write_open,
mime_type: self.mime_type.to_owned(),
}
}
}
pub fn bheap() -> &'static mut SharedMutex<Heap<DataStream>> {
unsafe { &mut BH }
}
fn bdrop() -> &'static mut SharedMutex<Vec<usize>> {
unsafe { &mut BD }
}
#[derive(Debug, Default)]
pub struct DataBytes {
pub data_ref: usize,
}
impl Clone for DataBytes{
fn clone(&self) -> Self {
let o = DataBytes{
data_ref: self.data_ref,
};
let _x = &mut bheap().lock().incr(self.data_ref);
o
}
}
impl DataBytes {
pub fn init() -> ((u64, u64),(u64, u64)){
unsafe {
BH.set(Heap::new());
BD.set(Vec::new());
}
DataBytes::share()
}
pub fn share() -> ((u64, u64), (u64, u64)){
unsafe{
let q = BH.share();
let r = BD.share();
(q, r)
}
}
pub fn mirror(q:(u64, u64), r:(u64, u64)){
unsafe {
BH.mirror(q.0, q.1);
BD.mirror(r.0, r.1);
}
}
pub fn new() -> DataBytes {
let data_ref = &mut bheap().lock().push(DataStream::new());
return DataBytes {
data_ref: *data_ref,
};
}
pub fn from_bytes(buf:&Vec<u8>) -> DataBytes {
let data_ref = &mut bheap().lock().push(DataStream::from_bytes(buf.to_vec()));
return DataBytes {
data_ref: *data_ref,
};
}
pub fn get_data(&self) -> Vec<u8> {
let heap = &mut bheap().lock();
let vec = heap.get(self.data_ref);
vec.data.to_owned()
}
pub fn write(&self, buf:&[u8]) -> bool {
let heap = &mut bheap().lock();
let vec = heap.get(self.data_ref);
if !vec.write_open || !vec.read_open { return false }
vec.data.extend_from_slice(buf);
true
}
pub fn read(&self, n:usize) -> Vec<u8> {
let heap = &mut bheap().lock();
let vec = heap.get(self.data_ref);
if !vec.read_open { panic!("Attempt to read from closed data stream"); }
let n = cmp::min(n, vec.data.len());
let d = vec.data[0..n].to_vec();
vec.data.drain(0..n);
if !vec.write_open && vec.data.len() == 0 {
vec.read_open = false;
}
d
}
pub fn set_data(&self, buf:&Vec<u8>) {
let heap = &mut bheap().lock();
let vec = heap.get(self.data_ref);
let len = buf.len();
vec.data.resize(len, 0); vec.data.clone_from_slice(buf);
vec.len = len;
vec.write_open = false;
}
pub fn current_len(&self) -> usize {
let heap = &mut bheap().lock();
let vec = heap.get(self.data_ref);
vec.data.len()
}
pub fn stream_len(&self) -> usize {
let heap = &mut bheap().lock();
let vec = heap.get(self.data_ref);
vec.len
}
pub fn set_stream_len(&self, len: usize) {
let heap = &mut bheap().lock();
let vec = heap.get(self.data_ref);
vec.len = len;
}
pub fn is_write_open(&self) -> bool {
let heap = &mut bheap().lock();
let vec = heap.get(self.data_ref);
vec.write_open
}
pub fn is_read_open(&self) -> bool {
let heap = &mut bheap().lock();
let vec = heap.get(self.data_ref);
vec.read_open
}
pub fn close_write(&self) {
let heap = &mut bheap().lock();
let vec = heap.get(self.data_ref);
vec.write_open = false;
}
pub fn close_read(&self) {
let heap = &mut bheap().lock();
let vec = heap.get(self.data_ref);
vec.read_open = false;
}
pub fn set_mime_type(&self, mime:Option<String>) {
let heap = &mut bheap().lock();
let vec = heap.get(self.data_ref);
vec.mime_type = mime;
}
pub fn get_mime_type(&self) -> Option<String> {
let heap = &mut bheap().lock();
let vec = heap.get(self.data_ref);
vec.mime_type.to_owned()
}
pub fn get(data_ref: usize) -> DataBytes {
let o = DataBytes{
data_ref: data_ref,
};
let _x = &mut bheap().lock().incr(data_ref);
o
}
pub fn incr(&self) {
let bheap = &mut bheap().lock();
bheap.incr(self.data_ref);
}
pub fn decr(&self) {
let bheap = &mut bheap().lock();
bheap.decr(self.data_ref);
}
#[deprecated(since="0.3.0", note="please use `clone` instead")]
pub fn duplicate(&self) -> DataBytes {
self.clone()
}
pub fn deep_copy(&self) -> DataBytes {
let heap = &mut bheap().lock();
let bytes = heap.get(self.data_ref);
let vec = bytes.deep_copy();
let data_ref = &mut bheap().lock().push(vec);
return DataBytes {
data_ref: *data_ref,
};
}
pub fn to_hex_string(&self) -> String {
let heap = &mut bheap().lock();
let bytes = heap.get(self.data_ref);
let strs: Vec<String> = bytes.data.iter()
.map(|b| format!("{:02X}", b))
.collect();
strs.join(" ")
}
#[cfg(not(feature="no_std_support"))]
pub fn print_heap() {
println!("bytes {:?}", &mut bheap().lock().keys());
}
pub fn gc() {
let bheap = &mut bheap().lock();
let bdrop = &mut bdrop().lock();
let mut i = bdrop.len();
while i>0 {
i = i - 1;
let x = bdrop.remove(0);
bheap.decr(x);
}
}
}
impl Drop for DataBytes {
fn drop(&mut self) {
bdrop().lock().push(self.data_ref);
}
}