1use crate::io::WireType;
2use crate::io::WireType::*;
3use enc::read_single_byte;
4use enc::var_int::VarInt128;
5use std::io::{Read, Write};
6
7impl WireType {
8 pub fn transfer<R, W>(self, r: &mut R, w: &mut W) -> Result<(), enc::Error>
15 where
16 R: Read,
17 W: Write,
18 {
19 match self {
20 Fixed1Byte => Self::transfer_fixed(r, w, 1),
21 Fixed2Byte => Self::transfer_fixed(r, w, 2),
22 Fixed4Byte => Self::transfer_fixed(r, w, 4),
23 Fixed8Byte => Self::transfer_fixed(r, w, 8),
24 Fixed16Byte => Self::transfer_fixed(r, w, 16),
25 VarInt => Self::transfer_varint(r, w),
26 LengthPrefixed => Self::transfer_length_prefixed(r, w),
27 List => Self::transfer_length_prefixed(r, w),
28 }
29 }
30
31 fn transfer_fixed<R, W>(r: &mut R, w: &mut W, n: usize) -> Result<(), enc::Error>
33 where
34 R: Read,
35 W: Write,
36 {
37 let mut buf: [u8; 16] = [0u8; 16];
38 r.read_exact(&mut buf[..n])?;
39 w.write_all(&buf[..n])?;
40 Ok(())
41 }
42
43 fn transfer_varint<R, W>(r: &mut R, w: &mut W) -> Result<(), enc::Error>
45 where
46 R: Read,
47 W: Write,
48 {
49 let mut buf: [u8; VarInt128::MAX_ENCODED_LEN] = [0u8; VarInt128::MAX_ENCODED_LEN];
50 let mut len: usize = 0;
51 while len < VarInt128::MAX_ENCODED_LEN {
52 let b: u8 = read_single_byte(r)?;
53 buf[len] = b;
54 len += 1;
55 if b & 0x80 == 0 {
56 w.write_all(&buf[..len])?;
57 return Ok(());
58 }
59 }
60 Err(enc::Error::InvalidEncodedData { reason: None }) }
62
63 fn transfer_length_prefixed<R, W>(r: &mut R, w: &mut W) -> Result<(), enc::Error>
70 where
71 R: Read,
72 W: Write,
73 {
74 use enc::DecodeFromReadPrefix;
75 use enc::var_int::VarIntSize;
76
77 let mut prefix_buf: [u8; VarIntSize::MAX_ENCODED_LEN] = [0u8; VarIntSize::MAX_ENCODED_LEN];
79 let mut prefix_len: usize = 0;
80 loop {
81 if prefix_len >= VarIntSize::MAX_ENCODED_LEN {
82 return Err(enc::Error::InvalidEncodedData { reason: None });
83 }
84 let b: u8 = read_single_byte(r)?;
85 prefix_buf[prefix_len] = b;
86 prefix_len += 1;
87 if b & 0x80 == 0 {
88 break;
89 }
90 }
91
92 let mut prefix_rest: &[u8] = &prefix_buf[1..prefix_len];
94 let len: usize =
95 VarIntSize::decode_from_read_prefix_with_first_byte(&mut prefix_rest, prefix_buf[0])?
96 .value();
97
98 w.write_all(&prefix_buf[..prefix_len])?;
100
101 let mut remaining: usize = len;
103 let mut buf: [u8; 1024] = [0u8; 1024]; while remaining > 0 {
105 let chunk: usize = remaining.min(buf.len());
106 r.read_exact(&mut buf[..chunk])?;
107 w.write_all(&buf[..chunk])?;
108 remaining -= chunk;
109 }
110 Ok(())
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use crate::io::WireType;
117 use crate::io::WireType::*;
118 use std::io::Cursor;
119
120 #[test]
121 #[allow(clippy::type_complexity)]
122 fn transfer() {
123 let mut large_lp: Vec<u8> = vec![0xDC, 0x0B];
126 large_lp.extend(std::iter::repeat_n(0xAB, 1500));
127
128 let overlong_varint: [u8; 20] = [0xFF; 20];
130
131 let overlong_lp_prefix: [u8; 16] = [0xFF; 16];
134
135 let cases: &[(WireType, &[u8], Option<&[u8]>)] = &[
137 (Fixed1Byte, &[0x42], Some(&[0x42])),
139 (Fixed2Byte, &[1, 2], Some(&[1, 2])),
140 (Fixed4Byte, &[1, 2, 3, 4], Some(&[1, 2, 3, 4])),
141 (
142 Fixed8Byte,
143 &[1, 2, 3, 4, 5, 6, 7, 8],
144 Some(&[1, 2, 3, 4, 5, 6, 7, 8]),
145 ),
146 (
147 Fixed16Byte,
148 &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
149 Some(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
150 ),
151 (VarInt, &[0x42], Some(&[0x42])),
153 (VarInt, &[0xAC, 0x02], Some(&[0xAC, 0x02])),
154 (VarInt, &[0xFF, 0xFF, 0x03], Some(&[0xFF, 0xFF, 0x03])),
155 (
156 VarInt,
157 &[0xFF, 0xFF, 0xFF, 0xFF, 0x0F],
158 Some(&[0xFF, 0xFF, 0xFF, 0xFF, 0x0F]),
159 ),
160 (VarInt, &overlong_varint, None),
162 (LengthPrefixed, &[0x00], Some(&[0x00])),
164 (
165 LengthPrefixed,
166 &[0x03, b'a', b'b', b'c'],
167 Some(&[0x03, b'a', b'b', b'c']),
168 ),
169 (
170 LengthPrefixed,
171 large_lp.as_slice(),
172 Some(large_lp.as_slice()),
173 ),
174 (LengthPrefixed, &overlong_lp_prefix, None),
176 (List, &[0x00], Some(&[0x00])),
178 (List, &[0x03, 1, 2, 3], Some(&[0x03, 1, 2, 3])),
179 ];
180
181 for (wire, input, expected) in cases {
182 let mut r: Cursor<&[u8]> = Cursor::new(*input);
183 let mut w: Vec<u8> = Vec::new();
184 let result: Result<(), enc::Error> = wire.transfer(&mut r, &mut w);
185 match (result, expected) {
186 (Ok(()), Some(exp)) => {
187 assert_eq!(
188 w.as_slice(),
189 *exp,
190 "wire={wire:?} input_len={}",
191 input.len()
192 );
193 }
194 (Err(_), None) => {}
195 (Ok(()), None) => {
196 panic!(
197 "wire={wire:?} input_len={}: expected error, got Ok",
198 input.len()
199 )
200 }
201 (Err(e), Some(_)) => {
202 panic!(
203 "wire={wire:?} input_len={}: expected Ok, got error: {e:?}",
204 input.len()
205 )
206 }
207 }
208 }
209 }
210}