flatbuffers_retained/
size_prefixed.rs

1//! This module focuses on validation and storage of flatbuffers
2//! with 32 bit size-prefixes. It allows validation of Flatbuffer buffers
3//! once at initialization time then safely use them, unchecked, later.
4
5use flatbuffers::{
6    size_prefixed_root_unchecked, Follow, ForwardsUOffset, InvalidFlatbuffer, SkipSizePrefix,
7    Verifiable, Verifier, VerifierOptions,
8};
9use std::marker::PhantomData;
10
11/// This struct holds data backing an size-prefixed flatbuffer.
12/// It is not possible to create this struct without a valid
13/// flatbuffer of type T.
14#[derive(Clone, Debug)]
15pub struct SizePrefixedFlatbufferRetained<'a, T: Follow<'a>> {
16    data: Vec<u8>,
17    phantom: PhantomData<&'a T>,
18}
19
20impl<'a, T> SizePrefixedFlatbufferRetained<'a, T>
21where
22    T: Follow<'a> + Verifiable,
23{
24    /// Make a new FlatbufferRetained class of type T from
25    /// a size-prefixed byte buffer.
26    ///
27    /// # Arguments
28    ///
29    /// * `data` - The data that represents a flatbuffer of type T,
30    ///            prefixed by size.
31    ///
32    /// # Errors
33    ///
34    /// May return any InvalidFlatbuffer error from run_verifier
35    /// when it parses the data.
36    pub fn new(data: Vec<u8>) -> Result<Self, InvalidFlatbuffer> {
37        let opts = VerifierOptions::default();
38        let mut v = Verifier::new(&opts, &data);
39        <SkipSizePrefix<ForwardsUOffset<T>>>::run_verifier(&mut v, 0)?;
40        Ok(SizePrefixedFlatbufferRetained {
41            data,
42            phantom: PhantomData::default(),
43        })
44    }
45
46    /// Return a valid root of type T from the flatbuffer
47    /// buffer stored in self.
48    pub fn get(&'a self) -> <T as Follow<'a>>::Inner {
49        unsafe { size_prefixed_root_unchecked::<T>(&self.data) }
50    }
51}
52
53impl<'a, T: Follow<'a>> SizePrefixedFlatbufferRetained<'a, T> {
54    /// Return an iterator to traverse over the contained Vec.
55    pub fn iter(&self) -> std::slice::Iter<u8> {
56        self.data.iter()
57    }
58
59    /// Deconstruct this class and return the Vec that
60    /// made up the data within it.
61    pub fn take(self) -> Vec<u8> {
62        self.data
63    }
64
65    /// Return a reference to the Vec that make up the data within.
66    pub fn as_vec(&self) -> &Vec<u8> {
67        &self.data
68    }
69}
70
71impl<'a, T: Follow<'a>> Into<Vec<u8>> for SizePrefixedFlatbufferRetained<'a, T> {
72    fn into(self) -> Vec<u8> {
73        self.take()
74    }
75}
76
77impl<'a, 'b, T: Follow<'a>> Into<&'b [u8]> for &'b SizePrefixedFlatbufferRetained<'a, T> {
78    fn into(self) -> &'b [u8] {
79        &self.data[..]
80    }
81}
82
83impl<'a, T: Follow<'a>> AsRef<[u8]> for SizePrefixedFlatbufferRetained<'a, T> {
84    fn as_ref(&self) -> &[u8] {
85        self.data.as_ref()
86    }
87}
88
89impl<'a, T: Follow<'a>> std::borrow::Borrow<[u8]> for SizePrefixedFlatbufferRetained<'a, T> {
90    fn borrow(&self) -> &[u8] {
91        self.data.borrow()
92    }
93}
94
95impl<'a, T: Follow<'a>> std::ops::Deref for SizePrefixedFlatbufferRetained<'a, T> {
96    type Target = [u8];
97    fn deref(&self) -> &[u8] {
98        self.data.deref()
99    }
100}
101
102impl<'a, T: Follow<'a>> IntoIterator for SizePrefixedFlatbufferRetained<'a, T> {
103    type Item = u8;
104    type IntoIter = <Vec<u8> as IntoIterator>::IntoIter;
105    fn into_iter(self) -> <Vec<u8> as IntoIterator>::IntoIter {
106        self.data.into_iter()
107    }
108}