use {Bytes};
use byteorder::ByteOrder;
use std::{cmp, io, ptr, usize};
pub trait Buf {
fn remaining(&self) -> usize;
fn bytes(&self) -> &[u8];
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 take(self, limit: usize) -> Take<Self>
where Self: Sized
{
Take {
inner: self,
limit: limit,
}
}
fn by_ref(&mut self) -> &mut Self where Self: Sized {
self
}
fn reader(self) -> Reader<Self> where Self: Sized {
Reader { buf: self }
}
}
pub trait BufMut {
fn remaining_mut(&self) -> usize;
unsafe fn advance_mut(&mut self, cnt: usize);
fn has_remaining_mut(&self) -> bool {
self.remaining_mut() > 0
}
unsafe fn bytes_mut(&mut self) -> &mut [u8];
fn put<S: Source>(&mut self, src: S) where Self: Sized {
src.copy_to_buf(self);
}
fn put_slice(&mut self, src: &[u8]) {
let mut off = 0;
assert!(self.remaining_mut() >= src.len(), "buffer overflow");
while off < src.len() {
let cnt;
unsafe {
let dst = self.bytes_mut();
cnt = cmp::min(dst.len(), src.len() - off);
ptr::copy_nonoverlapping(
src[off..].as_ptr(),
dst.as_mut_ptr(),
cnt);
off += cnt;
}
unsafe { self.advance_mut(cnt); }
}
}
fn put_u16<T: ByteOrder>(&mut self, n: u16) {
let mut buf = [0; 2];
T::write_u16(&mut buf, n);
self.put_slice(&buf)
}
fn put_i16<T: ByteOrder>(&mut self, n: i16) {
let mut buf = [0; 2];
T::write_i16(&mut buf, n);
self.put_slice(&buf)
}
fn put_u32<T: ByteOrder>(&mut self, n: u32) {
let mut buf = [0; 4];
T::write_u32(&mut buf, n);
self.put_slice(&buf)
}
fn put_i32<T: ByteOrder>(&mut self, n: i32) {
let mut buf = [0; 4];
T::write_i32(&mut buf, n);
self.put_slice(&buf)
}
fn put_u64<T: ByteOrder>(&mut self, n: u64) {
let mut buf = [0; 8];
T::write_u64(&mut buf, n);
self.put_slice(&buf)
}
fn put_i64<T: ByteOrder>(&mut self, n: i64) {
let mut buf = [0; 8];
T::write_i64(&mut buf, n);
self.put_slice(&buf)
}
fn put_uint<T: ByteOrder>(&mut self, n: u64, nbytes: usize) {
let mut buf = [0; 8];
T::write_uint(&mut buf, n, nbytes);
self.put_slice(&buf[0..nbytes])
}
fn put_int<T: ByteOrder>(&mut self, n: i64, nbytes: usize) {
let mut buf = [0; 8];
T::write_int(&mut buf, n, nbytes);
self.put_slice(&buf[0..nbytes])
}
fn put_f32<T: ByteOrder>(&mut self, n: f32) {
let mut buf = [0; 4];
T::write_f32(&mut buf, n);
self.put_slice(&buf)
}
fn put_f64<T: ByteOrder>(&mut self, n: f64) {
let mut buf = [0; 8];
T::write_f64(&mut buf, n);
self.put_slice(&buf)
}
fn by_ref(&mut self) -> &mut Self where Self: Sized {
self
}
fn writer(self) -> Writer<Self> where Self: Sized {
Writer { buf: self }
}
}
pub trait IntoBuf {
type Buf: Buf;
fn into_buf(self) -> Self::Buf;
}
impl<'a> IntoBuf for &'a [u8] {
type Buf = io::Cursor<&'a [u8]>;
fn into_buf(self) -> Self::Buf {
io::Cursor::new(self)
}
}
impl<'a> IntoBuf for &'a str {
type Buf = io::Cursor<&'a [u8]>;
fn into_buf(self) -> Self::Buf {
self.as_bytes().into_buf()
}
}
impl IntoBuf for Vec<u8> {
type Buf = io::Cursor<Vec<u8>>;
fn into_buf(self) -> Self::Buf {
io::Cursor::new(self)
}
}
impl<'a> IntoBuf for &'a &'static [u8] {
type Buf = io::Cursor<&'static [u8]>;
fn into_buf(self) -> Self::Buf {
io::Cursor::new(self)
}
}
impl<'a> IntoBuf for &'a &'static str {
type Buf = io::Cursor<&'static [u8]>;
fn into_buf(self) -> Self::Buf {
self.as_bytes().into_buf()
}
}
impl<'a> IntoBuf for &'a Vec<u8> {
type Buf = io::Cursor<&'a [u8]>;
fn into_buf(self) -> Self::Buf {
io::Cursor::new(&self[..])
}
}
impl IntoBuf for String {
type Buf = io::Cursor<Vec<u8>>;
fn into_buf(self) -> Self::Buf {
self.into_bytes().into_buf()
}
}
impl<'a> IntoBuf for &'a String {
type Buf = io::Cursor<&'a [u8]>;
fn into_buf(self) -> Self::Buf {
self.as_bytes().into_buf()
}
}
impl IntoBuf for () {
type Buf = io::Cursor<&'static [u8]>;
fn into_buf(self) -> Self::Buf {
io::Cursor::new(&[])
}
}
impl<'a> IntoBuf for &'a () {
type Buf = io::Cursor<&'static [u8]>;
fn into_buf(self) -> Self::Buf {
io::Cursor::new(&[])
}
}
pub trait Source {
fn copy_to_buf<B: BufMut>(self, buf: &mut B);
}
impl Source for Vec<u8> {
fn copy_to_buf<B: BufMut>(self, buf: &mut B) {
buf.put_slice(&self[..]);
}
}
impl<'a> Source for &'a Vec<u8> {
fn copy_to_buf<B: BufMut>(self, buf: &mut B) {
buf.put_slice(&self[..]);
}
}
impl<'a> Source for &'a [u8] {
fn copy_to_buf<B: BufMut>(self, buf: &mut B) {
buf.put_slice(self);
}
}
impl Source for String {
fn copy_to_buf<B: BufMut>(self, buf: &mut B) {
buf.put_slice(self.as_bytes());
}
}
impl<'a> Source for &'a String {
fn copy_to_buf<B: BufMut>(self, buf: &mut B) {
buf.put_slice(self.as_bytes());
}
}
impl<'a> Source for &'a str {
fn copy_to_buf<B: BufMut>(self, buf: &mut B) {
buf.put_slice(self.as_bytes());
}
}
impl Source for u8 {
fn copy_to_buf<B: BufMut>(self, buf: &mut B) {
let src = [self];
buf.put_slice(&src);
}
}
impl Source for i8 {
fn copy_to_buf<B: BufMut>(self, buf: &mut B) {
buf.put_slice(&[self as u8])
}
}
impl Source for Bytes {
fn copy_to_buf<B: BufMut>(self, buf: &mut B) {
Source::copy_to_buf(self.as_ref(), buf);
}
}
impl<'a> Source for &'a Bytes {
fn copy_to_buf<B: BufMut>(self, buf: &mut B) {
Source::copy_to_buf(self.as_ref(), buf);
}
}
impl<T: Buf> Source for T {
fn copy_to_buf<B: BufMut>(mut self, buf: &mut B) {
assert!(buf.remaining_mut() >= self.remaining());
while self.has_remaining() {
let l;
unsafe {
let s = self.bytes();
let d = buf.bytes_mut();
l = cmp::min(s.len(), d.len());
ptr::copy_nonoverlapping(
s.as_ptr(),
d.as_mut_ptr(),
l);
}
self.advance(l);
unsafe { buf.advance_mut(l); }
}
}
}
pub struct Take<T> {
inner: T,
limit: usize,
}
impl<T> Take<T> {
pub fn into_inner(self) -> T {
self.inner
}
pub fn get_ref(&self) -> &T {
&self.inner
}
pub fn get_mut(&mut self) -> &mut T {
&mut self.inner
}
pub fn limit(&self) -> usize {
self.limit
}
pub fn set_limit(&mut self, lim: usize) {
self.limit = lim
}
}
impl<T: Buf> Buf for Take<T> {
fn remaining(&self) -> usize {
cmp::min(self.inner.remaining(), self.limit)
}
fn bytes(&self) -> &[u8] {
&self.inner.bytes()[..self.limit]
}
fn advance(&mut self, cnt: usize) {
let cnt = cmp::min(cnt, self.limit);
self.limit -= cnt;
self.inner.advance(cnt);
}
}
pub struct Reader<B> {
buf: B,
}
impl<B: Buf> Reader<B> {
pub fn get_ref(&self) -> &B {
&self.buf
}
pub fn get_mut(&mut self) -> &mut B {
&mut self.buf
}
pub fn into_inner(self) -> B {
self.buf
}
}
impl<B: Buf + Sized> io::Read for Reader<B> {
fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
let len = cmp::min(self.buf.remaining(), dst.len());
Buf::copy_to_slice(&mut self.buf, &mut dst[0..len]);
Ok(len)
}
}
pub struct Writer<B> {
buf: B,
}
impl<B: BufMut> Writer<B> {
pub fn get_ref(&self) -> &B {
&self.buf
}
pub fn get_mut(&mut self) -> &mut B {
&mut self.buf
}
pub fn into_inner(self) -> B {
self.buf
}
}
impl<B: BufMut + Sized> io::Write for Writer<B> {
fn write(&mut self, src: &[u8]) -> io::Result<usize> {
let n = cmp::min(self.buf.remaining_mut(), src.len());
self.buf.put(&src[0..n]);
Ok(n)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
impl<'a, T: Buf> Buf for &'a mut T {
fn remaining(&self) -> usize {
(**self).remaining()
}
fn bytes(&self) -> &[u8] {
(**self).bytes()
}
fn advance(&mut self, cnt: usize) {
(**self).advance(cnt)
}
}
impl<'a, T: BufMut> BufMut for &'a mut T {
fn remaining_mut(&self) -> usize {
(**self).remaining_mut()
}
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
(**self).bytes_mut()
}
unsafe fn advance_mut(&mut self, cnt: usize) {
(**self).advance_mut(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 pos = self.position() as usize;
&(self.get_ref().as_ref())[pos..]
}
fn advance(&mut self, cnt: usize) {
let pos = self.position() as usize;
let pos = cmp::min(self.get_ref().as_ref().len(), pos + cnt);
self.set_position(pos as u64);
}
}
impl<T: AsMut<[u8]> + AsRef<[u8]>> BufMut for io::Cursor<T> {
fn remaining_mut(&self) -> usize {
self.remaining()
}
unsafe fn advance_mut(&mut self, cnt: usize) {
let pos = self.position() as usize;
let pos = cmp::min(self.get_mut().as_mut().len(), pos + cnt);
self.set_position(pos as u64);
}
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
let pos = self.position() as usize;
&mut (self.get_mut().as_mut())[pos..]
}
}
impl BufMut for Vec<u8> {
fn remaining_mut(&self) -> usize {
usize::MAX - self.len()
}
unsafe fn advance_mut(&mut self, cnt: usize) {
let len = self.len() + cnt;
if len > self.capacity() {
let cap = self.capacity();
self.reserve(cap - len);
}
self.set_len(len);
}
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
use std::slice;
if self.capacity() == self.len() {
self.reserve(64); }
let cap = self.capacity();
let len = self.len();
let ptr = self.as_mut_ptr();
&mut slice::from_raw_parts_mut(ptr, cap)[len..]
}
}