flatbuffers_rust/flatbuffers/
flatbuffer.rs

1use std::cell::RefCell;
2use std::rc::Rc;
3// flatbuffer 作为网络中传输的数据序列化工具
4// 本质就是一个连续的bytes数组
5
6/**                FlatBuffer 结构示意图  
7 *       
8 * SEPARATOR         vtable         pivot  SEPARATOR+data0  SEPARATOR+data1   S+d*
9 *            slot0   slot1  slot*  
10 *   0x55   | 4bytes  4bytes  ~~~ | 1byte | 0x55 + n bytes | 0x55 + n bytes | ~~~ | 
11 *           offset from the pivot
12 */
13
14// 需要生成用于网络传输的bytes数组时,将vtable pivot data 拼接起来
15static SEPARATOR: u8 = 0xff;
16
17#[derive(Debug, Clone)]
18// pivot 或者 data 至少一个不为None
19pub struct FlatBuffer {
20    pub vtable: Option<Rc<RefCell<Vec<u32>>>>, // 一个slot 占用的大小为4bytes
21    pivot: Option<u8>, // 表示vtable的length (255应该足够) 
22    pub data: Option<Rc<RefCell<Vec<u8>>>> // 原始的数据 头部填充 pivot*4+1+1 bytes
23}
24
25impl FlatBuffer {
26    pub fn new() -> FlatBuffer {
27        FlatBuffer {
28            vtable: None,
29            pivot: None,
30            data: None
31        }
32    }
33    pub fn with_pivot(num: u8) -> FlatBuffer {
34        let mut vtable = Vec::with_capacity(num as usize);
35        for _i in 0..num {
36            vtable.push(0u32);
37        }
38        FlatBuffer {
39            vtable: Some(Rc::new(RefCell::new(vtable))),
40            pivot: Some(num),
41            data: None,
42        }
43    }
44    pub fn with_primitive_type(data:&mut Vec<u8>) -> FlatBuffer {
45        // 在前方添加一个 SEPARATOR
46        let len = data.len();
47        let mut flatdata = Vec::with_capacity(len + 1);
48        flatdata.push(SEPARATOR);
49        for i in 0..len {
50            flatdata.push(data[i]);
51        }
52        FlatBuffer {
53            vtable: None,
54            pivot: None,
55            data: Some(Rc::new(RefCell::new(flatdata))),
56        }
57    }
58    // 返回字节数组,并且包含root的位置
59    pub fn bytes(&mut self) -> (Option<Vec<u8>>, usize) {
60        // 第一个字节一定是 SEPARATOR
61        let mut bytes = Vec::new();
62        let mut root = 0; // (None, 0)
63        // 判断是否为 primitive type 可以优化,步骤多余
64        match self.pivot {
65            None => (),
66            Some(pivot) => { bytes.push(SEPARATOR); root = 1;},
67        };
68        // 将 vtable 添加入bytes中
69        match self.vtable_to_bytes() {
70            None => (),
71            Some(mut vec) => bytes.append(&mut vec),
72        };
73        // 将 pivot 添加入bytes中
74        match self.pivot {
75            None => (),
76            Some(pivot) => { bytes.push(pivot); root = bytes.len() - 1;},
77        };
78        // 将 data 添加入bytes中
79        match self.data {
80            None => (),
81            // 逻辑有点问题,可能需要修改,没有clone 会出现难以想象的错误
82            Some(ref mut data) => bytes.append(&mut data.borrow_mut().clone()),
83        };
84        if bytes.len() == 0 {
85            (None, root)
86        } else {
87            (Some(bytes), root)
88        }
89    }
90    // pub fn add_data(flatbuffer: FlatBuffer, add:&mut Vec<u8>) -> FlatBuffer {
91    //     flatbuffer.data.unwrap().append(add);
92    //     flatbuffer
93    // }
94    fn vtable_to_bytes(&mut self) -> Option<Vec<u8>> {
95        let vtable = self.vtable.clone();
96        let table = match vtable {
97            None => return None,
98            Some(table) => table,
99        };
100        let mut bytes = Vec::new();
101        let slots_num = table.borrow().len();
102        for i in 0..slots_num {
103            let offset = table.borrow_mut()[i];
104            let b0 : u8 = ((offset >> 24) & 0xff) as u8;
105            let b1 : u8 = ((offset >> 16) & 0xff) as u8;
106            let b2 : u8 = ((offset >> 8) & 0xff) as u8;
107            let b3 : u8 = (offset & 0xff) as u8;
108            bytes.push(b3);
109            bytes.push(b2);
110            bytes.push(b1);
111            bytes.push(b0);
112        }
113        Some(bytes)
114    }
115}