use super::{IntoBuf, Take, Reader, Iter, FromBuf, Chain};
use byteorder::ByteOrder;
use iovec::IoVec;
use std::{cmp, io, ptr};
pub trait Buf {
fn remaining(&self) -> usize;
fn bytes(&self) -> &[u8];
fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize {
if dst.is_empty() {
return 0;
}
if self.has_remaining() {
dst[0] = self.bytes().into();
1
} else {
0
}
}
fn advance(&mut self, cnt: usize);
fn has_remaining(&self) -> bool {
self.remaining() > 0
}
fn copy_to_slice(&mut self, dst: &mut [u8]) {
let mut off = 0;
assert!(self.remaining() >= dst.len());
while off < dst.len() {
let cnt;
unsafe {
let src = self.bytes();
cnt = cmp::min(src.len(), dst.len() - off);
ptr::copy_nonoverlapping(
src.as_ptr(), dst[off..].as_mut_ptr(), cnt);
off += src.len();
}
self.advance(cnt);
}
}
fn get_u8(&mut self) -> u8 {
let mut buf = [0; 1];
self.copy_to_slice(&mut buf);
buf[0]
}
fn get_i8(&mut self) -> i8 {
let mut buf = [0; 1];
self.copy_to_slice(&mut buf);
buf[0] as i8
}
fn get_u16<T: ByteOrder>(&mut self) -> u16 {
let mut buf = [0; 2];
self.copy_to_slice(&mut buf);
T::read_u16(&buf)
}
fn get_i16<T: ByteOrder>(&mut self) -> i16 {
let mut buf = [0; 2];
self.copy_to_slice(&mut buf);
T::read_i16(&buf)
}
fn get_u32<T: ByteOrder>(&mut self) -> u32 {
let mut buf = [0; 4];
self.copy_to_slice(&mut buf);
T::read_u32(&buf)
}
fn get_i32<T: ByteOrder>(&mut self) -> i32 {
let mut buf = [0; 4];
self.copy_to_slice(&mut buf);
T::read_i32(&buf)
}
fn get_u64<T: ByteOrder>(&mut self) -> u64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf);
T::read_u64(&buf)
}
fn get_i64<T: ByteOrder>(&mut self) -> i64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf);
T::read_i64(&buf)
}
fn get_uint<T: ByteOrder>(&mut self, nbytes: usize) -> u64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf[..nbytes]);
T::read_uint(&buf[..nbytes], nbytes)
}
fn get_int<T: ByteOrder>(&mut self, nbytes: usize) -> i64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf[..nbytes]);
T::read_int(&buf[..nbytes], nbytes)
}
fn get_f32<T: ByteOrder>(&mut self) -> f32 {
let mut buf = [0; 4];
self.copy_to_slice(&mut buf);
T::read_f32(&buf)
}
fn get_f64<T: ByteOrder>(&mut self) -> f64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf);
T::read_f64(&buf)
}
fn collect<B>(self) -> B
where Self: Sized,
B: FromBuf,
{
B::from_buf(self)
}
fn take(self, limit: usize) -> Take<Self>
where Self: Sized
{
super::take::new(self, limit)
}
fn chain<U>(self, next: U) -> Chain<Self, U::Buf>
where U: IntoBuf,
Self: Sized,
{
Chain::new(self, next.into_buf())
}
fn by_ref(&mut self) -> &mut Self where Self: Sized {
self
}
fn reader(self) -> Reader<Self> where Self: Sized {
super::reader::new(self)
}
fn iter(self) -> Iter<Self> where Self: Sized {
super::iter::new(self)
}
}
impl<'a, T: Buf + ?Sized> Buf for &'a mut T {
fn remaining(&self) -> usize {
(**self).remaining()
}
fn bytes(&self) -> &[u8] {
(**self).bytes()
}
fn bytes_vec<'b>(&'b self, dst: &mut [&'b IoVec]) -> usize {
(**self).bytes_vec(dst)
}
fn advance(&mut self, cnt: usize) {
(**self).advance(cnt)
}
}
impl<T: Buf + ?Sized> Buf for Box<T> {
fn remaining(&self) -> usize {
(**self).remaining()
}
fn bytes(&self) -> &[u8] {
(**self).bytes()
}
fn bytes_vec<'b>(&'b self, dst: &mut [&'b IoVec]) -> usize {
(**self).bytes_vec(dst)
}
fn advance(&mut self, cnt: usize) {
(**self).advance(cnt)
}
}
impl<T: AsRef<[u8]>> Buf for io::Cursor<T> {
fn remaining(&self) -> usize {
let len = self.get_ref().as_ref().len();
let pos = self.position();
if pos >= len as u64 {
return 0;
}
len - pos as usize
}
fn bytes(&self) -> &[u8] {
let len = self.get_ref().as_ref().len();
let pos = self.position() as usize;
if pos >= len {
return Default::default();
}
&(self.get_ref().as_ref())[pos..]
}
fn advance(&mut self, cnt: usize) {
let pos = (self.position() as usize)
.checked_add(cnt).expect("overflow");
assert!(pos <= self.get_ref().as_ref().len());
self.set_position(pos as u64);
}
}
impl Buf for Option<[u8; 1]> {
fn remaining(&self) -> usize {
if self.is_some() {
1
} else {
0
}
}
fn bytes(&self) -> &[u8] {
self.as_ref().map(AsRef::as_ref)
.unwrap_or(Default::default())
}
fn advance(&mut self, cnt: usize) {
if cnt == 0 {
return;
}
if self.is_none() {
panic!("overflow");
} else {
assert_eq!(1, cnt);
*self = None;
}
}
}