1use std::io::Read;
2
3use bytes::{Buf, BufMut, Bytes, BytesMut};
4
5use crate::{TlvDecode, TlvEncode, TlvError, VarNum};
6
7pub trait Tlv {
9 const TYP: usize;
11
12 fn inner_size(&self) -> usize;
17
18 fn critical() -> bool {
20 tlv_critical::<Self>()
21 }
22
23 fn from_reader(mut reader: impl Read) -> Result<Self, TlvError>
25 where
26 Self: TlvDecode,
27 {
28 let mut header_buf = [0; 18];
29 let bytes_read = reader.read(&mut header_buf).map_err(TlvError::IOError)?;
30 let mut header_bytes = Bytes::copy_from_slice(&header_buf);
31
32 let typ = VarNum::decode(&mut header_bytes)?;
33 if typ.value() as usize != Self::TYP {
34 return Err(TlvError::TypeMismatch {
36 expected: Self::TYP,
37 found: typ.value() as usize,
38 });
39 }
40
41 let len = VarNum::decode(&mut header_bytes)?;
42 let total_len = typ.size() + len.size() + len.value() as usize;
43
44 let mut bytes = BytesMut::with_capacity(total_len);
45 bytes.put(&header_buf[0..bytes_read]);
46
47 let mut left_to_read = total_len - bytes_read;
48 let mut buf = [0; 1024];
49 while left_to_read > 0 {
50 let bytes_read = reader
51 .read(&mut buf[0..left_to_read])
52 .map_err(TlvError::IOError)?;
53 bytes.put(&buf[..left_to_read]);
54 left_to_read -= bytes_read;
55 }
56
57 Self::decode(&mut bytes.freeze())
58 }
59}
60
61pub const fn tlv_critical<T: Tlv + ?Sized>() -> bool {
66 tlv_typ_critical(T::TYP)
67}
68
69pub const fn tlv_typ_critical(typ: usize) -> bool {
74 typ < 32 || typ & 1 == 1
75}
76
77#[derive(Debug, Clone, PartialEq, Eq, Hash)]
79pub struct GenericTlv<T> {
80 pub typ: VarNum,
82 pub len: VarNum,
84 pub content: T,
86}
87
88impl<T> TlvDecode for GenericTlv<T>
89where
90 T: TlvDecode,
91{
92 fn decode(bytes: &mut Bytes) -> crate::Result<Self> {
93 let typ = VarNum::decode(bytes)?.into();
94 let len = VarNum::decode(bytes)?;
95
96 if bytes.remaining() < len.into() {
97 return Err(TlvError::UnexpectedEndOfStream);
98 }
99
100 let mut inner_data = bytes.split_to(len.into());
101 Ok(Self {
102 typ,
103 len,
104 content: T::decode(&mut inner_data)?,
105 })
106 }
107}
108
109impl<T> TlvEncode for GenericTlv<T>
110where
111 T: TlvEncode,
112{
113 fn encode(&self) -> Bytes {
114 let mut bytes = BytesMut::with_capacity(self.size());
115 bytes.put(self.typ.encode());
116 bytes.put(self.len.encode());
117
118 let mut content = self.content.encode();
119 content.truncate(self.len.into());
120 if content.len() != self.len.into() {
121 panic!("GenericTLV length longer than encoded content");
122 }
123 bytes.put(content);
124 bytes.freeze()
125 }
126
127 fn size(&self) -> usize {
128 self.typ.size() + self.len.size() + self.content.size()
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use bytes::{Buf, BufMut, Bytes, BytesMut};
135
136 use crate::tests::GenericNameComponent;
137 use crate::{error::TlvError, Result, TlvDecode, TlvEncode, VarNum};
138
139 use super::*;
140
141 #[derive(Debug)]
142 struct Name {
143 components: Vec<GenericNameComponent>,
144 }
145
146 impl Tlv for Name {
147 const TYP: usize = 7;
148
149 fn inner_size(&self) -> usize {
150 self.components.size()
151 }
152 }
153
154 impl TlvDecode for Name {
155 fn decode(mut bytes: &mut Bytes) -> Result<Self> {
156 let typ = VarNum::decode(&mut bytes)?;
157 if usize::from(typ) != Self::TYP {
158 return Err(TlvError::TypeMismatch {
159 expected: Self::TYP,
160 found: typ.into(),
161 });
162 }
163 let length = VarNum::decode(&mut bytes)?;
164 let mut inner_data = bytes.copy_to_bytes(length.into());
165 let components = Vec::<GenericNameComponent>::decode(&mut inner_data)?;
166
167 Ok(Self { components })
168 }
169 }
170
171 impl TlvEncode for Name {
172 fn encode(&self) -> Bytes {
173 let mut bytes = BytesMut::with_capacity(self.size());
174 bytes.put(VarNum::from(Self::TYP).encode());
175 bytes.put(VarNum::from(self.inner_size()).encode());
176 bytes.put(self.components.encode());
177
178 bytes.freeze()
179 }
180
181 fn size(&self) -> usize {
182 VarNum::from(Self::TYP).size()
183 + VarNum::from(self.inner_size()).size()
184 + self.components.size()
185 }
186 }
187
188 #[test]
189 fn wrong_type() {
190 let mut data = Bytes::from(&[9, 5, b'h', b'e', b'l', b'l', b'o', 255, 255, 255][..]);
191 let component = GenericNameComponent::decode(&mut data);
192
193 assert!(component.is_err());
194 let error = component.unwrap_err();
195
196 assert_eq!(
197 error,
198 TlvError::TypeMismatch {
199 expected: 8,
200 found: 9
201 }
202 );
203 }
204
205 #[test]
206 fn name() {
207 let mut data = Bytes::from(
208 &[
209 7, 14, 8, 5, b'h', b'e', b'l', b'l', b'o', 8, 5, b'w', b'o', b'r', b'l', b'd', 255,
210 255, 255,
211 ][..],
212 );
213 let name = Name::decode(&mut data).unwrap();
214
215 assert_eq!(data.remaining(), 3);
216 assert_eq!(name.components.len(), 2);
217 assert_eq!(name.components[0].name, &b"hello"[..]);
218 assert_eq!(name.components[1].name, &b"world"[..]);
219 }
220}