use desert::{ToBytes,FromBytes,CountBytes,varint};
use crate::{Point,Meta,TreeRef,Error,EyrosErrorKind};
impl<P> ToBytes for Meta<P> where P: Point, Self: CountBytes {
fn to_bytes(&self) -> Result<Vec<u8>,Error> {
let mut offset = 0;
let mut buf = vec![0u8;self.count_bytes()];
offset += varint::encode(self.next_tree as u64, &mut buf[offset..])?;
offset += varint::encode(self.roots.len() as u64, &mut buf[offset..])?;
for (i,r) in self.roots.iter().enumerate() {
if r.is_some() {
buf[offset+i/8] |= 1<<(i%8);
}
}
offset += (self.roots.len()+7)/8;
for root in self.roots.iter() {
match root {
Some(r) => {
offset += varint::encode(r.id as u64, &mut buf[offset..])?;
offset += r.bounds.to_bounds().unwrap().write_bytes(&mut buf[offset..])?;
},
None => {},
}
}
Ok(buf)
}
}
impl<P> FromBytes for Meta<P> where P: Point {
fn from_bytes(src: &[u8]) -> Result<(usize,Self),Error> {
let mut offset = 0;
let (n,next_tree) = varint::decode(&src[offset..])?;
offset += n;
let (n,len64) = varint::decode(&src[offset..])?;
offset += n;
let len = len64 as usize;
if src.len() < offset + (len+7)/8 {
return EyrosErrorKind::MetaBitfieldInsufficientBytes {}.raise();
}
let bitfield = &src[offset..offset+(len+7)/8];
offset += (len+7)/8;
let mut roots = Vec::with_capacity(len);
for i in 0..(len as usize) {
if (bitfield[i/8]>>(i%8))&1==1 {
let (n,id) = varint::decode(&src[offset..])?;
offset += n;
let (n,bounds) = <P::Bounds>::from_bytes(&src[offset..])?;
offset += n;
roots.push(Some(TreeRef { id, bounds: P::from_bounds(&bounds) }));
} else {
roots.push(None);
}
}
Ok((offset,Self { roots, next_tree }))
}
}
impl<P> CountBytes for Meta<P> where P: Point {
fn count_bytes(&self) -> usize {
let mut size = 0;
size += varint::length(self.next_tree as u64);
size += varint::length(self.roots.len() as u64);
size += (self.roots.len()+7)/8;
for root in self.roots.iter() {
size += match root {
Some(r) => varint::length(r.id as u64)
+ &r.bounds.to_bounds().unwrap().count_bytes(),
None => 0,
}
}
size
}
fn count_from_bytes(_src: &[u8]) -> Result<usize,Error> {
unimplemented![]
}
}