Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame^] | 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.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 | } |
| 61 | macro_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 | |
| 79 | bitflags! { |
| 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 | } |
| 99 | impl 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. |
| 107 | struct 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)] |
| 125 | pub struct Builder { |
| 126 | buffer: Vec<u8>, |
| 127 | values: Vec<Value>, |
| 128 | key_pool: Option<Vec<CachedKey>>, |
| 129 | } |
| 130 | impl Default for Builder { |
| 131 | fn default() -> Self { |
| 132 | let opts = Default::default(); |
| 133 | Builder::new(opts) |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | impl<'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. |
| 313 | pub 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. |
| 322 | fn 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 | |
| 330 | pub 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)] |
| 338 | pub 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 | } |