1use crate::{Decodable, Decoder, DerOrd, Encodable, Encoder, Error, ErrorKind, Result};
4use core::{
5 cmp::Ordering,
6 fmt,
7 ops::{Add, Sub},
8};
9
10const MAX_U32: u32 = 0xfff_ffff;
12
13#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
17pub struct Length(u32);
18
19impl Length {
20 pub const ZERO: Self = Self(0);
22
23 pub const ONE: Self = Self(1);
25
26 pub const MAX: Self = Self(MAX_U32);
28
29 pub const fn new(value: u16) -> Self {
33 Length(value as u32)
34 }
35
36 pub fn is_zero(self) -> bool {
38 self == Length::ZERO
39 }
40
41 pub fn for_tlv(self) -> Result<Self> {
44 Length(1) + self.encoded_len()? + self
45 }
46
47 fn initial_octet(self) -> Option<u8> {
60 match self.0 {
61 0x80..=0xFF => Some(0x81),
62 0x100..=0xFFFF => Some(0x82),
63 0x10000..=0xFFFFFF => Some(0x83),
64 0x1000000..=MAX_U32 => Some(0x84),
65 _ => None,
66 }
67 }
68}
69
70impl Add for Length {
71 type Output = Result<Self>;
72
73 fn add(self, other: Self) -> Result<Self> {
74 self.0
75 .checked_add(other.0)
76 .ok_or_else(|| ErrorKind::Overflow.into())
77 .and_then(TryInto::try_into)
78 }
79}
80
81impl Add<u8> for Length {
82 type Output = Result<Self>;
83
84 fn add(self, other: u8) -> Result<Self> {
85 self + Length::from(other)
86 }
87}
88
89impl Add<u16> for Length {
90 type Output = Result<Self>;
91
92 fn add(self, other: u16) -> Result<Self> {
93 self + Length::from(other)
94 }
95}
96
97impl Add<u32> for Length {
98 type Output = Result<Self>;
99
100 fn add(self, other: u32) -> Result<Self> {
101 self + Length::try_from(other)?
102 }
103}
104
105impl Add<usize> for Length {
106 type Output = Result<Self>;
107
108 fn add(self, other: usize) -> Result<Self> {
109 self + Length::try_from(other)?
110 }
111}
112
113impl Add<Length> for Result<Length> {
114 type Output = Self;
115
116 fn add(self, other: Length) -> Self {
117 self? + other
118 }
119}
120
121impl Sub for Length {
122 type Output = Result<Self>;
123
124 fn sub(self, other: Length) -> Result<Self> {
125 self.0
126 .checked_sub(other.0)
127 .ok_or_else(|| {
128 ErrorKind::Incomplete {
129 expected_len: other,
130 actual_len: self,
131 }
132 .into()
133 })
134 .and_then(TryInto::try_into)
135 }
136}
137
138impl Sub<Length> for Result<Length> {
139 type Output = Self;
140
141 fn sub(self, other: Length) -> Self {
142 self? - other
143 }
144}
145
146impl From<u8> for Length {
147 fn from(len: u8) -> Length {
148 Length(len as u32)
149 }
150}
151
152impl From<u16> for Length {
153 fn from(len: u16) -> Length {
154 Length(len as u32)
155 }
156}
157
158impl TryFrom<u32> for Length {
159 type Error = Error;
160
161 fn try_from(len: u32) -> Result<Length> {
162 if len <= Self::MAX.0 {
163 Ok(Length(len))
164 } else {
165 Err(ErrorKind::Overflow.into())
166 }
167 }
168}
169
170impl From<Length> for u32 {
171 fn from(length: Length) -> u32 {
172 length.0
173 }
174}
175
176impl TryFrom<usize> for Length {
177 type Error = Error;
178
179 fn try_from(len: usize) -> Result<Length> {
180 u32::try_from(len)
181 .map_err(|_| ErrorKind::Overflow)?
182 .try_into()
183 }
184}
185
186impl TryFrom<Length> for usize {
187 type Error = Error;
188
189 fn try_from(len: Length) -> Result<usize> {
190 len.0.try_into().map_err(|_| ErrorKind::Overflow.into())
191 }
192}
193
194impl Decodable<'_> for Length {
195 fn decode(decoder: &mut Decoder<'_>) -> Result<Length> {
196 match decoder.byte()? {
197 len if len < 0x80 => Ok(len.into()),
200 tag @ 0x81..=0x84 => {
202 let nbytes = tag.checked_sub(0x80).ok_or(ErrorKind::Overlength)? as usize;
203 debug_assert!(nbytes <= 4);
204
205 let mut decoded_len = 0;
206 for _ in 0..nbytes {
207 decoded_len = (decoded_len << 8) | decoder.byte()? as u32;
208 }
209
210 let length = Length::try_from(decoded_len)?;
211
212 if length.initial_octet() == Some(tag) {
215 Ok(length)
216 } else {
217 Err(ErrorKind::Overlength.into())
218 }
219 }
220 _ => {
221 Err(ErrorKind::Overlength.into())
223 }
224 }
225 }
226}
227
228impl Encodable for Length {
229 fn encoded_len(&self) -> Result<Length> {
230 match self.0 {
231 0..=0x7F => Ok(Length(1)),
232 0x80..=0xFF => Ok(Length(2)),
233 0x100..=0xFFFF => Ok(Length(3)),
234 0x10000..=0xFFFFFF => Ok(Length(4)),
235 0x1000000..=MAX_U32 => Ok(Length(5)),
236 _ => Err(ErrorKind::Overflow.into()),
237 }
238 }
239
240 fn encode(&self, encoder: &mut Encoder<'_>) -> Result<()> {
241 if let Some(tag_byte) = self.initial_octet() {
242 encoder.byte(tag_byte)?;
243
244 match self.0.to_be_bytes() {
246 [0, 0, 0, byte] => encoder.byte(byte),
247 [0, 0, bytes @ ..] => encoder.bytes(&bytes),
248 [0, bytes @ ..] => encoder.bytes(&bytes),
249 bytes => encoder.bytes(&bytes),
250 }
251 } else {
252 encoder.byte(self.0 as u8)
253 }
254 }
255}
256
257impl DerOrd for Length {
258 fn der_cmp(&self, other: &Self) -> Result<Ordering> {
259 let mut buf1 = [0u8; 5];
260 let mut buf2 = [0u8; 5];
261
262 let mut encoder1 = Encoder::new(&mut buf1);
263 encoder1.encode(self)?;
264
265 let mut encoder2 = Encoder::new(&mut buf2);
266 encoder2.encode(other)?;
267
268 Ok(encoder1.finish()?.cmp(encoder2.finish()?))
269 }
270}
271
272impl fmt::Display for Length {
273 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
274 self.0.fmt(f)
275 }
276}
277
278#[cfg(test)]
279mod tests {
280 use super::Length;
281 use crate::{Decodable, DerOrd, Encodable, ErrorKind};
282 use core::cmp::Ordering;
283
284 #[test]
285 fn decode() {
286 assert_eq!(Length::ZERO, Length::from_der(&[0x00]).unwrap());
287
288 assert_eq!(Length::from(0x7Fu8), Length::from_der(&[0x7F]).unwrap());
289
290 assert_eq!(
291 Length::from(0x80u8),
292 Length::from_der(&[0x81, 0x80]).unwrap()
293 );
294
295 assert_eq!(
296 Length::from(0xFFu8),
297 Length::from_der(&[0x81, 0xFF]).unwrap()
298 );
299
300 assert_eq!(
301 Length::from(0x100u16),
302 Length::from_der(&[0x82, 0x01, 0x00]).unwrap()
303 );
304
305 assert_eq!(
306 Length::try_from(0x10000u32).unwrap(),
307 Length::from_der(&[0x83, 0x01, 0x00, 0x00]).unwrap()
308 );
309 }
310
311 #[test]
312 fn encode() {
313 let mut buffer = [0u8; 4];
314
315 assert_eq!(&[0x00], Length::ZERO.encode_to_slice(&mut buffer).unwrap());
316
317 assert_eq!(
318 &[0x7F],
319 Length::from(0x7Fu8).encode_to_slice(&mut buffer).unwrap()
320 );
321
322 assert_eq!(
323 &[0x81, 0x80],
324 Length::from(0x80u8).encode_to_slice(&mut buffer).unwrap()
325 );
326
327 assert_eq!(
328 &[0x81, 0xFF],
329 Length::from(0xFFu8).encode_to_slice(&mut buffer).unwrap()
330 );
331
332 assert_eq!(
333 &[0x82, 0x01, 0x00],
334 Length::from(0x100u16).encode_to_slice(&mut buffer).unwrap()
335 );
336
337 assert_eq!(
338 &[0x83, 0x01, 0x00, 0x00],
339 Length::try_from(0x10000u32)
340 .unwrap()
341 .encode_to_slice(&mut buffer)
342 .unwrap()
343 );
344 }
345
346 #[test]
347 fn reject_indefinite_lengths() {
348 assert!(Length::from_der(&[0x80]).is_err());
349 }
350
351 #[test]
352 fn add_overflows_when_max_length_exceeded() {
353 let result = Length::MAX + Length::ONE;
354 assert_eq!(
355 result.err().map(|err| err.kind()),
356 Some(ErrorKind::Overflow)
357 );
358 }
359
360 #[test]
361 fn der_ord() {
362 assert_eq!(Length::ONE.der_cmp(&Length::MAX).unwrap(), Ordering::Less);
363 }
364}