1use crate::{DecodeValue, DerOrd, EncodeValue, Error, Header, Length, Reader, Result, Writer};
5use core::cmp::Ordering;
6
7#[derive(Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
9#[repr(transparent)]
10pub(crate) struct BytesRef([u8]);
11
12impl BytesRef {
13 pub const EMPTY: &'static Self = Self::new_unchecked(&[]);
15
16 pub const fn new(slice: &[u8]) -> Result<&Self> {
19 match Length::new_usize(slice.len()) {
20 Ok(_) => Ok(Self::new_unchecked(slice)),
21 Err(err) => Err(err),
22 }
23 }
24
25 pub(crate) const fn new_unchecked(slice: &[u8]) -> &Self {
27 #[allow(unsafe_code)]
29 unsafe {
30 &*(core::ptr::from_ref::<[u8]>(slice) as *const Self)
31 }
32 }
33
34 pub(crate) const fn as_ptr(&self) -> *const BytesRef {
36 core::ptr::from_ref::<BytesRef>(self)
37 }
38
39 pub const fn as_slice(&self) -> &[u8] {
41 &self.0
42 }
43
44 pub fn len(&self) -> Length {
46 debug_assert!(u32::try_from(self.0.len()).is_ok());
47
48 #[allow(clippy::cast_possible_truncation)] Length::new(self.0.len() as u32)
50 }
51
52 pub const fn is_empty(&self) -> bool {
54 self.0.is_empty()
55 }
56
57 pub fn prefix(&self, length: Length) -> Result<&Self> {
59 let inner = self
60 .as_slice()
61 .get(..usize::try_from(length)?)
62 .ok_or_else(|| Error::incomplete(self.len()))?;
63
64 Ok(Self::new_unchecked(inner))
65 }
66}
67
68impl AsRef<[u8]> for BytesRef {
69 fn as_ref(&self) -> &[u8] {
70 self.as_slice()
71 }
72}
73
74impl<'a> DecodeValue<'a> for &'a BytesRef {
75 type Error = Error;
76
77 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
78 BytesRef::new(reader.read_slice(header.length())?)
79 }
80}
81
82impl EncodeValue for BytesRef {
83 fn value_len(&self) -> Result<Length> {
84 Ok(self.len())
85 }
86
87 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
88 writer.write(self.as_ref())
89 }
90}
91
92impl DerOrd for BytesRef {
93 fn der_cmp(&self, other: &Self) -> Result<Ordering> {
94 Ok(self.as_slice().cmp(other.as_slice()))
95 }
96}
97
98impl<'a> TryFrom<&'a [u8]> for &'a BytesRef {
99 type Error = Error;
100
101 fn try_from(slice: &'a [u8]) -> Result<Self> {
102 BytesRef::new(slice)
103 }
104}
105
106#[cfg(feature = "arbitrary")]
109impl<'a> arbitrary::Arbitrary<'a> for &'a BytesRef {
110 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
111 let length: Length = u.arbitrary()?;
112 Ok(BytesRef::new_unchecked(
113 u.bytes(u32::from(length) as usize)?,
114 ))
115 }
116
117 fn size_hint(depth: usize) -> (usize, Option<usize>) {
118 arbitrary::size_hint::and(Length::size_hint(depth), (0, None))
119 }
120}
121
122#[cfg(feature = "alloc")]
123pub(crate) mod allocating {
124 use super::BytesRef;
125 #[cfg(feature = "ber")]
126 use crate::{ErrorKind, length::indefinite::read_constructed_vec};
127
128 use crate::{
129 DecodeValue, DerOrd, EncodeValue, Error, Header, Length, Reader, Result, Tag, Writer,
130 };
131
132 use alloc::{borrow::ToOwned, boxed::Box, vec::Vec};
133 use core::{borrow::Borrow, cmp::Ordering, ops::Deref};
134
135 #[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
137 pub(crate) struct BytesOwned {
138 length: Length,
140
141 inner: Box<[u8]>,
143 }
144
145 impl BytesOwned {
146 pub fn new(data: impl Into<Box<[u8]>>) -> Result<Self> {
149 let inner: Box<[u8]> = data.into();
150
151 Ok(Self {
152 length: Length::try_from(inner.len())?,
153 inner,
154 })
155 }
156 pub fn decode_value_parts<'a, R: Reader<'a>>(
158 reader: &mut R,
159 header: Header,
160 inner_tag: Tag,
161 ) -> Result<Self> {
162 #[cfg(feature = "ber")]
163 if header.is_constructed() {
164 if header.length().is_indefinite() && reader.encoding_rules().is_ber() {
165 return Self::new(read_constructed_vec(reader, header.length(), inner_tag)?);
167 } else {
168 return Err(Error::new(
176 ErrorKind::Noncanonical { tag: header.tag() },
177 reader.position().saturating_sub(Length::ONE),
178 ));
179 }
180 }
181
182 #[cfg(not(feature = "ber"))]
183 let _ = inner_tag;
184
185 Self::decode_value(reader, header)
186 }
187 }
188
189 impl AsRef<[u8]> for BytesOwned {
190 fn as_ref(&self) -> &[u8] {
191 &self.inner
192 }
193 }
194
195 impl AsRef<BytesRef> for BytesOwned {
196 fn as_ref(&self) -> &BytesRef {
197 BytesRef::new_unchecked(&self.inner)
198 }
199 }
200
201 impl Borrow<[u8]> for BytesOwned {
202 fn borrow(&self) -> &[u8] {
203 &self.inner
204 }
205 }
206
207 impl Borrow<BytesRef> for BytesOwned {
208 fn borrow(&self) -> &BytesRef {
209 BytesRef::new_unchecked(&self.inner)
210 }
211 }
212
213 impl Deref for BytesOwned {
214 type Target = BytesRef;
215
216 fn deref(&self) -> &BytesRef {
217 self.borrow()
218 }
219 }
220
221 impl<'a> DecodeValue<'a> for BytesOwned {
222 type Error = Error;
223
224 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
225 reader.read_vec(header.length()).and_then(Self::new)
226 }
227 }
228
229 impl EncodeValue for BytesOwned {
230 fn value_len(&self) -> Result<Length> {
231 Ok(self.length)
232 }
233
234 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
235 writer.write(self.as_ref())
236 }
237 }
238
239 impl Default for BytesOwned {
240 fn default() -> Self {
241 Self {
242 length: Length::ZERO,
243 inner: Box::new([]),
244 }
245 }
246 }
247
248 impl DerOrd for BytesOwned {
249 fn der_cmp(&self, other: &Self) -> Result<Ordering> {
250 Ok(self.as_slice().cmp(other.as_slice()))
251 }
252 }
253
254 impl From<BytesOwned> for Box<[u8]> {
255 fn from(bytes: BytesOwned) -> Box<[u8]> {
256 bytes.inner
257 }
258 }
259
260 impl From<&BytesRef> for BytesOwned {
261 fn from(bytes: &BytesRef) -> BytesOwned {
262 BytesOwned {
263 length: bytes.len(),
264 inner: bytes.as_slice().into(),
265 }
266 }
267 }
268
269 impl TryFrom<&[u8]> for BytesOwned {
270 type Error = Error;
271
272 fn try_from(bytes: &[u8]) -> Result<Self> {
273 Self::new(bytes)
274 }
275 }
276
277 impl TryFrom<Box<[u8]>> for BytesOwned {
278 type Error = Error;
279
280 fn try_from(bytes: Box<[u8]>) -> Result<Self> {
281 Self::new(bytes)
282 }
283 }
284
285 impl TryFrom<Vec<u8>> for BytesOwned {
286 type Error = Error;
287
288 fn try_from(bytes: Vec<u8>) -> Result<Self> {
289 Self::new(bytes)
290 }
291 }
292
293 impl ToOwned for BytesRef {
294 type Owned = BytesOwned;
295
296 fn to_owned(&self) -> BytesOwned {
297 BytesOwned {
298 inner: self.as_slice().into(),
299 length: self.len(),
300 }
301 }
302 }
303
304 #[cfg(feature = "arbitrary")]
307 impl<'a> arbitrary::Arbitrary<'a> for BytesOwned {
308 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
309 let length = u.arbitrary()?;
310 Ok(Self {
311 length,
312 inner: Box::from(u.bytes(u32::from(length) as usize)?),
313 })
314 }
315
316 fn size_hint(depth: usize) -> (usize, Option<usize>) {
317 arbitrary::size_hint::and(Length::size_hint(depth), (0, None))
318 }
319 }
320}