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