flatbuffers/
primitives.rsuse core::marker::PhantomData;
use core::mem::size_of;
use core::ops::Deref;
use crate::endian_scalar::{emplace_scalar, read_scalar, read_scalar_at};
use crate::follow::Follow;
use crate::push::Push;
pub const FLATBUFFERS_MAX_BUFFER_SIZE: usize = (1u64 << 31) as usize;
pub const FILE_IDENTIFIER_LENGTH: usize = 4;
pub const VTABLE_METADATA_FIELDS: usize = 2;
pub const SIZE_U8: usize = size_of::<u8>();
pub const SIZE_I8: usize = size_of::<i8>();
pub const SIZE_U16: usize = size_of::<u16>();
pub const SIZE_I16: usize = size_of::<i16>();
pub const SIZE_U32: usize = size_of::<u32>();
pub const SIZE_I32: usize = size_of::<i32>();
pub const SIZE_U64: usize = size_of::<u64>();
pub const SIZE_I64: usize = size_of::<i64>();
pub const SIZE_F32: usize = size_of::<f32>();
pub const SIZE_F64: usize = size_of::<f64>();
pub const SIZE_SOFFSET: usize = SIZE_I32;
pub const SIZE_UOFFSET: usize = SIZE_U32;
pub const SIZE_VOFFSET: usize = SIZE_I16;
pub const SIZE_SIZEPREFIX: usize = SIZE_UOFFSET;
pub type SOffsetT = i32;
pub type UOffsetT = u32;
pub type VOffsetT = u16;
#[derive(Clone, Copy)]
pub struct TableFinishedWIPOffset {}
#[derive(Clone, Copy)]
pub struct TableUnfinishedWIPOffset {}
#[derive(Clone, Copy)]
pub struct UnionWIPOffset {}
#[derive(Clone, Copy)]
pub struct VTableWIPOffset {}
#[derive(Debug)]
pub struct WIPOffset<T>(UOffsetT, PhantomData<T>);
impl<T> Copy for WIPOffset<T> {}
impl<T> Clone for WIPOffset<T> {
#[inline(always)]
fn clone(&self) -> Self {
*self
}
}
impl<T> Eq for WIPOffset<T> {}
impl<T> PartialEq for WIPOffset<T> {
fn eq(&self, o: &WIPOffset<T>) -> bool {
self.value() == o.value()
}
}
impl<T> Deref for WIPOffset<T> {
type Target = UOffsetT;
#[inline]
fn deref(&self) -> &UOffsetT {
&self.0
}
}
impl<'a, T: 'a> WIPOffset<T> {
#[inline]
pub fn new(o: UOffsetT) -> WIPOffset<T> {
WIPOffset(o, PhantomData)
}
#[inline(always)]
pub fn as_union_value(self) -> WIPOffset<UnionWIPOffset> {
WIPOffset::new(self.0)
}
#[inline(always)]
pub fn value(self) -> UOffsetT {
self.0
}
}
impl<T> Push for WIPOffset<T> {
type Output = ForwardsUOffset<T>;
#[inline(always)]
unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
let n = (SIZE_UOFFSET + written_len - self.value() as usize) as UOffsetT;
emplace_scalar::<UOffsetT>(dst, n);
}
}
impl<T> Push for ForwardsUOffset<T> {
type Output = Self;
#[inline(always)]
unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
self.value().push(dst, written_len);
}
}
#[derive(Debug)]
pub struct ForwardsUOffset<T>(UOffsetT, PhantomData<T>);
impl<T> Copy for ForwardsUOffset<T> {}
impl<T> Clone for ForwardsUOffset<T> {
#[inline(always)]
fn clone(&self) -> Self {
*self
}
}
impl<T> ForwardsUOffset<T> {
#[inline(always)]
pub fn value(self) -> UOffsetT {
self.0
}
}
impl<'a, T: Follow<'a>> Follow<'a> for ForwardsUOffset<T> {
type Inner = T::Inner;
#[inline(always)]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
let slice = &buf[loc..loc + SIZE_UOFFSET];
let off = read_scalar::<u32>(slice) as usize;
T::follow(buf, loc + off)
}
}
#[derive(Debug)]
pub struct ForwardsVOffset<T>(VOffsetT, PhantomData<T>);
impl<T> ForwardsVOffset<T> {
#[inline(always)]
pub fn value(&self) -> VOffsetT {
self.0
}
}
impl<'a, T: Follow<'a>> Follow<'a> for ForwardsVOffset<T> {
type Inner = T::Inner;
#[inline(always)]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
let slice = &buf[loc..loc + SIZE_VOFFSET];
let off = read_scalar::<VOffsetT>(slice) as usize;
T::follow(buf, loc + off)
}
}
impl<T> Push for ForwardsVOffset<T> {
type Output = Self;
#[inline]
unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
self.value().push(dst, written_len);
}
}
#[derive(Debug)]
pub struct BackwardsSOffset<T>(SOffsetT, PhantomData<T>);
impl<T> BackwardsSOffset<T> {
#[inline(always)]
pub fn value(&self) -> SOffsetT {
self.0
}
}
impl<'a, T: Follow<'a>> Follow<'a> for BackwardsSOffset<T> {
type Inner = T::Inner;
#[inline(always)]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
let slice = &buf[loc..loc + SIZE_SOFFSET];
let off = read_scalar::<SOffsetT>(slice);
T::follow(buf, (loc as SOffsetT - off) as usize)
}
}
impl<T> Push for BackwardsSOffset<T> {
type Output = Self;
#[inline]
unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
self.value().push(dst, written_len);
}
}
pub struct SkipSizePrefix<T>(PhantomData<T>);
impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipSizePrefix<T> {
type Inner = T::Inner;
#[inline(always)]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
T::follow(buf, loc + SIZE_SIZEPREFIX)
}
}
pub struct SkipRootOffset<T>(PhantomData<T>);
impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipRootOffset<T> {
type Inner = T::Inner;
#[inline(always)]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
T::follow(buf, loc + SIZE_UOFFSET)
}
}
pub struct FileIdentifier;
impl<'a> Follow<'a> for FileIdentifier {
type Inner = &'a [u8];
#[inline(always)]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
&buf[loc..loc + FILE_IDENTIFIER_LENGTH]
}
}
pub struct SkipFileIdentifier<T>(PhantomData<T>);
impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipFileIdentifier<T> {
type Inner = T::Inner;
#[inline(always)]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
T::follow(buf, loc + FILE_IDENTIFIER_LENGTH)
}
}
impl<'a> Follow<'a> for bool {
type Inner = bool;
#[inline(always)]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
read_scalar_at::<u8>(buf, loc) != 0
}
}
macro_rules! impl_follow_for_endian_scalar {
($ty:ident) => {
impl<'a> Follow<'a> for $ty {
type Inner = $ty;
#[inline(always)]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
read_scalar_at::<$ty>(buf, loc)
}
}
};
}
impl_follow_for_endian_scalar!(u8);
impl_follow_for_endian_scalar!(u16);
impl_follow_for_endian_scalar!(u32);
impl_follow_for_endian_scalar!(u64);
impl_follow_for_endian_scalar!(i8);
impl_follow_for_endian_scalar!(i16);
impl_follow_for_endian_scalar!(i32);
impl_follow_for_endian_scalar!(i64);
impl_follow_for_endian_scalar!(f32);
impl_follow_for_endian_scalar!(f64);