blob: 6b97e1057f271cec360abddb84defbd8379ab285 [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 super::{unpack_type, Error, Reader, ReaderIterator};
James Kuszmaul8e62b022022-03-22 09:33:25 -070016use crate::{BitWidth, Buffer, FlexBufferType};
Austin Schuh272c6132020-11-14 16:37:52 -080017
Austin Schuh272c6132020-11-14 16:37:52 -080018/// 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.
James Kuszmaul8e62b022022-03-22 09:33:25 -070024pub struct VectorReader<B> {
25 pub(super) reader: Reader<B>,
Austin Schuh272c6132020-11-14 16:37:52 -080026 // Cache the length because read_usize can be slow.
27 pub(super) length: usize,
28}
29
James Kuszmaul8e62b022022-03-22 09:33:25 -070030impl<B: Buffer> Clone for VectorReader<B> {
31 fn clone(&self) -> Self {
32 VectorReader {
33 reader: self.reader.clone(),
34 ..*self
35 }
36 }
37}
38
39impl<B: Buffer> Default for VectorReader<B> {
40 fn default() -> Self {
41 VectorReader {
42 reader: Reader::default(),
43 length: usize::default(),
44 }
45 }
46}
47
48impl<B: Buffer> VectorReader<B> {
Austin Schuh272c6132020-11-14 16:37:52 -080049 /// Returns the number of elements in the vector.
50 pub fn len(&self) -> usize {
51 self.length
52 }
53 /// Returns true if there are 0 elements in the vector.
54 pub fn is_empty(&self) -> bool {
55 self.length == 0
56 }
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.
James Kuszmaul8e62b022022-03-22 09:33:25 -070070 pub fn idx(&self, i: usize) -> Reader<B> {
Austin Schuh272c6132020-11-14 16:37:52 -080071 self.index(i).unwrap_or_default()
72 }
73 /// Index into a flexbuffer.
James Kuszmaul8e62b022022-03-22 09:33:25 -070074 pub fn index(&self, i: usize) -> Result<Reader<B>, Error> {
Austin Schuh272c6132020-11-14 16:37:52 -080075 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(
James Kuszmaul8e62b022022-03-22 09:33:25 -070081 self.reader.buffer.shallow_copy(),
Austin Schuh272c6132020-11-14 16:37:52 -080082 data_address,
83 fxb_type,
84 bw,
85 self.reader.width,
86 )
87 }
James Kuszmaul8e62b022022-03-22 09:33:25 -070088
89 pub fn iter(&self) -> ReaderIterator<B> {
Austin Schuh272c6132020-11-14 16:37:52 -080090 ReaderIterator::new(self.clone())
91 }
92}