blob: cdf59e083d23dc6bd0a8844e5a9ba28813011754 [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::{deref_offset, unpack_type, Error, Reader, ReaderIterator, VectorReader};
16use crate::BitWidth;
17use std::cmp::Ordering;
18use std::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator};
19
20/// Allows indexing on a flexbuffer map.
21///
22/// MapReaders may be indexed with strings or usizes. `index` returns a result type,
23/// which may indicate failure due to a missing key or bad data, `idx` returns an Null Reader in
24/// cases of error.
25#[derive(Default, Clone)]
26pub struct MapReader<'de> {
27 pub(super) buffer: &'de [u8],
28 pub(super) values_address: usize,
29 pub(super) keys_address: usize,
30 pub(super) values_width: BitWidth,
31 pub(super) keys_width: BitWidth,
32 pub(super) length: usize,
33}
34
35// manual implementation of Debug because buffer slice can't be automatically displayed
36impl<'de> std::fmt::Debug for MapReader<'de> {
37 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38 // skips buffer field
39 f.debug_struct("MapReader")
40 .field("values_address", &self.values_address)
41 .field("keys_address", &self.keys_address)
42 .field("values_width", &self.values_width)
43 .field("keys_width", &self.keys_width)
44 .field("length", &self.length)
45 .finish()
46 }
47}
48
49impl<'de> MapReader<'de> {
50 /// Returns the number of key/value pairs are in the map.
51 pub fn len(&self) -> usize {
52 self.length
53 }
54 /// Returns true if the map has zero key/value pairs.
55 pub fn is_empty(&self) -> bool {
56 self.length == 0
57 }
58 // Using &CStr will eagerly compute the length of the key. &str needs length info AND utf8
59 // validation. This version is faster than both.
60 fn lazy_strcmp(&self, key_addr: usize, key: &str) -> Ordering {
61 // TODO: Can we know this won't OOB and panic?
62 let k = self.buffer[key_addr..].iter().take_while(|&&b| b != b'\0');
63 k.cmp(key.as_bytes().iter())
64 }
65 /// Returns the index of a given key in the map.
66 pub fn index_key(&self, key: &str) -> Option<usize> {
67 let (mut low, mut high) = (0, self.length);
68 while low < high {
69 let i = (low + high) / 2;
70 let key_offset_address = self.keys_address + i * self.keys_width.n_bytes();
71 let key_address =
72 deref_offset(self.buffer, key_offset_address, self.keys_width).ok()?;
73 match self.lazy_strcmp(key_address, key) {
74 Ordering::Equal => return Some(i),
75 Ordering::Less => low = if i == low { i + 1 } else { i },
76 Ordering::Greater => high = i,
77 }
78 }
79 None
80 }
81 /// Index into a map with a key or usize.
82 pub fn index<I: MapReaderIndexer>(&self, i: I) -> Result<Reader<'de>, Error> {
83 i.index_map_reader(self)
84 }
85 /// Index into a map with a key or usize. If any errors occur a Null reader is returned.
86 pub fn idx<I: MapReaderIndexer>(&self, i: I) -> Reader<'de> {
87 i.index_map_reader(self).unwrap_or_default()
88 }
89 fn usize_index(&self, i: usize) -> Result<Reader<'de>, Error> {
90 if i >= self.length {
91 return Err(Error::IndexOutOfBounds);
92 }
93 let data_address = self.values_address + self.values_width.n_bytes() * i;
94 let type_address = self.values_address + self.values_width.n_bytes() * self.length + i;
95 let (fxb_type, width) = self
96 .buffer
97 .get(type_address)
98 .ok_or(Error::FlexbufferOutOfBounds)
99 .and_then(|&b| unpack_type(b))?;
100 Reader::new(
101 &self.buffer,
102 data_address,
103 fxb_type,
104 width,
105 self.values_width,
106 )
107 }
108 fn key_index(&self, k: &str) -> Result<Reader<'de>, Error> {
109 let i = self.index_key(k).ok_or(Error::KeyNotFound)?;
110 self.usize_index(i)
111 }
112 /// Iterate over the values of the map.
113 pub fn iter_values(&self) -> ReaderIterator<'de> {
114 ReaderIterator::new(VectorReader {
115 reader: Reader {
116 buffer: self.buffer,
117 fxb_type: crate::FlexBufferType::Map,
118 width: self.values_width,
119 address: self.values_address,
120 },
121 length: self.length,
122 })
123 }
124 /// Iterate over the keys of the map.
125 pub fn iter_keys(
126 &self,
127 ) -> impl Iterator<Item = &'de str> + DoubleEndedIterator + ExactSizeIterator + FusedIterator
128 {
129 self.keys_vector().iter().map(|k| k.as_str())
130 }
131 pub fn keys_vector(&self) -> VectorReader<'de> {
132 VectorReader {
133 reader: Reader {
134 buffer: self.buffer,
135 fxb_type: crate::FlexBufferType::VectorKey,
136 width: self.keys_width,
137 address: self.keys_address,
138 },
139 length: self.length,
140 }
141 }
142}
143pub trait MapReaderIndexer {
144 fn index_map_reader<'de>(self, r: &MapReader<'de>) -> Result<Reader<'de>, Error>;
145}
146impl MapReaderIndexer for usize {
147 #[inline]
148 fn index_map_reader<'de>(self, r: &MapReader<'de>) -> Result<Reader<'de>, Error> {
149 r.usize_index(self)
150 }
151}
152impl MapReaderIndexer for &str {
153 #[inline]
154 fn index_map_reader<'de>(self, r: &MapReader<'de>) -> Result<Reader<'de>, Error> {
155 r.key_index(self)
156 }
157}