xref: /aosp_15_r20/external/flatbuffers/rust/flexbuffers/src/builder/mod.rs (revision 890232f25432b36107d06881e0a25aaa6b473652)
1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 use crate::bitwidth::{align, BitWidth};
16 mod value;
17 use crate::FlexBufferType;
18 use std::cmp::max;
19 use value::{find_vector_type, store_value, Value};
20 mod map;
21 mod push;
22 mod ser;
23 mod vector;
24 use map::sort_map_by_keys;
25 pub use map::MapBuilder;
26 pub use push::Pushable;
27 pub use ser::{Error, FlexbufferSerializer};
28 pub use vector::VectorBuilder;
29 
30 macro_rules! push_slice {
31     ($push_name: ident, $scalar: ty, $Val: ident, $new_vec: ident) => {
32         fn $push_name<T, S>(&mut self, xs: S)
33         where
34             T: Into<$scalar> + Copy,
35             S: AsRef<[T]>,
36         {
37             let mut value = Value::$new_vec(xs.as_ref().len());
38             let mut width = xs
39                 .as_ref()
40                 .iter()
41                 .map(|x| BitWidth::from((*x).into()))
42                 .max()
43                 .unwrap_or_default();
44             if !value.is_fixed_length_vector() {
45                 let length = Value::UInt(xs.as_ref().len() as u64);
46                 width = std::cmp::max(width, length.width_or_child_width());
47                 align(&mut self.buffer, width);
48                 store_value(&mut self.buffer, length, width);
49             } else {
50                 align(&mut self.buffer, width);
51             }
52             let address = self.buffer.len();
53             for &x in xs.as_ref().iter() {
54                 store_value(&mut self.buffer, Value::$Val(x.into()), width);
55             }
56             value.set_address_or_panic(address);
57             value.set_child_width_or_panic(width);
58             self.values.push(value);
59         }
60     };
61 }
62 macro_rules! push_indirect {
63     ($push_name: ident, $scalar: ty, $Direct: ident, $Indirect: ident) => {
64         fn $push_name<T: Into<$scalar>>(&mut self, x: T) {
65             let x = Value::$Direct(x.into());
66             let child_width = x.width_or_child_width();
67             let address = self.buffer.len();
68             store_value(&mut self.buffer, x, child_width);
69             self.values.push(Value::Reference {
70                 address,
71                 child_width,
72                 fxb_type: FlexBufferType::$Indirect,
73             });
74         }
75     };
76 }
77 
78 bitflags! {
79     /// Options for sharing data within a flexbuffer.
80     ///
81     /// These increase serialization time but decrease the size of the resulting buffer. By
82     /// default, `SHARE_KEYS`. You may wish to turn on `SHARE_STRINGS` if you know your data has
83     /// many duplicate strings or `SHARE_KEY_VECTORS` if your data has many maps with identical
84     /// keys.
85     ///
86     /// ## Not Yet Implemented
87     /// - `SHARE_STRINGS`
88     /// - `SHARE_KEY_VECTORS`
89     pub struct BuilderOptions: u8 {
90         const SHARE_NONE = 0;
91         const SHARE_KEYS = 1;
92         const SHARE_STRINGS = 2;
93         const SHARE_KEYS_AND_STRINGS = 3;
94         const SHARE_KEY_VECTORS = 4;
95         const SHARE_ALL = 7;
96     }
97 }
98 impl Default for BuilderOptions {
default() -> Self99     fn default() -> Self {
100         Self::SHARE_KEYS
101     }
102 }
103 
104 #[derive(Debug, Clone, Copy)]
105 // Address of a Key inside of the buffer.
106 struct CachedKey(usize);
107 
108 /// **Use this struct to build a Flexbuffer.**
109 ///
110 /// Flexbuffers may only have a single root value, which may be constructed
111 /// with  one of the following functions.
112 /// * `build_singleton` will push 1 value to the buffer and serialize it as the root.
113 /// * `start_vector` returns a `VectorBuilder`, into which many (potentially
114 /// heterogenous) values can be pushed. The vector itself is the root and is serialized
115 /// when the `VectorBuilder` is dropped (or `end` is called).
116 /// * `start_map` returns a `MapBuilder`, which is similar to a `VectorBuilder` except
117 /// every value must be pushed with an associated key. The map is serialized when the
118 /// `MapBuilder` is dropped (or `end` is called).
119 ///
120 /// These functions reset and overwrite the Builder which means, while there are no
121 /// active `MapBuilder` or `VectorBuilder`, the internal buffer is empty or contains a
122 /// finished Flexbuffer. The internal buffer is accessed with `view`.
123 #[derive(Debug, Clone)]
124 pub struct Builder {
125     buffer: Vec<u8>,
126     values: Vec<Value>,
127     key_pool: Option<Vec<CachedKey>>,
128 }
129 impl Default for Builder {
default() -> Self130     fn default() -> Self {
131         let opts = Default::default();
132         Builder::new(opts)
133     }
134 }
135 
136 impl<'a> Builder {
new(opts: BuilderOptions) -> Self137     pub fn new(opts: BuilderOptions) -> Self {
138         let key_pool = if opts.contains(BuilderOptions::SHARE_KEYS) {
139             Some(vec![])
140         } else {
141             None
142         };
143         Builder {
144             key_pool,
145             values: Vec::new(),
146             buffer: Vec::new(),
147         }
148     }
149     /// Shows the internal flexbuffer. It will either be empty or populated with the most
150     /// recently built flexbuffer.
view(&self) -> &[u8]151     pub fn view(&self) -> &[u8] {
152         &self.buffer
153     }
154     /// Returns the internal buffer, replacing it with a new vector. The returned buffer will
155     /// either be empty or populated with the most recently built flexbuffer.
take_buffer(&mut self) -> Vec<u8>156     pub fn take_buffer(&mut self) -> Vec<u8> {
157         let mut b = Vec::new();
158         std::mem::swap(&mut self.buffer, &mut b);
159         b
160     }
161     /// Resets the internal state. Automatically called before building a new flexbuffer.
reset(&mut self)162     pub fn reset(&mut self) {
163         self.buffer.clear();
164         self.values.clear();
165         if let Some(pool) = self.key_pool.as_mut() {
166             pool.clear();
167         }
168     }
push_key(&mut self, key: &str)169     fn push_key(&mut self, key: &str) {
170         debug_assert!(
171             key.bytes().all(|b| b != b'\0'),
172             "Keys must not have internal nulls."
173         );
174         // Search key pool if there is one.
175         let found = self.key_pool.as_ref().map(|pool| {
176             pool.binary_search_by(|&CachedKey(addr)| {
177                 let old_key = map::get_key(&self.buffer, addr);
178                 old_key.cloned().cmp(key.bytes())
179             })
180         });
181         let address = if let Some(Ok(idx)) = found {
182             // Found key in key pool.
183             self.key_pool.as_ref().unwrap()[idx].0
184         } else {
185             // Key not in pool (or no pool).
186             let address = self.buffer.len();
187             self.buffer.extend_from_slice(key.as_bytes());
188             self.buffer.push(b'\0');
189             address
190         };
191         if let Some(Err(idx)) = found {
192             // Insert into key pool.
193             let pool = self.key_pool.as_mut().unwrap();
194             pool.insert(idx, CachedKey(address));
195         }
196         self.values.push(Value::Key(address));
197     }
push_uint<T: Into<u64>>(&mut self, x: T)198     fn push_uint<T: Into<u64>>(&mut self, x: T) {
199         self.values.push(Value::UInt(x.into()));
200     }
push_int<T: Into<i64>>(&mut self, x: T)201     fn push_int<T: Into<i64>>(&mut self, x: T) {
202         self.values.push(Value::Int(x.into()));
203     }
push_float<T: Into<f64>>(&mut self, x: T)204     fn push_float<T: Into<f64>>(&mut self, x: T) {
205         self.values.push(Value::Float(x.into()));
206     }
push_null(&mut self)207     fn push_null(&mut self) {
208         self.values.push(Value::Null);
209     }
push_bool(&mut self, x: bool)210     fn push_bool(&mut self, x: bool) {
211         self.values.push(Value::Bool(x));
212     }
store_blob(&mut self, xs: &[u8]) -> Value213     fn store_blob(&mut self, xs: &[u8]) -> Value {
214         let length = Value::UInt(xs.len() as u64);
215         let width = length.width_or_child_width();
216         align(&mut self.buffer, width);
217         store_value(&mut self.buffer, length, width);
218         let address = self.buffer.len();
219         self.buffer.extend_from_slice(xs);
220         Value::Reference {
221             fxb_type: FlexBufferType::Blob,
222             address,
223             child_width: width,
224         }
225     }
push_str(&mut self, x: &str)226     fn push_str(&mut self, x: &str) {
227         let mut string = self.store_blob(x.as_bytes());
228         self.buffer.push(b'\0');
229         string.set_fxb_type_or_panic(FlexBufferType::String);
230         self.values.push(string);
231     }
push_blob(&mut self, x: &[u8])232     fn push_blob(&mut self, x: &[u8]) {
233         let blob = self.store_blob(x);
234         self.values.push(blob);
235     }
push_bools(&mut self, xs: &[bool])236     fn push_bools(&mut self, xs: &[bool]) {
237         let length = Value::UInt(xs.len() as u64);
238         let width = length.width_or_child_width();
239         align(&mut self.buffer, width);
240         store_value(&mut self.buffer, length, width);
241         let address = self.buffer.len();
242         for &b in xs.iter() {
243             self.buffer.push(b as u8);
244             self.buffer.resize(self.buffer.len() + width as usize, 0);
245         }
246         self.values.push(Value::Reference {
247             fxb_type: FlexBufferType::VectorBool,
248             address,
249             child_width: width,
250         });
251     }
252 
253     push_slice!(push_uints, u64, UInt, new_uint_vector);
254     push_slice!(push_ints, i64, Int, new_int_vector);
255     push_slice!(push_floats, f64, Float, new_float_vector);
256     push_indirect!(push_indirect_int, i64, Int, IndirectInt);
257     push_indirect!(push_indirect_uint, u64, UInt, IndirectUInt);
258     push_indirect!(push_indirect_float, f64, Float, IndirectFloat);
259 
260     /// Resets the builder and starts a new flexbuffer with a vector at the root.
261     /// The exact Flexbuffer vector type is dynamically inferred.
start_vector(&'a mut self) -> VectorBuilder<'a>262     pub fn start_vector(&'a mut self) -> VectorBuilder<'a> {
263         self.reset();
264         VectorBuilder {
265             builder: self,
266             start: None,
267         }
268     }
269     /// Resets the builder and builds a new flexbuffer with a map at the root.
start_map(&'a mut self) -> MapBuilder<'a>270     pub fn start_map(&'a mut self) -> MapBuilder<'a> {
271         self.reset();
272         MapBuilder {
273             builder: self,
274             start: None,
275         }
276     }
277     /// Resets the builder and builds a new flexbuffer with the pushed value at the root.
build_singleton<P: Pushable>(&mut self, p: P)278     pub fn build_singleton<P: Pushable>(&mut self, p: P) {
279         self.reset();
280         p.push_to_builder(self);
281         let root = self.values.pop().unwrap();
282         store_root(&mut self.buffer, root);
283     }
push<P: Pushable>(&mut self, p: P)284     fn push<P: Pushable>(&mut self, p: P) {
285         p.push_to_builder(self);
286     }
287     /// Stores the values past `previous_end` as a map or vector depending on `is_map`.
288     /// If `previous_end` is None then this was a root map / vector and the last value
289     /// is stored as the root.
end_map_or_vector(&mut self, is_map: bool, previous_end: Option<usize>)290     fn end_map_or_vector(&mut self, is_map: bool, previous_end: Option<usize>) {
291         let split = previous_end.unwrap_or(0);
292         let value = if is_map {
293             let key_vals = &mut self.values[split..];
294             sort_map_by_keys(key_vals, &self.buffer);
295             let key_vector = store_vector(&mut self.buffer, key_vals, StoreOption::MapKeys);
296             store_vector(&mut self.buffer, key_vals, StoreOption::Map(key_vector))
297         } else {
298             store_vector(&mut self.buffer, &self.values[split..], StoreOption::Vector)
299         };
300         self.values.truncate(split);
301         if previous_end.is_some() {
302             self.values.push(value);
303         } else {
304             store_root(&mut self.buffer, value);
305         }
306     }
307 }
308 
309 /// Builds a Flexbuffer with the single pushed value as the root.
singleton<P: Pushable>(p: P) -> Vec<u8>310 pub fn singleton<P: Pushable>(p: P) -> Vec<u8> {
311     let mut b = Builder::default();
312     b.build_singleton(p);
313     let Builder { buffer, .. } = b;
314     buffer
315 }
316 
317 /// Stores the root value, root type and root width.
318 /// This should be called to finish the Flexbuffer.
store_root(buffer: &mut Vec<u8>, root: Value)319 fn store_root(buffer: &mut Vec<u8>, root: Value) {
320     let root_width = root.width_in_vector(buffer.len(), 0);
321     align(buffer, root_width);
322     store_value(buffer, root, root_width);
323     buffer.push(root.packed_type(root_width));
324     buffer.push(root_width.n_bytes() as u8);
325 }
326 
327 pub enum StoreOption {
328     Vector,
329     Map(Value),
330     MapKeys,
331 }
332 /// Writes a Flexbuffer Vector or Map.
333 /// StoreOption::Map(Keys) must be a Value::Key or this will panic.
334 // #[inline(always)]
store_vector(buffer: &mut Vec<u8>, values: &[Value], opt: StoreOption) -> Value335 pub fn store_vector(buffer: &mut Vec<u8>, values: &[Value], opt: StoreOption) -> Value {
336     let (skip, stride) = match opt {
337         StoreOption::Vector => (0, 1),
338         StoreOption::MapKeys => (0, 2),
339         StoreOption::Map(_) => (1, 2),
340     };
341     let iter_values = || values.iter().skip(skip).step_by(stride);
342 
343     // Figure out vector type and how long is the prefix.
344     let mut result = if let StoreOption::Map(_) = opt {
345         Value::new_map()
346     } else {
347         find_vector_type(iter_values())
348     };
349     let length_slot = if !result.is_fixed_length_vector() {
350         let length = iter_values().count();
351         Some(Value::UInt(length as u64))
352     } else {
353         None
354     };
355     // Measure required width and align to it.
356     let mut width = BitWidth::W8;
357     if let StoreOption::Map(keys) = opt {
358         width = max(width, keys.width_in_vector(buffer.len(), 0))
359     }
360     if let Some(l) = length_slot {
361         width = max(width, l.width_or_child_width());
362     }
363     let prefix_length = result.prefix_length();
364     for (i, &val) in iter_values().enumerate() {
365         width = max(width, val.width_in_vector(buffer.len(), i + prefix_length));
366     }
367     align(buffer, width);
368     #[allow(deprecated)]
369     {
370         debug_assert_ne!(
371             result.fxb_type(),
372             FlexBufferType::VectorString,
373             "VectorString is deprecated and cannot be written.\
374              (https://github.com/google/flatbuffers/issues/5627)"
375         );
376     }
377     // Write Prefix.
378     if let StoreOption::Map(keys) = opt {
379         let key_width = Value::UInt(keys.width_or_child_width().n_bytes() as u64);
380         store_value(buffer, keys, width);
381         store_value(buffer, key_width, width);
382     }
383     if let Some(len) = length_slot {
384         store_value(buffer, len, width);
385     }
386     // Write data.
387     let address = buffer.len();
388     for &v in iter_values() {
389         store_value(buffer, v, width);
390     }
391     // Write types
392     if result.is_typed_vector_or_map() {
393         for v in iter_values() {
394             buffer.push(v.packed_type(width));
395         }
396     }
397     // Return Value representing this Vector.
398     result.set_address_or_panic(address);
399     result.set_child_width_or_panic(width);
400     result
401 }
402