ms_pdb_msfz/
stream_data.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use core::ops::Range;
use std::sync::Arc;

use zerocopy::FromZeros;

#[cfg(doc)]
use crate::Msfz;

/// Contains the contents of an entire stream.
///
/// This is used as the return type for [`Msfz::read_stream`] function. This type either contains
/// an owned buffer (`Vec`) or a counted reference to a slice of an `Arc<[u8]>`.
///
/// See the `[Msfz::read_stream]` function for more details.
pub enum StreamData {
    /// Owned contents of stream data
    Box(Box<[u8]>),
    /// Shared contents of stream data.  The `Range` gives the range of bytes within the `Arc`.
    ArcSlice(Arc<[u8]>, Range<usize>),
}

impl StreamData {
    /// Gets a slice over the contained stream data.
    #[inline(always)]
    pub fn as_slice(&self) -> &[u8] {
        match self {
            Self::Box(v) => v,
            Self::ArcSlice(arc, range) => &arc[range.clone()],
        }
    }

    /// Returns `true` if the stream contains no data.
    pub fn is_empty(&self) -> bool {
        self.as_slice().is_empty()
    }

    /// Converts this `StreamData` into an owned `Vec<u8>`.
    pub fn into_vec(self) -> Vec<u8> {
        self.into_boxed().into()
    }

    /// Converts this `StreamData` into an owned `Box<[u8]>`.
    pub fn into_boxed(self) -> Box<[u8]> {
        match self {
            Self::Box(b) => b,
            Self::ArcSlice(arc, range) => {
                let mut b: Box<[u8]> = FromZeros::new_box_zeroed_with_elems(range.len()).unwrap();
                b.copy_from_slice(&arc[range]);
                b
            }
        }
    }
}

impl From<StreamData> for Box<[u8]> {
    fn from(s: StreamData) -> Self {
        s.into_boxed()
    }
}

impl core::ops::Deref for StreamData {
    type Target = [u8];

    #[inline(always)]
    fn deref(&self) -> &[u8] {
        self.as_slice()
    }
}

impl AsRef<[u8]> for StreamData {
    #[inline(always)]
    fn as_ref(&self) -> &[u8] {
        self.as_slice()
    }
}

impl Default for StreamData {
    fn default() -> Self {
        Self::empty()
    }
}

impl StreamData {
    /// An empty value for `StreamData`
    pub fn empty() -> Self {
        Self::Box(Box::from(&[] as &[u8]))
    }
}