1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use super::{unpack_type, Error, Reader, ReaderIterator};
use crate::{BitWidth, FlexBufferType};

#[derive(Default, Clone)]
/// Allows indexing on any flexbuffer vector type, (heterogenous vector, typed vector, or fixed
/// length typed vector).
///
/// VectorReaders may be indexed with usize, `index` returns a result type
/// which may indicate failure due to indexing out of bounds or bad data. `idx` returns a
/// Null Reader in the event of any failure.
pub struct VectorReader<'de> {
    pub(super) reader: Reader<'de>,
    // Cache the length because read_usize can be slow.
    pub(super) length: usize,
}

impl<'de> VectorReader<'de> {
    /// Returns the number of elements in the vector.
    pub fn len(&self) -> usize {
        self.length
    }
    /// Returns true if there are 0 elements in the vector.
    pub fn is_empty(&self) -> bool {
        self.length == 0
    }
    fn get_elem_type(&self, i: usize) -> Result<(FlexBufferType, BitWidth), Error> {
        if let Some(ty) = self.reader.fxb_type.typed_vector_type() {
            Ok((ty, self.reader.width))
        } else {
            let types_addr = self.reader.address + self.length * self.reader.width.n_bytes();
            self.reader
                .buffer
                .get(types_addr + i)
                .ok_or(Error::FlexbufferOutOfBounds)
                .and_then(|&t| unpack_type(t))
        }
    }
    /// Index into a flexbuffer vector. Any errors are defaulted to Null Readers.
    pub fn idx(&self, i: usize) -> Reader<'de> {
        self.index(i).unwrap_or_default()
    }
    /// Index into a flexbuffer.
    pub fn index(&self, i: usize) -> Result<Reader<'de>, Error> {
        if i >= self.length {
            return Err(Error::IndexOutOfBounds);
        }
        let (fxb_type, bw) = self.get_elem_type(i)?;
        let data_address = self.reader.address + self.reader.width.n_bytes() * i;
        Reader::new(
            self.reader.buffer,
            data_address,
            fxb_type,
            bw,
            self.reader.width,
        )
    }
    pub fn iter(&self) -> ReaderIterator<'de> {
        ReaderIterator::new(self.clone())
    }
}