Reorganize crate

This commit is contained in:
Carl Lerche
2016-09-23 12:05:32 -07:00
parent d05bfb6346
commit 98e0d954b5
19 changed files with 54 additions and 65 deletions
-115
View File
@@ -1,115 +0,0 @@
use alloc;
use buf::{MutBuf};
use bytes::Bytes;
use std::cell::Cell;
/// A `Buf` backed by a contiguous region of memory.
///
/// This buffer can only be written to once. Byte strings (immutable views) can
/// be created at any time, not just when the writing is complete.
pub struct AppendBuf {
mem: alloc::MemRef,
rd: Cell<u32>, // Read cursor
wr: u32, // Write cursor
cap: u32,
}
impl AppendBuf {
pub fn with_capacity(mut capacity: u32) -> AppendBuf {
// Round the capacity to the closest power of 2
capacity = capacity.next_power_of_two();
unsafe {
// Allocate the memory
let mem = alloc::heap(capacity as usize);
AppendBuf::from_mem_ref(mem, capacity, 0)
}
}
pub unsafe fn from_mem_ref(mem: alloc::MemRef, cap: u32, pos: u32) -> AppendBuf {
AppendBuf {
mem: mem,
rd: Cell::new(pos),
wr: pos,
cap: cap,
}
}
#[inline]
pub fn len(&self) -> usize {
(self.wr - self.rd.get()) as usize
}
#[inline]
pub fn capacity(&self) -> usize {
(self.cap - self.rd.get()) as usize
}
pub fn bytes(&self) -> &[u8] {
let rd = self.rd.get() as usize;
let wr = self.wr as usize;
unsafe { &self.mem.bytes_slice(rd, wr) }
}
pub fn shift(&self, n: usize) -> Bytes {
let ret = self.slice(0, n);
self.rd.set(self.rd.get() + ret.len() as u32);
assert!(self.rd.get() <= self.wr, "buffer overflow");
ret
}
pub fn drop(&self, n: usize) {
assert!(n <= self.len());
self.rd.set(self.rd.get() + n as u32);
}
pub fn slice(&self, begin: usize, end: usize) -> Bytes {
// TODO: Fix overflow potential
let rd = self.rd.get();
let wr = self.wr;
let begin = begin as u32 + rd;
let end = end as u32 + rd;
assert!(begin <= end && end <= wr, "invalid range");
unsafe { Bytes::from_mem_ref(self.mem.clone(), begin, end - begin) }
}
}
impl MutBuf for AppendBuf {
#[inline]
fn remaining(&self) -> usize {
(self.cap - self.wr) as usize
}
#[inline]
fn has_remaining(&self) -> bool {
// Implemented as an equality for the perfz
self.cap != self.wr
}
#[inline]
unsafe fn advance(&mut self, cnt: usize) {
self.wr += cnt as u32;
if self.wr > self.cap {
panic!("buffer overflow");
}
}
#[inline]
unsafe fn mut_bytes<'a>(&'a mut self) -> &'a mut [u8] {
let wr = self.wr as usize;
let cap = self.cap as usize;
self.mem.mut_bytes_slice(wr, cap)
}
}
impl AsRef<[u8]> for AppendBuf {
fn as_ref(&self) -> &[u8] {
self.bytes()
}
}
-367
View File
@@ -1,367 +0,0 @@
#![allow(warnings)]
use {Buf, MutBuf, AppendBuf, Bytes};
use alloc::{self, /* Pool */};
use std::{cmp, ptr, slice};
use std::io::Cursor;
use std::rc::Rc;
use std::collections::{vec_deque, VecDeque};
/// Append only buffer backed by a chain of `AppendBuf` buffers.
///
/// Each `AppendBuf` block is of a fixed size and allocated on demand. This
/// makes the total capacity of a `BlockBuf` potentially much larger than what
/// is currently allocated.
pub struct BlockBuf {
len: usize,
cap: usize,
blocks: VecDeque<AppendBuf>,
new_block: NewBlock,
}
enum NewBlock {
Heap(usize),
// Pool(Rc<Pool>),
}
pub struct BlockBufCursor<'a> {
rem: usize,
blocks: vec_deque::Iter<'a, AppendBuf>,
curr: Option<Cursor<&'a [u8]>>,
}
// TODO:
//
// - Add `comapct` fn which moves all buffered data into one block.
// - Add `slice` fn which returns `Bytes` for arbitrary views into the Buf
//
impl BlockBuf {
/// Create BlockBuf
pub fn new(max_blocks: usize, block_size: usize) -> BlockBuf {
assert!(max_blocks > 1, "at least 2 blocks required");
let new_block = NewBlock::Heap(block_size);
BlockBuf {
len: 0,
cap: max_blocks * new_block.block_size(),
blocks: VecDeque::with_capacity(max_blocks),
new_block: new_block,
}
}
/// Returns the number of buffered bytes
#[inline]
pub fn len(&self) -> usize {
debug_assert_eq!(self.len, self.blocks.iter().map(|b| b.len()).fold(0, |a, b| a+b));
self.len
}
/// Returns true if there are no buffered bytes
#[inline]
pub fn is_empty(&self) -> bool {
return self.len() == 0
}
/// Returns a `Buf` for the currently buffered bytes.
#[inline]
pub fn buf(&self) -> BlockBufCursor {
let mut iter = self.blocks.iter();
// Get the next leaf node buffer
let block = iter.next()
.map(|block| Cursor::new(block.bytes()));
BlockBufCursor {
rem: self.len(),
blocks: iter,
curr: block,
}
}
/// Consumes `n` buffered bytes, returning them as an immutable `Bytes`
/// value.
///
/// # Panics
///
/// Panics if `n` is greater than the number of buffered bytes.
#[inline]
pub fn shift(&mut self, n: usize) -> Bytes {
trace!("BlockBuf::shift; n={}", n);
// Fast path
match self.blocks.len() {
0 => {
assert!(n == 0, "buffer overflow");
Bytes::empty()
}
1 => {
let (ret, pop) = {
let block = self.blocks.front().expect("unexpected state");
let ret = block.shift(n);
self.len -= n;
(ret, self.len == 0 && !MutBuf::has_remaining(block))
};
if pop {
let _ = self.blocks.pop_front();
}
ret
}
_ => {
self.shift_multi(n)
}
}
}
fn shift_multi(&mut self, mut n: usize) -> Bytes {
let mut ret: Option<Bytes> = None;
while n > 0 {
if !self.have_buffered_data() {
panic!("shift len out of buffered range");
}
let (segment, pop) = {
let block = self.blocks.front().expect("unexpected state");
let block_len = block.len();
let segment_n = cmp::min(n, block_len);
n -= segment_n;
self.len -= segment_n;
let pop = block_len == segment_n && !MutBuf::has_remaining(block);
(block.shift(segment_n), pop)
};
if pop {
let _ = self.blocks.pop_front();
}
ret = Some(match ret.take() {
Some(curr) => {
curr.concat(&segment)
}
None => segment,
});
}
ret.unwrap_or_else(|| Bytes::empty())
}
/// Drop the first `n` buffered bytes
///
/// # Panics
///
/// Panics if `n` is greater than the number of buffered bytes.
pub fn drop(&mut self, mut n: usize) {
while n > 0 {
if !self.have_buffered_data() {
panic!("shift len out of buffered range");
}
let pop = {
let block = self.blocks.front().expect("unexpected state");
let segment_n = cmp::min(n, block.len());
n -= segment_n;
self.len -= segment_n;
block.drop(segment_n);
block.len() == 0
};
if pop {
let _ = self.blocks.pop_front();
}
}
}
pub fn is_compact(&mut self) -> bool {
self.blocks.len() <= 1
}
/// Moves all buffered bytes into a single block.
///
/// # Panics
///
/// Panics if the buffered bytes cannot fit in a single block.
pub fn compact(&mut self) {
trace!("BlockBuf::compact; attempting compaction");
if self.can_compact() {
trace!("BlockBuf::compact; data not aligned at start -- compacting");
let mut compacted = self.new_block.new_block()
.expect("unable to allocate block");
for block in self.blocks.drain(..) {
compacted.write_slice(block.bytes());
}
assert!(self.blocks.is_empty(), "blocks not removed");
self.blocks.push_back(compacted);
}
}
#[inline]
fn can_compact(&self) -> bool {
if self.blocks.len() > 1 {
return true;
}
self.blocks.front()
.map(|b| b.capacity() != self.new_block.block_size())
.unwrap_or(false)
}
/// Return byte slice if bytes are in sequential memory
#[inline]
pub fn bytes(&self) -> Option<&[u8]> {
match self.blocks.len() {
0 => Some(unsafe { slice::from_raw_parts(ptr::null(), 0) }),
1 => self.blocks.front().map(|b| b.bytes()),
_ => None,
}
}
#[inline]
fn block_size(&self) -> usize {
self.new_block.block_size()
}
#[inline]
fn allocate_block(&mut self) {
if let Some(block) = self.new_block.new_block() {
// Store the block
self.blocks.push_back(block);
}
}
#[inline]
fn have_buffered_data(&self) -> bool {
self.len() > 0
}
#[inline]
fn needs_alloc(&self) -> bool {
if let Some(buf) = self.blocks.back() {
// `unallocated_blocks` is checked here because if further blocks
// cannot be allocated, an empty slice should be returned.
if MutBuf::has_remaining(buf) {
return false;
}
}
true
}
}
impl MutBuf for BlockBuf {
#[inline]
fn remaining(&self) -> usize {
// TODO: Ensure that the allocator has enough capacity to provide the
// remaining bytes
self.cap - self.len
}
#[inline]
fn has_remaining(&self) -> bool {
// TODO: Ensure that the allocator has enough capacity to provide the
// remaining bytes
self.cap != self.len
}
unsafe fn advance(&mut self, cnt: usize) {
trace!("BlockBuf::advance; cnt={:?}", cnt);
// `mut_bytes` only returns bytes from the last block, thus it should
// only be possible to advance the last block
if let Some(buf) = self.blocks.back_mut() {
self.len += cnt;
buf.advance(cnt);
}
}
#[inline]
unsafe fn mut_bytes(&mut self) -> &mut [u8] {
if self.needs_alloc() {
if self.blocks.len() != self.blocks.capacity() {
self.allocate_block()
}
}
self.blocks.back_mut()
.map(|buf| buf.mut_bytes())
.unwrap_or(slice::from_raw_parts_mut(ptr::null_mut(), 0))
}
}
impl Default for BlockBuf {
fn default() -> BlockBuf {
BlockBuf::new(16, 8_192)
}
}
impl<'a> Buf for BlockBufCursor<'a> {
fn remaining(&self) -> usize {
self.rem
}
fn bytes(&self) -> &[u8] {
self.curr.as_ref()
.map(|buf| Buf::bytes(buf))
.unwrap_or(unsafe { slice::from_raw_parts(ptr::null(), 0)})
}
fn advance(&mut self, mut cnt: usize) {
cnt = cmp::min(cnt, self.rem);
// Advance the internal cursor
self.rem -= cnt;
// Advance the leaf buffer
while cnt > 0 {
{
let curr = self.curr.as_mut()
.expect("expected a value");
if curr.remaining() > cnt {
curr.advance(cnt);
break;
}
cnt -= curr.remaining();
}
self.curr = self.blocks.next()
.map(|block| Cursor::new(block.bytes()));
}
}
}
impl NewBlock {
#[inline]
fn block_size(&self) -> usize {
match *self {
NewBlock::Heap(size) => size,
// NewBlock::Pool(ref pool) => pool.buffer_len(),
}
}
#[inline]
fn new_block(&self) -> Option<AppendBuf> {
match *self {
NewBlock::Heap(size) => Some(AppendBuf::with_capacity(size as u32)),
// NewBlock::Pool(ref pool) => pool.new_append_buf(),
}
}
}
-240
View File
@@ -1,240 +0,0 @@
use {alloc, Buf, MutBuf, Bytes, MAX_CAPACITY};
use std::{cmp, fmt};
/*
*
* ===== ByteBuf =====
*
*/
/// A `Buf` backed by a contiguous region of memory.
///
/// This `Buf` is better suited for cases where there is a clear delineation
/// between reading and writing.
pub struct ByteBuf {
mem: alloc::MemRef,
cap: u32,
pos: u32,
lim: u32,
mark: Option<u32>,
}
impl ByteBuf {
/// Create a new `ByteBuf` by copying the contents of the given slice.
pub fn from_slice(bytes: &[u8]) -> ByteBuf {
let mut buf = MutByteBuf::with_capacity(bytes.len());
buf.write_slice(bytes);
buf.flip()
}
pub unsafe fn from_mem_ref(mem: alloc::MemRef, cap: u32, pos: u32, lim: u32) -> ByteBuf {
debug_assert!(pos <= lim && lim <= cap, "invalid arguments; cap={}; pos={}; lim={}", cap, pos, lim);
ByteBuf {
mem: mem,
cap: cap,
pos: pos,
lim: lim,
mark: None,
}
}
fn new(mut capacity: u32) -> ByteBuf {
// Round the capacity to the closest power of 2
capacity = capacity.next_power_of_two();
unsafe {
// Allocate the memory
let mem = alloc::heap(capacity as usize);
ByteBuf {
mem: mem,
cap: capacity,
pos: 0,
lim: capacity,
mark: None,
}
}
}
pub fn capacity(&self) -> usize {
self.cap as usize
}
pub fn flip(self) -> MutByteBuf {
let mut buf = MutByteBuf { buf: self };
buf.clear();
buf
}
/// Flips the buffer back to mutable, resetting the write position
/// to the byte after the previous write.
pub fn resume(mut self) -> MutByteBuf {
self.pos = self.lim;
self.lim = self.cap;
MutByteBuf { buf: self }
}
pub fn read_slice(&mut self, dst: &mut [u8]) {
assert!(self.remaining() >= dst.len());
let len = dst.len();
let cnt = len as u32;
let pos = self.pos as usize;
unsafe {
dst.copy_from_slice(&self.mem.bytes()[pos..pos+len]);
}
self.pos += cnt;
}
/// Marks the current read location.
///
/// Together with `reset`, this can be used to read from a section of the
/// buffer multiple times. The marked location will be cleared when the
/// buffer is flipped.
pub fn mark(&mut self) {
self.mark = Some(self.pos);
}
/// Resets the read position to the previously marked position.
///
/// Together with `mark`, this can be used to read from a section of the
/// buffer multiple times.
///
/// # Panics
///
/// This method will panic if no mark has been set.
pub fn reset(&mut self) {
self.pos = self.mark.take().expect("no mark set");
}
#[inline]
fn pos(&self) -> usize {
self.pos as usize
}
#[inline]
fn lim(&self) -> usize {
self.lim as usize
}
#[inline]
fn remaining_u32(&self) -> u32 {
self.lim - self.pos
}
}
impl Buf for ByteBuf {
#[inline]
fn remaining(&self) -> usize {
self.remaining_u32() as usize
}
#[inline]
fn bytes<'a>(&'a self) -> &'a [u8] {
unsafe { &self.mem.bytes()[self.pos()..self.lim()] }
}
#[inline]
fn advance(&mut self, mut cnt: usize) {
cnt = cmp::min(cnt, self.remaining());
self.pos += cnt as u32;
}
#[inline]
fn read_slice(&mut self, dst: &mut [u8]) {
ByteBuf::read_slice(self, dst)
}
}
impl From<ByteBuf> for Bytes {
fn from(src: ByteBuf) -> Bytes {
unsafe {
let ByteBuf { mem, pos, lim, .. } = src;
Bytes::from_mem_ref(mem, pos, lim - pos)
}
}
}
impl fmt::Debug for ByteBuf {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
self.bytes().fmt(fmt)
}
}
/*
*
* ===== MutByteBuf =====
*
*/
pub struct MutByteBuf {
buf: ByteBuf,
}
impl MutByteBuf {
pub fn with_capacity(capacity: usize) -> MutByteBuf {
assert!(capacity <= MAX_CAPACITY);
MutByteBuf { buf: ByteBuf::new(capacity as u32) }
}
pub fn capacity(&self) -> usize {
self.buf.capacity() as usize
}
pub fn flip(self) -> ByteBuf {
let mut buf = self.buf;
buf.lim = buf.pos;
buf.pos = 0;
buf
}
pub fn clear(&mut self) {
self.buf.pos = 0;
self.buf.lim = self.buf.cap;
}
#[inline]
pub fn write_slice(&mut self, src: &[u8]) -> usize {
let cnt = cmp::min(src.len(), self.buf.remaining());
let pos = self.buf.pos as usize;
unsafe {
self.buf.mem.mut_bytes()[pos..pos+cnt]
.copy_from_slice(&src[0..cnt]);
}
self.buf.pos += cnt as u32;
cnt
}
pub fn bytes<'a>(&'a self) -> &'a [u8] {
unsafe { &self.buf.mem.bytes()[..self.buf.pos()] }
}
}
impl MutBuf for MutByteBuf {
fn remaining(&self) -> usize {
self.buf.remaining()
}
unsafe fn advance(&mut self, cnt: usize) {
self.buf.advance(cnt)
}
unsafe fn mut_bytes<'a>(&'a mut self) -> &'a mut [u8] {
let pos = self.buf.pos();
let lim = self.buf.lim();
&mut self.buf.mem.mut_bytes()[pos..lim]
}
}
impl fmt::Debug for MutByteBuf {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
self.bytes().fmt(fmt)
}
}
-675
View File
@@ -1,675 +0,0 @@
pub mod append;
pub mod block;
pub mod byte;
pub mod ring;
pub mod take;
use {Bytes, Take};
use byteorder::ByteOrder;
use std::{cmp, fmt, io, ptr, usize};
/// A trait for values that provide sequential read access to bytes.
pub trait Buf {
/// Returns the number of bytes that can be accessed from the Buf
fn remaining(&self) -> usize;
/// Returns a slice starting at the current Buf position and of length
/// between 0 and `Buf::remaining()`.
fn bytes(&self) -> &[u8];
/// Advance the internal cursor of the Buf
fn advance(&mut self, cnt: usize);
/// Returns true if there are any more bytes to consume
fn has_remaining(&self) -> bool {
self.remaining() > 0
}
fn copy_to<S: Sink>(&mut self, dst: S) -> usize
where Self: Sized {
let rem = self.remaining();
dst.copy_from(self);
rem - self.remaining()
}
/// Read bytes from the `Buf` into the given slice and advance the cursor by
/// the number of bytes read.
/// Returns the number of bytes read.
///
/// ```
/// use std::io::Cursor;
/// use bytes::Buf;
///
/// let mut buf = Cursor::new(b"hello world");
/// let mut dst = [0; 5];
///
/// buf.read_slice(&mut dst);
/// assert_eq!(b"hello", &dst);
/// assert_eq!(6, buf.remaining());
/// ```
fn read_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);
}
}
/// Reads an unsigned 8 bit integer from the `Buf` without advancing the
/// buffer cursor
fn peek_u8(&self) -> Option<u8> {
if self.has_remaining() {
Some(self.bytes()[0])
} else {
None
}
}
/// Reads an unsigned 8 bit integer from the `Buf`.
fn read_u8(&mut self) -> u8 {
let mut buf = [0; 1];
self.read_slice(&mut buf);
buf[0]
}
/// Reads a signed 8 bit integer from the `Buf`.
fn read_i8(&mut self) -> i8 {
let mut buf = [0; 1];
self.read_slice(&mut buf);
buf[0] as i8
}
/// Reads an unsigned 16 bit integer from the `Buf`
fn read_u16<T: ByteOrder>(&mut self) -> u16 {
let mut buf = [0; 2];
self.read_slice(&mut buf);
T::read_u16(&buf)
}
/// Reads a signed 16 bit integer from the `Buf`
fn read_i16<T: ByteOrder>(&mut self) -> i16 {
let mut buf = [0; 2];
self.read_slice(&mut buf);
T::read_i16(&buf)
}
/// Reads an unsigned 32 bit integer from the `Buf`
fn read_u32<T: ByteOrder>(&mut self) -> u32 {
let mut buf = [0; 4];
self.read_slice(&mut buf);
T::read_u32(&buf)
}
/// Reads a signed 32 bit integer from the `Buf`
fn read_i32<T: ByteOrder>(&mut self) -> i32 {
let mut buf = [0; 4];
self.read_slice(&mut buf);
T::read_i32(&buf)
}
/// Reads an unsigned 64 bit integer from the `Buf`
fn read_u64<T: ByteOrder>(&mut self) -> u64 {
let mut buf = [0; 8];
self.read_slice(&mut buf);
T::read_u64(&buf)
}
/// Reads a signed 64 bit integer from the `Buf`
fn read_i64<T: ByteOrder>(&mut self) -> i64 {
let mut buf = [0; 8];
self.read_slice(&mut buf);
T::read_i64(&buf)
}
/// Reads an unsigned n-bytes integer from the `Buf`
fn read_uint<T: ByteOrder>(&mut self, nbytes: usize) -> u64 {
let mut buf = [0; 8];
self.read_slice(&mut buf[..nbytes]);
T::read_uint(&buf[..nbytes], nbytes)
}
/// Reads a signed n-bytes integer from the `Buf`
fn read_int<T: ByteOrder>(&mut self, nbytes: usize) -> i64 {
let mut buf = [0; 8];
self.read_slice(&mut buf[..nbytes]);
T::read_int(&buf[..nbytes], nbytes)
}
/// Reads a IEEE754 single-precision (4 bytes) floating point number from
/// the `Buf`
fn read_f32<T: ByteOrder>(&mut self) -> f32 {
let mut buf = [0; 4];
self.read_slice(&mut buf);
T::read_f32(&buf)
}
/// Reads a IEEE754 double-precision (8 bytes) floating point number from
/// the `Buf`
fn read_f64<T: ByteOrder>(&mut self) -> f64 {
let mut buf = [0; 8];
self.read_slice(&mut buf);
T::read_f64(&buf)
}
/// Creates a "by reference" adaptor for this instance of Buf
fn by_ref(&mut self) -> &mut Self where Self: Sized {
self
}
/// Create an adapter which will limit at most `limit` bytes from it.
fn take(self, limit: usize) -> Take<Self> where Self: Sized {
Take::new(self, limit)
}
/// Return a `Reader` for the value. Allows using a `Buf` as an `io::Read`
fn reader(self) -> Reader<Self> where Self: Sized {
Reader::new(self)
}
}
/// A trait for values that provide sequential write access to bytes.
pub trait MutBuf {
/// Returns the number of bytes that can be written to the MutBuf
fn remaining(&self) -> usize;
/// Advance the internal cursor of the MutBuf
unsafe fn advance(&mut self, cnt: usize);
/// Returns true iff there is any more space for bytes to be written
fn has_remaining(&self) -> bool {
self.remaining() > 0
}
/// Returns a mutable slice starting at the current MutBuf position and of
/// length between 0 and `MutBuf::remaining()`.
///
/// The returned byte slice may represent uninitialized memory.
unsafe fn mut_bytes<'a>(&'a mut self) -> &'a mut [u8];
fn copy_from<S: Source>(&mut self, src: S) -> usize
where Self: Sized {
let rem = self.remaining();
src.copy_to(self);
rem - self.remaining()
}
/// Write bytes from the given slice into the `MutBuf` and advance the
/// cursor by the number of bytes written.
/// Returns the number of bytes written.
///
/// ```
/// use bytes::MutBuf;
/// use std::io::Cursor;
///
/// let mut dst = [0; 6];
///
/// {
/// let mut buf = Cursor::new(&mut dst);
/// buf.write_slice(b"hello");
///
/// assert_eq!(1, buf.remaining());
/// }
///
/// assert_eq!(b"hello\0", &dst);
/// ```
fn write_slice(&mut self, src: &[u8]) {
let mut off = 0;
assert!(self.remaining() >= src.len(), "buffer overflow");
while off < src.len() {
let cnt;
unsafe {
let dst = self.mut_bytes();
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(cnt); }
}
}
fn write_str(&mut self, src: &str) {
self.write_slice(src.as_bytes());
}
/// Writes an unsigned 8 bit integer to the MutBuf.
fn write_u8(&mut self, n: u8) {
self.write_slice(&[n])
}
/// Writes a signed 8 bit integer to the MutBuf.
fn write_i8(&mut self, n: i8) {
self.write_slice(&[n as u8])
}
/// Writes an unsigned 16 bit integer to the MutBuf.
fn write_u16<T: ByteOrder>(&mut self, n: u16) {
let mut buf = [0; 2];
T::write_u16(&mut buf, n);
self.write_slice(&buf)
}
/// Writes a signed 16 bit integer to the MutBuf.
fn write_i16<T: ByteOrder>(&mut self, n: i16) {
let mut buf = [0; 2];
T::write_i16(&mut buf, n);
self.write_slice(&buf)
}
/// Writes an unsigned 32 bit integer to the MutBuf.
fn write_u32<T: ByteOrder>(&mut self, n: u32) {
let mut buf = [0; 4];
T::write_u32(&mut buf, n);
self.write_slice(&buf)
}
/// Writes a signed 32 bit integer to the MutBuf.
fn write_i32<T: ByteOrder>(&mut self, n: i32) {
let mut buf = [0; 4];
T::write_i32(&mut buf, n);
self.write_slice(&buf)
}
/// Writes an unsigned 64 bit integer to the MutBuf.
fn write_u64<T: ByteOrder>(&mut self, n: u64) {
let mut buf = [0; 8];
T::write_u64(&mut buf, n);
self.write_slice(&buf)
}
/// Writes a signed 64 bit integer to the MutBuf.
fn write_i64<T: ByteOrder>(&mut self, n: i64) {
let mut buf = [0; 8];
T::write_i64(&mut buf, n);
self.write_slice(&buf)
}
/// Writes an unsigned n-bytes integer to the MutBuf.
///
/// If the given integer is not representable in the given number of bytes,
/// this method panics. If `nbytes > 8`, this method panics.
fn write_uint<T: ByteOrder>(&mut self, n: u64, nbytes: usize) {
let mut buf = [0; 8];
T::write_uint(&mut buf, n, nbytes);
self.write_slice(&buf[0..nbytes])
}
/// Writes a signed n-bytes integer to the MutBuf.
///
/// If the given integer is not representable in the given number of bytes,
/// this method panics. If `nbytes > 8`, this method panics.
fn write_int<T: ByteOrder>(&mut self, n: i64, nbytes: usize) {
let mut buf = [0; 8];
T::write_int(&mut buf, n, nbytes);
self.write_slice(&buf[0..nbytes])
}
/// Writes a IEEE754 single-precision (4 bytes) floating point number to
/// the MutBuf.
fn write_f32<T: ByteOrder>(&mut self, n: f32) {
let mut buf = [0; 4];
T::write_f32(&mut buf, n);
self.write_slice(&buf)
}
/// Writes a IEEE754 double-precision (8 bytes) floating point number to
/// the MutBuf.
fn write_f64<T: ByteOrder>(&mut self, n: f64) {
let mut buf = [0; 8];
T::write_f64(&mut buf, n);
self.write_slice(&buf)
}
/// Creates a "by reference" adaptor for this instance of MutBuf
fn by_ref(&mut self) -> &mut Self where Self: Sized {
self
}
/// Create an adapter which will limit at most `limit` bytes from it.
fn take(self, limit: usize) -> Take<Self> where Self: Sized {
Take::new(self, limit)
}
/// Return a `Write` for the value. Allows using a `MutBuf` as an
/// `io::Write`
fn writer(self) -> Writer<Self> where Self: Sized {
Writer::new(self)
}
}
/*
*
* ===== Sink / Source =====
*
*/
/// A value that writes bytes from itself into a `MutBuf`.
pub trait Source {
fn copy_to<B: MutBuf>(self, buf: &mut B);
}
impl<'a> Source for &'a [u8] {
fn copy_to<B: MutBuf>(self, buf: &mut B) {
buf.write_slice(self);
}
}
impl Source for u8 {
fn copy_to<B: MutBuf>(self, buf: &mut B) {
let src = [self];
buf.write_slice(&src);
}
}
impl Source for Bytes {
fn copy_to<B: MutBuf>(self, buf: &mut B) {
Source::copy_to(&self, buf);
}
}
impl<'a> Source for &'a Bytes {
fn copy_to<B: MutBuf>(self, buf: &mut B) {
Source::copy_to(self.buf(), buf);
}
}
impl<T: Buf> Source for T {
fn copy_to<B: MutBuf>(mut self, buf: &mut B) {
while self.has_remaining() && buf.has_remaining() {
let l;
unsafe {
let s = self.bytes();
let d = buf.mut_bytes();
l = cmp::min(s.len(), d.len());
ptr::copy_nonoverlapping(
s.as_ptr(),
d.as_mut_ptr(),
l);
}
self.advance(l);
unsafe { buf.advance(l); }
}
}
}
pub trait Sink {
fn copy_from<B: Buf>(self, buf: &mut B);
}
impl<'a> Sink for &'a mut [u8] {
fn copy_from<B: Buf>(self, buf: &mut B) {
buf.read_slice(self);
}
}
impl<'a> Sink for &'a mut Vec<u8> {
fn copy_from<B: Buf>(self, buf: &mut B) {
use std::slice;
self.clear();
let rem = buf.remaining();
// Ensure that the vec is big enough
if rem > self.capacity() {
// current length is 0, so reserve completely
self.reserve(rem);
}
debug_assert!(rem <= self.capacity());
unsafe {
{
let dst = &mut self[..];
buf.read_slice(slice::from_raw_parts_mut(dst.as_mut_ptr(), rem));
}
self.set_len(rem);
}
}
}
/*
*
* ===== Read / Write =====
*
*/
/// Adapts a `Buf` to the `io::Read` trait
pub struct Reader<B> {
buf: B,
}
impl<B: Buf> Reader<B> {
/// Return a `Reader` for the given `buf`
pub fn new(buf: B) -> Reader<B> {
Reader { buf: buf }
}
/// Gets a reference to the underlying buf.
pub fn get_ref(&self) -> &B {
&self.buf
}
/// Gets a mutable reference to the underlying buf.
pub fn get_mut(&mut self) -> &mut B {
&mut self.buf
}
/// Unwraps this `Reader`, returning the underlying `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(&mut self.buf, &mut dst[0..len]);
Ok(len)
}
}
/// Buffer related extension for `io::Read`
pub trait ReadExt {
fn read_buf<B: MutBuf>(&mut self, buf: &mut B) -> io::Result<usize>;
}
impl<T: io::Read> ReadExt for T {
fn read_buf<B: MutBuf>(&mut self, buf: &mut B) -> io::Result<usize> {
if !buf.has_remaining() {
return Ok(0);
}
unsafe {
let i = try!(self.read(buf.mut_bytes()));
buf.advance(i);
Ok(i)
}
}
}
/// Adapts a `MutBuf` to the `io::Write` trait
pub struct Writer<B> {
buf: B,
}
impl<B: MutBuf> Writer<B> {
/// Return a `Writer` for teh given `buf`
pub fn new(buf: B) -> Writer<B> {
Writer { buf: buf }
}
/// Gets a reference to the underlying buf.
pub fn get_ref(&self) -> &B {
&self.buf
}
/// Gets a mutable reference to the underlying buf.
pub fn get_mut(&mut self) -> &mut B {
&mut self.buf
}
/// Unwraps this `Writer`, returning the underlying `MutBuf`
pub fn into_inner(self) -> B {
self.buf
}
}
impl<B: MutBuf + Sized> io::Write for Writer<B> {
fn write(&mut self, src: &[u8]) -> io::Result<usize> {
let n = cmp::min(self.buf.remaining(), src.len());
self.buf.copy_from(&src[0..n]);
Ok(n)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
/// Buffer related extension for `io::Write`
pub trait WriteExt {
fn write_buf<B: Buf>(&mut self, buf: &mut B) -> io::Result<usize>;
}
impl<T: io::Write> WriteExt for T {
fn write_buf<B: Buf>(&mut self, buf: &mut B) -> io::Result<usize> {
if !buf.has_remaining() {
return Ok(0);
}
let i = try!(self.write(buf.bytes()));
buf.advance(i);
Ok(i)
}
}
/*
*
* ===== Buf impls =====
*
*/
impl<T: AsRef<[u8]>> Buf for io::Cursor<T> {
fn remaining(&self) -> usize {
self.get_ref().as_ref().len() - self.position() 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]>> MutBuf for io::Cursor<T> {
fn remaining(&self) -> usize {
self.get_ref().as_ref().len() - self.position() as usize
}
/// Advance the internal cursor of the MutBuf
unsafe fn advance(&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);
}
/// Returns a mutable slice starting at the current MutBuf position and of
/// length between 0 and `MutBuf::remaining()`.
///
/// The returned byte slice may represent uninitialized memory.
unsafe fn mut_bytes<'a>(&'a mut self) -> &'a mut [u8] {
let pos = self.position() as usize;
&mut (self.get_mut().as_mut())[pos..]
}
}
impl MutBuf for Vec<u8> {
fn remaining(&self) -> usize {
usize::MAX - self.len()
}
unsafe fn advance(&mut self, cnt: usize) {
let len = self.len() + cnt;
if len > self.capacity() {
// Reserve additional
// TODO: Should this case panic?
let cap = self.capacity();
self.reserve(cap - len);
}
self.set_len(len);
}
unsafe fn mut_bytes(&mut self) -> &mut [u8] {
use std::slice;
if self.capacity() == self.len() {
self.reserve(64); // Grow the vec
}
let cap = self.capacity();
let len = self.len();
let ptr = self.as_mut_ptr();
&mut slice::from_raw_parts_mut(ptr, cap)[len..]
}
}
/*
*
* ===== fmt impls =====
*
*/
pub struct Fmt<'a, B: 'a>(pub &'a mut B);
impl<'a, B: MutBuf> fmt::Write for Fmt<'a, B> {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.0.write_str(s);
Ok(())
}
fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result {
fmt::write(self, args)
}
}
-187
View File
@@ -1,187 +0,0 @@
use {alloc, Buf, MutBuf};
use std::{cmp, fmt};
enum Mark {
NoMark,
At { pos: usize, len: usize },
}
/// Buf backed by a continous chunk of memory. Maintains a read cursor and a
/// write cursor. When reads and writes reach the end of the allocated buffer,
/// wraps around to the start.
///
/// This type is suited for use cases where reads and writes are intermixed.
pub struct RingBuf {
ptr: alloc::MemRef, // Pointer to the memory
cap: usize, // Capacity of the buffer
pos: usize, // Offset of read cursor
len: usize, // Number of bytes to read
mark: Mark, // Marked read position
}
// TODO: There are most likely many optimizations that can be made
impl RingBuf {
/// Allocates a new `RingBuf` with the specified capacity.
pub fn with_capacity(mut capacity: usize) -> RingBuf {
// Round to the next power of 2 for better alignment
capacity = capacity.next_power_of_two();
unsafe {
let mem = alloc::heap(capacity as usize);
RingBuf {
ptr: mem,
cap: capacity,
pos: 0,
len: 0,
mark: Mark::NoMark,
}
}
}
/// Returns `true` if the buf cannot accept any further writes.
pub fn is_full(&self) -> bool {
self.cap == self.len
}
/// Returns `true` if the buf cannot accept any further reads.
pub fn is_empty(&self) -> bool {
self.len == 0
}
/// Returns the number of bytes that the buf can hold.
pub fn capacity(&self) -> usize {
self.cap
}
/// Marks the current read location.
///
/// Together with `reset`, this can be used to read from a section of the
/// buffer multiple times. The mark will be cleared if it is overwritten
/// during a write.
pub fn mark(&mut self) {
self.mark = Mark::At { pos: self.pos, len: self.len };
}
/// Resets the read position to the previously marked position.
///
/// Together with `mark`, this can be used to read from a section of the
/// buffer multiple times.
///
/// # Panics
///
/// This method will panic if no mark has been set,
pub fn reset(&mut self){
match self.mark {
Mark::NoMark => panic!("no mark set"),
Mark::At {pos, len} => {
self.pos = pos;
self.len = len;
self.mark = Mark::NoMark;
}
}
}
/// Resets all internal state to the initial state.
pub fn clear(&mut self) {
self.pos = 0;
self.len = 0;
self.mark = Mark::NoMark;
}
/// Returns the number of bytes remaining to read.
fn read_remaining(&self) -> usize {
self.len
}
/// Returns the remaining write capacity until which the buf becomes full.
fn write_remaining(&self) -> usize {
self.cap - self.len
}
fn advance_reader(&mut self, mut cnt: usize) {
if self.cap == 0 {
return;
}
cnt = cmp::min(cnt, self.read_remaining());
self.pos += cnt;
self.pos %= self.cap;
self.len -= cnt;
}
fn advance_writer(&mut self, mut cnt: usize) {
cnt = cmp::min(cnt, self.write_remaining());
self.len += cnt;
// Adjust the mark to account for bytes written.
if let Mark::At { ref mut len, .. } = self.mark {
*len += cnt;
}
// Clear the mark if we've written past it.
if let Mark::At { len, .. } = self.mark {
if len > self.cap {
self.mark = Mark::NoMark;
}
}
}
}
impl fmt::Debug for RingBuf {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "RingBuf[.. {}]", self.len)
}
}
impl Buf for RingBuf {
fn remaining(&self) -> usize {
self.read_remaining()
}
fn bytes(&self) -> &[u8] {
let mut to = self.pos + self.len;
if to > self.cap {
to = self.cap
}
unsafe { &self.ptr.bytes()[self.pos .. to] }
}
fn advance(&mut self, cnt: usize) {
self.advance_reader(cnt)
}
}
impl MutBuf for RingBuf {
fn remaining(&self) -> usize {
self.write_remaining()
}
unsafe fn advance(&mut self, cnt: usize) {
self.advance_writer(cnt)
}
unsafe fn mut_bytes(&mut self) -> &mut [u8] {
if self.cap == 0 {
return self.ptr.mut_bytes();
}
let mut from;
let mut to;
from = self.pos + self.len;
from %= self.cap;
to = from + <Self as MutBuf>::remaining(&self);
if to >= self.cap {
to = self.cap;
}
&mut self.ptr.mut_bytes()[from..to]
}
}
unsafe impl Send for RingBuf { }
-69
View File
@@ -1,69 +0,0 @@
use buf::{Buf, MutBuf};
use std::{cmp};
#[derive(Debug)]
pub struct Take<T> {
inner: T,
limit: usize,
}
impl<T> Take<T> {
pub fn new(inner: T, limit: usize) -> Take<T> {
Take {
inner: inner,
limit: limit,
}
}
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<'a>(&'a self) -> &'a [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);
}
}
impl<T: MutBuf> MutBuf for Take<T> {
fn remaining(&self) -> usize {
cmp::min(self.inner.remaining(), self.limit)
}
unsafe fn mut_bytes<'a>(&'a mut self) -> &'a mut [u8] {
&mut self.inner.mut_bytes()[..self.limit]
}
unsafe fn advance(&mut self, cnt: usize) {
let cnt = cmp::min(cnt, self.limit);
self.limit -= cnt;
self.inner.advance(cnt);
}
}