1use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
4use core::fmt;
5use std::io::{Cursor, Read, Result, Write};
6
7pub struct TlvBuffer {
23 pub data: Vec<u8>,
24}
25
26const TYPE_INT_1: u8 = 0;
27const TYPE_INT_2: u8 = 1;
28const TYPE_INT_4: u8 = 2;
29const TYPE_INT_8: u8 = 3;
30const TYPE_UINT_1: u8 = 4;
31const TYPE_UINT_2: u8 = 5;
32const TYPE_UINT_4: u8 = 6;
33const TYPE_UINT_8: u8 = 7;
34const TYPE_BOOL_FALSE: u8 = 8;
35const TYPE_BOOL_TRUE: u8 = 9;
36const TYPE_FLOAT_4: u8 = 0xA;
37const TYPE_FLOAT_8: u8 = 0xB;
38const TYPE_UTF8_L1: u8 = 0xC;
39const TYPE_OCTET_STRING_L1: u8 = 0x10;
40const TYPE_OCTET_STRING_L2: u8 = 0x11;
41const TYPE_OCTET_STRING_L4: u8 = 0x12;
42const TYPE_OCTET_STRING_L8: u8 = 0x13;
43
44const TYPE_STRUCT: u8 = 0x15;
45const TYPE_ARRAY: u8 = 0x16;
46const TYPE_LIST: u8 = 0x17;
47const TYPE_END_CONTAINER: u8 = 0x18;
48
49const CTRL_CTX_L1: u8 = 1 << 5;
50
51impl TlvBuffer {
52 pub fn new() -> Self {
53 Self {
54 data: Vec::with_capacity(1024),
55 }
56 }
57 pub fn from_vec(v: Vec<u8>) -> Self {
58 Self { data: v }
59 }
60 pub fn write_raw(&mut self, data: &[u8]) -> Result<()> {
61 self.data.write_all(data)
62 }
63 pub fn write_anon_struct(&mut self) -> Result<()> {
64 self.data.write_u8(TYPE_STRUCT)?;
65 Ok(())
66 }
67 pub fn write_anon_list(&mut self) -> Result<()> {
68 self.data.write_u8(TYPE_LIST)?;
69 Ok(())
70 }
71 pub fn write_struct(&mut self, tag: u8) -> Result<()> {
72 self.data.write_u8(CTRL_CTX_L1 | TYPE_STRUCT)?;
73 self.data.write_u8(tag)?;
74 Ok(())
75 }
76 pub fn write_array(&mut self, tag: u8) -> Result<()> {
77 self.data.write_u8(CTRL_CTX_L1 | TYPE_ARRAY)?;
78 self.data.write_u8(tag)?;
79 Ok(())
80 }
81 pub fn write_list(&mut self, tag: u8) -> Result<()> {
82 self.data.write_u8(CTRL_CTX_L1 | TYPE_LIST)?;
83 self.data.write_u8(tag)?;
84 Ok(())
85 }
86 pub fn write_struct_end(&mut self) -> Result<()> {
87 self.data.write_u8(TYPE_END_CONTAINER)?;
88 Ok(())
89 }
90 pub fn write_string(&mut self, tag: u8, data: &str) -> Result<()> {
91 let ctrl = CTRL_CTX_L1 | TYPE_UTF8_L1;
92 let bytes = data.as_bytes();
93 self.data.write_u8(ctrl)?;
94 self.data.write_u8(tag)?;
95 self.data.write_u8(bytes.len() as u8)?;
96 self.data.write_all(bytes)?;
97 Ok(())
98 }
99 pub fn write_octetstring(&mut self, tag: u8, data: &[u8]) -> Result<()> {
100 if data.len() > 0xff {
101 self.data.write_u8(CTRL_CTX_L1 | TYPE_OCTET_STRING_L2)?;
102 self.data.write_u8(tag)?;
103 self.data.write_u16::<LittleEndian>(data.len() as u16)?;
104 } else {
105 self.data.write_u8(CTRL_CTX_L1 | TYPE_OCTET_STRING_L1)?;
106 self.data.write_u8(tag)?;
107 self.data.write_u8(data.len() as u8)?;
108 }
109 self.data.write_all(data)?;
110 Ok(())
111 }
112 pub fn write_int8(&mut self, tag: u8, value: i8) -> Result<()> {
113 self.data.write_u8(CTRL_CTX_L1 | TYPE_INT_1)?;
114 self.data.write_u8(tag)?;
115 self.data.write_i8(value)
116 }
117 pub fn write_int16(&mut self, tag: u8, value: i16) -> Result<()> {
118 self.data.write_u8(CTRL_CTX_L1 | TYPE_INT_2)?;
119 self.data.write_u8(tag)?;
120 self.data.write_i16::<LittleEndian>(value)
121 }
122 pub fn write_int32(&mut self, tag: u8, value: i32) -> Result<()> {
123 self.data.write_u8(CTRL_CTX_L1 | TYPE_INT_4)?;
124 self.data.write_u8(tag)?;
125 self.data.write_i32::<LittleEndian>(value)
126 }
127 pub fn write_int64(&mut self, tag: u8, value: i64) -> Result<()> {
128 self.data.write_u8(CTRL_CTX_L1 | TYPE_INT_8)?;
129 self.data.write_u8(tag)?;
130 self.data.write_i64::<LittleEndian>(value)
131 }
132 pub fn write_uint8(&mut self, tag: u8, value: u8) -> Result<()> {
133 self.data.write_u8(CTRL_CTX_L1 | TYPE_UINT_1)?;
134 self.data.write_u8(tag)?;
135 self.data.write_u8(value)
136 }
137 pub fn write_octetstring_notag(&mut self, data: &[u8]) -> Result<()> {
138 if data.len() > 0xff {
139 self.data.write_u8(TYPE_OCTET_STRING_L2)?;
140 self.data.write_u16::<LittleEndian>(data.len() as u16)?;
141 } else {
142 self.data.write_u8(TYPE_OCTET_STRING_L1)?;
143 self.data.write_u8(data.len() as u8)?;
144 }
145 self.data.write_all(data)
146 }
147 pub fn write_uint8_notag(&mut self, value: u8) -> Result<()> {
148 self.data.write_u8(TYPE_UINT_1)?;
149 self.data.write_u8(value)
150 }
151 pub fn write_uint16_notag(&mut self, value: u16) -> Result<()> {
152 self.data.write_u8(TYPE_UINT_2)?;
153 self.data.write_u16::<LittleEndian>(value)
154 }
155 pub fn write_uint32_notag(&mut self, value: u32) -> Result<()> {
156 self.data.write_u8(TYPE_UINT_4)?;
157 self.data.write_u32::<LittleEndian>(value)
158 }
159 pub fn write_uint16(&mut self, tag: u8, value: u16) -> Result<()> {
160 self.data.write_u8(CTRL_CTX_L1 | TYPE_UINT_2)?;
161 self.data.write_u8(tag)?;
162 self.data.write_u16::<LittleEndian>(value)
163 }
164 pub fn write_uint32(&mut self, tag: u8, value: u32) -> Result<()> {
165 self.data.write_u8(CTRL_CTX_L1 | TYPE_UINT_4)?;
166 self.data.write_u8(tag)?;
167 self.data.write_u32::<LittleEndian>(value)
168 }
169 pub fn write_uint64(&mut self, tag: u8, value: u64) -> Result<()> {
170 self.data.write_u8(CTRL_CTX_L1 | TYPE_UINT_8)?;
171 self.data.write_u8(tag)?;
172 self.data.write_u64::<LittleEndian>(value)
173 }
174 pub fn write_bool(&mut self, tag: u8, value: bool) -> Result<()> {
175 if value {
176 self.data.write_u8(CTRL_CTX_L1 | TYPE_BOOL_TRUE)?;
177 } else {
178 self.data.write_u8(CTRL_CTX_L1 | TYPE_BOOL_FALSE)?;
179 }
180 self.data.write_u8(tag)
181 }
182}
183
184impl Default for TlvBuffer {
185 fn default() -> Self {
186 Self::new()
187 }
188}
189
190#[derive(Clone, PartialEq)]
192pub enum TlvItemValue {
193 Int(u64),
194 Bool(bool),
195 String(String),
196 OctetString(Vec<u8>),
197 Float(f64),
198 List(Vec<TlvItem>),
199 Nil(),
200 Invalid(),
201}
202
203impl From<TlvItemValue> for bool {
204 fn from(value: TlvItemValue) -> Self {
205 match value {
206 TlvItemValue::Bool(b) => b,
207 _ => false,
208 }
209 }
210}
211impl From<TlvItemValue> for String {
212 fn from(value: TlvItemValue) -> Self {
213 match value {
214 TlvItemValue::String(s) => s,
215 _ => String::new(),
216 }
217 }
218}
219
220impl<'a> TryFrom<&'a TlvItemValue> for &'a [u8] {
221 type Error = &'static str;
222 fn try_from(value: &'a TlvItemValue) -> std::result::Result<Self, Self::Error> {
223 if let TlvItemValue::OctetString(ref s) = value {
224 Ok(s.as_slice())
225 } else {
226 Err("Not an octet string")
227 }
228 }
229}
230impl From<TlvItemValue> for Vec<u8> {
231 fn from(value: TlvItemValue) -> Self {
232 match value {
233 TlvItemValue::OctetString(s) => s,
234 _ => Vec::new(),
235 }
236 }
237}
238impl From<TlvItemValue> for u64 {
239 fn from(value: TlvItemValue) -> Self {
240 match value {
241 TlvItemValue::Int(i) => i,
242 _ => 0,
243 }
244 }
245}
246impl From<TlvItemValue> for Vec<TlvItem> {
247 fn from(value: TlvItemValue) -> Self {
248 match value {
249 TlvItemValue::List(lst) => lst,
250 _ => panic!("Cannot convert to Vec<TlvItem>"),
251 }
252 }
253}
254
255#[derive(Debug, Clone, PartialEq)]
257pub struct TlvItem {
258 pub tag: u8,
259 pub value: TlvItemValue,
260}
261
262impl fmt::Debug for TlvItemValue {
263 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
264 match self {
265 Self::Int(arg0) => f.debug_tuple("Int").field(arg0).finish(),
266 Self::Bool(arg0) => f.debug_tuple("Bool").field(arg0).finish(),
267 Self::String(arg0) => f.debug_tuple("String").field(arg0).finish(),
268 Self::OctetString(arg0) => f
269 .debug_tuple("OctetString")
270 .field(&hex::encode(arg0))
271 .finish(),
272 Self::List(arg0) => f.debug_tuple("List").field(arg0).finish(),
273 Self::Nil() => f.debug_tuple("Nil").finish(),
274 Self::Invalid() => f.debug_tuple("Invalid").finish(),
275 Self::Float(arg0) => f.debug_tuple("Float").field(arg0).finish(),
276 }
277 }
278}
279
280impl TlvItem {
281 pub fn get(&self, tag: &[u8]) -> Option<&TlvItemValue> {
282 if !tag.is_empty() {
283 if let TlvItemValue::List(lst) = &self.value {
284 for l in lst {
285 if l.tag == tag[0] {
286 return l.get(&tag[1..]);
287 };
288 }
289 }
290 None
291 } else {
292 Some(&self.value)
293 }
294 }
295 pub fn get_item(&self, tag: &[u8]) -> Option<&TlvItem> {
296 if !tag.is_empty() {
297 if let TlvItemValue::List(lst) = &self.value {
298 for l in lst {
299 if l.tag == tag[0] {
300 return l.get_item(&tag[1..]);
301 };
302 }
303 }
304 None
305 } else {
306 Some(self)
307 }
308 }
309 pub fn get_int(&self, tag: &[u8]) -> Option<u64> {
310 let found = self.get(tag);
311 if let Some(TlvItemValue::Int(i)) = found {
312 Some(*i)
313 } else {
314 None
315 }
316 }
317 pub fn get_t<T>(&self, tag: &[u8]) -> Option<T>
318 where
319 T: From<TlvItemValue>,
320 {
321 self.get(tag).map(|f| f.clone().into())
322 }
323
324 pub fn get_bool(&self, tag: &[u8]) -> Option<bool> {
325 self.get(tag).map(|f| f.clone().into())
326 }
333 pub fn get_u8(&self, tag: &[u8]) -> Option<u8> {
334 let found = self.get(tag);
335 if let Some(TlvItemValue::Int(i)) = found {
336 Some(*i as u8)
337 } else {
338 None
339 }
340 }
341 pub fn get_u16(&self, tag: &[u8]) -> Option<u16> {
342 let found = self.get(tag);
343 if let Some(TlvItemValue::Int(i)) = found {
344 Some(*i as u16)
345 } else {
346 None
347 }
348 }
349 pub fn get_u32(&self, tag: &[u8]) -> Option<u32> {
350 let found = self.get(tag);
351 if let Some(TlvItemValue::Int(i)) = found {
352 Some(*i as u32)
353 } else {
354 None
355 }
356 }
357 pub fn get_u64(&self, tag: &[u8]) -> Option<u64> {
358 let found = self.get(tag);
359 if let Some(TlvItemValue::Int(i)) = found {
360 Some(*i)
361 } else {
362 None
363 }
364 }
365 pub fn get_octet_string(&self, tag: &[u8]) -> Option<&[u8]> {
366 let found = self.get(tag);
367 if let Some(TlvItemValue::OctetString(o)) = found {
368 Some(o)
369 } else {
370 None
371 }
372 }
373 pub fn get_octet_string_owned(&self, tag: &[u8]) -> Option<Vec<u8>> {
374 let found = self.get(tag);
375 if let Some(TlvItemValue::OctetString(o)) = found {
376 Some(o.to_owned())
377 } else {
378 None
379 }
380 }
381 pub fn get_string_owned(&self, tag: &[u8]) -> Option<String> {
382 let found = self.get(tag);
383 if let Some(TlvItemValue::String(o)) = found {
384 Some(o.clone())
385 } else {
386 None
387 }
388 }
389 pub fn dump(&self, indent: usize) {
390 match &self.value {
391 TlvItemValue::List(vec) => {
392 println!("{} {}", " ".to_owned().repeat(indent), self.tag);
393 for v in vec {
394 v.dump(indent + 1);
395 }
396 }
397 _ => {
398 println!(
399 "{} {} {:?}",
400 " ".to_owned().repeat(indent),
401 self.tag,
402 self.value
403 );
404 }
405 }
406 }
407}
408
409fn read_tag(tagctrl: u8, cursor: &mut Cursor<&[u8]>) -> Result<u8> {
410 if tagctrl == 1 {
411 cursor.read_u8()
412 } else {
413 Ok(0)
414 }
415}
416
417fn decode(cursor: &mut Cursor<&[u8]>, container: &mut Vec<TlvItem>) -> Result<()> {
418 while cursor.position() < cursor.get_ref().len() as u64 {
419 let fb = cursor.read_u8()?;
420 let tp = fb & 0x1f;
421 let tagctrl = fb >> 5;
422 let tag = read_tag(tagctrl, cursor)?;
423 match tp {
424 TYPE_INT_1 => {
425 let value = cursor.read_u8()?;
426 let item = TlvItem {
427 tag,
428 value: TlvItemValue::Int(value as u64),
429 };
430 container.push(item);
431 }
432 TYPE_INT_2 => {
433 let value = cursor.read_i16::<LittleEndian>()?;
434 let item = TlvItem {
435 tag,
436 value: TlvItemValue::Int(value as u64),
437 };
438 container.push(item);
439 }
440 TYPE_INT_4 => {
441 let value = cursor.read_i32::<LittleEndian>()?;
442 let item = TlvItem {
443 tag,
444 value: TlvItemValue::Int(value as u64),
445 };
446 container.push(item);
447 }
448 TYPE_INT_8 => {
449 let value = cursor.read_i64::<LittleEndian>()?;
450 let item = TlvItem {
451 tag,
452 value: TlvItemValue::Int(value as u64),
453 };
454 container.push(item);
455 }
456 TYPE_UINT_1 => {
457 let value = cursor.read_u8()?;
458 let item = TlvItem {
459 tag,
460 value: TlvItemValue::Int(value as u64),
461 };
462 container.push(item);
463 }
464 TYPE_UINT_2 => {
465 let value = cursor.read_u16::<LittleEndian>()?;
466 let item = TlvItem {
467 tag,
468 value: TlvItemValue::Int(value as u64),
469 };
470 container.push(item);
471 }
472 TYPE_UINT_4 => {
473 let value = cursor.read_u32::<LittleEndian>()?;
474 let item = TlvItem {
475 tag,
476 value: TlvItemValue::Int(value as u64),
477 };
478 container.push(item);
479 }
480 TYPE_UINT_8 => {
481 let value = cursor.read_u64::<LittleEndian>()?;
482 let item = TlvItem {
483 tag,
484 value: TlvItemValue::Int(value),
485 };
486 container.push(item);
487 }
488 TYPE_BOOL_FALSE => {
489 let item = TlvItem {
490 tag,
491 value: TlvItemValue::Bool(false),
492 };
493 container.push(item);
494 }
495 TYPE_BOOL_TRUE => {
496 let item = TlvItem {
497 tag,
498 value: TlvItemValue::Bool(true),
499 };
500 container.push(item);
501 }
502 TYPE_FLOAT_4 => {
503 let value = cursor.read_f32::<LittleEndian>()?;
504 let item = TlvItem {
505 tag,
506 value: TlvItemValue::Float(value as f64),
507 };
508 container.push(item);
509 }
510 TYPE_FLOAT_8 => {
511 let value = cursor.read_f64::<LittleEndian>()?;
512 let item = TlvItem {
513 tag,
514 value: TlvItemValue::Float(value),
515 };
516 container.push(item);
517 }
518 TYPE_UTF8_L1 => {
519 let size = cursor.read_u8()?;
521 let mut value = vec![0; size as usize];
522 cursor.read_exact(&mut value)?;
523 let str = String::from_utf8(value);
524 let typ = match str {
525 Ok(s) => TlvItemValue::String(s),
526 Err(_) => TlvItemValue::Invalid(),
527 };
528 let item = TlvItem { tag, value: typ };
529 container.push(item);
530 }
531 TYPE_OCTET_STRING_L1 => {
532 let size = cursor.read_u8()?;
534 let mut value = vec![0; size as usize];
535 cursor.read_exact(&mut value)?;
536 let item = TlvItem {
537 tag,
538 value: TlvItemValue::OctetString(value),
539 };
540 container.push(item);
541 }
542 TYPE_OCTET_STRING_L2 => {
543 let size = cursor.read_u16::<LittleEndian>()?;
545 let mut value = vec![0; size as usize];
546 cursor.read_exact(&mut value)?;
547 let item = TlvItem {
548 tag,
549 value: TlvItemValue::OctetString(value),
550 };
551 container.push(item);
552 }
553 TYPE_OCTET_STRING_L4 => {
554 let size = cursor.read_u32::<LittleEndian>()?;
556 let mut value = vec![0; size as usize];
557 cursor.read_exact(&mut value)?;
558 let item = TlvItem {
559 tag,
560 value: TlvItemValue::OctetString(value),
561 };
562 container.push(item);
563 }
564 TYPE_OCTET_STRING_L8 => {
565 let size = cursor.read_u64::<LittleEndian>()?;
567 let mut value = vec![0; size as usize];
568 cursor.read_exact(&mut value)?;
569 let item = TlvItem {
570 tag,
571 value: TlvItemValue::OctetString(value),
572 };
573 container.push(item);
574 }
575 TYPE_STRUCT => {
576 let mut c2 = Vec::new();
578 decode(cursor, &mut c2)?;
579 let item = TlvItem {
580 tag,
581 value: TlvItemValue::List(c2),
582 };
583 container.push(item);
584 }
585 TYPE_ARRAY => {
586 let mut c2 = Vec::new();
588 decode(cursor, &mut c2)?;
589 let item = TlvItem {
590 tag,
591 value: TlvItemValue::List(c2),
592 };
593 container.push(item);
594 }
595 TYPE_LIST => {
596 let mut c2 = Vec::new();
598 decode(cursor, &mut c2)?;
599 let item = TlvItem {
600 tag,
601 value: TlvItemValue::List(c2),
602 };
603 container.push(item);
604 }
605 TYPE_END_CONTAINER => return Ok(()),
606 0x14 => {
607 let item = TlvItem {
608 tag,
609 value: TlvItemValue::Nil(),
610 };
611 container.push(item);
612 }
613 _ => {
614 return Err(std::io::Error::new(
615 std::io::ErrorKind::InvalidData,
616 format!("unknown tlv type 0x{:x}", tp),
617 ))
618 }
619 }
620 }
621 Ok(())
622}
623
624pub fn decode_tlv(data: &[u8]) -> Result<TlvItem> {
626 let mut container = Vec::new();
627 let mut cursor = std::io::Cursor::new(data);
628 decode(&mut cursor, &mut container)?;
629 if container.len() == 1 {
630 if let Some(i) = container.pop() {
631 Ok(i)
632 } else {
633 Err(std::io::Error::new(
634 std::io::ErrorKind::InvalidData,
635 "no data found",
636 ))
637 }
638 } else {
639 Ok(TlvItem {
640 tag: 0,
641 value: TlvItemValue::List(container),
642 })
643 }
644}
645
646#[derive(Debug)]
647pub enum TlvItemValueEnc {
648 Int8(i8),
649 Int16(i16),
650 Int32(i32),
651 Int64(i64),
652 UInt8(u8),
653 UInt8Anonymous(u8),
654 UInt16(u16),
655 UInt32(u32),
656 UInt64(u64),
657 Bool(bool),
658 String(String),
659 OctetString(Vec<u8>),
660 StructAnon(Vec<TlvItemEnc>),
661 StructInvisible(Vec<TlvItemEnc>),
662 Struct(Vec<TlvItemEnc>),
663 List(Vec<TlvItemEnc>),
664 Array(Vec<TlvItemEnc>),
665 Invalid(),
666}
667
668#[derive(Debug)]
682pub struct TlvItemEnc {
683 pub tag: u8,
684 pub value: TlvItemValueEnc,
685}
686
687impl From<(u8, TlvItemValueEnc)> for TlvItemEnc {
688 fn from(item: (u8, TlvItemValueEnc)) -> Self {
689 TlvItemEnc {
690 tag: item.0,
691 value: item.1,
692 }
693 }
694}
695
696impl TlvItemEnc {
697 fn encode_internal(&self, buf: &mut TlvBuffer) -> Result<()> {
698 match &self.value {
699 TlvItemValueEnc::Int8(i) => {
700 buf.write_int8(self.tag, *i)?;
701 }
702 TlvItemValueEnc::Int16(i) => {
703 buf.write_int16(self.tag, *i)?;
704 }
705 TlvItemValueEnc::Int32(i) => {
706 buf.write_int32(self.tag, *i)?;
707 }
708 TlvItemValueEnc::Int64(i) => {
709 buf.write_int64(self.tag, *i)?;
710 }
711 TlvItemValueEnc::UInt8(i) => {
712 buf.write_uint8(self.tag, *i)?;
713 }
714 TlvItemValueEnc::UInt8Anonymous(i) => {
715 buf.write_uint8_notag(*i)?;
716 }
717 TlvItemValueEnc::UInt16(i) => {
718 buf.write_uint16(self.tag, *i)?;
719 }
720 TlvItemValueEnc::UInt32(i) => {
721 buf.write_uint32(self.tag, *i)?;
722 }
723 TlvItemValueEnc::UInt64(i) => {
724 buf.write_uint64(self.tag, *i)?;
725 }
726 TlvItemValueEnc::Bool(v) => {
727 buf.write_bool(self.tag, *v)?;
728 }
729 TlvItemValueEnc::String(s) => {
730 buf.write_string(self.tag, s)?;
731 }
732 TlvItemValueEnc::OctetString(vec) => {
733 buf.write_octetstring(self.tag, vec)?;
734 }
735 TlvItemValueEnc::StructAnon(vec) => {
736 buf.write_anon_struct()?;
737 for i in vec {
738 i.encode_internal(buf)?;
739 }
740 buf.write_struct_end()?;
741 }
742 TlvItemValueEnc::Struct(vec) => {
743 buf.write_struct(self.tag)?;
744 for i in vec {
745 i.encode_internal(buf)?;
746 }
747 buf.write_struct_end()?;
748 }
749 TlvItemValueEnc::List(vec) => {
750 buf.write_list(self.tag)?;
751 for i in vec {
752 i.encode_internal(buf)?;
753 }
754 buf.write_struct_end()?;
755 }
756 TlvItemValueEnc::Array(vec) => {
757 buf.write_array(self.tag)?;
758 for i in vec {
759 i.encode_internal(buf)?;
760 }
761 buf.write_struct_end()?;
762 }
763 TlvItemValueEnc::StructInvisible(vec) => {
764 for i in vec {
765 i.encode_internal(buf)?;
766 }
767 }
768 TlvItemValueEnc::Invalid() => todo!(),
769 }
770 Ok(())
771 }
772
773 pub fn encode(&self) -> Result<Vec<u8>> {
774 let mut tlv = TlvBuffer::new();
775 self.encode_internal(&mut tlv)?;
776 Ok(tlv.data)
777 }
778}
779
780#[cfg(test)]
781mod tests {
782 use super::{decode_tlv, TlvBuffer, TlvItemEnc, TlvItemValue, TlvItemValueEnc};
783
784 #[test]
785 fn test_1() {
786 let t1 = TlvItemEnc {
787 tag: 0,
788 value: TlvItemValueEnc::StructAnon(vec![
789 TlvItemEnc {
790 tag: 0,
791 value: TlvItemValueEnc::UInt8(6),
792 },
793 TlvItemEnc {
794 tag: 1,
795 value: TlvItemValueEnc::UInt8(7),
796 },
797 ]),
798 };
799 let o = t1.encode().unwrap();
800 assert_eq!(hex::encode(o), "1524000624010718");
801
802 let mut tlv = TlvBuffer::new();
803 tlv.write_anon_struct().unwrap();
804 tlv.write_octetstring(0x1, &[1, 2, 3]).unwrap();
805 tlv.write_struct_end().unwrap();
806 assert_eq!(hex::encode(tlv.data), "1530010301020318");
807
808 let t1 = TlvItemEnc {
809 tag: 0,
810 value: TlvItemValueEnc::StructAnon(vec![TlvItemEnc {
811 tag: 1,
812 value: TlvItemValueEnc::OctetString(vec![1, 2, 3]),
813 }]),
814 }
815 .encode()
816 .unwrap();
817 assert_eq!(hex::encode(t1), "1530010301020318");
818 }
819
820 #[test]
821 fn test_decode_integers() {
822 let mut tlv = TlvBuffer::new();
824 tlv.write_uint8(1, 42).unwrap();
825 let decoded = decode_tlv(&tlv.data).unwrap();
826 assert_eq!(decoded.get_u8(&[]), Some(42));
827
828 let mut tlv = TlvBuffer::new();
830 tlv.write_uint16(2, 1000).unwrap();
831 let decoded = decode_tlv(&tlv.data).unwrap();
832 assert_eq!(decoded.get_u16(&[]), Some(1000));
833
834 let mut tlv = TlvBuffer::new();
836 tlv.write_uint32(3, 100000).unwrap();
837 let decoded = decode_tlv(&tlv.data).unwrap();
838 assert_eq!(decoded.get_u32(&[]), Some(100000));
839
840 let mut tlv = TlvBuffer::new();
842 tlv.write_uint64(4, 1000000000000).unwrap();
843 let decoded = decode_tlv(&tlv.data).unwrap();
844 assert_eq!(decoded.get_u64(&[]), Some(1000000000000));
845 }
846
847 #[test]
848 fn test_decode_booleans() {
849 let mut tlv = TlvBuffer::new();
851 tlv.write_bool(1, true).unwrap();
852 let decoded = decode_tlv(&tlv.data).unwrap();
853 assert_eq!(decoded.get_bool(&[]), Some(true));
854
855 let mut tlv = TlvBuffer::new();
857 tlv.write_bool(2, false).unwrap();
858 let decoded = decode_tlv(&tlv.data).unwrap();
859 assert_eq!(decoded.get_bool(&[]), Some(false));
860 assert_eq!(decoded.get_t(&[]), Some(false));
861 }
862
863 #[test]
864 fn test_decode_strings() {
865 let mut tlv = TlvBuffer::new();
866 tlv.write_string(1, "hello world").unwrap();
867 let decoded = decode_tlv(&tlv.data).unwrap();
868 assert_eq!(
869 decoded.get_string_owned(&[]),
870 Some("hello world".to_string())
871 );
872 assert_eq!(decoded.get_t(&[]), Some("hello world".to_string()));
873 }
874
875 #[test]
876 fn test_decode_octet_strings() {
877 let mut tlv = TlvBuffer::new();
879 let data = vec![1, 2, 3, 4, 5];
880 tlv.write_octetstring(1, &data).unwrap();
881 let decoded = decode_tlv(&tlv.data).unwrap();
882 assert_eq!(decoded.get_octet_string(&[]), Some(data.as_slice()));
883
884 let mut tlv = TlvBuffer::new();
886 let large_data = vec![0; 300]; tlv.write_octetstring(2, &large_data).unwrap();
888 let decoded = decode_tlv(&tlv.data).unwrap();
889 assert_eq!(decoded.get_octet_string(&[]), Some(large_data.as_slice()));
890 assert_eq!(
891 decoded.get_octet_string_owned(&[]),
892 Some(large_data.clone())
893 );
894 }
895
896 #[test]
897 fn test_decode_structures() {
898 let mut tlv = TlvBuffer::new();
899 tlv.write_struct(1).unwrap();
900 tlv.write_uint8(0, 100).unwrap();
901 tlv.write_string(1, "test").unwrap();
902 tlv.write_bool(2, true).unwrap();
903 tlv.write_struct_end().unwrap();
904
905 let decoded = decode_tlv(&tlv.data).unwrap();
906
907 assert_eq!(decoded.get_u8(&[0]), Some(100));
909 assert_eq!(decoded.get_string_owned(&[1]), Some("test".to_string()));
910 assert_eq!(decoded.get_bool(&[2]), Some(true));
911
912 if let TlvItemValue::List(items) = &decoded.value {
914 assert_eq!(items.len(), 3);
915 }
916 }
917
918 #[test]
919 fn test_decode_anonymous_structures() {
920 let mut tlv = TlvBuffer::new();
921 tlv.write_anon_struct().unwrap();
922 tlv.write_uint8_notag(42).unwrap();
923 tlv.write_uint8_notag(84).unwrap();
924 tlv.write_struct_end().unwrap();
925
926 let decoded = decode_tlv(&tlv.data).unwrap();
927
928 if let TlvItemValue::List(items) = &decoded.value {
929 assert_eq!(items.len(), 2);
930 assert_eq!(items[0].tag, 0);
931 assert_eq!(items[1].tag, 0);
932 }
933 }
934
935 #[test]
936 fn test_decode_arrays_and_lists() {
937 let mut tlv = TlvBuffer::new();
939 tlv.write_array(1).unwrap();
940 tlv.write_uint8(0, 1).unwrap();
941 tlv.write_uint8(0, 2).unwrap();
942 tlv.write_uint8(0, 3).unwrap();
943 tlv.write_struct_end().unwrap();
944
945 let decoded = decode_tlv(&tlv.data).unwrap();
946 if let Some(TlvItemValue::List(items)) = decoded.get(&[]) {
947 assert_eq!(items.len(), 3);
948 assert_eq!(items[0].get_u8(&[]), Some(1));
949 assert_eq!(items[1].get_u8(&[]), Some(2));
950 assert_eq!(items[2].get_u8(&[]), Some(3));
951 } else {
952 panic!("Expected array structure");
953 }
954
955 let mut tlv = TlvBuffer::new();
957 tlv.write_list(2).unwrap();
958 tlv.write_string(0, "item1").unwrap();
959 tlv.write_string(1, "item2").unwrap();
960 tlv.write_struct_end().unwrap();
961
962 let decoded = decode_tlv(&tlv.data).unwrap();
963 if let Some(TlvItemValue::List(items)) = decoded.get(&[]) {
964 assert_eq!(items.len(), 2);
965 assert_eq!(items[0].get_string_owned(&[]), Some("item1".to_string()));
966 assert_eq!(items[1].get_string_owned(&[]), Some("item2".to_string()));
967 } else {
968 panic!("Expected list structure");
969 }
970 }
971
972 #[test]
973 fn test_decode_mixed_container() {
974 let mut tlv = TlvBuffer::new();
975 tlv.write_uint8(0, 255).unwrap();
976 tlv.write_string(1, "mixed").unwrap();
977 tlv.write_bool(2, false).unwrap();
978
979 let decoded = decode_tlv(&tlv.data).unwrap();
980
981 if let TlvItemValue::List(items) = &decoded.value {
983 assert_eq!(items.len(), 3);
984 assert_eq!(items[0].get_u8(&[]), Some(255));
985 assert_eq!(items[1].get_string_owned(&[]), Some("mixed".to_string()));
986 assert_eq!(items[2].get_bool(&[]), Some(false));
987 } else {
988 panic!("Expected list of items");
989 }
990 }
991
992 #[test]
993 fn test_decode_nested_structures() {
994 let mut tlv = TlvBuffer::new();
995 tlv.write_struct(1).unwrap();
996 tlv.write_struct(2).unwrap();
997 tlv.write_uint8(3, 42).unwrap();
998 tlv.write_struct_end().unwrap(); tlv.write_string(4, "outer").unwrap();
1000 tlv.write_struct_end().unwrap(); let decoded = decode_tlv(&tlv.data).unwrap();
1003
1004 assert_eq!(decoded.get_u8(&[2, 3]), Some(42));
1006 assert_eq!(decoded.get_string_owned(&[4]), Some("outer".to_string()));
1007 }
1008
1009 #[test]
1010 fn test_decode_getter_methods() {
1011 let mut tlv = TlvBuffer::new();
1012 tlv.write_struct(0).unwrap();
1013 tlv.write_uint64(1, 0xFFFFFFFFFFFFFFFF).unwrap();
1014 tlv.write_uint32(2, 0xFFFFFFFF).unwrap();
1015 tlv.write_uint16(3, 0xFFFF).unwrap();
1016 tlv.write_uint8(4, 0xFF).unwrap();
1017 tlv.write_struct_end().unwrap();
1018
1019 let decoded = decode_tlv(&tlv.data).unwrap();
1020
1021 assert_eq!(decoded.get_u64(&[1]), Some(0xFFFFFFFFFFFFFFFF));
1023 assert_eq!(decoded.get_u32(&[2]), Some(0xFFFFFFFF));
1024 assert_eq!(decoded.get_u16(&[3]), Some(0xFFFF));
1025 assert_eq!(decoded.get_u8(&[4]), Some(0xFF));
1026
1027 assert_eq!(decoded.get_u8(&[1]), Some(0xFF)); assert_eq!(decoded.get_u16(&[1]), Some(0xFFFF)); }
1031
1032 #[test]
1033 fn test_decode_invalid_access() {
1034 let mut tlv = TlvBuffer::new();
1035 tlv.write_uint8(1, 42).unwrap();
1036 let decoded = decode_tlv(&tlv.data).unwrap();
1037
1038 assert_eq!(decoded.get_u8(&[99]), None);
1040 assert_eq!(decoded.get_string_owned(&[1]), None); assert_eq!(decoded.get_bool(&[1]), None); }
1043
1044 #[test]
1045 fn test_decode_empty_structure() {
1046 let mut tlv = TlvBuffer::new();
1047 tlv.write_anon_struct().unwrap();
1048 tlv.write_struct_end().unwrap();
1049
1050 let decoded = decode_tlv(&tlv.data).unwrap();
1051
1052 if let TlvItemValue::List(items) = &decoded.value {
1053 assert_eq!(items.len(), 0);
1054 } else {
1055 panic!("Expected empty list");
1056 }
1057 }
1058
1059 #[test]
1060 fn test_get_item_method() {
1061 let mut tlv = TlvBuffer::new();
1062 tlv.write_struct(1).unwrap();
1063 tlv.write_uint8(2, 100).unwrap();
1064 tlv.write_string(3, "test").unwrap();
1065 tlv.write_bool(4, true).unwrap();
1066 tlv.write_struct(5).unwrap();
1067 tlv.write_string(1, "inner").unwrap();
1068 tlv.write_struct_end().unwrap();
1069 tlv.write_struct_end().unwrap();
1070
1071 let decoded = decode_tlv(&tlv.data).unwrap();
1072
1073 let item = decoded.get_item(&[2]).unwrap();
1075 assert_eq!(item.tag, 2);
1076 if let TlvItemValue::Int(val) = &item.value {
1077 assert_eq!(*val, 100);
1078 } else {
1079 panic!("Expected Int value");
1080 }
1081 let item = decoded.get_item(&[3]).unwrap();
1082 assert_eq!(item.tag, 3);
1083 if let TlvItemValue::String(val) = &item.value {
1084 assert_eq!(*val, "test");
1085 } else {
1086 panic!("Expected String value");
1087 }
1088 let item = decoded.get_item(&[4]).unwrap();
1089 assert_eq!(item.tag, 4);
1090 if let TlvItemValue::Bool(val) = &item.value {
1091 assert!(*val);
1092 } else {
1093 panic!("Expected Bool value");
1094 }
1095 let item = decoded.get_item(&[5]).unwrap();
1096 assert_eq!(item.tag, 5);
1097 if let TlvItemValue::List(items) = &item.value {
1098 assert_eq!(items.len(), 1);
1099 let inner_item = &items[0];
1100 assert_eq!(inner_item.tag, 1);
1101 if let TlvItemValue::String(val) = &inner_item.value {
1102 assert_eq!(*val, "inner");
1103 } else {
1104 panic!("Expected String value");
1105 }
1106 } else {
1107 panic!("Expected List value");
1108 }
1109 let item = decoded.get_item(&[99]);
1110 assert!(item.is_none());
1111 }
1112}