blob: 5236ea16e098b3fb7758be83ec17475a25def3c5 [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
Austin Schuh272c6132020-11-14 16:37:52 -080017use std::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator};
Austin Schuhe89fa2d2019-08-14 20:24:23 -070018use std::marker::PhantomData;
19use std::mem::size_of;
20use std::slice::from_raw_parts;
21use std::str::from_utf8_unchecked;
Austin Schuh272c6132020-11-14 16:37:52 -080022use std::fmt::{Debug, Result, Formatter};
Austin Schuhe89fa2d2019-08-14 20:24:23 -070023
Austin Schuh272c6132020-11-14 16:37:52 -080024use crate::endian_scalar::read_scalar_at;
Austin Schuhe89fa2d2019-08-14 20:24:23 -070025#[cfg(target_endian = "little")]
Austin Schuh272c6132020-11-14 16:37:52 -080026use crate::endian_scalar::EndianScalar;
27use crate::follow::Follow;
28use crate::primitives::*;
Austin Schuhe89fa2d2019-08-14 20:24:23 -070029
Austin Schuhe89fa2d2019-08-14 20:24:23 -070030pub struct Vector<'a, T: 'a>(&'a [u8], usize, PhantomData<T>);
31
Austin Schuh272c6132020-11-14 16:37:52 -080032impl<'a, T> Debug for Vector<'a, T>
33where
34 T: 'a + Follow<'a>,
35 <T as Follow<'a>>::Inner : Debug
36{
37 fn fmt(&self, f: &mut Formatter) -> Result {
38 f.debug_list().entries(self.iter()).finish()
39 }
40}
41
42
43// We cannot use derive for these two impls, as it would only implement Copy
44// and Clone for `T: Copy` and `T: Clone` respectively. However `Vector<'a, T>`
45// can always be copied, no matter that `T` you have.
46impl<'a, T> Copy for Vector<'a, T> {}
47impl<'a, T> Clone for Vector<'a, T> {
48 fn clone(&self) -> Self {
49 *self
50 }
51}
52
Austin Schuhe89fa2d2019-08-14 20:24:23 -070053impl<'a, T: 'a> Vector<'a, T> {
54 #[inline(always)]
55 pub fn new(buf: &'a [u8], loc: usize) -> Self {
56 Vector {
57 0: buf,
58 1: loc,
59 2: PhantomData,
60 }
61 }
62
63 #[inline(always)]
64 pub fn len(&self) -> usize {
Austin Schuh272c6132020-11-14 16:37:52 -080065 read_scalar_at::<UOffsetT>(&self.0, self.1) as usize
66 }
67 #[inline(always)]
68 pub fn is_empty(&self) -> bool {
69 self.len() == 0
Austin Schuhe89fa2d2019-08-14 20:24:23 -070070 }
71}
72
73impl<'a, T: Follow<'a> + 'a> Vector<'a, T> {
74 #[inline(always)]
75 pub fn get(&self, idx: usize) -> T::Inner {
Austin Schuh272c6132020-11-14 16:37:52 -080076 debug_assert!(idx < read_scalar_at::<u32>(&self.0, self.1) as usize);
Austin Schuhe89fa2d2019-08-14 20:24:23 -070077 let sz = size_of::<T>();
78 debug_assert!(sz > 0);
79 T::follow(self.0, self.1 as usize + SIZE_UOFFSET + sz * idx)
80 }
Austin Schuh272c6132020-11-14 16:37:52 -080081
82 #[inline(always)]
83 pub fn iter(&self) -> VectorIter<'a, T> {
84 VectorIter::new(*self)
85 }
Austin Schuhe89fa2d2019-08-14 20:24:23 -070086}
87
88pub trait SafeSliceAccess {}
89impl<'a, T: SafeSliceAccess + 'a> Vector<'a, T> {
90 pub fn safe_slice(self) -> &'a [T] {
91 let buf = self.0;
92 let loc = self.1;
93 let sz = size_of::<T>();
94 debug_assert!(sz > 0);
95 let len = read_scalar_at::<UOffsetT>(&buf, loc) as usize;
96 let data_buf = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len * sz];
97 let ptr = data_buf.as_ptr() as *const T;
98 let s: &'a [T] = unsafe { from_raw_parts(ptr, len) };
99 s
100 }
101}
102
103impl SafeSliceAccess for u8 {}
104impl SafeSliceAccess for i8 {}
105impl SafeSliceAccess for bool {}
106
107#[cfg(target_endian = "little")]
108mod le_safe_slice_impls {
109 impl super::SafeSliceAccess for u16 {}
110 impl super::SafeSliceAccess for u32 {}
111 impl super::SafeSliceAccess for u64 {}
112
113 impl super::SafeSliceAccess for i16 {}
114 impl super::SafeSliceAccess for i32 {}
115 impl super::SafeSliceAccess for i64 {}
116
117 impl super::SafeSliceAccess for f32 {}
118 impl super::SafeSliceAccess for f64 {}
119}
120
121#[cfg(target_endian = "little")]
122pub use self::le_safe_slice_impls::*;
123
124pub fn follow_cast_ref<'a, T: Sized + 'a>(buf: &'a [u8], loc: usize) -> &'a T {
125 let sz = size_of::<T>();
126 let buf = &buf[loc..loc + sz];
127 let ptr = buf.as_ptr() as *const T;
128 unsafe { &*ptr }
129}
130
131impl<'a> Follow<'a> for &'a str {
132 type Inner = &'a str;
133 fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
134 let len = read_scalar_at::<UOffsetT>(&buf, loc) as usize;
135 let slice = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len];
Austin Schuh272c6132020-11-14 16:37:52 -0800136 unsafe { from_utf8_unchecked(slice) }
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700137 }
138}
139
140#[cfg(target_endian = "little")]
141fn follow_slice_helper<T>(buf: &[u8], loc: usize) -> &[T] {
142 let sz = size_of::<T>();
143 debug_assert!(sz > 0);
144 let len = read_scalar_at::<UOffsetT>(&buf, loc) as usize;
145 let data_buf = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len * sz];
146 let ptr = data_buf.as_ptr() as *const T;
147 let s: &[T] = unsafe { from_raw_parts(ptr, len) };
148 s
149}
150
151/// Implement direct slice access if the host is little-endian.
152#[cfg(target_endian = "little")]
153impl<'a, T: EndianScalar> Follow<'a> for &'a [T] {
154 type Inner = &'a [T];
155 fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
156 follow_slice_helper::<T>(buf, loc)
157 }
158}
159
160/// Implement Follow for all possible Vectors that have Follow-able elements.
161impl<'a, T: Follow<'a> + 'a> Follow<'a> for Vector<'a, T> {
162 type Inner = Vector<'a, T>;
163 fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
164 Vector::new(buf, loc)
165 }
166}
Austin Schuh272c6132020-11-14 16:37:52 -0800167
168/// An iterator over a `Vector`.
169#[derive(Debug)]
170pub struct VectorIter<'a, T: 'a> {
171 buf: &'a [u8],
172 loc: usize,
173 remaining: usize,
174 phantom: PhantomData<T>,
175}
176
177impl<'a, T: 'a> VectorIter<'a, T> {
178 #[inline]
179 pub fn new(inner: Vector<'a, T>) -> Self {
180 VectorIter {
181 buf: inner.0,
182 // inner.1 is the location of the data for the vector.
183 // The first SIZE_UOFFSET bytes is the length. We skip
184 // that to get to the actual vector content.
185 loc: inner.1 + SIZE_UOFFSET,
186 remaining: inner.len(),
187 phantom: PhantomData,
188 }
189 }
190}
191
192impl<'a, T: Follow<'a> + 'a> Clone for VectorIter<'a, T> {
193 #[inline]
194 fn clone(&self) -> Self {
195 VectorIter {
196 buf: self.buf,
197 loc: self.loc,
198 remaining: self.remaining,
199 phantom: self.phantom,
200 }
201 }
202}
203
204impl<'a, T: Follow<'a> + 'a> Iterator for VectorIter<'a, T> {
205 type Item = T::Inner;
206
207 #[inline]
208 fn next(&mut self) -> Option<T::Inner> {
209 let sz = size_of::<T>();
210 debug_assert!(sz > 0);
211
212 if self.remaining == 0 {
213 None
214 } else {
215 let result = T::follow(self.buf, self.loc);
216 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;
252 Some(T::follow(self.buf, self.loc + sz * self.remaining))
253 }
254 }
255
256 #[inline]
257 fn nth_back(&mut self, n: usize) -> Option<T::Inner> {
258 self.remaining = self.remaining.saturating_sub(n);
259 self.next_back()
260 }
261}
262
263impl<'a, T: 'a + Follow<'a>> ExactSizeIterator for VectorIter<'a, T> {
264 #[inline]
265 fn len(&self) -> usize {
266 self.remaining
267 }
268}
269
270impl<'a, T: 'a + Follow<'a>> FusedIterator for VectorIter<'a, T> {}
271
272impl<'a, T: Follow<'a> + 'a> IntoIterator for Vector<'a, T> {
273 type Item = T::Inner;
274 type IntoIter = VectorIter<'a, T>;
275 #[inline]
276 fn into_iter(self) -> Self::IntoIter {
277 self.iter()
278 }
279}
280
281impl<'a, 'b, T: Follow<'a> + 'a> IntoIterator for &'b Vector<'a, T> {
282 type Item = T::Inner;
283 type IntoIter = VectorIter<'a, T>;
284 fn into_iter(self) -> Self::IntoIter {
285 self.iter()
286 }
287}