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