forked from BigfootDev/flatbuffers
* Implement Serialize for flexbuffer::Reader * bump version * Remove use of experimantal or-patterns * Remove more use of experimantal or-patterns Co-authored-by: Casper Neo <cneo@google.com>
93 lines
3.0 KiB
Rust
93 lines
3.0 KiB
Rust
// 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, Buffer, FlexBufferType};
|
|
|
|
/// 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<B> {
|
|
pub(super) reader: Reader<B>,
|
|
// Cache the length because read_usize can be slow.
|
|
pub(super) length: usize,
|
|
}
|
|
|
|
impl<B: Buffer> Clone for VectorReader<B> {
|
|
fn clone(&self) -> Self {
|
|
VectorReader {
|
|
reader: self.reader.clone(),
|
|
..*self
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<B: Buffer> Default for VectorReader<B> {
|
|
fn default() -> Self {
|
|
VectorReader {
|
|
reader: Reader::default(),
|
|
length: usize::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<B: Buffer> VectorReader<B> {
|
|
/// 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<B> {
|
|
self.index(i).unwrap_or_default()
|
|
}
|
|
/// Index into a flexbuffer.
|
|
pub fn index(&self, i: usize) -> Result<Reader<B>, 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.shallow_copy(),
|
|
data_address,
|
|
fxb_type,
|
|
bw,
|
|
self.reader.width,
|
|
)
|
|
}
|
|
|
|
pub fn iter(&self) -> ReaderIterator<B> {
|
|
ReaderIterator::new(self.clone())
|
|
}
|
|
}
|