Rename & refactor ByteBuf -> SliceBuf

This commit is contained in:
Carl Lerche
2016-09-25 22:40:35 -07:00
parent c16ad2bc9d
commit b1dc10e907
19 changed files with 333 additions and 333 deletions
+10 -1
View File
@@ -73,7 +73,7 @@ impl AppendBuf {
assert!(begin <= end && end <= wr, "invalid range");
unsafe { Bytes::from_mem_ref(self.mem.clone(), begin, end - begin) }
Bytes::from_boxed(self.mem.get_ref().clone(), begin as usize, (end - begin) as usize)
}
}
@@ -111,3 +111,12 @@ impl AsRef<[u8]> for AppendBuf {
self.bytes()
}
}
impl From<AppendBuf> for Bytes {
fn from(src: AppendBuf) -> Bytes {
let rd = src.rd.get();
let wr = src.wr;
Bytes::from_boxed(src.mem.get_ref().clone(), rd as usize, (wr - rd) as usize)
}
}
-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(&self) -> &[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(&self) -> &[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(&mut self) -> &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)
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
pub mod append;
pub mod block;
pub mod byte;
pub mod slice_buf;
pub mod ring;
pub mod take;
+154
View File
@@ -0,0 +1,154 @@
//! A buffer backed by a contiguous region of memory.
use {Buf, MutBuf};
use imp::alloc;
use std::fmt;
/*
*
* ===== SliceBuf =====
*
*/
/// 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 SliceBuf<T = Box<[u8]>> {
// Contiguous memory
mem: T,
// Current read position
rd: usize,
// Current write position
wr: usize,
}
impl SliceBuf {
/// Constructs a new, empty `SliceBuf` with the specified capacity
///
/// The `SliceBuf` will be backed by a `Box<[u8]>`.
pub fn with_capacity(capacity: usize) -> SliceBuf {
let mem = unsafe { alloc::with_capacity(capacity) };
SliceBuf::new(mem)
}
/// Create a new `SliceBuf` and copy the contents of the given slice into
/// it.
pub fn from_slice<T: AsRef<[u8]>>(bytes: &T) -> SliceBuf {
let mut buf = SliceBuf::with_capacity(bytes.as_ref().len());
buf.write_slice(bytes.as_ref());
buf
}
}
impl<T: AsRef<[u8]>> SliceBuf<T> {
/// Creates a new `SliceBuf` wrapping the provided slice
pub fn new(mem: T) -> SliceBuf<T> {
SliceBuf {
mem: mem,
rd: 0,
wr: 0,
}
}
/// Return the number of bytes the buffer can contain
pub fn capacity(&self) -> usize {
self.mem.as_ref().len()
}
/// Return the read cursor position
pub fn position(&self) -> usize {
self.rd
}
/// Set the read cursor position
pub fn set_position(&mut self, position: usize) {
assert!(position <= self.wr, "position out of bounds");
self.rd = position
}
/// Return the number of buffered bytes
pub fn len(&self) -> usize {
self.wr
}
/// Returns `true` if the buffer contains no unread bytes
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/// Clears the buffer, removing any written data
pub fn clear(&mut self) {
self.rd = 0;
self.wr = 0;
}
/// Return the number of bytes left to read
pub fn remaining_read(&self) -> usize {
self.wr - self.rd
}
/// Return the remaining write capacity
pub fn remaining_write(&self) -> usize {
self.capacity() - self.wr
}
}
impl<T> Buf for SliceBuf<T>
where T: AsRef<[u8]>,
{
fn remaining(&self) -> usize {
self.remaining_read()
}
fn bytes(&self) -> &[u8] {
&self.mem.as_ref()[self.rd..self.wr]
}
fn advance(&mut self, cnt: usize) {
assert!(cnt <= self.remaining(), "buffer overflow");
self.rd += cnt;
}
fn read_slice(&mut self, dst: &mut [u8]) {
assert!(self.remaining() >= dst.len());
let len = dst.len();
dst.copy_from_slice(&self.mem.as_ref()[self.rd..self.rd+len]);
self.rd += len;
}
}
impl<T> MutBuf for SliceBuf<T>
where T: AsRef<[u8]> + AsMut<[u8]>,
{
fn remaining(&self) -> usize {
self.remaining_write()
}
unsafe fn advance(&mut self, cnt: usize) {
assert!(cnt <= self.remaining_write());
self.wr += cnt;
}
unsafe fn mut_bytes(&mut self) -> &mut [u8] {
&mut self.mem.as_mut()[self.wr..]
}
fn write_slice(&mut self, src: &[u8]) {
let wr = self.wr;
self.mem.as_mut()[wr..wr+src.len()]
.copy_from_slice(src);
self.wr += src.len();
}
}
impl<T> fmt::Debug for SliceBuf<T>
where T: AsRef<[u8]>,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
self.bytes().fmt(fmt)
}
}