ndn_transport/
tlv_codec.rs1use bytes::{Bytes, BytesMut};
2use tokio_util::codec::{Decoder, Encoder};
3
4use ndn_tlv::read_varu64;
5
6#[derive(Clone, Copy)]
24pub struct TlvCodec;
25
26impl Decoder for TlvCodec {
27 type Item = Bytes;
28 type Error = std::io::Error;
29
30 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
31 if src.is_empty() {
32 return Ok(None);
33 }
34
35 let (_, type_len) = match read_varu64(src) {
37 Ok(r) => r,
38 Err(_) => return Ok(None), };
40
41 if src.len() < type_len + 1 {
43 return Ok(None);
44 }
45 let (value_len, len_len) = match read_varu64(&src[type_len..]) {
46 Ok(r) => r,
47 Err(_) => return Ok(None), };
49
50 let header_len = type_len + len_len;
51 let frame_len = header_len + value_len as usize;
52
53 if src.len() < frame_len {
54 src.reserve(frame_len - src.len());
56 return Ok(None);
57 }
58
59 Ok(Some(src.split_to(frame_len).freeze()))
60 }
61}
62
63impl Encoder<Bytes> for TlvCodec {
64 type Error = std::io::Error;
65
66 fn encode(&mut self, item: Bytes, dst: &mut BytesMut) -> Result<(), Self::Error> {
67 dst.extend_from_slice(&item);
68 Ok(())
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 use bytes::BufMut;
76 use ndn_tlv::TlvWriter;
77
78 fn make_tlv(typ: u8, value: &[u8]) -> Bytes {
79 let mut w = TlvWriter::new();
80 w.write_tlv(typ as u64, value);
81 w.finish()
82 }
83
84 fn decode_one(src: &mut BytesMut) -> Option<Bytes> {
85 TlvCodec.decode(src).unwrap()
86 }
87
88 #[test]
91 fn decode_complete_tlv() {
92 let tlv = make_tlv(0x05, b"hello");
93 let mut src = BytesMut::from(tlv.as_ref());
94 let frame = decode_one(&mut src).unwrap();
95 assert_eq!(frame.as_ref(), tlv.as_ref());
97 assert!(src.is_empty());
98 }
99
100 #[test]
101 fn decode_empty_value_tlv() {
102 let tlv = make_tlv(0x21, &[]);
103 let mut src = BytesMut::from(tlv.as_ref());
104 let frame = decode_one(&mut src).unwrap();
105 assert_eq!(frame.as_ref(), &[0x21, 0x00]);
106 }
107
108 #[test]
109 fn decode_incomplete_returns_none() {
110 let mut src = BytesMut::from(&[0x05u8][..]);
112 assert!(decode_one(&mut src).is_none());
113 }
114
115 #[test]
116 fn decode_partial_value_returns_none() {
117 let mut src = BytesMut::new();
119 src.put_u8(0x08); src.put_u8(0x05); src.put_slice(&[0xAA, 0xBB]); assert!(decode_one(&mut src).is_none());
123 }
124
125 #[test]
126 fn decode_two_sequential_frames() {
127 let t1 = make_tlv(0x07, b"foo");
128 let t2 = make_tlv(0x08, b"bar");
129 let mut src = BytesMut::new();
130 src.extend_from_slice(&t1);
131 src.extend_from_slice(&t2);
132
133 let f1 = decode_one(&mut src).unwrap();
134 let f2 = decode_one(&mut src).unwrap();
135 assert_eq!(f1.as_ref(), t1.as_ref());
136 assert_eq!(f2.as_ref(), t2.as_ref());
137 assert!(src.is_empty());
138 }
139
140 #[test]
141 fn decode_large_value() {
142 let value = vec![0xABu8; 300]; let mut w = TlvWriter::new();
144 w.write_tlv(0x06, &value);
145 let tlv = w.finish();
146 let mut src = BytesMut::from(tlv.as_ref());
147 let frame = decode_one(&mut src).unwrap();
148 assert_eq!(frame.as_ref(), tlv.as_ref());
149 }
150
151 #[test]
154 fn encode_appends_bytes_as_is() {
155 let pkt = Bytes::from_static(&[0x05, 0x03, b'a', b'b', b'c']);
156 let mut dst = BytesMut::new();
157 TlvCodec.encode(pkt.clone(), &mut dst).unwrap();
158 assert_eq!(dst.as_ref(), pkt.as_ref());
159 }
160
161 #[test]
162 fn encode_then_decode_roundtrip() {
163 let tlv = make_tlv(0x15, b"content");
164 let mut dst = BytesMut::new();
165 TlvCodec.encode(tlv.clone(), &mut dst).unwrap();
166 let frame = decode_one(&mut dst).unwrap();
167 assert_eq!(frame.as_ref(), tlv.as_ref());
168 }
169}