use Read;
use Write;
use error::BufError;
use ::void::Void;
pub trait BufRead: Read {
fn fill_buf(&mut self) -> Result<&[u8], Self::ReadError>;
fn consume(&mut self, amount: usize);
}
impl<'a, R: BufRead> BufRead for &'a mut R {
fn fill_buf(&mut self) -> Result<&[u8], Self::ReadError> {
(*self).fill_buf()
}
fn consume(&mut self, amount: usize) {
(*self).consume(amount)
}
}
impl<'a> BufRead for &'a [u8] {
fn fill_buf(&mut self) -> Result<&[u8], Self::ReadError> {
Ok(*self)
}
fn consume(&mut self, mut amount: usize) {
if amount > self.len() {
amount = self.len();
}
let buf = *self;
*self = &buf[amount..];
}
}
pub trait BufReadProgress: BufRead {
type BufReadError;
fn fill_progress(&mut self) -> Result<&[u8], BufError<Self::BufReadError, Self::ReadError>>;
}
pub trait BufReadRequire: BufRead {
type BufReadError;
fn require_bytes(&mut self, amount: usize) -> Result<&[u8], BufError<Self::BufReadError, Self::ReadError>>;
}
impl<'a> BufReadRequire for &'a [u8] {
type BufReadError = Void;
fn require_bytes(&mut self, amount: usize) -> Result<&[u8], BufError<Self::BufReadError, Self::ReadError>> {
if amount <= self.len() {
Ok(*self)
} else {
Err(BufError::End)
}
}
}
pub unsafe trait BufWrite: Write {
fn request_buffer(&mut self) -> Result<*mut [u8], Self::WriteError>;
unsafe fn submit_buffer(&mut self, size: usize);
fn write_byte(&mut self, byte: u8) -> Result<(), Self::WriteError> {
unsafe {
(*self.request_buffer()?)[0] = byte;
self.submit_buffer(1);
}
Ok(())
}
}
pub unsafe trait BufWriteRequire: BufWrite {
type BufWriteError;
fn require_buffer(&mut self, size: usize) -> Result<*mut [u8], Self::BufWriteError>;
}
pub trait AsRawBuf {
fn as_raw_buf(&mut self) -> *mut [u8];
fn len(&self) -> usize;
}
impl<T: AsRef<[u8]> + AsMut<[u8]>> AsRawBuf for T {
fn as_raw_buf(&mut self) -> *mut [u8] {
self.as_mut()
}
fn len(&self) -> usize {
self.as_ref().len()
}
}
pub struct BufWriter<W, B> {
writer: W,
buffer: B,
cursor: usize,
}
impl<W: Write, B: AsRawBuf> BufWriter<W, B> {
pub fn new(writer: W, buffer: B) -> Self {
BufWriter {
writer,
buffer,
cursor: 0,
}
}
fn flush_if_full(&mut self) -> Result<(), <Self as Write>::WriteError> {
if self.cursor == self.buffer.len() {
self.flush()
} else {
Ok(())
}
}
}
impl<W: Write, B: AsRawBuf> Write for BufWriter<W, B> {
type WriteError = W::WriteError;
type FlushError = W::WriteError;
fn write(&mut self, data: &[u8]) -> Result<usize, Self::WriteError> {
let buf_len = self.buffer.len();
if self.cursor == buf_len {
self.flush()?;
if data.len() >= buf_len {
return self.writer.write(&data);
}
}
unsafe {
let buf = &mut (*self.buffer.as_raw_buf())[self.cursor..];
let to_copy = ::core::cmp::min(buf_len, data.len());
buf[0..to_copy].copy_from_slice(&data[0..to_copy]);
self.cursor += to_copy;
Ok(to_copy)
}
}
fn flush(&mut self) -> Result<(), Self::FlushError> {
let buf = unsafe {
&mut (*self.buffer.as_raw_buf())[0..self.cursor]
};
self.cursor = 0;
self.writer.write_all(buf)
}
fn size_hint(&mut self, bytes: usize) {
self.writer.size_hint(bytes)
}
fn uses_size_hint(&self) -> bool {
self.writer.uses_size_hint()
}
}
unsafe impl<W: Write, B: AsRawBuf> BufWrite for BufWriter<W, B> {
fn request_buffer(&mut self) -> Result<*mut [u8], Self::WriteError> {
self.flush_if_full()?;
unsafe {
let slice = &mut (*self.buffer.as_raw_buf())[self.cursor..];
assert!(slice.len() > 0);
Ok(slice)
}
}
unsafe fn submit_buffer(&mut self, size: usize) {
self.cursor += size;
}
}
unsafe impl<'a, W: BufWrite> BufWrite for &'a mut W {
fn request_buffer(&mut self) -> Result<*mut [u8], Self::WriteError> {
(*self).request_buffer()
}
unsafe fn submit_buffer(&mut self, size: usize) {
(*self).submit_buffer(size)
}
}
unsafe impl<'a> BufWrite for &'a mut [u8] {
fn request_buffer(&mut self) -> Result<*mut [u8], Self::WriteError> {
if self.len() > 0 {
Ok(*self)
} else {
Err(::error::BufferOverflow)
}
}
unsafe fn submit_buffer(&mut self, size: usize) {
let tmp = ::core::mem::replace(self, &mut []);
*self = &mut tmp[size..];
}
}