flatbuffers/
primitives.rs1use core::marker::PhantomData;
18use core::mem::size_of;
19use core::ops::Deref;
20
21use crate::endian_scalar::{emplace_scalar, read_scalar, read_scalar_at};
22use crate::follow::Follow;
23use crate::push::Push;
24
25pub const FLATBUFFERS_MAX_BUFFER_SIZE: usize = (1u64 << 31) as usize;
26
27pub const FILE_IDENTIFIER_LENGTH: usize = 4;
28
29pub const VTABLE_METADATA_FIELDS: usize = 2;
30
31pub const SIZE_U8: usize = size_of::<u8>();
32pub const SIZE_I8: usize = size_of::<i8>();
33
34pub const SIZE_U16: usize = size_of::<u16>();
35pub const SIZE_I16: usize = size_of::<i16>();
36
37pub const SIZE_U32: usize = size_of::<u32>();
38pub const SIZE_I32: usize = size_of::<i32>();
39
40pub const SIZE_U64: usize = size_of::<u64>();
41pub const SIZE_I64: usize = size_of::<i64>();
42
43pub const SIZE_F32: usize = size_of::<f32>();
44pub const SIZE_F64: usize = size_of::<f64>();
45
46pub const SIZE_SOFFSET: usize = SIZE_I32;
47pub const SIZE_UOFFSET: usize = SIZE_U32;
48pub const SIZE_VOFFSET: usize = SIZE_I16;
49
50pub const SIZE_SIZEPREFIX: usize = SIZE_UOFFSET;
51
52pub type SOffsetT = i32;
54
55pub type UOffsetT = u32;
57
58pub type VOffsetT = u16;
60
61#[derive(Clone, Copy)]
63pub struct TableFinishedWIPOffset {}
64
65#[derive(Clone, Copy)]
67pub struct TableUnfinishedWIPOffset {}
68
69#[derive(Clone, Copy)]
71pub struct UnionWIPOffset {}
72
73#[derive(Clone, Copy)]
75pub struct VTableWIPOffset {}
76
77#[derive(Debug)]
82pub struct WIPOffset<T>(UOffsetT, PhantomData<T>);
83
84impl<T> Copy for WIPOffset<T> {}
89impl<T> Clone for WIPOffset<T> {
90 #[inline(always)]
91 fn clone(&self) -> Self {
92 *self
93 }
94}
95
96impl<T> Eq for WIPOffset<T> {}
97
98impl<T> PartialEq for WIPOffset<T> {
99 fn eq(&self, o: &WIPOffset<T>) -> bool {
100 self.value() == o.value()
101 }
102}
103
104impl<T> Deref for WIPOffset<T> {
105 type Target = UOffsetT;
106 #[inline]
107 fn deref(&self) -> &UOffsetT {
108 &self.0
109 }
110}
111impl<'a, T: 'a> WIPOffset<T> {
112 #[inline]
114 pub fn new(o: UOffsetT) -> WIPOffset<T> {
115 WIPOffset(o, PhantomData)
116 }
117
118 #[inline(always)]
121 pub fn as_union_value(self) -> WIPOffset<UnionWIPOffset> {
122 WIPOffset::new(self.0)
123 }
124 #[inline(always)]
126 pub fn value(self) -> UOffsetT {
127 self.0
128 }
129}
130
131impl<T> Push for WIPOffset<T> {
132 type Output = ForwardsUOffset<T>;
133
134 #[inline(always)]
135 unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
136 let n = (SIZE_UOFFSET + written_len - self.value() as usize) as UOffsetT;
137 emplace_scalar::<UOffsetT>(dst, n);
138 }
139}
140
141impl<T> Push for ForwardsUOffset<T> {
142 type Output = Self;
143
144 #[inline(always)]
145 unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
146 self.value().push(dst, written_len);
147 }
148}
149
150#[derive(Debug)]
153pub struct ForwardsUOffset<T>(UOffsetT, PhantomData<T>);
154
155impl<T> Copy for ForwardsUOffset<T> {}
160impl<T> Clone for ForwardsUOffset<T> {
161 #[inline(always)]
162 fn clone(&self) -> Self {
163 *self
164 }
165}
166
167impl<T> ForwardsUOffset<T> {
168 #[inline(always)]
169 pub fn value(self) -> UOffsetT {
170 self.0
171 }
172}
173
174impl<'a, T: Follow<'a>> Follow<'a> for ForwardsUOffset<T> {
175 type Inner = T::Inner;
176 #[inline(always)]
177 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
178 let slice = &buf[loc..loc + SIZE_UOFFSET];
179 let off = read_scalar::<u32>(slice) as usize;
180 T::follow(buf, loc + off)
181 }
182}
183
184#[derive(Debug)]
187pub struct ForwardsVOffset<T>(VOffsetT, PhantomData<T>);
188impl<T> ForwardsVOffset<T> {
189 #[inline(always)]
190 pub fn value(&self) -> VOffsetT {
191 self.0
192 }
193}
194
195impl<'a, T: Follow<'a>> Follow<'a> for ForwardsVOffset<T> {
196 type Inner = T::Inner;
197 #[inline(always)]
198 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
199 let slice = &buf[loc..loc + SIZE_VOFFSET];
200 let off = read_scalar::<VOffsetT>(slice) as usize;
201 T::follow(buf, loc + off)
202 }
203}
204
205impl<T> Push for ForwardsVOffset<T> {
206 type Output = Self;
207
208 #[inline]
209 unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
210 self.value().push(dst, written_len);
211 }
212}
213
214#[derive(Debug)]
217pub struct BackwardsSOffset<T>(SOffsetT, PhantomData<T>);
218impl<T> BackwardsSOffset<T> {
219 #[inline(always)]
220 pub fn value(&self) -> SOffsetT {
221 self.0
222 }
223}
224
225impl<'a, T: Follow<'a>> Follow<'a> for BackwardsSOffset<T> {
226 type Inner = T::Inner;
227 #[inline(always)]
228 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
229 let slice = &buf[loc..loc + SIZE_SOFFSET];
230 let off = read_scalar::<SOffsetT>(slice);
231 T::follow(buf, (loc as SOffsetT - off) as usize)
232 }
233}
234
235impl<T> Push for BackwardsSOffset<T> {
236 type Output = Self;
237
238 #[inline]
239 unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
240 self.value().push(dst, written_len);
241 }
242}
243
244pub struct SkipSizePrefix<T>(PhantomData<T>);
247impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipSizePrefix<T> {
248 type Inner = T::Inner;
249 #[inline(always)]
250 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
251 T::follow(buf, loc + SIZE_SIZEPREFIX)
252 }
253}
254
255pub struct SkipRootOffset<T>(PhantomData<T>);
258impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipRootOffset<T> {
259 type Inner = T::Inner;
260 #[inline(always)]
261 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
262 T::follow(buf, loc + SIZE_UOFFSET)
263 }
264}
265
266pub struct FileIdentifier;
269impl<'a> Follow<'a> for FileIdentifier {
270 type Inner = &'a [u8];
271 #[inline(always)]
272 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
273 &buf[loc..loc + FILE_IDENTIFIER_LENGTH]
274 }
275}
276
277pub struct SkipFileIdentifier<T>(PhantomData<T>);
281impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipFileIdentifier<T> {
282 type Inner = T::Inner;
283 #[inline(always)]
284 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
285 T::follow(buf, loc + FILE_IDENTIFIER_LENGTH)
286 }
287}
288
289impl<'a> Follow<'a> for bool {
290 type Inner = bool;
291 #[inline(always)]
292 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
293 read_scalar_at::<u8>(buf, loc) != 0
294 }
295}
296
297macro_rules! impl_follow_for_endian_scalar {
303 ($ty:ident) => {
304 impl<'a> Follow<'a> for $ty {
305 type Inner = $ty;
306 #[inline(always)]
307 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
308 read_scalar_at::<$ty>(buf, loc)
309 }
310 }
311 };
312}
313
314impl_follow_for_endian_scalar!(u8);
315impl_follow_for_endian_scalar!(u16);
316impl_follow_for_endian_scalar!(u32);
317impl_follow_for_endian_scalar!(u64);
318impl_follow_for_endian_scalar!(i8);
319impl_follow_for_endian_scalar!(i16);
320impl_follow_for_endian_scalar!(i32);
321impl_follow_for_endian_scalar!(i64);
322impl_follow_for_endian_scalar!(f32);
323impl_follow_for_endian_scalar!(f64);