/// SOffsetT is a relative pointer from tables to their vtables. pubtype SOffsetT = i32;
/// UOffsetT is used represent both for relative pointers and lengths of vectors. pubtype UOffsetT = u32;
/// VOffsetT is a relative pointer in vtables to point from tables to field data. pubtype VOffsetT = u16;
/// TableFinishedWIPOffset marks a WIPOffset as being for a finished table. #[derive(Clone, Copy)] pubstruct TableFinishedWIPOffset {}
/// TableUnfinishedWIPOffset marks a WIPOffset as being for an unfinished table. #[derive(Clone, Copy)] pubstruct TableUnfinishedWIPOffset {}
/// UnionWIPOffset marks a WIPOffset as being for a union value. #[derive(Clone, Copy)] pubstruct UnionWIPOffset {}
/// VTableWIPOffset marks a WIPOffset as being for a vtable. #[derive(Clone, Copy)] pubstruct VTableWIPOffset {}
/// WIPOffset contains an UOffsetT with a special meaning: it is the location of /// data relative to the *end* of an in-progress FlatBuffer. The /// FlatBufferBuilder uses this to track the location of objects in an absolute /// way. The impl of Push converts a WIPOffset into a ForwardsUOffset. #[derive(Debug)] pubstruct WIPOffset<T>(UOffsetT, PhantomData<T>);
// We cannot use derive for these two impls, as the derived impls would only // implement `Copy` and `Clone` for `T: Copy` and `T: Clone` respectively. // However `WIPOffset<T>` can always be copied, no matter that `T` you // have. impl<T> Copy for WIPOffset<T> {} impl<T> Clone for WIPOffset<T> { #[inline(always)] fn clone(&self) -> Self {
*self
}
}
impl<T> Deref for WIPOffset<T> { type Target = UOffsetT; #[inline] fn deref(&self) -> &UOffsetT {
&self.0
}
} impl<'a, T: 'a> WIPOffset<T> { /// Create a new WIPOffset. #[inline] pubfn new(o: UOffsetT) -> WIPOffset<T> {
WIPOffset(o, PhantomData)
}
/// Return a wrapped value that brings its meaning as a union WIPOffset /// into the type system. #[inline(always)] pubfn as_union_value(self) -> WIPOffset<UnionWIPOffset> {
WIPOffset::new(self.0)
} /// Get the underlying value. #[inline(always)] pubfn value(self) -> UOffsetT { self.0
}
}
impl<T> Push for WIPOffset<T> { type Output = ForwardsUOffset<T>;
#[inline(always)] unsafefn 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;
/// ForwardsUOffset is used by Follow to traverse a FlatBuffer: the pointer /// is incremented by the value contained in this type. #[derive(Debug)] pubstruct ForwardsUOffset<T>(UOffsetT, PhantomData<T>);
// We cannot use derive for these two impls, as the derived impls would only // implement `Copy` and `Clone` for `T: Copy` and `T: Clone` respectively. // However `ForwardsUOffset<T>` can always be copied, no matter that `T` you // have. impl<T> Copy for ForwardsUOffset<T> {} impl<T> Clone for ForwardsUOffset<T> { #[inline(always)] fn clone(&self) -> Self {
*self
}
}
impl<'a, T: Follow<'a>> Follow<'a> for ForwardsUOffset<T> { type Inner = T::Inner; #[inline(always)] unsafefn 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)
}
}
/// ForwardsVOffset is used by Follow to traverse a FlatBuffer: the pointer /// is incremented by the value contained in this type. #[derive(Debug)] pubstruct ForwardsVOffset<T>(VOffsetT, PhantomData<T>); impl<T> ForwardsVOffset<T> { #[inline(always)] pubfn value(&self) -> VOffsetT { self.0
}
}
impl<'a, T: Follow<'a>> Follow<'a> for ForwardsVOffset<T> { type Inner = T::Inner; #[inline(always)] unsafefn 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;
/// ForwardsSOffset is used by Follow to traverse a FlatBuffer: the pointer /// is incremented by the *negative* of the value contained in this type. #[derive(Debug)] pubstruct BackwardsSOffset<T>(SOffsetT, PhantomData<T>); impl<T> BackwardsSOffset<T> { #[inline(always)] pubfn value(&self) -> SOffsetT { self.0
}
}
impl<'a, T: Follow<'a>> Follow<'a> for BackwardsSOffset<T> { type Inner = T::Inner; #[inline(always)] unsafefn 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;
/// SkipSizePrefix is used by Follow to traverse a FlatBuffer: the pointer is /// incremented by a fixed constant in order to skip over the size prefix value. pubstruct SkipSizePrefix<T>(PhantomData<T>); impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipSizePrefix<T> { type Inner = T::Inner; #[inline(always)] unsafefn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
T::follow(buf, loc + SIZE_SIZEPREFIX)
}
}
/// SkipRootOffset is used by Follow to traverse a FlatBuffer: the pointer is /// incremented by a fixed constant in order to skip over the root offset value. pubstruct SkipRootOffset<T>(PhantomData<T>); impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipRootOffset<T> { type Inner = T::Inner; #[inline(always)] unsafefn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
T::follow(buf, loc + SIZE_UOFFSET)
}
}
/// FileIdentifier is used by Follow to traverse a FlatBuffer: the pointer is /// dereferenced into a byte slice, whose bytes are the file identifer value. pubstruct FileIdentifier; impl<'a> Follow<'a> for FileIdentifier { type Inner = &'a [u8]; #[inline(always)] unsafefn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
&buf[loc..loc + FILE_IDENTIFIER_LENGTH]
}
}
/// SkipFileIdentifier is used by Follow to traverse a FlatBuffer: the pointer /// is incremented by a fixed constant in order to skip over the file /// identifier value. pubstruct SkipFileIdentifier<T>(PhantomData<T>); impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipFileIdentifier<T> { type Inner = T::Inner; #[inline(always)] unsafefn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
T::follow(buf, loc + FILE_IDENTIFIER_LENGTH)
}
}
/// Follow trait impls for primitive types. /// /// Ideally, these would be implemented as a single impl using trait bounds on /// EndianScalar, but implementing Follow that way causes a conflict with /// other impls.
macro_rules! impl_follow_for_endian_scalar {
($ty:ident) => { impl<'a> Follow<'a> for $ty { type Inner = $ty; #[inline(always)] unsafefn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
read_scalar_at::<$ty>(buf, loc)
}
}
};
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.