Skip to main content

ms_pdb_msfz/
stream_data.rs

1use core::ops::Range;
2use std::sync::Arc;
3
4use zerocopy::FromZeros;
5
6#[cfg(doc)]
7use crate::Msfz;
8
9/// Contains the contents of an entire stream.
10///
11/// This is used as the return type for [`Msfz::read_stream`] function. This type either contains
12/// an owned buffer (`Vec`) or a counted reference to a slice of an `Arc<[u8]>`.
13///
14/// See the `[Msfz::read_stream]` function for more details.
15pub enum StreamData {
16    /// Owned contents of stream data
17    Box(Box<[u8]>),
18    /// Shared contents of stream data.  The `Range` gives the range of bytes within the `Arc`.
19    ArcSlice(Arc<[u8]>, Range<usize>),
20}
21
22impl StreamData {
23    /// Gets a slice over the contained stream data.
24    #[inline(always)]
25    pub fn as_slice(&self) -> &[u8] {
26        match self {
27            Self::Box(v) => v,
28            Self::ArcSlice(arc, range) => &arc[range.clone()],
29        }
30    }
31
32    /// Returns `true` if the stream contains no data.
33    pub fn is_empty(&self) -> bool {
34        self.as_slice().is_empty()
35    }
36
37    /// Converts this `StreamData` into an owned `Vec<u8>`.
38    pub fn into_vec(self) -> Vec<u8> {
39        self.into_boxed().into()
40    }
41
42    /// Converts this `StreamData` into an owned `Box<[u8]>`.
43    pub fn into_boxed(self) -> Box<[u8]> {
44        match self {
45            Self::Box(b) => b,
46            Self::ArcSlice(arc, range) => {
47                let mut b: Box<[u8]> = FromZeros::new_box_zeroed_with_elems(range.len()).unwrap();
48                b.copy_from_slice(&arc[range]);
49                b
50            }
51        }
52    }
53}
54
55impl From<StreamData> for Box<[u8]> {
56    fn from(s: StreamData) -> Self {
57        s.into_boxed()
58    }
59}
60
61impl core::ops::Deref for StreamData {
62    type Target = [u8];
63
64    #[inline(always)]
65    fn deref(&self) -> &[u8] {
66        self.as_slice()
67    }
68}
69
70impl AsRef<[u8]> for StreamData {
71    #[inline(always)]
72    fn as_ref(&self) -> &[u8] {
73        self.as_slice()
74    }
75}
76
77impl Default for StreamData {
78    fn default() -> Self {
79        Self::empty()
80    }
81}
82
83impl StreamData {
84    /// An empty value for `StreamData`
85    pub fn empty() -> Self {
86        Self::Box(Box::from(&[] as &[u8]))
87    }
88}