1use bytes::Bytes;
2
3use crate::{TlvError, read_varu64};
4
5pub struct TlvReader {
10 buf: Bytes,
11 pos: usize,
12}
13
14impl TlvReader {
15 pub fn new(buf: Bytes) -> Self {
16 Self { buf, pos: 0 }
17 }
18
19 pub fn remaining(&self) -> usize {
20 self.buf.len() - self.pos
21 }
22
23 pub fn is_empty(&self) -> bool {
24 self.pos >= self.buf.len()
25 }
26
27 pub fn position(&self) -> usize {
29 self.pos
30 }
31
32 pub fn read_type(&mut self) -> Result<u64, TlvError> {
34 let (v, n) = read_varu64(&self.buf[self.pos..])?;
35 self.pos += n;
36 Ok(v)
37 }
38
39 pub fn read_length(&mut self) -> Result<usize, TlvError> {
41 let (v, n) = read_varu64(&self.buf[self.pos..])?;
42 self.pos += n;
43 Ok(v as usize)
44 }
45
46 pub fn read_bytes(&mut self, len: usize) -> Result<Bytes, TlvError> {
48 if self.pos + len > self.buf.len() {
49 return Err(TlvError::UnexpectedEof);
50 }
51 let slice = self.buf.slice(self.pos..self.pos + len);
52 self.pos += len;
53 Ok(slice)
54 }
55
56 pub fn read_tlv(&mut self) -> Result<(u64, Bytes), TlvError> {
58 let typ = self.read_type()?;
59 let len = self.read_length()?;
60 let val = self.read_bytes(len)?;
61 Ok((typ, val))
62 }
63
64 pub fn peek_type(&self) -> Result<u64, TlvError> {
66 let (v, _) = read_varu64(&self.buf[self.pos..])?;
67 Ok(v)
68 }
69
70 pub fn skip_unknown(&mut self, typ: u64) -> Result<(), TlvError> {
76 if typ <= 31 || typ & 1 == 1 {
77 return Err(TlvError::UnknownCriticalType(typ));
78 }
79 let len = self.read_length()?;
80 if self.pos + len > self.buf.len() {
81 return Err(TlvError::UnexpectedEof);
82 }
83 self.pos += len;
84 Ok(())
85 }
86
87 pub fn scoped(&mut self, len: usize) -> Result<TlvReader, TlvError> {
89 let slice = self.read_bytes(len)?;
90 Ok(TlvReader::new(slice))
91 }
92
93 pub fn as_bytes(&self) -> Bytes {
95 self.buf.slice(self.pos..)
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 fn make_tlv(typ: u8, value: &[u8]) -> Bytes {
104 let mut v = vec![typ, value.len() as u8];
105 v.extend_from_slice(value);
106 Bytes::from(v)
107 }
108
109 #[test]
112 fn read_tlv_basic() {
113 let raw = make_tlv(0x08, b"hello");
114 let mut r = TlvReader::new(raw);
115 let (typ, val) = r.read_tlv().unwrap();
116 assert_eq!(typ, 0x08);
117 assert_eq!(val.as_ref(), b"hello");
118 assert!(r.is_empty());
119 }
120
121 #[test]
122 fn read_tlv_zero_length_value() {
123 let raw = Bytes::from(vec![0x21, 0x00]); let mut r = TlvReader::new(raw);
125 let (typ, val) = r.read_tlv().unwrap();
126 assert_eq!(typ, 0x21);
127 assert_eq!(val.len(), 0);
128 }
129
130 #[test]
131 fn read_tlv_zero_copy_same_allocation() {
132 let raw = Bytes::from(vec![0x15, 0x03, 0xAA, 0xBB, 0xCC]);
133 let ptr = raw.as_ptr();
134 let mut r = TlvReader::new(raw);
135 let (_, val) = r.read_tlv().unwrap();
136 assert_eq!(val.as_ptr(), unsafe { ptr.add(2) });
138 }
139
140 #[test]
141 fn read_tlv_three_byte_type() {
142 let raw = vec![0xFD, 0x03, 0x20, 0x02, 0xAA, 0xBB];
144 let bytes = Bytes::from(raw);
145 let mut r = TlvReader::new(bytes);
146 let (typ, val) = r.read_tlv().unwrap();
147 assert_eq!(typ, 0x0320);
148 assert_eq!(val.as_ref(), &[0xAA, 0xBB]);
149 }
150
151 #[test]
152 fn read_tlv_multiple_sequential() {
153 let mut raw = vec![];
154 raw.extend_from_slice(&[0x07, 0x03, b'f', b'o', b'o']);
155 raw.extend_from_slice(&[0x08, 0x03, b'b', b'a', b'r']);
156 let mut r = TlvReader::new(Bytes::from(raw));
157 let (t1, v1) = r.read_tlv().unwrap();
158 let (t2, v2) = r.read_tlv().unwrap();
159 assert_eq!(t1, 0x07);
160 assert_eq!(v1.as_ref(), b"foo");
161 assert_eq!(t2, 0x08);
162 assert_eq!(v2.as_ref(), b"bar");
163 assert!(r.is_empty());
164 }
165
166 #[test]
169 fn peek_type_does_not_advance() {
170 let raw = make_tlv(0x05, b"data");
171 let r = TlvReader::new(raw);
172 let t1 = r.peek_type().unwrap();
173 let t2 = r.peek_type().unwrap();
174 assert_eq!(t1, 0x05);
175 assert_eq!(t2, 0x05);
176 assert_eq!(r.remaining(), 6); }
178
179 #[test]
182 fn remaining_and_is_empty() {
183 let raw = Bytes::from(vec![0x08, 0x01, 0x42]);
184 let mut r = TlvReader::new(raw);
185 assert!(!r.is_empty());
186 assert_eq!(r.remaining(), 3);
187 r.read_tlv().unwrap();
188 assert!(r.is_empty());
189 assert_eq!(r.remaining(), 0);
190 }
191
192 #[test]
195 fn skip_unknown_even_type_above_31_succeeds() {
196 let raw = Bytes::from(vec![0x22, 0x02, 0xAA, 0xBB, 0x08, 0x01, 0x42]);
198 let mut r = TlvReader::new(raw);
199 let typ = r.read_type().unwrap();
200 assert_eq!(typ, 0x22);
201 r.skip_unknown(typ).unwrap();
202 let (t, v) = r.read_tlv().unwrap();
204 assert_eq!(t, 0x08);
205 assert_eq!(v.as_ref(), &[0x42]);
206 }
207
208 #[test]
209 fn skip_unknown_even_type_0_to_31_is_critical() {
210 let raw = Bytes::from(vec![0x12, 0x02, 0xAA, 0xBB]);
212 let mut r = TlvReader::new(raw);
213 let typ = r.read_type().unwrap();
214 assert_eq!(typ, 0x12);
215 let err = r.skip_unknown(typ).unwrap_err();
216 assert_eq!(err, TlvError::UnknownCriticalType(0x12));
217 }
218
219 #[test]
220 fn skip_unknown_odd_type_errors() {
221 let raw = Bytes::from(vec![0x21, 0x00]);
223 let mut r = TlvReader::new(raw);
224 let typ = r.read_type().unwrap();
225 let err = r.skip_unknown(typ).unwrap_err();
226 assert_eq!(err, TlvError::UnknownCriticalType(0x21));
227 }
228
229 #[test]
232 fn scoped_reader_contains_only_inner_bytes() {
233 let inner: Vec<u8> = vec![0x08, 0x01, b'A', 0x08, 0x01, b'B'];
235 let mut raw = vec![0x07, inner.len() as u8];
236 raw.extend_from_slice(&inner);
237 raw.extend_from_slice(&[0x15, 0x01, 0x99]); let mut r = TlvReader::new(Bytes::from(raw));
239
240 let (typ, _) = r.read_tlv().unwrap();
241 assert_eq!(typ, 0x07);
242
243 let inner2: Vec<u8> = vec![0x08, 0x01, b'A', 0x08, 0x01, b'B'];
245 let mut raw2 = vec![0x07, inner2.len() as u8];
246 raw2.extend_from_slice(&inner2);
247 raw2.push(0x15);
248 raw2.push(0x01);
249 raw2.push(0x99);
250 let mut r2 = TlvReader::new(Bytes::from(raw2));
251 let _outer_type = r2.read_type().unwrap();
252 let outer_len = r2.read_length().unwrap();
253 let mut inner_r = r2.scoped(outer_len).unwrap();
254
255 let (t1, v1) = inner_r.read_tlv().unwrap();
256 let (t2, v2) = inner_r.read_tlv().unwrap();
257 assert_eq!(t1, 0x08);
258 assert_eq!(v1.as_ref(), b"A");
259 assert_eq!(t2, 0x08);
260 assert_eq!(v2.as_ref(), b"B");
261 assert!(inner_r.is_empty());
262
263 let (t3, _) = r2.read_tlv().unwrap();
265 assert_eq!(t3, 0x15);
266 }
267
268 #[test]
271 fn read_tlv_truncated_value_errors() {
272 let raw = Bytes::from(vec![0x08, 0x05, 0xAA, 0xBB]);
274 let mut r = TlvReader::new(raw);
275 assert_eq!(r.read_tlv().unwrap_err(), TlvError::UnexpectedEof);
276 }
277
278 #[test]
279 fn read_bytes_truncated_errors() {
280 let raw = Bytes::from(vec![0x01, 0x02]);
281 let mut r = TlvReader::new(raw);
282 assert_eq!(r.read_bytes(10).unwrap_err(), TlvError::UnexpectedEof);
283 }
284}