use flatbuffers::flatbuffer_manager::FlatBufferManager;
static SEPARATOR: u8 = 0xff;
#[derive(Debug)]
pub struct FlatBufferHandler {}
impl FlatBufferHandler {
pub fn get_field_bytes_pivot(&self, type_name: &str, field_name: &str, manager: &FlatBufferManager, data: &mut Vec<u8>, pivot: usize) -> Result<(Option<Vec<u8>>, usize), String> {
let mut vec = manager.to_local_vec(field_name, type_name).unwrap();
let mut position = manager.field_position(&mut vec).unwrap();
self.get_part_data_level(&mut position, pivot, &data)
}
pub fn get_part_data_level(&self, level:&mut Vec<usize>, root: usize, data: &Vec<u8>) -> Result<(Option<Vec<u8>>, usize), String> {
let l = level.len();
let mut want_vec = Vec::new();
let mut want_root = 0;
let part = level.pop().unwrap();
let (child_data, child_root) = match self.get_part_data(part, root, &data) {
Ok((child_data, child_root)) => (child_data, child_root),
Err(e) => return Err(e),
};
match child_data {
Some(d) => { want_vec = d; want_root = child_root; },
None => {
if 1 == l {
return Ok((None, 0)); } else {
return Err(format!("访问层次有误"));
}
},
};
for i in 0..l-1 {
let part = level.pop().unwrap();
let (child_data, child_root) = match self.get_part_data(part, want_root, &want_vec) {
Ok((child_data, child_root)) => (child_data, child_root),
Err(e) => return Err(e),
};
match child_data {
Some(d) => { want_vec = d; want_root = child_root; },
None => {
if i == l {
return Ok((None, 0)); } else {
return Err(format!("访问层次有误"));
}
},
};
}
Ok((Some(want_vec), want_root))
}
pub fn get_part_data(&self, part: usize, root: usize, data: &Vec<u8>) -> Result<(Option<Vec<u8>>, usize), String> {
if part == 0 {
return Err(format!("part is {}", part));
}
if root == 1 {
return Err(format!("{:?} is a primitive type", data));
}
let slot_num = data[root] as usize;
if part > slot_num {
return Err(format!("slot's num is {}, {} > slot's", slot_num, part));
}
let (start, child_root) = self.get_start(part, slot_num, root, data);
if start == 0 {
return Ok((None, 0));
}
let end = self.get_end(part, slot_num, root, data);
Ok((Some(data[start..end].to_vec()), child_root-start))
}
fn get_end(&self, part: usize, slot_num: usize, root: usize, data: &Vec<u8>) -> usize {
let mut part = part;
if slot_num == part {
return data.len();
} else {
loop {
part += 1;
if slot_num == part && data[root - 4] == 0u8 {
return data.len();
}
let (end, pivot) = self.get_start(part, slot_num, root, data);
if end != 0 {
return end;
}
}
}
}
fn get_start(&self, part: usize, slot_num: usize, root: usize, data: &Vec<u8>) -> (usize, usize) {
let size = 4;
let mut offset = 0;
let mut scale = 1;
let offset_vec = data[root-(slot_num-part+1)*size..root-(slot_num-part)*size].to_vec();
for i in 0..size {
offset += (offset_vec[i] as usize) *scale;
scale *= 256;
}
if offset == 0 {
return (0, 0);
}
let child_root = offset as usize + root;
let mut start = 0;
if data[child_root - 1] == SEPARATOR {
start = child_root - 1;
} else {
let child_slot_num = data[child_root];
start = child_root - size*child_slot_num as usize -1; }
(start, child_root)
}
}