1 //! Common handling for types backed by byte allocation with enforcement of a
2 //! library-level length limitation i.e. `Length::max()`.
3 
4 use crate::{
5     referenced::OwnedToRef, BytesRef, DecodeValue, DerOrd, EncodeValue, Error, Header, Length,
6     Reader, Result, StrRef, Writer,
7 };
8 use alloc::{boxed::Box, vec::Vec};
9 use core::cmp::Ordering;
10 
11 /// Byte slice newtype which respects the `Length::max()` limit.
12 #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
13 pub(crate) struct BytesOwned {
14     /// Precomputed `Length` (avoids possible panicking conversions)
15     length: Length,
16 
17     /// Inner value
18     inner: Box<[u8]>,
19 }
20 
21 impl BytesOwned {
22     /// Create a new [`BytesOwned`], ensuring that the provided `slice` value
23     /// is shorter than `Length::max()`.
new(data: impl Into<Box<[u8]>>) -> Result<Self>24     pub fn new(data: impl Into<Box<[u8]>>) -> Result<Self> {
25         let inner: Box<[u8]> = data.into();
26 
27         Ok(Self {
28             length: Length::try_from(inner.len())?,
29             inner,
30         })
31     }
32 
33     /// Borrow the inner byte slice
as_slice(&self) -> &[u8]34     pub fn as_slice(&self) -> &[u8] {
35         &self.inner
36     }
37 
38     /// Get the [`Length`] of this [`BytesRef`]
len(&self) -> Length39     pub fn len(&self) -> Length {
40         self.length
41     }
42 
43     /// Is this [`BytesOwned`] empty?
is_empty(&self) -> bool44     pub fn is_empty(&self) -> bool {
45         self.len() == Length::ZERO
46     }
47 }
48 
49 impl AsRef<[u8]> for BytesOwned {
as_ref(&self) -> &[u8]50     fn as_ref(&self) -> &[u8] {
51         self.as_slice()
52     }
53 }
54 
55 impl<'a> DecodeValue<'a> for BytesOwned {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>56     fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
57         reader.read_vec(header.length).and_then(Self::new)
58     }
59 }
60 
61 impl EncodeValue for BytesOwned {
value_len(&self) -> Result<Length>62     fn value_len(&self) -> Result<Length> {
63         Ok(self.length)
64     }
65 
encode_value(&self, writer: &mut impl Writer) -> Result<()>66     fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
67         writer.write(self.as_ref())
68     }
69 }
70 
71 impl Default for BytesOwned {
default() -> Self72     fn default() -> Self {
73         Self {
74             length: Length::ZERO,
75             inner: Box::new([]),
76         }
77     }
78 }
79 
80 impl DerOrd for BytesOwned {
der_cmp(&self, other: &Self) -> Result<Ordering>81     fn der_cmp(&self, other: &Self) -> Result<Ordering> {
82         Ok(self.as_slice().cmp(other.as_slice()))
83     }
84 }
85 
86 impl From<BytesOwned> for Box<[u8]> {
from(bytes: BytesOwned) -> Box<[u8]>87     fn from(bytes: BytesOwned) -> Box<[u8]> {
88         bytes.inner
89     }
90 }
91 
92 impl From<StrRef<'_>> for BytesOwned {
from(s: StrRef<'_>) -> BytesOwned93     fn from(s: StrRef<'_>) -> BytesOwned {
94         let bytes = s.as_bytes();
95         debug_assert_eq!(bytes.len(), usize::try_from(s.length).expect("overflow"));
96 
97         BytesOwned {
98             inner: Box::from(bytes),
99             length: s.length,
100         }
101     }
102 }
103 
104 impl OwnedToRef for BytesOwned {
105     type Borrowed<'a> = BytesRef<'a>;
owned_to_ref(&self) -> Self::Borrowed<'_>106     fn owned_to_ref(&self) -> Self::Borrowed<'_> {
107         BytesRef {
108             length: self.length,
109             inner: self.inner.as_ref(),
110         }
111     }
112 }
113 
114 impl From<BytesRef<'_>> for BytesOwned {
from(s: BytesRef<'_>) -> BytesOwned115     fn from(s: BytesRef<'_>) -> BytesOwned {
116         BytesOwned {
117             length: s.length,
118             inner: Box::from(s.inner),
119         }
120     }
121 }
122 
123 impl TryFrom<&[u8]> for BytesOwned {
124     type Error = Error;
125 
try_from(bytes: &[u8]) -> Result<Self>126     fn try_from(bytes: &[u8]) -> Result<Self> {
127         Self::new(bytes)
128     }
129 }
130 
131 impl TryFrom<Box<[u8]>> for BytesOwned {
132     type Error = Error;
133 
try_from(bytes: Box<[u8]>) -> Result<Self>134     fn try_from(bytes: Box<[u8]>) -> Result<Self> {
135         Self::new(bytes)
136     }
137 }
138 
139 impl TryFrom<Vec<u8>> for BytesOwned {
140     type Error = Error;
141 
try_from(bytes: Vec<u8>) -> Result<Self>142     fn try_from(bytes: Vec<u8>) -> Result<Self> {
143         Self::new(bytes)
144     }
145 }
146 
147 // Implement by hand because the derive would create invalid values.
148 // Make sure the length and the inner.len matches.
149 #[cfg(feature = "arbitrary")]
150 impl<'a> arbitrary::Arbitrary<'a> for BytesOwned {
arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self>151     fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
152         let length = u.arbitrary()?;
153         Ok(Self {
154             length,
155             inner: Box::from(u.bytes(u32::from(length) as usize)?),
156         })
157     }
158 
size_hint(depth: usize) -> (usize, Option<usize>)159     fn size_hint(depth: usize) -> (usize, Option<usize>) {
160         arbitrary::size_hint::and(Length::size_hint(depth), (0, None))
161     }
162 }
163