1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
use std::cmp::{ self, Ordering }; use bytes::Buf; use iovec::IoVec; pub struct VecBuf<'a, 'b: 'a> { pos: usize, cur: usize, inner: &'a [&'b [u8]] } impl<'a, 'b> VecBuf<'a, 'b> { pub fn new(vbytes: &'a [&'b [u8]]) -> Self { VecBuf { pos: 0, cur: 0, inner: vbytes } } } impl<'a, 'b> Buf for VecBuf<'a, 'b> { fn remaining(&self) -> usize { let sum = self.inner .iter() .skip(self.pos) .map(|bytes| bytes.len()) .sum::<usize>(); sum - self.cur } fn bytes(&self) -> &[u8] { &self.inner[self.pos][self.cur..] } fn advance(&mut self, cnt: usize) { let current = self.inner[self.pos].len(); match (self.cur + cnt).cmp(¤t) { Ordering::Equal => if self.pos + 1 < self.inner.len() { self.pos += 1; self.cur = 0; } else { self.cur += cnt; }, Ordering::Greater => { if self.pos + 1 < self.inner.len() { self.pos += 1; } let remaining = self.cur + cnt - current; self.advance(remaining); }, Ordering::Less => self.cur += cnt, } } #[allow(clippy::needless_range_loop)] fn bytes_vec<'c>(&'c self, dst: &mut [&'c IoVec]) -> usize { let len = cmp::min(self.inner.len() - self.pos, dst.len()); if len > 0 { dst[0] = self.bytes().into(); } for i in 1..len { dst[i] = self.inner[self.pos + i].into(); } len } } #[cfg(test)] mod test_vecbuf { use super::*; #[test] fn test_fresh_cursor_vec() { let mut buf = VecBuf::new(&[b"he", b"llo"]); assert_eq!(buf.remaining(), 5); assert_eq!(buf.bytes(), b"he"); buf.advance(2); assert_eq!(buf.remaining(), 3); assert_eq!(buf.bytes(), b"llo"); buf.advance(3); assert_eq!(buf.remaining(), 0); assert_eq!(buf.bytes(), b""); } #[test] fn test_get_u8() { let mut buf = VecBuf::new(&[b"\x21z", b"omg"]); assert_eq!(0x21, buf.get_u8()); } #[test] fn test_get_u16() { let mut buf = VecBuf::new(&[b"\x21\x54z", b"omg"]); assert_eq!(0x2154, buf.get_u16_be()); let mut buf = VecBuf::new(&[b"\x21\x54z", b"omg"]); assert_eq!(0x5421, buf.get_u16_le()); } #[test] #[should_panic] fn test_get_u16_buffer_underflow() { let mut buf = VecBuf::new(&[b"\x21"]); buf.get_u16_be(); } #[test] fn test_bufs_vec() { let buf = VecBuf::new(&[b"he", b"llo"]); let b1: &[u8] = &mut [0]; let b2: &[u8] = &mut [0]; let mut dst: [&IoVec; 2] = [b1.into(), b2.into()]; assert_eq!(2, buf.bytes_vec(&mut dst[..])); } }