use std::cell::RefCell;
use std::rc::Rc;
static SEPARATOR: u8 = 0xff;
#[derive(Debug, Clone)]
pub struct FlatBuffer {
pub vtable: Option<Rc<RefCell<Vec<u32>>>>, pivot: Option<u8>, pub data: Option<Rc<RefCell<Vec<u8>>>> }
impl FlatBuffer {
pub fn new() -> FlatBuffer {
FlatBuffer {
vtable: None,
pivot: None,
data: None
}
}
pub fn with_pivot(num: u8) -> FlatBuffer {
let mut vtable = Vec::with_capacity(num as usize);
for _i in 0..num {
vtable.push(0u32);
}
FlatBuffer {
vtable: Some(Rc::new(RefCell::new(vtable))),
pivot: Some(num),
data: None,
}
}
pub fn with_primitive_type(data:&mut Vec<u8>) -> FlatBuffer {
let len = data.len();
let mut flatdata = Vec::with_capacity(len + 1);
flatdata.push(SEPARATOR);
for i in 0..len {
flatdata.push(data[i]);
}
FlatBuffer {
vtable: None,
pivot: None,
data: Some(Rc::new(RefCell::new(flatdata))),
}
}
pub fn bytes(&mut self) -> (Option<Vec<u8>>, usize) {
let mut bytes = Vec::new();
let mut root = 0; match self.pivot {
None => (),
Some(pivot) => { bytes.push(SEPARATOR); root = 1;},
};
match self.vtable_to_bytes() {
None => (),
Some(mut vec) => bytes.append(&mut vec),
};
match self.pivot {
None => (),
Some(pivot) => { bytes.push(pivot); root = bytes.len() - 1;},
};
match self.data {
None => (),
Some(ref mut data) => bytes.append(&mut data.borrow_mut().clone()),
};
if bytes.len() == 0 {
(None, root)
} else {
(Some(bytes), root)
}
}
fn vtable_to_bytes(&mut self) -> Option<Vec<u8>> {
let vtable = self.vtable.clone();
let table = match vtable {
None => return None,
Some(table) => table,
};
let mut bytes = Vec::new();
let slots_num = table.borrow().len();
for i in 0..slots_num {
let offset = table.borrow_mut()[i];
let b0 : u8 = ((offset >> 24) & 0xff) as u8;
let b1 : u8 = ((offset >> 16) & 0xff) as u8;
let b2 : u8 = ((offset >> 8) & 0xff) as u8;
let b3 : u8 = (offset & 0xff) as u8;
bytes.push(b3);
bytes.push(b2);
bytes.push(b1);
bytes.push(b0);
}
Some(bytes)
}
}