der/asn1/integer/
bigint.rs1use super::uint;
4use crate::{
5 asn1::AnyRef, ord::OrdIsValueOrd, ByteSlice, DecodeValue, EncodeValue, Error, ErrorKind,
6 FixedTag, Header, Length, Reader, Result, Tag, Writer,
7};
8
9#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
17pub struct UIntRef<'a> {
18 inner: ByteSlice<'a>,
20}
21
22impl<'a> UIntRef<'a> {
23 pub fn new(bytes: &'a [u8]) -> Result<Self> {
25 let inner = ByteSlice::new(uint::strip_leading_zeroes(bytes))
26 .map_err(|_| ErrorKind::Length { tag: Self::TAG })?;
27
28 Ok(Self { inner })
29 }
30
31 pub fn as_bytes(&self) -> &'a [u8] {
34 self.inner.as_slice()
35 }
36
37 pub fn len(&self) -> Length {
39 self.inner.len()
40 }
41
42 pub fn is_empty(&self) -> bool {
44 self.inner.is_empty()
45 }
46}
47
48impl<'a> DecodeValue<'a> for UIntRef<'a> {
49 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
50 let bytes = ByteSlice::decode_value(reader, header)?.as_slice();
51 let result = Self::new(uint::decode_to_slice(bytes)?)?;
52
53 if result.value_len()? != header.length {
55 return Err(Self::TAG.non_canonical_error());
56 }
57
58 Ok(result)
59 }
60}
61
62impl<'a> EncodeValue for UIntRef<'a> {
63 fn value_len(&self) -> Result<Length> {
64 uint::encoded_len(self.inner.as_slice())
65 }
66
67 fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
68 if self.value_len()? > self.len() {
70 writer.write_byte(0)?;
71 }
72
73 writer.write(self.as_bytes())
74 }
75}
76
77impl<'a> From<&UIntRef<'a>> for UIntRef<'a> {
78 fn from(value: &UIntRef<'a>) -> UIntRef<'a> {
79 *value
80 }
81}
82
83impl<'a> TryFrom<AnyRef<'a>> for UIntRef<'a> {
84 type Error = Error;
85
86 fn try_from(any: AnyRef<'a>) -> Result<UIntRef<'a>> {
87 any.decode_into()
88 }
89}
90
91impl<'a> FixedTag for UIntRef<'a> {
92 const TAG: Tag = Tag::Integer;
93}
94
95impl<'a> OrdIsValueOrd for UIntRef<'a> {}
96
97#[cfg(test)]
98mod tests {
99 use super::UIntRef;
100 use crate::{
101 asn1::{integer::tests::*, AnyRef},
102 Decode, Encode, ErrorKind, SliceWriter, Tag,
103 };
104
105 #[test]
106 fn decode_uint_bytes() {
107 assert_eq!(&[0], UIntRef::from_der(I0_BYTES).unwrap().as_bytes());
108 assert_eq!(&[127], UIntRef::from_der(I127_BYTES).unwrap().as_bytes());
109 assert_eq!(&[128], UIntRef::from_der(I128_BYTES).unwrap().as_bytes());
110 assert_eq!(&[255], UIntRef::from_der(I255_BYTES).unwrap().as_bytes());
111
112 assert_eq!(
113 &[0x01, 0x00],
114 UIntRef::from_der(I256_BYTES).unwrap().as_bytes()
115 );
116
117 assert_eq!(
118 &[0x7F, 0xFF],
119 UIntRef::from_der(I32767_BYTES).unwrap().as_bytes()
120 );
121 }
122
123 #[test]
124 fn encode_uint_bytes() {
125 for &example in &[
126 I0_BYTES,
127 I127_BYTES,
128 I128_BYTES,
129 I255_BYTES,
130 I256_BYTES,
131 I32767_BYTES,
132 ] {
133 let uint = UIntRef::from_der(example).unwrap();
134
135 let mut buf = [0u8; 128];
136 let mut encoder = SliceWriter::new(&mut buf);
137 uint.encode(&mut encoder).unwrap();
138
139 let result = encoder.finish().unwrap();
140 assert_eq!(example, result);
141 }
142 }
143
144 #[test]
145 fn reject_oversize_without_extra_zero() {
146 let err = UIntRef::try_from(AnyRef::new(Tag::Integer, &[0x81]).unwrap())
147 .err()
148 .unwrap();
149
150 assert_eq!(err.kind(), ErrorKind::Value { tag: Tag::Integer });
151 }
152}