xref: /aosp_15_r20/external/flatbuffers/rust/flexbuffers/src/reader/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::BitWidth;
16 use crate::flexbuffer_type::FlexBufferType;
17 use crate::{Blob, Buffer};
18 use std::convert::{TryFrom, TryInto};
19 use std::fmt;
20 use std::ops::Rem;
21 use std::str::FromStr;
22 mod de;
23 mod iter;
24 mod map;
25 mod serialize;
26 mod vector;
27 pub use de::DeserializationError;
28 pub use iter::ReaderIterator;
29 pub use map::{MapReader, MapReaderIndexer};
30 pub use vector::VectorReader;
31 
32 /// All the possible errors when reading a flexbuffer.
33 #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
34 pub enum Error {
35     /// One of the following data errors occured:
36     ///
37     /// *    The read flexbuffer had an offset that pointed outside the flexbuffer.
38     /// *    The 'negative indicies' where length and map keys are stored were out of bounds
39     /// *    The buffer was too small to contain a flexbuffer root.
40     FlexbufferOutOfBounds,
41     /// Failed to parse a valid FlexbufferType and Bitwidth from a type byte.
42     InvalidPackedType,
43     /// Flexbuffer type of the read data does not match function used.
44     UnexpectedFlexbufferType {
45         expected: FlexBufferType,
46         actual: FlexBufferType,
47     },
48     /// BitWidth type of the read data does not match function used.
49     UnexpectedBitWidth {
50         expected: BitWidth,
51         actual: BitWidth,
52     },
53     /// Read a flexbuffer offset or length that overflowed usize.
54     ReadUsizeOverflowed,
55     /// Tried to index a type that's not one of the Flexbuffer vector types.
56     CannotIndexAsVector,
57     /// Tried to index a Flexbuffer vector or map out of bounds.
58     IndexOutOfBounds,
59     /// A Map was indexed with a key that it did not contain.
60     KeyNotFound,
61     /// Failed to parse a Utf8 string.
62     /// The Option will be `None` if and only if this Error was deserialized.
63     // NOTE: std::str::Utf8Error does not implement Serialize, Deserialize, nor Default. We tell
64     // serde to skip the field and default to None. We prefer to have the boxed error so it can be
65     // used with std::error::Error::source, though another (worse) option could be to drop that
66     // information.
67     Utf8Error(#[serde(skip)] Option<Box<std::str::Utf8Error>>),
68     /// get_slice failed because the given data buffer is misaligned.
69     AlignmentError,
70     InvalidRootWidth,
71     InvalidMapKeysVectorWidth,
72 }
73 impl std::convert::From<std::str::Utf8Error> for Error {
from(e: std::str::Utf8Error) -> Self74     fn from(e: std::str::Utf8Error) -> Self {
75         Self::Utf8Error(Some(Box::new(e)))
76     }
77 }
78 impl fmt::Display for Error {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result79     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80         match self {
81             Self::UnexpectedBitWidth { expected, actual } => write!(
82                 f,
83                 "Error reading flexbuffer: Expected bitwidth: {:?}, found bitwidth: {:?}",
84                 expected, actual
85             ),
86             Self::UnexpectedFlexbufferType { expected, actual } => write!(
87                 f,
88                 "Error reading flexbuffer: Expected type: {:?}, found type: {:?}",
89                 expected, actual
90             ),
91             _ => write!(f, "Error reading flexbuffer: {:?}", self),
92         }
93     }
94 }
95 impl std::error::Error for Error {
source(&self) -> Option<&(dyn std::error::Error + 'static)>96     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
97         if let Self::Utf8Error(Some(e)) = self {
98             Some(e)
99         } else {
100             None
101         }
102     }
103 }
104 
105 pub trait ReadLE: crate::private::Sealed + std::marker::Sized {
106     const VECTOR_TYPE: FlexBufferType;
107     const WIDTH: BitWidth;
108 }
109 macro_rules! rle {
110     ($T: ty, $VECTOR_TYPE: ident, $WIDTH: ident) => {
111         impl ReadLE for $T {
112             const VECTOR_TYPE: FlexBufferType = FlexBufferType::$VECTOR_TYPE;
113             const WIDTH: BitWidth = BitWidth::$WIDTH;
114         }
115     };
116 }
117 rle!(u8, VectorUInt, W8);
118 rle!(u16, VectorUInt, W16);
119 rle!(u32, VectorUInt, W32);
120 rle!(u64, VectorUInt, W64);
121 rle!(i8, VectorInt, W8);
122 rle!(i16, VectorInt, W16);
123 rle!(i32, VectorInt, W32);
124 rle!(i64, VectorInt, W64);
125 rle!(f32, VectorFloat, W32);
126 rle!(f64, VectorFloat, W64);
127 
128 macro_rules! as_default {
129     ($as: ident, $get: ident, $T: ty) => {
130         pub fn $as(&self) -> $T {
131             self.$get().unwrap_or_default()
132         }
133     };
134 }
135 
136 /// `Reader`s allow access to data stored in a Flexbuffer.
137 ///
138 /// Each reader represents a single address in the buffer so data is read lazily. Start a reader
139 /// by calling `get_root` on your flexbuffer `&[u8]`.
140 ///
141 /// - The `get_T` methods return a `Result<T, Error>`. They return an OK value if and only if the
142 /// flexbuffer type matches `T`. This is analogous to the behavior of Rust's json library, though
143 /// with Result instead of Option.
144 /// - The `as_T` methods will try their best to return to a value of type `T`
145 /// (by casting or even parsing a string if necessary) but ultimately returns `T::default` if it
146 /// fails. This behavior is analogous to that of flexbuffers C++.
147 pub struct Reader<B> {
148     fxb_type: FlexBufferType,
149     width: BitWidth,
150     address: usize,
151     buffer: B,
152 }
153 
154 impl<B: Buffer> Clone for Reader<B> {
clone(&self) -> Self155     fn clone(&self) -> Self {
156         Reader {
157             fxb_type: self.fxb_type,
158             width: self.width,
159             address: self.address,
160             buffer: self.buffer.shallow_copy(),
161         }
162     }
163 }
164 
165 impl<B: Buffer> Default for Reader<B> {
default() -> Self166     fn default() -> Self {
167         Reader {
168             fxb_type: FlexBufferType::default(),
169             width: BitWidth::default(),
170             address: usize::default(),
171             buffer: B::empty(),
172         }
173     }
174 }
175 
176 // manual implementation of Debug because buffer slice can't be automatically displayed
177 impl<B> std::fmt::Debug for Reader<B> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result178     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
179         // skips buffer field
180         f.debug_struct("Reader")
181             .field("fxb_type", &self.fxb_type)
182             .field("width", &self.width)
183             .field("address", &self.address)
184             .finish()
185     }
186 }
187 
188 macro_rules! try_cast_fn {
189     ($name: ident, $full_width: ident, $Ty: ident) => {
190         pub fn $name(&self) -> $Ty {
191             self.$full_width().try_into().unwrap_or_default()
192         }
193     };
194 }
195 
safe_sub(a: usize, b: usize) -> Result<usize, Error>196 fn safe_sub(a: usize, b: usize) -> Result<usize, Error> {
197     a.checked_sub(b).ok_or(Error::FlexbufferOutOfBounds)
198 }
199 
deref_offset(buffer: &[u8], address: usize, width: BitWidth) -> Result<usize, Error>200 fn deref_offset(buffer: &[u8], address: usize, width: BitWidth) -> Result<usize, Error> {
201     let off = read_usize(buffer, address, width);
202     safe_sub(address, off)
203 }
204 
205 impl<B: Buffer> Reader<B> {
new( buffer: B, mut address: usize, mut fxb_type: FlexBufferType, width: BitWidth, parent_width: BitWidth, ) -> Result<Self, Error>206     fn new(
207         buffer: B,
208         mut address: usize,
209         mut fxb_type: FlexBufferType,
210         width: BitWidth,
211         parent_width: BitWidth,
212     ) -> Result<Self, Error> {
213         if fxb_type.is_reference() {
214             address = deref_offset(&buffer, address, parent_width)?;
215             // Indirects were dereferenced.
216             if let Some(t) = fxb_type.to_direct() {
217                 fxb_type = t;
218             }
219         }
220         Ok(Reader {
221             address,
222             fxb_type,
223             width,
224             buffer,
225         })
226     }
227 
228     /// Parses the flexbuffer from the given buffer. Assumes the flexbuffer root is the last byte
229     /// of the buffer.
get_root(buffer: B) -> Result<Self, Error>230     pub fn get_root(buffer: B) -> Result<Self, Error> {
231         let end = buffer.len();
232         if end < 3 {
233             return Err(Error::FlexbufferOutOfBounds);
234         }
235         // Last byte is the root width.
236         let root_width = BitWidth::from_nbytes(buffer[end - 1]).ok_or(Error::InvalidRootWidth)?;
237         // Second last byte is root type.
238         let (fxb_type, width) = unpack_type(buffer[end - 2])?;
239         // Location of root data. (BitWidth bits before root type)
240         let address = safe_sub(end - 2, root_width.n_bytes())?;
241         Self::new(buffer, address, fxb_type, width, root_width)
242     }
243 
244     /// Convenience function to get the underlying buffer. By using `shallow_copy`, this preserves
245     /// the lifetime that the underlying buffer has.
buffer(&self) -> B246     pub fn buffer(&self) -> B {
247         self.buffer.shallow_copy()
248     }
249 
250     /// Returns the FlexBufferType of this Reader.
flexbuffer_type(&self) -> FlexBufferType251     pub fn flexbuffer_type(&self) -> FlexBufferType {
252         self.fxb_type
253     }
254 
255     /// Returns the bitwidth of this Reader.
bitwidth(&self) -> BitWidth256     pub fn bitwidth(&self) -> BitWidth {
257         self.width
258     }
259 
260     /// Returns the length of the Flexbuffer. If the type has no length, or if an error occurs,
261     /// 0 is returned.
length(&self) -> usize262     pub fn length(&self) -> usize {
263         if let Some(len) = self.fxb_type.fixed_length_vector_length() {
264             len
265         } else if self.fxb_type.has_length_slot() && self.address >= self.width.n_bytes() {
266             read_usize(
267                 &self.buffer,
268                 self.address - self.width.n_bytes(),
269                 self.width,
270             )
271         } else {
272             0
273         }
274     }
275     /// Returns true if the flexbuffer is aligned to 8 bytes. This guarantees, for valid
276     /// flexbuffers, that the data is correctly aligned in memory and slices can be read directly
277     /// e.g. with `get_f64s` or `get_i16s`.
278     #[inline]
is_aligned(&self) -> bool279     pub fn is_aligned(&self) -> bool {
280         (self.buffer.as_ptr() as usize).rem(8) == 0
281     }
282 
283     as_default!(as_vector, get_vector, VectorReader<B>);
284     as_default!(as_map, get_map, MapReader<B>);
285 
expect_type(&self, ty: FlexBufferType) -> Result<(), Error>286     fn expect_type(&self, ty: FlexBufferType) -> Result<(), Error> {
287         if self.fxb_type == ty {
288             Ok(())
289         } else {
290             Err(Error::UnexpectedFlexbufferType {
291                 expected: ty,
292                 actual: self.fxb_type,
293             })
294         }
295     }
expect_bw(&self, bw: BitWidth) -> Result<(), Error>296     fn expect_bw(&self, bw: BitWidth) -> Result<(), Error> {
297         if self.width == bw {
298             Ok(())
299         } else {
300             Err(Error::UnexpectedBitWidth {
301                 expected: bw,
302                 actual: self.width,
303             })
304         }
305     }
306 
307     /// Directly reads a slice of type `T` where `T` is one of `u8,u16,u32,u64,i8,i16,i32,i64,f32,f64`.
308     /// Returns Err if the type, bitwidth, or memory alignment does not match. Since the bitwidth is
309     /// dynamic, its better to use a VectorReader unless you know your data and performance is critical.
310     #[cfg(target_endian = "little")]
311     #[deprecated(
312         since = "0.3.0",
313         note = "This function is unsafe - if this functionality is needed use `Reader::buffer::align_to`"
314     )]
get_slice<T: ReadLE>(&self) -> Result<&[T], Error>315     pub fn get_slice<T: ReadLE>(&self) -> Result<&[T], Error> {
316         if self.flexbuffer_type().typed_vector_type() != T::VECTOR_TYPE.typed_vector_type() {
317             self.expect_type(T::VECTOR_TYPE)?;
318         }
319         if self.bitwidth().n_bytes() != std::mem::size_of::<T>() {
320             self.expect_bw(T::WIDTH)?;
321         }
322         let end = self.address + self.length() * std::mem::size_of::<T>();
323         let slice: &[u8] = self
324             .buffer
325             .get(self.address..end)
326             .ok_or(Error::FlexbufferOutOfBounds)?;
327 
328         // `align_to` is required because the point of this function is to directly hand back a
329         // slice of scalars. This can fail because Rust's default allocator is not 16byte aligned
330         // (though in practice this only happens for small buffers).
331         let (pre, mid, suf) = unsafe { slice.align_to::<T>() };
332         if pre.is_empty() && suf.is_empty() {
333             Ok(mid)
334         } else {
335             Err(Error::AlignmentError)
336         }
337     }
338 
339     /// Returns the value of the reader if it is a boolean.
340     /// Otherwise Returns error.
get_bool(&self) -> Result<bool, Error>341     pub fn get_bool(&self) -> Result<bool, Error> {
342         self.expect_type(FlexBufferType::Bool)?;
343         Ok(
344             self.buffer[self.address..self.address + self.width.n_bytes()]
345                 .iter()
346                 .any(|&b| b != 0),
347         )
348     }
349 
350     /// Gets the length of the key if this type is a key.
351     ///
352     /// Otherwise, returns an error.
353     #[inline]
get_key_len(&self) -> Result<usize, Error>354     fn get_key_len(&self) -> Result<usize, Error> {
355         self.expect_type(FlexBufferType::Key)?;
356         let (length, _) = self.buffer[self.address..]
357             .iter()
358             .enumerate()
359             .find(|(_, &b)| b == b'\0')
360             .unwrap_or((0, &0));
361         Ok(length)
362     }
363 
364     /// Retrieves the string value up until the first `\0` character.
get_key(&self) -> Result<B::BufferString, Error>365     pub fn get_key(&self) -> Result<B::BufferString, Error> {
366         let bytes = self
367             .buffer
368             .slice(self.address..self.address + self.get_key_len()?)
369             .ok_or(Error::IndexOutOfBounds)?;
370         Ok(bytes.buffer_str()?)
371     }
372 
get_blob(&self) -> Result<Blob<B>, Error>373     pub fn get_blob(&self) -> Result<Blob<B>, Error> {
374         self.expect_type(FlexBufferType::Blob)?;
375         Ok(Blob(
376             self.buffer
377                 .slice(self.address..self.address + self.length())
378                 .ok_or(Error::IndexOutOfBounds)?,
379         ))
380     }
381 
as_blob(&self) -> Blob<B>382     pub fn as_blob(&self) -> Blob<B> {
383         self.get_blob().unwrap_or(Blob(B::empty()))
384     }
385 
386     /// Retrieves str pointer, errors if invalid UTF-8, or the provided index
387     /// is out of bounds.
get_str(&self) -> Result<B::BufferString, Error>388     pub fn get_str(&self) -> Result<B::BufferString, Error> {
389         self.expect_type(FlexBufferType::String)?;
390         let bytes = self
391             .buffer
392             .slice(self.address..self.address + self.length());
393         Ok(bytes.ok_or(Error::ReadUsizeOverflowed)?.buffer_str()?)
394     }
395 
get_map_info(&self) -> Result<(usize, BitWidth), Error>396     fn get_map_info(&self) -> Result<(usize, BitWidth), Error> {
397         self.expect_type(FlexBufferType::Map)?;
398         if 3 * self.width.n_bytes() >= self.address {
399             return Err(Error::FlexbufferOutOfBounds);
400         }
401         let keys_offset_address = self.address - 3 * self.width.n_bytes();
402         let keys_width = {
403             let kw_addr = self.address - 2 * self.width.n_bytes();
404             let kw = read_usize(&self.buffer, kw_addr, self.width);
405             BitWidth::from_nbytes(kw).ok_or(Error::InvalidMapKeysVectorWidth)
406         }?;
407         Ok((keys_offset_address, keys_width))
408     }
409 
get_map(&self) -> Result<MapReader<B>, Error>410     pub fn get_map(&self) -> Result<MapReader<B>, Error> {
411         let (keys_offset_address, keys_width) = self.get_map_info()?;
412         let keys_address = deref_offset(&self.buffer, keys_offset_address, self.width)?;
413         // TODO(cneo): Check that vectors length equals keys length.
414         Ok(MapReader {
415             buffer: self.buffer.shallow_copy(),
416             values_address: self.address,
417             values_width: self.width,
418             keys_address,
419             keys_width,
420             length: self.length(),
421         })
422     }
423 
424     /// Tries to read a FlexBufferType::UInt. Returns Err if the type is not a UInt or if the
425     /// address is out of bounds.
get_u64(&self) -> Result<u64, Error>426     pub fn get_u64(&self) -> Result<u64, Error> {
427         self.expect_type(FlexBufferType::UInt)?;
428         let cursor = self
429             .buffer
430             .get(self.address..self.address + self.width.n_bytes());
431         match self.width {
432             BitWidth::W8 => cursor.map(|s| s[0] as u8).map(Into::into),
433             BitWidth::W16 => cursor
434                 .and_then(|s| s.try_into().ok())
435                 .map(<u16>::from_le_bytes)
436                 .map(Into::into),
437             BitWidth::W32 => cursor
438                 .and_then(|s| s.try_into().ok())
439                 .map(<u32>::from_le_bytes)
440                 .map(Into::into),
441             BitWidth::W64 => cursor
442                 .and_then(|s| s.try_into().ok())
443                 .map(<u64>::from_le_bytes),
444         }
445         .ok_or(Error::FlexbufferOutOfBounds)
446     }
447     /// Tries to read a FlexBufferType::Int. Returns Err if the type is not a UInt or if the
448     /// address is out of bounds.
get_i64(&self) -> Result<i64, Error>449     pub fn get_i64(&self) -> Result<i64, Error> {
450         self.expect_type(FlexBufferType::Int)?;
451         let cursor = self
452             .buffer
453             .get(self.address..self.address + self.width.n_bytes());
454         match self.width {
455             BitWidth::W8 => cursor.map(|s| s[0] as i8).map(Into::into),
456             BitWidth::W16 => cursor
457                 .and_then(|s| s.try_into().ok())
458                 .map(<i16>::from_le_bytes)
459                 .map(Into::into),
460             BitWidth::W32 => cursor
461                 .and_then(|s| s.try_into().ok())
462                 .map(<i32>::from_le_bytes)
463                 .map(Into::into),
464             BitWidth::W64 => cursor
465                 .and_then(|s| s.try_into().ok())
466                 .map(<i64>::from_le_bytes),
467         }
468         .ok_or(Error::FlexbufferOutOfBounds)
469     }
470     /// Tries to read a FlexBufferType::Float. Returns Err if the type is not a UInt, if the
471     /// address is out of bounds, or if its a f16 or f8 (not currently supported).
get_f64(&self) -> Result<f64, Error>472     pub fn get_f64(&self) -> Result<f64, Error> {
473         self.expect_type(FlexBufferType::Float)?;
474         let cursor = self
475             .buffer
476             .get(self.address..self.address + self.width.n_bytes());
477         match self.width {
478             BitWidth::W8 | BitWidth::W16 => return Err(Error::InvalidPackedType),
479             BitWidth::W32 => cursor
480                 .and_then(|s| s.try_into().ok())
481                 .map(f32_from_le_bytes)
482                 .map(Into::into),
483             BitWidth::W64 => cursor
484                 .and_then(|s| s.try_into().ok())
485                 .map(f64_from_le_bytes),
486         }
487         .ok_or(Error::FlexbufferOutOfBounds)
488     }
as_bool(&self) -> bool489     pub fn as_bool(&self) -> bool {
490         use FlexBufferType::*;
491         match self.fxb_type {
492             Bool => self.get_bool().unwrap_or_default(),
493             UInt => self.as_u64() != 0,
494             Int => self.as_i64() != 0,
495             Float => self.as_f64().abs() > std::f64::EPSILON,
496             String | Key => !self.as_str().is_empty(),
497             Null => false,
498             Blob => self.length() != 0,
499             ty if ty.is_vector() => self.length() != 0,
500             _ => unreachable!(),
501         }
502     }
503     /// Returns a u64, casting if necessary. For Maps and Vectors, their length is
504     /// returned. If anything fails, 0 is returned.
as_u64(&self) -> u64505     pub fn as_u64(&self) -> u64 {
506         match self.fxb_type {
507             FlexBufferType::UInt => self.get_u64().unwrap_or_default(),
508             FlexBufferType::Int => self
509                 .get_i64()
510                 .unwrap_or_default()
511                 .try_into()
512                 .unwrap_or_default(),
513             FlexBufferType::Float => self.get_f64().unwrap_or_default() as u64,
514             FlexBufferType::String => {
515                 if let Ok(s) = self.get_str() {
516                     if let Ok(f) = u64::from_str(&s) {
517                         return f;
518                     }
519                 }
520                 0
521             }
522             _ if self.fxb_type.is_vector() => self.length() as u64,
523             _ => 0,
524         }
525     }
526     try_cast_fn!(as_u32, as_u64, u32);
527     try_cast_fn!(as_u16, as_u64, u16);
528     try_cast_fn!(as_u8, as_u64, u8);
529 
530     /// Returns an i64, casting if necessary. For Maps and Vectors, their length is
531     /// returned. If anything fails, 0 is returned.
as_i64(&self) -> i64532     pub fn as_i64(&self) -> i64 {
533         match self.fxb_type {
534             FlexBufferType::Int => self.get_i64().unwrap_or_default(),
535             FlexBufferType::UInt => self
536                 .get_u64()
537                 .unwrap_or_default()
538                 .try_into()
539                 .unwrap_or_default(),
540             FlexBufferType::Float => self.get_f64().unwrap_or_default() as i64,
541             FlexBufferType::String => {
542                 if let Ok(s) = self.get_str() {
543                     if let Ok(f) = i64::from_str(&s) {
544                         return f;
545                     }
546                 }
547                 0
548             }
549             _ if self.fxb_type.is_vector() => self.length() as i64,
550             _ => 0,
551         }
552     }
553     try_cast_fn!(as_i32, as_i64, i32);
554     try_cast_fn!(as_i16, as_i64, i16);
555     try_cast_fn!(as_i8, as_i64, i8);
556 
557     /// Returns an f64, casting if necessary. For Maps and Vectors, their length is
558     /// returned. If anything fails, 0 is returned.
as_f64(&self) -> f64559     pub fn as_f64(&self) -> f64 {
560         match self.fxb_type {
561             FlexBufferType::Int => self.get_i64().unwrap_or_default() as f64,
562             FlexBufferType::UInt => self.get_u64().unwrap_or_default() as f64,
563             FlexBufferType::Float => self.get_f64().unwrap_or_default(),
564             FlexBufferType::String => {
565                 if let Ok(s) = self.get_str() {
566                     if let Ok(f) = f64::from_str(&s) {
567                         return f;
568                     }
569                 }
570                 0.0
571             }
572             _ if self.fxb_type.is_vector() => self.length() as f64,
573             _ => 0.0,
574         }
575     }
as_f32(&self) -> f32576     pub fn as_f32(&self) -> f32 {
577         self.as_f64() as f32
578     }
579 
580     /// Returns empty string if you're not trying to read a string.
as_str(&self) -> B::BufferString581     pub fn as_str(&self) -> B::BufferString {
582         match self.fxb_type {
583             FlexBufferType::String => self.get_str().unwrap_or(B::empty_str()),
584             FlexBufferType::Key => self.get_key().unwrap_or(B::empty_str()),
585             _ => B::empty_str(),
586         }
587     }
588 
get_vector(&self) -> Result<VectorReader<B>, Error>589     pub fn get_vector(&self) -> Result<VectorReader<B>, Error> {
590         if !self.fxb_type.is_vector() {
591             self.expect_type(FlexBufferType::Vector)?;
592         };
593         Ok(VectorReader {
594             reader: self.clone(),
595             length: self.length(),
596         })
597     }
598 }
599 
600 impl<B: Buffer> fmt::Display for Reader<B> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result601     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
602         use FlexBufferType::*;
603         match self.flexbuffer_type() {
604             Null => write!(f, "null"),
605             UInt => write!(f, "{}", self.as_u64()),
606             Int => write!(f, "{}", self.as_i64()),
607             Float => write!(f, "{}", self.as_f64()),
608             Key | String => write!(f, "{:?}", &self.as_str() as &str),
609             Bool => write!(f, "{}", self.as_bool()),
610             Blob => write!(f, "blob"),
611             Map => {
612                 write!(f, "{{")?;
613                 let m = self.as_map();
614                 let mut pairs = m.iter_keys().zip(m.iter_values());
615                 if let Some((k, v)) = pairs.next() {
616                     write!(f, "{:?}: {}", &k as &str, v)?;
617                     for (k, v) in pairs {
618                         write!(f, ", {:?}: {}", &k as &str, v)?;
619                     }
620                 }
621                 write!(f, "}}")
622             }
623             t if t.is_vector() => {
624                 write!(f, "[")?;
625                 let mut elems = self.as_vector().iter();
626                 if let Some(first) = elems.next() {
627                     write!(f, "{}", first)?;
628                     for e in elems {
629                         write!(f, ", {}", e)?;
630                     }
631                 }
632                 write!(f, "]")
633             }
634             _ => unreachable!("Display not implemented for {:?}", self),
635         }
636     }
637 }
638 
639 // TODO(cneo): Use <f..>::from_le_bytes when we move past rustc 1.39.
f32_from_le_bytes(bytes: [u8; 4]) -> f32640 fn f32_from_le_bytes(bytes: [u8; 4]) -> f32 {
641     let bits = <u32>::from_le_bytes(bytes);
642     <f32>::from_bits(bits)
643 }
644 
f64_from_le_bytes(bytes: [u8; 8]) -> f64645 fn f64_from_le_bytes(bytes: [u8; 8]) -> f64 {
646     let bits = <u64>::from_le_bytes(bytes);
647     <f64>::from_bits(bits)
648 }
649 
read_usize(buffer: &[u8], address: usize, width: BitWidth) -> usize650 fn read_usize(buffer: &[u8], address: usize, width: BitWidth) -> usize {
651     let cursor = &buffer[address..];
652     match width {
653         BitWidth::W8 => cursor[0] as usize,
654         BitWidth::W16 => cursor
655             .get(0..2)
656             .and_then(|s| s.try_into().ok())
657             .map(<u16>::from_le_bytes)
658             .unwrap_or_default() as usize,
659         BitWidth::W32 => cursor
660             .get(0..4)
661             .and_then(|s| s.try_into().ok())
662             .map(<u32>::from_le_bytes)
663             .unwrap_or_default() as usize,
664         BitWidth::W64 => cursor
665             .get(0..8)
666             .and_then(|s| s.try_into().ok())
667             .map(<u64>::from_le_bytes)
668             .unwrap_or_default() as usize,
669     }
670 }
671 
unpack_type(ty: u8) -> Result<(FlexBufferType, BitWidth), Error>672 fn unpack_type(ty: u8) -> Result<(FlexBufferType, BitWidth), Error> {
673     let w = BitWidth::try_from(ty & 3u8).map_err(|_| Error::InvalidPackedType)?;
674     let t = FlexBufferType::try_from(ty >> 2).map_err(|_| Error::InvalidPackedType)?;
675     Ok((t, w))
676 }
677