1use std::collections::BTreeMap;
19use std::marker::PhantomData;
20
21use crate::error::Error;
22
23use super::bit_util::{bitmap_width, is_bit_set, round_up_to_word, slot_width};
24use super::row::{Row, RowValue};
25
26pub trait RowView<'a> {
28 fn as_bytes(&self) -> &'a [u8];
30
31 #[inline]
33 fn encoded_len(&self) -> usize {
34 self.as_bytes().len()
35 }
36}
37
38#[doc(hidden)]
43#[derive(Clone, Copy)]
44pub struct StructView<'a> {
45 bytes: &'a [u8],
46 bitmap_width: usize,
47 num_fields: usize,
48 fixed_end: usize,
49}
50
51impl<'a> StructView<'a> {
52 pub fn new(bytes: &'a [u8], num_fields: usize) -> Result<Self, Error> {
54 let bitmap_width = bitmap_width(num_fields)?;
55 let slots_size = num_fields
56 .checked_mul(8)
57 .ok_or_else(|| Error::invalid_data("row fixed region size overflow"))?;
58 let fixed_end = bitmap_width
59 .checked_add(slots_size)
60 .ok_or_else(|| Error::invalid_data("row fixed region size overflow"))?;
61 ensure_range(bytes, 0, fixed_end)?;
62 Ok(Self {
63 bytes,
64 bitmap_width,
65 num_fields,
66 fixed_end,
67 })
68 }
69
70 pub fn get<T: RowValue>(&self, index: usize) -> Result<T::View<'a>, Error> {
72 self.check_index(index)?;
73 let bitmap = &self.bytes[..self.bitmap_width];
74 if is_bit_set(bitmap, index) {
75 return T::read_null();
76 }
77
78 let slot_offset = self
79 .bitmap_width
80 .checked_add(index * 8)
81 .ok_or_else(|| Error::invalid_data("row field offset overflow"))?;
82 let value = match T::FIXED_SIZE {
83 Some(width) => {
84 slot_width(Some(width))?;
85 checked_slice(self.bytes, slot_offset, width)?
86 }
87 None => variable_slice(self.bytes, slot_offset, self.fixed_end)?,
88 };
89 T::read(value)
90 }
91
92 pub fn is_null(&self, index: usize) -> Result<bool, Error> {
94 self.check_index(index)?;
95 Ok(is_bit_set(&self.bytes[..self.bitmap_width], index))
96 }
97
98 fn check_index(&self, index: usize) -> Result<(), Error> {
99 if index >= self.num_fields {
100 Err(Error::buffer_out_of_bound(index, 1, self.num_fields))
101 } else {
102 Ok(())
103 }
104 }
105}
106
107impl<'a> RowView<'a> for StructView<'a> {
108 #[inline]
109 fn as_bytes(&self) -> &'a [u8] {
110 self.bytes
111 }
112}
113
114pub struct ArrayView<'a, T: RowValue> {
116 bytes: &'a [u8],
117 num_elements: usize,
118 bitmap_width: usize,
119 header_size: usize,
120 element_size: usize,
121 fixed_end: usize,
122 marker: PhantomData<T>,
123}
124
125impl<T: RowValue> Copy for ArrayView<'_, T> {}
126
127impl<T: RowValue> Clone for ArrayView<'_, T> {
128 fn clone(&self) -> Self {
129 *self
130 }
131}
132
133impl<'a, T: RowValue> ArrayView<'a, T> {
134 pub(crate) fn new(bytes: &'a [u8]) -> Result<Self, Error> {
135 let count = read_u64(bytes, 0)?;
136 let num_elements = usize::try_from(count)
137 .map_err(|_| Error::invalid_data("row array element count exceeds usize"))?;
138 let bitmap_width = bitmap_width(num_elements)?;
139 let header_size = 8usize
140 .checked_add(bitmap_width)
141 .ok_or_else(|| Error::invalid_data("row array header size overflow"))?;
142 let element_size = slot_width(T::FIXED_SIZE)?;
143 let element_bytes = num_elements
144 .checked_mul(element_size)
145 .ok_or_else(|| Error::invalid_data("row array fixed region size overflow"))?;
146 let aligned_element_bytes = round_up_to_word(element_bytes)?;
147 let fixed_end = header_size
148 .checked_add(aligned_element_bytes)
149 .ok_or_else(|| Error::invalid_data("row array fixed region size overflow"))?;
150 ensure_range(bytes, 0, fixed_end)?;
151 Ok(Self {
152 bytes,
153 num_elements,
154 bitmap_width,
155 header_size,
156 element_size,
157 fixed_end,
158 marker: PhantomData,
159 })
160 }
161
162 pub fn len(&self) -> usize {
164 self.num_elements
165 }
166
167 pub fn is_empty(&self) -> bool {
169 self.num_elements == 0
170 }
171
172 pub fn iter(&self) -> ArrayIter<'_, 'a, T> {
174 ArrayIter {
175 view: self,
176 index: 0,
177 }
178 }
179
180 pub fn get(&self, index: usize) -> Result<T::View<'a>, Error> {
182 self.check_index(index)?;
183 let bitmap = &self.bytes[8..8 + self.bitmap_width];
184 if is_bit_set(bitmap, index) {
185 return T::read_null();
186 }
187 let slot_offset = self
188 .header_size
189 .checked_add(index * self.element_size)
190 .ok_or_else(|| Error::invalid_data("row array element offset overflow"))?;
191 let value = match T::FIXED_SIZE {
192 Some(width) => checked_slice(self.bytes, slot_offset, width)?,
193 None => variable_slice(self.bytes, slot_offset, self.fixed_end)?,
194 };
195 T::read(value)
196 }
197
198 pub fn is_null(&self, index: usize) -> Result<bool, Error> {
200 self.check_index(index)?;
201 let bitmap_start = 8;
202 let bitmap = &self.bytes[bitmap_start..bitmap_start + self.bitmap_width];
203 Ok(is_bit_set(bitmap, index))
204 }
205
206 fn check_index(&self, index: usize) -> Result<(), Error> {
207 if index >= self.num_elements {
208 Err(Error::buffer_out_of_bound(index, 1, self.num_elements))
209 } else {
210 Ok(())
211 }
212 }
213}
214
215impl<'a, T: RowValue> RowView<'a> for ArrayView<'a, T> {
216 #[inline]
217 fn as_bytes(&self) -> &'a [u8] {
218 self.bytes
219 }
220}
221
222pub struct ArrayIter<'view, 'row, T: RowValue> {
224 view: &'view ArrayView<'row, T>,
225 index: usize,
226}
227
228impl<'row, T: RowValue> Iterator for ArrayIter<'_, 'row, T> {
229 type Item = Result<T::View<'row>, Error>;
230
231 fn next(&mut self) -> Option<Self::Item> {
232 if self.index == self.view.len() {
233 return None;
234 }
235 let index = self.index;
236 self.index += 1;
237 Some(self.view.get(index))
238 }
239
240 fn size_hint(&self) -> (usize, Option<usize>) {
241 let remaining = self.view.len() - self.index;
242 (remaining, Some(remaining))
243 }
244}
245
246impl<T: RowValue> ExactSizeIterator for ArrayIter<'_, '_, T> {}
247
248impl<'view, 'row, T: RowValue> IntoIterator for &'view ArrayView<'row, T> {
249 type Item = Result<T::View<'row>, Error>;
250 type IntoIter = ArrayIter<'view, 'row, T>;
251
252 fn into_iter(self) -> Self::IntoIter {
253 self.iter()
254 }
255}
256
257pub struct MapView<'a, K: RowValue, V: RowValue> {
259 bytes: &'a [u8],
260 keys: ArrayView<'a, K>,
261 values: ArrayView<'a, V>,
262}
263
264impl<K: RowValue, V: RowValue> Copy for MapView<'_, K, V> {}
265
266impl<K: RowValue, V: RowValue> Clone for MapView<'_, K, V> {
267 fn clone(&self) -> Self {
268 *self
269 }
270}
271
272impl<'a, K: RowValue, V: RowValue> MapView<'a, K, V> {
273 pub(crate) fn new(bytes: &'a [u8]) -> Result<Self, Error> {
274 let keys_size = read_u64(bytes, 0)?;
275 let keys_size = usize::try_from(keys_size)
276 .map_err(|_| Error::invalid_data("row map key array size exceeds usize"))?;
277 let keys_end = 8usize
278 .checked_add(keys_size)
279 .ok_or_else(|| Error::invalid_data("row map key array size overflow"))?;
280 ensure_range(bytes, 8, keys_size)?;
281 let keys = ArrayView::<K>::new(&bytes[8..keys_end])?;
282 let values = ArrayView::<V>::new(&bytes[keys_end..])?;
283 if keys.len() != values.len() {
284 return Err(Error::invalid_data(
285 "row map key and value arrays have different lengths",
286 ));
287 }
288 Ok(Self {
289 bytes,
290 keys,
291 values,
292 })
293 }
294
295 pub fn len(&self) -> usize {
297 self.keys.len()
298 }
299
300 pub fn is_empty(&self) -> bool {
302 self.keys.is_empty()
303 }
304
305 pub fn key(&self, index: usize) -> Result<K::View<'a>, Error> {
307 self.keys.get(index)
308 }
309
310 pub fn value(&self, index: usize) -> Result<V::View<'a>, Error> {
312 self.values.get(index)
313 }
314
315 pub fn keys(&self) -> &ArrayView<'a, K> {
317 &self.keys
318 }
319
320 pub fn values(&self) -> &ArrayView<'a, V> {
322 &self.values
323 }
324
325 pub fn to_btree_map(
327 &self,
328 ) -> Result<BTreeMap<<K as RowValue>::View<'a>, <V as RowValue>::View<'a>>, Error>
329 where
330 <K as RowValue>::View<'a>: Ord,
331 {
332 let mut map = BTreeMap::new();
333 for index in 0..self.keys.len() {
334 map.insert(self.keys.get(index)?, self.values.get(index)?);
335 }
336 Ok(map)
337 }
338}
339
340impl<'a, K: RowValue, V: RowValue> RowView<'a> for MapView<'a, K, V> {
341 #[inline]
342 fn as_bytes(&self) -> &'a [u8] {
343 self.bytes
344 }
345}
346
347fn variable_slice(bytes: &[u8], slot_offset: usize, fixed_end: usize) -> Result<&[u8], Error> {
348 let offset_and_size = read_u64(bytes, slot_offset)?;
349 let relative_offset = usize::try_from(offset_and_size >> 32)
350 .map_err(|_| Error::invalid_data("row variable offset exceeds usize"))?;
351 let size = (offset_and_size as u32) as usize;
352 if relative_offset < fixed_end {
353 return Err(Error::invalid_data(
354 "row variable value overlaps the fixed region",
355 ));
356 }
357 checked_slice(bytes, relative_offset, size)
358}
359
360fn read_u64(bytes: &[u8], offset: usize) -> Result<u64, Error> {
361 let value = checked_slice(bytes, offset, 8)?;
362 let mut array = [0u8; 8];
363 array.copy_from_slice(value);
364 Ok(u64::from_le_bytes(array))
365}
366
367fn checked_slice(bytes: &[u8], offset: usize, size: usize) -> Result<&[u8], Error> {
368 let end = offset
369 .checked_add(size)
370 .ok_or_else(|| Error::buffer_out_of_bound(offset, size, bytes.len()))?;
371 if end > bytes.len() {
372 Err(Error::buffer_out_of_bound(offset, size, bytes.len()))
373 } else {
374 Ok(&bytes[offset..end])
375 }
376}
377
378fn ensure_range(bytes: &[u8], offset: usize, size: usize) -> Result<(), Error> {
379 checked_slice(bytes, offset, size).map(|_| ())
380}
381
382pub fn from_row<T: Row>(bytes: &[u8]) -> Result<T::View<'_>, Error> {
384 T::read(bytes)
385}