1use crate::follow::Follow;
18use crate::primitives::*;
19use crate::vtable::VTable;
20
21#[derive(Clone, Copy, Debug, PartialEq, Eq)]
22pub struct Table<'a> {
23 buf: &'a [u8],
24 loc: usize,
25}
26
27impl<'a> Table<'a> {
28 #[inline]
29 pub fn buf(&self) -> &'a [u8] {
30 self.buf
31 }
32
33 #[inline]
34 pub fn loc(&self) -> usize {
35 self.loc
36 }
37
38 #[inline]
42 pub unsafe fn new(buf: &'a [u8], loc: usize) -> Self {
43 Table { buf, loc }
44 }
45
46 #[inline]
47 pub fn vtable(&self) -> VTable<'a> {
48 unsafe { <BackwardsSOffset<VTable<'a>>>::follow(self.buf, self.loc) }
51 }
52
53 #[inline]
60 pub unsafe fn get<T: Follow<'a> + 'a>(
61 &self,
62 slot_byte_loc: VOffsetT,
63 default: Option<T::Inner>,
64 ) -> Option<T::Inner> {
65 let o = self.vtable().get(slot_byte_loc) as usize;
66 if o == 0 {
67 return default;
68 }
69 Some(<T>::follow(self.buf, self.loc + o))
70 }
71}
72
73impl<'a> Follow<'a> for Table<'a> {
74 type Inner = Table<'a>;
75 #[inline]
76 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
77 Table { buf, loc }
78 }
79}
80
81#[inline]
83pub fn buffer_has_identifier(data: &[u8], ident: &str, size_prefixed: bool) -> bool {
84 assert_eq!(ident.len(), FILE_IDENTIFIER_LENGTH);
85
86 let got = if size_prefixed {
87 assert!(data.len() >= SIZE_SIZEPREFIX + SIZE_UOFFSET + FILE_IDENTIFIER_LENGTH);
88 unsafe { <SkipSizePrefix<SkipRootOffset<FileIdentifier>>>::follow(data, 0) }
91 } else {
92 assert!(data.len() >= SIZE_UOFFSET + FILE_IDENTIFIER_LENGTH);
93 unsafe { <SkipRootOffset<FileIdentifier>>::follow(data, 0) }
96 };
97
98 ident.as_bytes() == got
99}