use std::intrinsics::unlikely;
use crate::{ErrorInner, Result};
pub trait BufferReader {
fn bytes(&self) -> &[u8];
fn advance(&mut self, count: usize);
fn read_bytes(&mut self, count: usize) -> Result<&[u8]>;
}
impl<T: AsRef<[u8]>> BufferReader for std::io::Cursor<T> {
#[inline]
fn bytes(&self) -> &[u8] {
let pos = self.position() as usize;
let slice = self.get_ref().as_ref();
slice.get(pos..).unwrap_or(&[])
}
#[inline]
fn advance(&mut self, count: usize) {
let mut pos = self.position();
pos += count as u64;
self.set_position(pos);
}
fn read_bytes(&mut self, count: usize) -> Result<&[u8]> {
if unlikely(count == 0) {
return Ok(&[]);
}
let pos = self.position() as usize;
let slice = self.get_ref().as_ref();
if unlikely(pos + count >= slice.len()) {
return Err(ErrorInner::eof().into());
}
let new_pos = pos + count;
self.set_position(new_pos as u64);
Ok(&self.get_ref().as_ref()[pos..new_pos])
}
}
impl<'a> BufferReader for &'a [u8] {
#[inline]
fn bytes(&self) -> &[u8] {
self
}
#[inline]
fn advance(&mut self, count: usize) {
*self = &self[count..]
}
fn read_bytes(&mut self, count: usize) -> Result<&[u8]> {
if unlikely(self.len() < count) {
return Err(ErrorInner::eof().into());
}
let (left, right) = self.split_at(count);
*self = right;
Ok(left)
}
}
impl<'a, T: BufferReader + ?Sized> BufferReader for &'a mut T {
#[inline]
fn bytes(&self) -> &[u8] {
(**self).bytes()
}
#[inline]
fn advance(&mut self, count: usize) {
(**self).advance(count)
}
#[inline]
fn read_bytes(&mut self, count: usize) -> Result<&[u8]> {
(**self).read_bytes(count)
}
}
impl<T: BufferReader + ?Sized> BufferReader for Box<T> {
#[inline]
fn bytes(&self) -> &[u8] {
(**self).bytes()
}
#[inline]
fn advance(&mut self, count: usize) {
(**self).advance(count)
}
#[inline]
fn read_bytes(&mut self, count: usize) -> Result<&[u8]> {
(**self).read_bytes(count)
}
}
pub trait BufferWriter {
unsafe fn bytes_mut(&mut self, size: usize) -> &mut [u8];
unsafe fn advance_mut(&mut self, count: usize);
fn write_bytes(&mut self, values: &[u8]) -> Result<()>;
}
impl<T: AsMut<[u8]>> BufferWriter for std::io::Cursor<T> {
#[inline]
unsafe fn bytes_mut(&mut self, _size: usize) -> &mut [u8] {
let pos = self.position() as usize;
let slice = self.get_mut().as_mut();
slice.get_mut(pos..).unwrap_or(&mut [])
}
#[inline]
unsafe fn advance_mut(&mut self, count: usize) {
let mut pos = self.position();
pos += count as u64;
self.set_position(pos);
}
fn write_bytes(&mut self, values: &[u8]) -> Result<()> {
let write_len = values.len();
if unlikely(write_len == 0) {
return Ok(());
}
let pos = self.position() as usize;
let slice = self.get_mut().as_mut();
if unlikely(pos + write_len >= slice.len()) {
return Err(ErrorInner::eof().into());
}
let new_pos = pos + write_len;
slice[pos..new_pos].copy_from_slice(values);
self.set_position(new_pos as u64);
Ok(())
}
}
impl<'a> BufferWriter for &'a mut [u8] {
#[inline]
unsafe fn bytes_mut(&mut self, _size: usize) -> &mut [u8] {
self
}
#[inline]
unsafe fn advance_mut(&mut self, count: usize) {
let original_self = std::mem::replace(self, &mut []);
*self = &mut original_self[count..];
}
fn write_bytes(&mut self, values: &[u8]) -> Result<()> {
let write_len = values.len();
if unlikely(self.len() < write_len) {
return Err(ErrorInner::eof().into());
}
let original_self = std::mem::replace(self, &mut []);
original_self[..write_len].copy_from_slice(values);
*self = &mut original_self[write_len..];
Ok(())
}
}
impl BufferWriter for Vec<u8> {
unsafe fn bytes_mut(&mut self, size: usize) -> &mut [u8] {
self.reserve(size);
let ptr = self.as_mut_ptr();
&mut std::slice::from_raw_parts_mut(ptr, self.capacity())[self.len()..]
}
#[inline]
unsafe fn advance_mut(&mut self, count: usize) {
let len = self.len();
self.set_len(len + count);
}
#[inline]
fn write_bytes(&mut self, values: &[u8]) -> Result<()> {
self.extend_from_slice(values);
Ok(())
}
}
impl<'a, T: BufferWriter + ?Sized> BufferWriter for &'a mut T {
#[inline]
unsafe fn bytes_mut(&mut self, size: usize) -> &mut [u8] {
(**self).bytes_mut(size)
}
#[inline]
unsafe fn advance_mut(&mut self, count: usize) {
(**self).advance_mut(count)
}
#[inline]
fn write_bytes(&mut self, values: &[u8]) -> Result<()> {
(**self).write_bytes(values)
}
}
impl<T: BufferWriter + ?Sized> BufferWriter for Box<T> {
#[inline]
unsafe fn bytes_mut(&mut self, size: usize) -> &mut [u8] {
(**self).bytes_mut(size)
}
#[inline]
unsafe fn advance_mut(&mut self, count: usize) {
(**self).advance_mut(count)
}
#[inline]
fn write_bytes(&mut self, values: &[u8]) -> Result<()> {
(**self).write_bytes(values)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_buffer_reader_cursor() {
let mut base: Vec<u8> = Vec::with_capacity(40);
for _ in 0..40 {
base.push(rand::random());
}
let mut buffer = std::io::Cursor::new(base.clone());
assert_eq!(buffer.bytes(), &base[0..40]);
buffer.advance(13);
assert_eq!(buffer.position(), 13);
assert_eq!(buffer.bytes(), &base[13..40]);
buffer.advance(5);
assert_eq!(buffer.position(), 18);
assert_eq!(buffer.bytes(), &base[18..40]);
assert_eq!(buffer.read_bytes(0).unwrap(), &[]);
assert_eq!(buffer.position(), 18);
assert_eq!(buffer.bytes(), &base[18..40]);
assert_eq!(buffer.read_bytes(2).unwrap(), &base[18..20]);
assert_eq!(buffer.position(), 20);
assert_eq!(buffer.bytes(), &base[20..40]);
buffer.set_position(7);
assert_eq!(buffer.bytes(), &base[7..40]);
buffer.advance(31);
assert_eq!(buffer.position(), 38);
assert_eq!(buffer.bytes(), &base[38..40]);
buffer.advance(2);
assert_eq!(buffer.position(), 40);
assert_eq!(buffer.bytes(), &base[40..40]);
buffer.advance(7);
assert_eq!(buffer.position(), 47);
assert_eq!(buffer.bytes(), &base[40..40]);
buffer.set_position(0);
assert_eq!(buffer.bytes(), &base[0..40]);
buffer.set_position(100);
assert_eq!(buffer.bytes(), &base[40..40]);
assert_eq!(buffer.read_bytes(0).unwrap(), &[]);
buffer.set_position(39);
assert!(buffer.read_bytes(2).is_err());
assert_eq!(buffer.position(), 39);
assert_eq!(buffer.bytes(), &base[39..40]);
}
#[test]
fn test_buffer_reader_slice() {
let mut base: Vec<u8> = Vec::with_capacity(40);
for _ in 0..40 {
base.push(rand::random());
}
let buffer = base.clone();
let mut buffer = buffer.as_slice();
assert_eq!(buffer, &base[0..40]);
assert_eq!(buffer.bytes(), &base[0..40]);
buffer.advance(13);
assert_eq!(buffer, &base[13..40]);
assert_eq!(buffer.bytes(), &base[13..40]);
buffer.advance(5);
assert_eq!(buffer, &base[18..40]);
assert_eq!(buffer.bytes(), &base[18..40]);
assert_eq!(buffer.read_bytes(0).unwrap(), &[]);
assert_eq!(buffer, &base[18..40]);
assert_eq!(buffer.bytes(), &base[18..40]);
buffer.advance(1);
assert_eq!(buffer.read_bytes(2).unwrap(), &base[19..21]);
assert_eq!(buffer, &base[21..40]);
assert_eq!(buffer.bytes(), &base[21..40]);
assert!(buffer.read_bytes(20).is_err());
buffer.advance(19);
assert_eq!(buffer, &[]);
assert_eq!(buffer.bytes(), &[]);
assert_eq!(buffer.read_bytes(0).unwrap(), &[]);
assert!(buffer.read_bytes(1).is_err());
}
#[test]
fn test_buffer_writer_cursor() {
unsafe {
let mut base: Vec<u8> = Vec::with_capacity(40);
for _ in 0..40 {
base.push(rand::random());
}
let mut base_write: Vec<u8> = Vec::with_capacity(100);
for _ in 0..100 {
base_write.push(rand::random());
}
let mut buffer = std::io::Cursor::new(base.clone());
buffer.bytes_mut(13)[..13].clone_from_slice(&base_write[0..13]);
buffer.advance_mut(13);
assert_eq!(&buffer.get_ref()[0..13], &base_write[0..13]);
assert_eq!(&buffer.get_ref()[13..], &base[13..]);
assert_eq!(buffer.position(), 13);
buffer.bytes_mut(10)[..5].clone_from_slice(&base_write[13..18]);
buffer.advance_mut(5);
assert_eq!(&buffer.get_ref()[0..18], &base_write[0..18]);
assert_eq!(&buffer.get_ref()[18..], &base[18..]);
assert_eq!(buffer.position(), 18);
buffer.write_bytes(&base_write[18..20]).unwrap();
assert_eq!(&buffer.get_ref()[0..20], &base_write[0..20]);
assert_eq!(&buffer.get_ref()[20..], &base[20..]);
assert_eq!(buffer.position(), 20);
assert!(buffer.write_bytes(&base_write[20..]).is_err());
assert_eq!(&buffer.get_ref()[0..20], &base_write[0..20]);
assert_eq!(&buffer.get_ref()[20..], &base[20..]);
assert_eq!(buffer.position(), 20);
buffer.set_position(7);
buffer.bytes_mut(16)[..16].clone_from_slice(&base_write[18..34]);
buffer.advance_mut(16);
assert_eq!(&buffer.get_ref()[0..7], &base_write[0..7]);
assert_eq!(&buffer.get_ref()[7..23], &base_write[18..34]);
assert_eq!(&buffer.get_ref()[23..], &base[23..]);
assert_eq!(buffer.position(), 23);
buffer.bytes_mut(15)[..15].clone_from_slice(&base_write[34..49]);
buffer.advance_mut(15);
assert_eq!(&buffer.get_ref()[0..7], &base_write[0..7]);
assert_eq!(&buffer.get_ref()[7..38], &base_write[18..49]);
assert_eq!(&buffer.get_ref()[38..], &base[38..]);
assert_eq!(buffer.position(), 38);
assert_eq!(buffer.bytes_mut(5).len(), 2);
buffer.bytes_mut(2)[..2].clone_from_slice(&base_write[49..51]);
buffer.advance_mut(2);
assert_eq!(&buffer.get_ref()[0..7], &base_write[0..7]);
assert_eq!(&buffer.get_ref()[7..38], &base_write[18..49]);
assert_eq!(&buffer.get_ref()[7..40], &base_write[18..51]);
assert_eq!(buffer.position(), 40);
buffer.set_position(0);
buffer.bytes_mut(5)[..5].clone_from_slice(&base_write[51..56]);
buffer.advance_mut(5);
assert_eq!(&buffer.get_ref()[0..5], &base_write[51..56]);
assert_eq!(&buffer.get_ref()[5..7], &base_write[5..7]);
assert_eq!(&buffer.get_ref()[7..40], &base_write[18..51]);
assert_eq!(buffer.position(), 5);
buffer.set_position(100);
assert_eq!(buffer.bytes_mut(1).len(), 0);
assert_eq!(&buffer.get_ref()[0..5], &base_write[51..56]);
assert_eq!(&buffer.get_ref()[5..7], &base_write[5..7]);
assert_eq!(&buffer.get_ref()[7..40], &base_write[18..51]);
buffer.write_bytes(&[]).unwrap();
assert_eq!(buffer.bytes_mut(1).len(), 0);
assert_eq!(&buffer.get_ref()[0..5], &base_write[51..56]);
assert_eq!(&buffer.get_ref()[5..7], &base_write[5..7]);
assert_eq!(&buffer.get_ref()[7..40], &base_write[18..51]);
}
}
#[test]
fn test_buffer_writer_slice() {
unsafe {
let mut base: Vec<u8> = Vec::with_capacity(40);
for _ in 0..40 {
base.push(rand::random());
}
let mut base_write: Vec<u8> = Vec::with_capacity(100);
for _ in 0..100 {
base_write.push(rand::random());
}
let mut buffer = base.clone();
let mut buf_slice = buffer.as_mut_slice();
buf_slice.bytes_mut(13)[..13].clone_from_slice(&base_write[0..13]);
assert_eq!(&buf_slice[0..13], &base_write[0..13]);
assert_eq!(&buf_slice[13..], &base[13..]);
buf_slice.advance_mut(13);
assert_eq!(buf_slice.as_ptr(), buffer[13..].as_ptr());
assert_eq!(&buffer[0..13], &base_write[0..13]);
assert_eq!(&buffer[13..], &base[13..]);
let mut buf_slice = &mut buffer[13..];
buf_slice.bytes_mut(10)[..5].clone_from_slice(&base_write[13..18]);
assert_eq!(&buf_slice[0..5], &base_write[13..18]);
assert_eq!(&buf_slice[5..], &base[18..]);
buf_slice.advance_mut(5);
assert_eq!(buf_slice.as_ptr(), buffer[18..].as_ptr());
assert_eq!(&buffer[0..18], &base_write[0..18]);
assert_eq!(&buffer[18..], &base[18..]);
let mut buf_slice = &mut buffer[18..];
buf_slice.write_bytes(&base_write[18..20]).unwrap();
assert_eq!(buf_slice, &base[20..]);
assert_eq!(buf_slice.as_ptr(), buffer[20..].as_ptr());
assert_eq!(&buffer[0..20], &base_write[0..20]);
assert_eq!(&buffer[20..], &base[20..]);
let mut buf_slice = &mut buffer[20..];
assert!(buf_slice.write_bytes(&base_write[20..41]).is_err());
buf_slice.bytes_mut(20)[..20].clone_from_slice(&base_write[20..40]);
assert_eq!(&buf_slice[0..20], &base_write[20..40]);
buf_slice.advance_mut(20);
assert_eq!(buf_slice.as_ptr(), buffer[40..].as_ptr());
assert_eq!(buffer, &base_write[0..40]);
let mut buf_slice = &mut buffer[40..];
buf_slice.write_bytes(&base_write[40..40]).unwrap();
assert_eq!(buf_slice.as_ptr(), buffer[40..].as_ptr());
}
}
#[test]
fn test_buffer_writer_vec() {
unsafe {
let mut base_write: Vec<u8> = Vec::with_capacity(100);
for _ in 0..100 {
base_write.push(rand::random());
}
let mut buffer: Vec<u8> = Vec::with_capacity(20);
buffer.bytes_mut(13)[..13].clone_from_slice(&base_write[0..13]);
buffer.advance_mut(13);
assert_eq!(&buffer[0..13], &base_write[0..13]);
assert_eq!(buffer.len(), 13);
assert!(buffer.bytes_mut(10).len() >= 10);
buffer.bytes_mut(10)[..5].clone_from_slice(&base_write[13..18]);
buffer.advance_mut(5);
assert_eq!(&buffer[0..18], &base_write[0..18]);
assert_eq!(buffer.len(), 18);
buffer.write_bytes(&base_write[18..28]).unwrap();
assert_eq!(&buffer[0..28], &base_write[0..28]);
assert_eq!(buffer.len(), 28);
buffer.set_len(7);
buffer.bytes_mut(16)[..16].clone_from_slice(&base_write[18..34]);
buffer.advance_mut(16);
assert_eq!(&buffer[0..7], &base_write[0..7]);
assert_eq!(&buffer[7..23], &base_write[18..34]);
assert_eq!(buffer.len(), 23);
buffer.bytes_mut(15)[..15].clone_from_slice(&base_write[34..49]);
buffer.advance_mut(15);
assert_eq!(&buffer[0..7], &base_write[0..7]);
assert_eq!(&buffer[7..38], &base_write[18..49]);
assert_eq!(buffer.len(), 38);
buffer.bytes_mut(2)[..2].clone_from_slice(&base_write[49..51]);
buffer.advance_mut(2);
assert_eq!(&buffer[0..7], &base_write[0..7]);
assert_eq!(&buffer[7..40], &base_write[18..51]);
assert_eq!(buffer.len(), 40);
}
}
#[test]
#[ignore]
fn test_vec_reallocate() {
let mut in_place_reallocs = 0;
const MAX_IN_PLACE_REALLOCS: usize = 32;
for payload_len in 1..1024 {
let mut payload: Vec<u8> = Vec::with_capacity(payload_len);
for _ in 0..payload_len {
payload.push(rand::random());
}
let mut vec: Vec<u8> = Vec::with_capacity(payload_len);
let vec_ptr = vec.as_ptr();
unsafe {
let slice = vec.bytes_mut(payload_len);
slice[..payload_len].clone_from_slice(payload.as_slice());
}
let _alloc_noise: Vec<u8> = Vec::with_capacity(payload_len);
let _alloc_noise: Vec<u8> = Vec::with_capacity(1);
vec.reserve(::std::cmp::max(payload_len * 3, 32));
if vec_ptr == vec.as_ptr() {
in_place_reallocs += 1;
}
unsafe {
vec.advance_mut(payload_len);
}
assert_eq!(vec.as_slice(), payload.as_slice());
}
if in_place_reallocs > MAX_IN_PLACE_REALLOCS {
panic!("realloc test realloc enough");
}
}
}