1#![allow(unknown_lints)]
2#![allow(bare_trait_objects)]
3#![allow(ellipsis_inclusive_range_patterns)]
4
5use super::errors::{Error, ErrorKind};
6use std::cmp;
7use std::io;
8
9#[derive(Eq, PartialEq, Debug, Copy, Clone)]
11pub enum PacketType {
12 Flush,
14 Delim,
16 Data(usize),
20}
21
22#[derive(Eq, PartialEq, Debug, Clone)]
24pub struct Packet {
25 typ: PacketType,
26 data: Vec<u8>,
27}
28
29impl Packet {
30 pub fn new(t: PacketType, data: &[u8]) -> Self {
31 Packet {
32 typ: t,
33 data: data.to_vec(),
34 }
35 }
36
37 fn new_from_vec(t: PacketType, vec: Vec<u8>) -> Self {
38 Packet { typ: t, data: vec }
39 }
40
41 pub fn packet_type(&self) -> PacketType {
42 self.typ
43 }
44
45 pub fn data(&self) -> Option<&[u8]> {
46 match self.typ {
47 PacketType::Data(_) => Some(&self.data),
48 _ => None,
49 }
50 }
51}
52
53pub struct Reader<R: io::Read> {
54 rdr: R,
55 buf: [u8; 65536],
56 off: usize,
57 len: usize,
58}
59
60impl<R: io::Read> Reader<R> {
61 const MAX_PACKET_LEN: usize = 65516;
62
63 pub fn new(rdr: R) -> Self {
64 Reader {
65 rdr,
66 buf: [0u8; 65536],
67 off: 0,
68 len: 0,
69 }
70 }
71
72 fn read_one(rdr: &mut R, buf: &mut [u8]) -> Result<PacketType, Error> {
73 let mut hdr = [0u8; 4];
74 rdr.read_exact(&mut hdr)?;
75 let size = Self::parse_header(hdr)? as usize;
76 match size {
77 0 => Ok(PacketType::Flush),
78 1 => Ok(PacketType::Delim),
79 2 | 3 => Err(Error::new_simple(ErrorKind::BadPktlineHeader)),
80 n if n > Self::MAX_PACKET_LEN + 4 => {
81 Err(Error::new_simple(ErrorKind::BadPktlineHeader))
82 }
83 _ => {
84 rdr.read_exact(&mut buf[0..(size - 4)])?;
85 Ok(PacketType::Data(size - 4))
86 }
87 }
88 }
89
90 pub fn read_packet(&mut self) -> Result<Packet, Error> {
91 let mut hdr = [0u8; 4];
92 self.rdr.read_exact(&mut hdr)?;
93 let size = Self::parse_header(hdr)? as usize;
94 match size {
95 0 => Ok(Packet::new(PacketType::Flush, b"")),
96 1 => Ok(Packet::new(PacketType::Delim, b"")),
97 2 | 3 => Err(Error::new_simple(ErrorKind::BadPktlineHeader)),
98 _ => {
99 let mut v = vec![0u8; size - 4];
100 self.rdr.read_exact(&mut v)?;
101 Ok(Packet::new_from_vec(PacketType::Data(size - 4), v))
102 }
103 }
104 }
105
106 fn parse_header(buf: [u8; 4]) -> Result<u16, Error> {
107 let x: Result<Vec<u16>, Error> = buf
108 .iter()
109 .enumerate()
110 .map(|(i, x)| {
111 let v = match *x {
112 b'0'...b':' => x - b'0',
113 b'a'...b'g' => x - b'a' + 10,
114 _ => return Err(Error::new_simple(ErrorKind::BadPktlineHeader)),
115 };
116 Ok((v as u16) << ((3 - i) * 4))
117 })
118 .collect();
119 Ok(x?.into_iter().sum())
120 }
121
122 pub fn iter(&mut self) -> iter::ReaderIterator<'_, R> {
123 iter::ReaderIterator::new(self)
124 }
125}
126
127impl<R: io::Read> io::Read for Reader<R> {
128 fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
129 let n = cmp::min(self.len - self.off, buf.len());
130 if n > 0 {
131 buf[0..n].copy_from_slice(&self.buf[self.off..self.off + n]);
132 if n == self.len - self.off {
133 self.off = 0;
134 self.len = 0;
135 } else {
136 self.off += n;
137 }
138 return Ok(n);
139 }
140 loop {
141 let (r, copy) = if buf.len() >= Self::MAX_PACKET_LEN {
142 (Self::read_one(&mut self.rdr, buf), false)
143 } else {
144 (Self::read_one(&mut self.rdr, &mut self.buf), true)
145 };
146 let n = match (r, copy) {
147 (Ok(PacketType::Delim), _) => return Ok(0),
148 (Ok(PacketType::Flush), _) => return Ok(0),
149 (Ok(PacketType::Data(0)), false) => n,
150 (Ok(PacketType::Data(n)), false) => return Ok(n),
151 (Ok(PacketType::Data(n)), true) => n,
152 (Err(e), _) => return Err(e.into()),
153 };
154 if n > 0 {
155 let c = cmp::min(n, buf.len());
156 buf[0..c].copy_from_slice(&self.buf[0..c]);
157 self.len = n;
158 self.off = c;
159 return Ok(c);
160 }
161 }
162 }
163}
164
165pub struct Writer<W: io::Write> {
166 writer: W,
167}
168
169impl<W: io::Write> Writer<W> {
170 const MAX_PACKET_LEN: usize = 65516;
171
172 pub fn new(writer: W) -> Self {
173 Writer { writer }
174 }
175
176 fn write_one(writer: &mut W, buf: &[u8]) -> Result<usize, Error> {
177 let header = format!("{:04x}", buf.len() + 4);
178 writer.write_all(header.as_bytes())?;
179 writer.write_all(buf)?;
180 Ok(buf.len())
181 }
182
183 pub fn write_packet(&mut self, pkt: &Packet) -> Result<usize, Error> {
184 match pkt.packet_type() {
185 PacketType::Flush => {
186 self.writer.write_all(b"0000")?;
187 self.writer.flush()?;
188 Ok(4)
189 }
190 PacketType::Delim => {
191 self.writer.write_all(b"0001")?;
192 Ok(4)
193 }
194 PacketType::Data(_) => Self::write_one(
195 &mut self.writer,
196 pkt.data()
197 .ok_or_else(|| Error::new_simple(ErrorKind::InvalidPacket))?,
198 ),
199 }
200 }
201}
202
203impl<W: io::Write> io::Write for Writer<W> {
204 fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
205 let mut total = 0;
206 for chunk in buf.chunks(Self::MAX_PACKET_LEN) {
207 total += match Self::write_one(&mut self.writer, chunk) {
208 Ok(sz) => sz,
209 Err(e) => return Err(e.into()),
210 }
211 }
212 Ok(total)
213 }
214
215 fn flush(&mut self) -> Result<(), io::Error> {
216 self.writer.flush()
217 }
218}
219
220mod iter {
221 use super::{Packet, Reader};
222 use crate::errors::Error;
223 use std::io;
224 use std::iter;
225
226 pub struct ReaderIterator<'a, R: io::Read> {
227 rdr: &'a mut Reader<R>,
228 }
229
230 impl<'a, R: io::Read> ReaderIterator<'a, R> {
231 pub fn new(rdr: &'a mut Reader<R>) -> Self {
232 ReaderIterator { rdr }
233 }
234 }
235
236 impl<'a, R: io::Read> iter::Iterator for ReaderIterator<'a, R> {
237 type Item = Result<Packet, Error>;
238
239 fn next(&mut self) -> Option<Result<Packet, Error>> {
240 match self.rdr.read_packet() {
241 Ok(x) => Some(Ok(x)),
242 Err(ref e) if e.io_kind() == io::ErrorKind::UnexpectedEof => None,
243 Err(e) => Some(Err(e)),
244 }
245 }
246 }
247}
248
249#[cfg(test)]
250mod tests {
251 use super::{Error, ErrorKind};
252 use super::{PacketType, Reader, Writer};
253 use std::io;
254 use std::io::Write;
255
256 fn reader_from_buf<'a>(buf: &'a [u8]) -> Reader<io::Cursor<&'a [u8]>> {
257 Reader::new(io::Cursor::new(buf))
258 }
259
260 fn writer() -> Writer<io::Cursor<Vec<u8>>> {
261 Writer::new(io::Cursor::new(Vec::new()))
262 }
263
264 fn check_packet(buf: &[u8], r: Result<(PacketType, Option<&[u8]>), Error>) {
265 let mut rdr = reader_from_buf(buf);
266 let mut v = vec![0u8; 65536];
267 let pt = Reader::read_one(&mut rdr.rdr, &mut v);
268 let data: Result<(PacketType, Option<&[u8]>), Error> = match pt {
269 Ok(PacketType::Data(x)) => {
270 v.truncate(x);
271 Ok((PacketType::Data(x), Some(&v)))
272 }
273 Ok(x) => Ok((x, None)),
274 Err(e) => Err(e),
275 };
276 assert_eq!(data, r);
277
278 let mut rdr = reader_from_buf(buf);
279 let pkt = rdr.read_packet();
280 let unwrapped = match &pkt {
281 &Ok(ref p) => Some(p.clone()),
282 &Err(_) => None,
283 };
284 assert_eq!(
285 pkt.map(|p| (p.packet_type().clone(), p.data().map(|x| x.to_vec()))),
286 r.map(|(pt, sl)| (pt.clone(), sl.map(|x| x.to_vec())))
287 );
288
289 if let Some(pkt) = unwrapped {
290 let mut wrtr = writer();
291 wrtr.write_packet(&pkt).unwrap();
292 assert_eq!(wrtr.writer.into_inner(), buf);
293 }
294 }
295
296 fn pattern_of_size(n: usize) -> Vec<u8> {
297 (0..n)
298 .map(|x| (x + (x >> 8) + (x >> 16) + (x >> 24)) as u8)
299 .collect()
300 }
301
302 #[test]
303 fn pktline_headers() {
304 assert_eq!(Reader::<io::Cursor<&[u8]>>::parse_header(*b"0000"), Ok(0));
305 assert_eq!(Reader::<io::Cursor<&[u8]>>::parse_header(*b"0001"), Ok(1));
306 assert_eq!(Reader::<io::Cursor<&[u8]>>::parse_header(*b"0004"), Ok(4));
307 assert_eq!(
308 Reader::<io::Cursor<&[u8]>>::parse_header(*b"ffff"),
309 Ok(65535)
310 );
311 assert_eq!(
312 Reader::<io::Cursor<&[u8]>>::parse_header(*b"2204"),
313 Ok(8708)
314 );
315 assert_eq!(
316 Reader::<io::Cursor<&[u8]>>::parse_header(*b"cafe"),
317 Ok(51966)
318 );
319 assert_eq!(
320 Reader::<io::Cursor<&[u8]>>::parse_header(*b"cafE"),
321 Err(Error::new_simple(ErrorKind::BadPktlineHeader))
322 );
323 assert_eq!(
324 Reader::<io::Cursor<&[u8]>>::parse_header(*b"\xc2\xa9fe"),
325 Err(Error::new_simple(ErrorKind::BadPktlineHeader))
326 );
327 }
328
329 #[test]
330 fn parse_packet() {
331 check_packet(b"0000", Ok((PacketType::Flush, None)));
332 check_packet(b"0001", Ok((PacketType::Delim, None)));
333 check_packet(b"0004", Ok((PacketType::Data(0), Some(b""))));
334 check_packet(b"0005a", Ok((PacketType::Data(1), Some(b"a"))));
335 check_packet(
336 b"0046\xff\xfee3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
337 Ok((
338 PacketType::Data(66),
339 Some(b"\xff\xfee3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"),
340 )),
341 );
342 }
343
344 #[test]
345 fn write_data() {
346 let mut wrtr = writer();
347 wrtr.write(b"abc").unwrap();
348 wrtr.write(b"\xff\xfe\xc2\xa90123456").unwrap();
349 assert_eq!(
350 wrtr.writer.into_inner(),
351 b"0007abc000f\xff\xfe\xc2\xa90123456"
352 );
353 }
354
355 #[test]
356 fn write_data_large() {
357 let mut wrtr = writer();
358 let buf = pattern_of_size(65536);
359 let expected: [&[u8]; 4] = [b"fff0", &buf[0..65516], b"0018", &buf[65516..65536]];
360 let expected = expected.concat();
361 wrtr.write(&buf).unwrap();
362 wrtr.flush().unwrap();
363 assert_eq!(expected, wrtr.writer.into_inner());
364 }
365
366 #[test]
367 fn read_data_large() {
368 let buf = pattern_of_size(1048576);
369 for chunk_size in &[10, 17, 2204, 32768, 32771, 65516] {
370 let mut input: Vec<u8> = buf
371 .chunks(*chunk_size)
372 .flat_map(|x| {
373 let mut vec = format!("{:04x}", x.len() + 4).as_bytes().to_vec();
374 vec.extend(x);
375 vec
376 })
377 .collect();
378 input.extend(b"0000");
379 let mut rdr = reader_from_buf(&input);
380 let mut cursor = io::Cursor::new(Vec::new());
381 io::copy(&mut rdr, &mut cursor).unwrap();
382 let actual = cursor.into_inner();
383 assert_eq!(buf, actual);
384 }
385 }
386}