• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 super::{unpack_type, Error, Reader, ReaderIterator};
16 use crate::{BitWidth, Buffer, FlexBufferType};
17 
18 /// Allows indexing on any flexbuffer vector type, (heterogenous vector, typed vector, or fixed
19 /// length typed vector).
20 ///
21 /// VectorReaders may be indexed with usize, `index` returns a result type
22 /// which may indicate failure due to indexing out of bounds or bad data. `idx` returns a
23 /// Null Reader in the event of any failure.
24 pub struct VectorReader<B> {
25     pub(super) reader: Reader<B>,
26     // Cache the length because read_usize can be slow.
27     pub(super) length: usize,
28 }
29 
30 impl<B: Buffer> Clone for VectorReader<B> {
clone(&self) -> Self31     fn clone(&self) -> Self {
32         VectorReader {
33             reader: self.reader.clone(),
34             ..*self
35         }
36     }
37 }
38 
39 impl<B: Buffer> Default for VectorReader<B> {
default() -> Self40     fn default() -> Self {
41         VectorReader {
42             reader: Reader::default(),
43             length: usize::default(),
44         }
45     }
46 }
47 
48 impl<B: Buffer> VectorReader<B> {
49     /// Returns the number of elements in the vector.
len(&self) -> usize50     pub fn len(&self) -> usize {
51         self.length
52     }
53     /// Returns true if there are 0 elements in the vector.
is_empty(&self) -> bool54     pub fn is_empty(&self) -> bool {
55         self.length == 0
56     }
get_elem_type(&self, i: usize) -> Result<(FlexBufferType, BitWidth), Error>57     fn get_elem_type(&self, i: usize) -> Result<(FlexBufferType, BitWidth), Error> {
58         if let Some(ty) = self.reader.fxb_type.typed_vector_type() {
59             Ok((ty, self.reader.width))
60         } else {
61             let types_addr = self.reader.address + self.length * self.reader.width.n_bytes();
62             self.reader
63                 .buffer
64                 .get(types_addr + i)
65                 .ok_or(Error::FlexbufferOutOfBounds)
66                 .and_then(|&t| unpack_type(t))
67         }
68     }
69     /// Index into a flexbuffer vector. Any errors are defaulted to Null Readers.
idx(&self, i: usize) -> Reader<B>70     pub fn idx(&self, i: usize) -> Reader<B> {
71         self.index(i).unwrap_or_default()
72     }
73     /// Index into a flexbuffer.
index(&self, i: usize) -> Result<Reader<B>, Error>74     pub fn index(&self, i: usize) -> Result<Reader<B>, Error> {
75         if i >= self.length {
76             return Err(Error::IndexOutOfBounds);
77         }
78         let (fxb_type, bw) = self.get_elem_type(i)?;
79         let data_address = self.reader.address + self.reader.width.n_bytes() * i;
80         Reader::new(
81             self.reader.buffer.shallow_copy(),
82             data_address,
83             fxb_type,
84             bw,
85             self.reader.width,
86         )
87     }
88 
iter(&self) -> ReaderIterator<B>89     pub fn iter(&self) -> ReaderIterator<B> {
90         ReaderIterator::new(self.clone())
91     }
92 }
93