blob: b486ff33c01f146d7b8962f3057586bb598ff83e [file] [log] [blame]
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001/*
2 * Copyright 2018 Google Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
James Kuszmaul8e62b022022-03-22 09:33:25 -070017use core::fmt::{Debug, Formatter, Result};
18use core::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator};
19use core::marker::PhantomData;
James Kuszmaul3b15b0c2022-11-08 14:03:16 -080020use core::mem::{align_of, size_of};
James Kuszmaul8e62b022022-03-22 09:33:25 -070021use core::str::from_utf8_unchecked;
Austin Schuhe89fa2d2019-08-14 20:24:23 -070022
Austin Schuh272c6132020-11-14 16:37:52 -080023use crate::endian_scalar::read_scalar_at;
Austin Schuh272c6132020-11-14 16:37:52 -080024use crate::follow::Follow;
25use crate::primitives::*;
Austin Schuhe89fa2d2019-08-14 20:24:23 -070026
Austin Schuhe89fa2d2019-08-14 20:24:23 -070027pub struct Vector<'a, T: 'a>(&'a [u8], usize, PhantomData<T>);
28
James Kuszmaul8e62b022022-03-22 09:33:25 -070029impl<'a, T: 'a> Default for Vector<'a, T> {
30 fn default() -> Self {
31 // Static, length 0 vector.
32 // Note that derived default causes UB due to issues in read_scalar_at /facepalm.
33 Self(
34 &[0; core::mem::size_of::<UOffsetT>()],
35 0,
36 Default::default(),
37 )
38 }
39}
40
Austin Schuh272c6132020-11-14 16:37:52 -080041impl<'a, T> Debug for Vector<'a, T>
42where
43 T: 'a + Follow<'a>,
James Kuszmaul8e62b022022-03-22 09:33:25 -070044 <T as Follow<'a>>::Inner: Debug,
Austin Schuh272c6132020-11-14 16:37:52 -080045{
46 fn fmt(&self, f: &mut Formatter) -> Result {
47 f.debug_list().entries(self.iter()).finish()
48 }
49}
50
Austin Schuh272c6132020-11-14 16:37:52 -080051// We cannot use derive for these two impls, as it would only implement Copy
52// and Clone for `T: Copy` and `T: Clone` respectively. However `Vector<'a, T>`
53// can always be copied, no matter that `T` you have.
54impl<'a, T> Copy for Vector<'a, T> {}
James Kuszmaul3b15b0c2022-11-08 14:03:16 -080055
Austin Schuh272c6132020-11-14 16:37:52 -080056impl<'a, T> Clone for Vector<'a, T> {
57 fn clone(&self) -> Self {
58 *self
59 }
60}
61
Austin Schuhe89fa2d2019-08-14 20:24:23 -070062impl<'a, T: 'a> Vector<'a, T> {
James Kuszmaul3b15b0c2022-11-08 14:03:16 -080063 /// # Safety
64 ///
65 /// `buf` contains a valid vector at `loc` consisting of
66 ///
67 /// - UOffsetT element count
68 /// - Consecutive list of `T` elements
Austin Schuhe89fa2d2019-08-14 20:24:23 -070069 #[inline(always)]
James Kuszmaul3b15b0c2022-11-08 14:03:16 -080070 pub unsafe fn new(buf: &'a [u8], loc: usize) -> Self {
71 Vector(buf, loc, PhantomData)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070072 }
73
74 #[inline(always)]
75 pub fn len(&self) -> usize {
James Kuszmaul3b15b0c2022-11-08 14:03:16 -080076 // Safety:
77 // Valid vector at time of construction starting with UOffsetT element count
James Kuszmaul8e62b022022-03-22 09:33:25 -070078 unsafe { read_scalar_at::<UOffsetT>(self.0, self.1) as usize }
Austin Schuh272c6132020-11-14 16:37:52 -080079 }
James Kuszmaul3b15b0c2022-11-08 14:03:16 -080080
Austin Schuh272c6132020-11-14 16:37:52 -080081 #[inline(always)]
82 pub fn is_empty(&self) -> bool {
83 self.len() == 0
Austin Schuhe89fa2d2019-08-14 20:24:23 -070084 }
James Kuszmaul3b15b0c2022-11-08 14:03:16 -080085
86 #[inline(always)]
87 pub fn bytes(&self) -> &'a [u8] {
88 let sz = size_of::<T>();
89 let len = self.len();
90 &self.0[self.1 + SIZE_UOFFSET..self.1 + SIZE_UOFFSET + sz * len]
91 }
Austin Schuhe89fa2d2019-08-14 20:24:23 -070092}
93
94impl<'a, T: Follow<'a> + 'a> Vector<'a, T> {
95 #[inline(always)]
96 pub fn get(&self, idx: usize) -> T::Inner {
James Kuszmaul3b15b0c2022-11-08 14:03:16 -080097 assert!(idx < self.len());
Austin Schuhe89fa2d2019-08-14 20:24:23 -070098 let sz = size_of::<T>();
99 debug_assert!(sz > 0);
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800100 // Safety:
101 // Valid vector at time of construction, verified that idx < element count
102 unsafe { T::follow(self.0, self.1 as usize + SIZE_UOFFSET + sz * idx) }
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700103 }
Austin Schuh272c6132020-11-14 16:37:52 -0800104
105 #[inline(always)]
106 pub fn iter(&self) -> VectorIter<'a, T> {
James Kuszmaul8e62b022022-03-22 09:33:25 -0700107 VectorIter::from_vector(*self)
Austin Schuh272c6132020-11-14 16:37:52 -0800108 }
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700109}
110
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800111/// # Safety
112///
113/// `buf` must contain a value of T at `loc` and have alignment of 1
114pub unsafe fn follow_cast_ref<'a, T: Sized + 'a>(buf: &'a [u8], loc: usize) -> &'a T {
115 assert_eq!(align_of::<T>(), 1);
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700116 let sz = size_of::<T>();
117 let buf = &buf[loc..loc + sz];
118 let ptr = buf.as_ptr() as *const T;
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800119 // SAFETY
120 // buf contains a value at loc of type T and T has no alignment requirements
121 &*ptr
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700122}
123
124impl<'a> Follow<'a> for &'a str {
125 type Inner = &'a str;
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800126 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
127 let len = read_scalar_at::<UOffsetT>(buf, loc) as usize;
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700128 let slice = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len];
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800129 from_utf8_unchecked(slice)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700130 }
131}
132
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800133impl<'a> Follow<'a> for &'a [u8] {
134 type Inner = &'a [u8];
135 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
136 let len = read_scalar_at::<UOffsetT>(buf, loc) as usize;
137 &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len]
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700138 }
139}
140
141/// Implement Follow for all possible Vectors that have Follow-able elements.
142impl<'a, T: Follow<'a> + 'a> Follow<'a> for Vector<'a, T> {
143 type Inner = Vector<'a, T>;
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800144 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700145 Vector::new(buf, loc)
146 }
147}
Austin Schuh272c6132020-11-14 16:37:52 -0800148
149/// An iterator over a `Vector`.
150#[derive(Debug)]
151pub struct VectorIter<'a, T: 'a> {
152 buf: &'a [u8],
153 loc: usize,
154 remaining: usize,
155 phantom: PhantomData<T>,
156}
157
158impl<'a, T: 'a> VectorIter<'a, T> {
159 #[inline]
James Kuszmaul8e62b022022-03-22 09:33:25 -0700160 pub fn from_vector(inner: Vector<'a, T>) -> Self {
Austin Schuh272c6132020-11-14 16:37:52 -0800161 VectorIter {
162 buf: inner.0,
163 // inner.1 is the location of the data for the vector.
164 // The first SIZE_UOFFSET bytes is the length. We skip
165 // that to get to the actual vector content.
166 loc: inner.1 + SIZE_UOFFSET,
167 remaining: inner.len(),
168 phantom: PhantomData,
169 }
170 }
James Kuszmaul8e62b022022-03-22 09:33:25 -0700171
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800172 /// Creates a new `VectorIter` from the provided slice
173 ///
174 /// # Safety
175 ///
176 /// buf must contain a contiguous sequence of `items_num` values of `T`
177 ///
James Kuszmaul8e62b022022-03-22 09:33:25 -0700178 #[inline]
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800179 pub unsafe fn from_slice(buf: &'a [u8], items_num: usize) -> Self {
James Kuszmaul8e62b022022-03-22 09:33:25 -0700180 VectorIter {
181 buf,
182 loc: 0,
183 remaining: items_num,
184 phantom: PhantomData,
185 }
186 }
Austin Schuh272c6132020-11-14 16:37:52 -0800187}
188
189impl<'a, T: Follow<'a> + 'a> Clone for VectorIter<'a, T> {
190 #[inline]
191 fn clone(&self) -> Self {
192 VectorIter {
193 buf: self.buf,
194 loc: self.loc,
195 remaining: self.remaining,
196 phantom: self.phantom,
197 }
198 }
199}
200
201impl<'a, T: Follow<'a> + 'a> Iterator for VectorIter<'a, T> {
202 type Item = T::Inner;
203
204 #[inline]
205 fn next(&mut self) -> Option<T::Inner> {
206 let sz = size_of::<T>();
207 debug_assert!(sz > 0);
208
209 if self.remaining == 0 {
210 None
211 } else {
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800212 // Safety:
213 // VectorIter can only be created from a contiguous sequence of `items_num`
214 // And remaining is initialized to `items_num`
215 let result = unsafe { T::follow(self.buf, self.loc) };
Austin Schuh272c6132020-11-14 16:37:52 -0800216 self.loc += sz;
217 self.remaining -= 1;
218 Some(result)
219 }
220 }
221
222 #[inline]
223 fn nth(&mut self, n: usize) -> Option<T::Inner> {
224 let sz = size_of::<T>();
225 debug_assert!(sz > 0);
226
227 self.remaining = self.remaining.saturating_sub(n);
228
229 // Note that this might overflow, but that is okay because
230 // in that case self.remaining will have been set to zero.
231 self.loc = self.loc.wrapping_add(sz * n);
232
233 self.next()
234 }
235
236 #[inline]
237 fn size_hint(&self) -> (usize, Option<usize>) {
238 (self.remaining, Some(self.remaining))
239 }
240}
241
242impl<'a, T: Follow<'a> + 'a> DoubleEndedIterator for VectorIter<'a, T> {
243 #[inline]
244 fn next_back(&mut self) -> Option<T::Inner> {
245 let sz = size_of::<T>();
246 debug_assert!(sz > 0);
247
248 if self.remaining == 0 {
249 None
250 } else {
251 self.remaining -= 1;
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800252 // Safety:
253 // VectorIter can only be created from a contiguous sequence of `items_num`
254 // And remaining is initialized to `items_num`
255 Some(unsafe { T::follow(self.buf, self.loc + sz * self.remaining) })
Austin Schuh272c6132020-11-14 16:37:52 -0800256 }
257 }
258
259 #[inline]
260 fn nth_back(&mut self, n: usize) -> Option<T::Inner> {
261 self.remaining = self.remaining.saturating_sub(n);
262 self.next_back()
263 }
264}
265
266impl<'a, T: 'a + Follow<'a>> ExactSizeIterator for VectorIter<'a, T> {
267 #[inline]
268 fn len(&self) -> usize {
269 self.remaining
270 }
271}
272
273impl<'a, T: 'a + Follow<'a>> FusedIterator for VectorIter<'a, T> {}
274
275impl<'a, T: Follow<'a> + 'a> IntoIterator for Vector<'a, T> {
276 type Item = T::Inner;
277 type IntoIter = VectorIter<'a, T>;
278 #[inline]
279 fn into_iter(self) -> Self::IntoIter {
280 self.iter()
281 }
282}
283
284impl<'a, 'b, T: Follow<'a> + 'a> IntoIterator for &'b Vector<'a, T> {
285 type Item = T::Inner;
286 type IntoIter = VectorIter<'a, T>;
287 fn into_iter(self) -> Self::IntoIter {
288 self.iter()
289 }
290}
James Kuszmaul8e62b022022-03-22 09:33:25 -0700291
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800292#[cfg(feature = "serialize")]
James Kuszmaul8e62b022022-03-22 09:33:25 -0700293impl<'a, T> serde::ser::Serialize for Vector<'a, T>
294where
295 T: 'a + Follow<'a>,
296 <T as Follow<'a>>::Inner: serde::ser::Serialize,
297{
298 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
299 where
300 S: serde::ser::Serializer,
301 {
302 use serde::ser::SerializeSeq;
303 let mut seq = serializer.serialize_seq(Some(self.len()))?;
304 for element in self {
305 seq.serialize_element(&element)?;
306 }
307 seq.end()
308 }
309}