blob: 97838c21c4c0537d903b429dece80f1506d8604e [file] [log] [blame]
Austin Schuh272c6132020-11-14 16:37:52 -08001// 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
15use crate::bitwidth::{align, BitWidth};
16mod value;
17use crate::FlexBufferType;
18use std::cmp::max;
19use value::{find_vector_type, store_value, Value};
20mod map;
21mod push;
22mod ser;
23mod vector;
24use map::sort_map_by_keys;
25pub use map::MapBuilder;
26pub use push::Pushable;
27pub use ser::{Error, FlexbufferSerializer};
28pub use vector::VectorBuilder;
29
30macro_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,
James Kuszmaul8e62b022022-03-22 09:33:25 -070035 S: AsRef<[T]>,
Austin Schuh272c6132020-11-14 16:37:52 -080036 {
37 let mut value = Value::$new_vec(xs.as_ref().len());
James Kuszmaul8e62b022022-03-22 09:33:25 -070038 let mut width = xs
39 .as_ref()
Austin Schuh272c6132020-11-14 16:37:52 -080040 .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 }
James Kuszmaul8e62b022022-03-22 09:33:25 -070060 };
Austin Schuh272c6132020-11-14 16:37:52 -080061}
62macro_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);
James Kuszmaul8e62b022022-03-22 09:33:25 -070069 self.values.push(Value::Reference {
70 address,
71 child_width,
72 fxb_type: FlexBufferType::$Indirect,
73 });
Austin Schuh272c6132020-11-14 16:37:52 -080074 }
James Kuszmaul8e62b022022-03-22 09:33:25 -070075 };
Austin Schuh272c6132020-11-14 16:37:52 -080076}
77
78bitflags! {
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}
98impl Default for BuilderOptions {
99 fn default() -> Self {
100 Self::SHARE_KEYS
101 }
102}
103
104#[derive(Debug, Clone, Copy)]
105// Address of a Key inside of the buffer.
106struct 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)]
124pub struct Builder {
125 buffer: Vec<u8>,
126 values: Vec<Value>,
127 key_pool: Option<Vec<CachedKey>>,
128}
129impl Default for Builder {
130 fn default() -> Self {
131 let opts = Default::default();
132 Builder::new(opts)
133 }
134}
135
136impl<'a> Builder {
137 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.
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.
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.
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 }
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 }
198 fn push_uint<T: Into<u64>>(&mut self, x: T) {
199 self.values.push(Value::UInt(x.into()));
200 }
201 fn push_int<T: Into<i64>>(&mut self, x: T) {
202 self.values.push(Value::Int(x.into()));
203 }
204 fn push_float<T: Into<f64>>(&mut self, x: T) {
205 self.values.push(Value::Float(x.into()));
206 }
207 fn push_null(&mut self) {
208 self.values.push(Value::Null);
209 }
210 fn push_bool(&mut self, x: bool) {
211 self.values.push(Value::Bool(x));
212 }
213 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 }
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 }
232 fn push_blob(&mut self, x: &[u8]) {
233 let blob = self.store_blob(x);
234 self.values.push(blob);
235 }
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);
James Kuszmaul8e62b022022-03-22 09:33:25 -0700244 self.buffer.resize(self.buffer.len() + width as usize, 0);
Austin Schuh272c6132020-11-14 16:37:52 -0800245 }
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.
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.
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.
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 }
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.
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.
310pub 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.
319fn 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
327pub 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)]
335pub 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}