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