mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-16 00:00:15 +02:00
Rename & refactor ByteBuf -> SliceBuf
This commit is contained in:
+10
-1
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -1,6 +1,6 @@
|
||||
pub mod append;
|
||||
pub mod block;
|
||||
pub mod byte;
|
||||
pub mod slice_buf;
|
||||
pub mod ring;
|
||||
pub mod take;
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user