mirror of
https://github.com/openharmony/third_party_rust_bytes.git
synced 2026-07-20 20:06:46 -04:00
Polish API surface
This commit is contained in:
+51
-48
@@ -2,9 +2,30 @@ use {Bytes};
|
||||
use byteorder::ByteOrder;
|
||||
use std::{cmp, io, ptr, usize};
|
||||
|
||||
/// A trait for values that provide sequential read access to bytes.
|
||||
/// Read bytes from a buffer.
|
||||
///
|
||||
/// A buffer stores bytes in memory such that read access is infallible. The
|
||||
/// underlying storage may or may not be in contiguous memory. A `Buf` value is
|
||||
/// a cursor into the buffer. Reading from `Buf` advances the cursor position.
|
||||
///
|
||||
/// The simplest `Buf` is a `Cursor` wrapping a `[u8]`.
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"hello world");
|
||||
///
|
||||
/// assert_eq!(b'h', buf.get_u8());
|
||||
/// assert_eq!(b'e', buf.get_u8());
|
||||
/// assert_eq!(b'l', buf.get_u8());
|
||||
///
|
||||
/// let mut rest = vec![];
|
||||
/// buf.copy_to(&mut rest);
|
||||
///
|
||||
/// assert_eq!(&rest[..], b"lo world");
|
||||
/// ```
|
||||
pub trait Buf {
|
||||
|
||||
/// Returns the number of bytes that can be accessed from the Buf
|
||||
fn remaining(&self) -> usize;
|
||||
|
||||
@@ -70,16 +91,6 @@ pub trait Buf {
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets 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
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets an unsigned 8 bit integer from the `Buf`.
|
||||
fn get_u8(&mut self) -> u8 {
|
||||
let mut buf = [0; 1];
|
||||
@@ -203,7 +214,7 @@ pub trait BufMut {
|
||||
///
|
||||
/// Panics if `self` does not have enough capacity to copy all the data
|
||||
/// from `src`
|
||||
fn copy_from<S: Source>(&mut self, src: S) where Self: Sized {
|
||||
fn put<S: Source>(&mut self, src: S) where Self: Sized {
|
||||
src.source(self);
|
||||
}
|
||||
|
||||
@@ -219,14 +230,14 @@ pub trait BufMut {
|
||||
///
|
||||
/// {
|
||||
/// let mut buf = Cursor::new(&mut dst);
|
||||
/// buf.copy_from_slice(b"hello");
|
||||
/// buf.put_slice(b"hello");
|
||||
///
|
||||
/// assert_eq!(1, buf.remaining_mut());
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(b"hello\0", &dst);
|
||||
/// ```
|
||||
fn copy_from_slice(&mut self, src: &[u8]) {
|
||||
fn put_slice(&mut self, src: &[u8]) {
|
||||
let mut off = 0;
|
||||
|
||||
assert!(self.remaining_mut() >= src.len(), "buffer overflow");
|
||||
@@ -251,66 +262,46 @@ pub trait BufMut {
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes the given string into self.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// The function panics if `self` does not have enough remaining capacity
|
||||
/// to write the full string.
|
||||
fn put_str(&mut self, src: &str) {
|
||||
self.copy_from_slice(src.as_bytes());
|
||||
}
|
||||
|
||||
/// Writes an unsigned 8 bit integer to the BufMut.
|
||||
fn put_u8(&mut self, n: u8) {
|
||||
self.copy_from_slice(&[n])
|
||||
}
|
||||
|
||||
/// Writes a signed 8 bit integer to the BufMut.
|
||||
fn put_i8(&mut self, n: i8) {
|
||||
self.copy_from_slice(&[n as u8])
|
||||
}
|
||||
|
||||
/// Writes an unsigned 16 bit integer to the BufMut.
|
||||
fn put_u16<T: ByteOrder>(&mut self, n: u16) {
|
||||
let mut buf = [0; 2];
|
||||
T::write_u16(&mut buf, n);
|
||||
self.copy_from_slice(&buf)
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 16 bit integer to the BufMut.
|
||||
fn put_i16<T: ByteOrder>(&mut self, n: i16) {
|
||||
let mut buf = [0; 2];
|
||||
T::write_i16(&mut buf, n);
|
||||
self.copy_from_slice(&buf)
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an unsigned 32 bit integer to the BufMut.
|
||||
fn put_u32<T: ByteOrder>(&mut self, n: u32) {
|
||||
let mut buf = [0; 4];
|
||||
T::write_u32(&mut buf, n);
|
||||
self.copy_from_slice(&buf)
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 32 bit integer to the BufMut.
|
||||
fn put_i32<T: ByteOrder>(&mut self, n: i32) {
|
||||
let mut buf = [0; 4];
|
||||
T::write_i32(&mut buf, n);
|
||||
self.copy_from_slice(&buf)
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an unsigned 64 bit integer to the BufMut.
|
||||
fn put_u64<T: ByteOrder>(&mut self, n: u64) {
|
||||
let mut buf = [0; 8];
|
||||
T::write_u64(&mut buf, n);
|
||||
self.copy_from_slice(&buf)
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 64 bit integer to the BufMut.
|
||||
fn put_i64<T: ByteOrder>(&mut self, n: i64) {
|
||||
let mut buf = [0; 8];
|
||||
T::write_i64(&mut buf, n);
|
||||
self.copy_from_slice(&buf)
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an unsigned n-bytes integer to the BufMut.
|
||||
@@ -320,7 +311,7 @@ pub trait BufMut {
|
||||
fn put_uint<T: ByteOrder>(&mut self, n: u64, nbytes: usize) {
|
||||
let mut buf = [0; 8];
|
||||
T::write_uint(&mut buf, n, nbytes);
|
||||
self.copy_from_slice(&buf[0..nbytes])
|
||||
self.put_slice(&buf[0..nbytes])
|
||||
}
|
||||
|
||||
/// Writes a signed n-bytes integer to the BufMut.
|
||||
@@ -330,7 +321,7 @@ pub trait BufMut {
|
||||
fn put_int<T: ByteOrder>(&mut self, n: i64, nbytes: usize) {
|
||||
let mut buf = [0; 8];
|
||||
T::write_int(&mut buf, n, nbytes);
|
||||
self.copy_from_slice(&buf[0..nbytes])
|
||||
self.put_slice(&buf[0..nbytes])
|
||||
}
|
||||
|
||||
/// Writes a IEEE754 single-precision (4 bytes) floating point number to
|
||||
@@ -338,7 +329,7 @@ pub trait BufMut {
|
||||
fn put_f32<T: ByteOrder>(&mut self, n: f32) {
|
||||
let mut buf = [0; 4];
|
||||
T::write_f32(&mut buf, n);
|
||||
self.copy_from_slice(&buf)
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a IEEE754 double-precision (8 bytes) floating point number to
|
||||
@@ -346,7 +337,7 @@ pub trait BufMut {
|
||||
fn put_f64<T: ByteOrder>(&mut self, n: f64) {
|
||||
let mut buf = [0; 8];
|
||||
T::write_f64(&mut buf, n);
|
||||
self.copy_from_slice(&buf)
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Creates a "by reference" adaptor for this instance of BufMut
|
||||
@@ -446,14 +437,26 @@ pub trait Source {
|
||||
|
||||
impl<'a> Source for &'a [u8] {
|
||||
fn source<B: BufMut>(self, buf: &mut B) {
|
||||
buf.copy_from_slice(self);
|
||||
buf.put_slice(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Source for &'a str {
|
||||
fn source<B: BufMut>(self, buf: &mut B) {
|
||||
buf.put_slice(self.as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
impl Source for u8 {
|
||||
fn source<B: BufMut>(self, buf: &mut B) {
|
||||
let src = [self];
|
||||
buf.copy_from_slice(&src);
|
||||
buf.put_slice(&src);
|
||||
}
|
||||
}
|
||||
|
||||
impl Source for i8 {
|
||||
fn source<B: BufMut>(self, buf: &mut B) {
|
||||
buf.put_slice(&[self as u8])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -584,7 +587,7 @@ 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.copy_from(&src[0..n]);
|
||||
self.buf.put(&src[0..n]);
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
-182
@@ -1,182 +0,0 @@
|
||||
use {Buf, BufMut};
|
||||
use std::{cmp, fmt};
|
||||
|
||||
/// A buffer adapter which limits the bytes read from an underlying value.
|
||||
#[derive(Debug)]
|
||||
pub struct Take<T> {
|
||||
inner: T,
|
||||
limit: usize,
|
||||
}
|
||||
|
||||
/// A buffer adapter which limits the bytes written from an underlying value.
|
||||
#[derive(Debug)]
|
||||
pub struct TakeMut<T> {
|
||||
inner: T,
|
||||
limit: usize,
|
||||
}
|
||||
|
||||
pub fn new<T>(inner: T, limit: usize) -> Take<T> {
|
||||
Take {
|
||||
inner: inner,
|
||||
limit: limit,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_mut<T>(inner: T, limit: usize) -> TakeMut<T> {
|
||||
TakeMut {
|
||||
inner: inner,
|
||||
limit: limit,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* ===== impl Take =====
|
||||
*
|
||||
*/
|
||||
|
||||
impl<T> Take<T> {
|
||||
/// Consumes this `Take`, returning the underlying value.
|
||||
pub fn into_inner(self) -> T {
|
||||
self.inner
|
||||
}
|
||||
|
||||
/// Gets a reference to the underlying value in this `Take`.
|
||||
pub fn get_ref(&self) -> &T {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the underlying value in this `Take`.
|
||||
pub fn get_mut(&mut self) -> &mut T {
|
||||
&mut self.inner
|
||||
}
|
||||
|
||||
/// Returns the maximum number of bytes that are made available from the
|
||||
/// underlying value.
|
||||
pub fn limit(&self) -> usize {
|
||||
self.limit
|
||||
}
|
||||
|
||||
/// Sets the maximum number of bytes that are made available from the
|
||||
/// underlying value.
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BufMut> BufMut for Take<T> {
|
||||
fn remaining_mut(&self) -> usize {
|
||||
self.inner.remaining_mut()
|
||||
}
|
||||
|
||||
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
|
||||
self.inner.bytes_mut()
|
||||
}
|
||||
|
||||
unsafe fn advance_mut(&mut self, cnt: usize) {
|
||||
self.inner.advance_mut(cnt)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BufMut> fmt::Write for Take<T> {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
BufMut::put_str(self, s);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result {
|
||||
fmt::write(self, args)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* ===== impl TakeMut =====
|
||||
*
|
||||
*/
|
||||
|
||||
impl<T> TakeMut<T> {
|
||||
/// Consumes this `TakeMut`, returning the underlying value.
|
||||
pub fn into_inner(self) -> T {
|
||||
self.inner
|
||||
}
|
||||
|
||||
/// Gets a reference to the underlying value in this `TakeMut`.
|
||||
pub fn get_ref(&self) -> &T {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the underlying value in this `TakeMut`.
|
||||
pub fn get_mut(&mut self) -> &mut T {
|
||||
&mut self.inner
|
||||
}
|
||||
|
||||
/// Returns the maximum number of bytes that are made available from the
|
||||
/// underlying value.
|
||||
pub fn limit(&self) -> usize {
|
||||
self.limit
|
||||
}
|
||||
|
||||
/// Sets the maximum number of bytes that are made available from the
|
||||
/// underlying value.
|
||||
pub fn set_limit(&mut self, lim: usize) {
|
||||
self.limit = lim
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Buf> Buf for TakeMut<T> {
|
||||
fn remaining(&self) -> usize {
|
||||
self.inner.remaining()
|
||||
}
|
||||
|
||||
fn bytes(&self) -> &[u8] {
|
||||
self.inner.bytes()
|
||||
}
|
||||
|
||||
fn advance(&mut self, cnt: usize) {
|
||||
self.inner.advance(cnt)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BufMut> BufMut for TakeMut<T> {
|
||||
fn remaining_mut(&self) -> usize {
|
||||
cmp::min(self.inner.remaining_mut(), self.limit)
|
||||
}
|
||||
|
||||
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
|
||||
&mut self.inner.bytes_mut()[..self.limit]
|
||||
}
|
||||
|
||||
unsafe fn advance_mut(&mut self, cnt: usize) {
|
||||
let cnt = cmp::min(cnt, self.limit);
|
||||
self.limit -= cnt;
|
||||
self.inner.advance_mut(cnt);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BufMut> fmt::Write for TakeMut<T> {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
BufMut::put_str(self, s);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result {
|
||||
fmt::write(self, args)
|
||||
}
|
||||
}
|
||||
+287
-8
@@ -114,9 +114,9 @@ pub struct Bytes {
|
||||
///
|
||||
/// let mut buf = BytesMut::with_capacity(64);
|
||||
///
|
||||
/// buf.put_u8(b'h');
|
||||
/// buf.put_u8(b'e');
|
||||
/// buf.put_str("llo");
|
||||
/// buf.put(b'h');
|
||||
/// buf.put(b'e');
|
||||
/// buf.put("llo");
|
||||
///
|
||||
/// assert_eq!(&buf[..], b"hello");
|
||||
///
|
||||
@@ -489,12 +489,24 @@ impl From<Vec<u8>> for Bytes {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Bytes {
|
||||
fn from(src: String) -> Bytes {
|
||||
BytesMut::from(src).freeze()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a [u8]> for Bytes {
|
||||
fn from(src: &'a [u8]) -> Bytes {
|
||||
BytesMut::from(src).freeze()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for Bytes {
|
||||
fn from(src: &'a str) -> Bytes {
|
||||
BytesMut::from(src).freeze()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Bytes {
|
||||
fn eq(&self, other: &Bytes) -> bool {
|
||||
self.inner.as_ref() == other.inner.as_ref()
|
||||
@@ -538,7 +550,7 @@ impl BytesMut {
|
||||
/// // `bytes` contains no data, even though there is capacity
|
||||
/// assert_eq!(bytes.len(), 0);
|
||||
///
|
||||
/// bytes.copy_from_slice(b"hello world");
|
||||
/// bytes.put(&b"hello world"[..]);
|
||||
///
|
||||
/// assert_eq!(&bytes[..], b"hello world");
|
||||
/// ```
|
||||
@@ -618,7 +630,7 @@ impl BytesMut {
|
||||
/// use std::thread;
|
||||
///
|
||||
/// let mut b = BytesMut::with_capacity(64);
|
||||
/// b.put_str("hello world");
|
||||
/// b.put("hello world");
|
||||
/// let b1 = b.freeze();
|
||||
/// let b2 = b1.clone();
|
||||
///
|
||||
@@ -785,6 +797,63 @@ impl BytesMut {
|
||||
pub unsafe fn set_len(&mut self, len: usize) {
|
||||
self.inner.set_len(len)
|
||||
}
|
||||
|
||||
/// Reserves capacity for at least `additional` more bytes to be inserted
|
||||
/// into the given `BytesMut`.
|
||||
///
|
||||
/// More than `additional` bytes may be reserved in order to avoid frequent
|
||||
/// reallocations. A call to `reserve` may result in an allocation.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BytesMut;
|
||||
///
|
||||
/// let mut b = BytesMut::from(&b"hello"[..]);
|
||||
/// b.reserve(64);
|
||||
/// assert!(b.capacity() >= 69);
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the new capacity overflows usize.
|
||||
pub fn reserve(&mut self, additional: usize) {
|
||||
self.inner.reserve(additional)
|
||||
}
|
||||
|
||||
/// Attempts to reclaim ownership of the full buffer.
|
||||
///
|
||||
/// Returns `true` if the reclaim is successful.
|
||||
///
|
||||
/// If the `BytesMut` handle is the only outstanding handle pointing to the
|
||||
/// memory slice, the handle's view will be set to the full memory slice,
|
||||
/// enabling reusing buffer space without allocating.
|
||||
///
|
||||
/// Any data in the `BytesMut` handle will be copied to the start of the
|
||||
/// memory region.
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::BytesMut;
|
||||
///
|
||||
/// let mut bytes = BytesMut::from(
|
||||
/// "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
||||
///
|
||||
/// // Create a new handle to the shared memory region
|
||||
/// let a = bytes.drain_to(5);
|
||||
///
|
||||
/// // Attempting to reclaim here will fail due to `a` still being in
|
||||
/// // existence.
|
||||
/// assert!(!bytes.try_reclaim());
|
||||
/// assert_eq!(bytes.capacity(), 51);
|
||||
///
|
||||
/// // Dropping the handle will allow reclaim to succeed.
|
||||
/// drop(a);
|
||||
/// assert!(bytes.try_reclaim());
|
||||
/// assert_eq!(bytes.capacity(), 56);
|
||||
/// ```
|
||||
pub fn try_reclaim(&mut self) -> bool {
|
||||
self.inner.try_reclaim()
|
||||
}
|
||||
}
|
||||
|
||||
impl BufMut for BytesMut {
|
||||
@@ -806,7 +875,7 @@ impl BufMut for BytesMut {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn copy_from_slice(&mut self, src: &[u8]) {
|
||||
fn put_slice(&mut self, src: &[u8]) {
|
||||
assert!(self.remaining_mut() >= src.len());
|
||||
|
||||
let len = src.len();
|
||||
@@ -875,6 +944,12 @@ impl From<Vec<u8>> for BytesMut {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for BytesMut {
|
||||
fn from(src: String) -> BytesMut {
|
||||
BytesMut::from(src.into_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a [u8]> for BytesMut {
|
||||
fn from(src: &'a [u8]) -> BytesMut {
|
||||
if src.len() <= INLINE_CAP {
|
||||
@@ -894,12 +969,18 @@ impl<'a> From<&'a [u8]> for BytesMut {
|
||||
}
|
||||
} else {
|
||||
let mut buf = BytesMut::with_capacity(src.len());
|
||||
buf.copy_from_slice(src.as_ref());
|
||||
buf.put(src.as_ref());
|
||||
buf
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for BytesMut {
|
||||
fn from(src: &'a str) -> BytesMut {
|
||||
BytesMut::from(src.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Bytes> for BytesMut {
|
||||
fn from(src: Bytes) -> BytesMut {
|
||||
src.try_mut()
|
||||
@@ -924,7 +1005,7 @@ impl fmt::Debug for BytesMut {
|
||||
|
||||
impl fmt::Write for BytesMut {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
BufMut::put_str(self, s);
|
||||
BufMut::put(self, s);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1220,6 +1301,150 @@ impl Inner {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn reserve(&mut self, additional: usize) {
|
||||
let len = self.len();
|
||||
let rem = self.capacity() - len;
|
||||
|
||||
if additional <= rem {
|
||||
// Nothing more to do
|
||||
return;
|
||||
}
|
||||
|
||||
match self.kind() {
|
||||
Kind::Vec => {
|
||||
unsafe {
|
||||
let d = &mut *self.data.get();
|
||||
|
||||
// Promote this `Bytes` to an arc, and clone it
|
||||
let mut v = Vec::from_raw_parts(d.ptr, d.len, d.cap);
|
||||
v.reserve(additional);
|
||||
|
||||
// Update the info
|
||||
d.ptr = v.as_mut_ptr();
|
||||
d.len = v.len();
|
||||
d.cap = v.capacity();
|
||||
|
||||
// Drop the vec reference
|
||||
mem::forget(v);
|
||||
}
|
||||
}
|
||||
Kind::Arc => {
|
||||
unsafe {
|
||||
// Compute the new capacity
|
||||
let new_cap = len + additional;
|
||||
|
||||
// Create a new vector to store the data
|
||||
let mut v = Vec::with_capacity(new_cap);
|
||||
|
||||
// Copy the bytes
|
||||
v.extend_from_slice(self.as_ref());
|
||||
|
||||
let d = &mut *self.data.get();
|
||||
|
||||
d.ptr = v.as_mut_ptr();
|
||||
d.len = v.len();
|
||||
d.cap = v.capacity();
|
||||
|
||||
mem::forget(v);
|
||||
|
||||
// Drop the arc reference
|
||||
let _: Arc<UnsafeCell<Vec<u8>>> = mem::transmute(self.arc.get());
|
||||
|
||||
self.arc.set(0);
|
||||
}
|
||||
}
|
||||
Kind::Inline => {
|
||||
let new_cap = len + additional;
|
||||
|
||||
unsafe {
|
||||
if new_cap <= INLINE_CAP {
|
||||
let dst = &mut self.data as *mut _ as *mut u8;
|
||||
let src = self.inline_ptr();
|
||||
|
||||
ptr::copy(src, dst, len);
|
||||
|
||||
let mut a = KIND_INLINE;
|
||||
a |= len << INLINE_LEN_OFFSET;
|
||||
|
||||
self.arc.set(a);
|
||||
} else {
|
||||
let mut v = Vec::with_capacity(new_cap);
|
||||
|
||||
// Copy the bytes
|
||||
v.extend_from_slice(self.as_ref());
|
||||
|
||||
let d = &mut *self.data.get();
|
||||
|
||||
d.ptr = v.as_mut_ptr();
|
||||
d.len = v.len();
|
||||
d.cap = v.capacity();
|
||||
|
||||
mem::forget(v);
|
||||
|
||||
self.arc.set(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Kind::Static => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
/// This must take `&mut self` in order to be able to copy memory in the
|
||||
/// inline case.
|
||||
#[inline]
|
||||
fn try_reclaim(&mut self) -> bool {
|
||||
match self.kind() {
|
||||
Kind::Inline => {
|
||||
if self.inline_start() > 0 {
|
||||
// Shift the data back to the front
|
||||
unsafe {
|
||||
let len = self.inline_len();
|
||||
let dst = &mut self.data as *mut _ as *mut u8;
|
||||
let src = self.inline_ptr();
|
||||
|
||||
ptr::copy(src, dst, len);
|
||||
|
||||
let mut a = KIND_INLINE;
|
||||
a |= len << INLINE_LEN_OFFSET;
|
||||
|
||||
self.arc.set(a);
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
Kind::Arc => {
|
||||
unsafe {
|
||||
let arc: &mut Shared = mem::transmute(&mut self.arc);
|
||||
|
||||
// Check if mut safe
|
||||
if Arc::get_mut(arc).is_none() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let v = &mut *arc.get();
|
||||
let d = &mut *self.data.get();
|
||||
|
||||
let len = v.len();
|
||||
let ptr = v.as_mut_ptr();
|
||||
|
||||
ptr::copy(d.ptr, ptr, len);
|
||||
|
||||
d.ptr = ptr;
|
||||
d.len = len;
|
||||
d.cap = v.capacity();
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
Kind::Vec => {
|
||||
true
|
||||
}
|
||||
Kind::Static => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn kind(&self) -> Kind {
|
||||
let arc = self.arc.get();
|
||||
@@ -1283,6 +1508,12 @@ impl PartialEq<[u8]> for BytesMut {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<str> for BytesMut {
|
||||
fn eq(&self, other: &str) -> bool {
|
||||
&**self == other.as_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<BytesMut> for [u8] {
|
||||
fn eq(&self, other: &BytesMut) -> bool {
|
||||
*other == *self
|
||||
@@ -1295,12 +1526,24 @@ impl PartialEq<Vec<u8>> for BytesMut {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<String> for BytesMut {
|
||||
fn eq(&self, other: &String) -> bool {
|
||||
*self == &other[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<BytesMut> for Vec<u8> {
|
||||
fn eq(&self, other: &BytesMut) -> bool {
|
||||
*other == *self
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<BytesMut> for String {
|
||||
fn eq(&self, other: &BytesMut) -> bool {
|
||||
*other == *self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> PartialEq<&'a T> for BytesMut
|
||||
where BytesMut: PartialEq<T>
|
||||
{
|
||||
@@ -1315,36 +1558,72 @@ impl<'a> PartialEq<BytesMut> for &'a [u8] {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PartialEq<BytesMut> for &'a str {
|
||||
fn eq(&self, other: &BytesMut) -> bool {
|
||||
*other == *self
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<[u8]> for Bytes {
|
||||
fn eq(&self, other: &[u8]) -> bool {
|
||||
self.inner.as_ref() == other
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<str> for Bytes {
|
||||
fn eq(&self, other: &str) -> bool {
|
||||
self.inner.as_ref() == other.as_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Bytes> for [u8] {
|
||||
fn eq(&self, other: &Bytes) -> bool {
|
||||
*other == *self
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Bytes> for str {
|
||||
fn eq(&self, other: &Bytes) -> bool {
|
||||
*other == *self
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Vec<u8>> for Bytes {
|
||||
fn eq(&self, other: &Vec<u8>) -> bool {
|
||||
*self == &other[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<String> for Bytes {
|
||||
fn eq(&self, other: &String) -> bool {
|
||||
*self == &other[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Bytes> for Vec<u8> {
|
||||
fn eq(&self, other: &Bytes) -> bool {
|
||||
*other == *self
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Bytes> for String {
|
||||
fn eq(&self, other: &Bytes) -> bool {
|
||||
*other == *self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PartialEq<Bytes> for &'a [u8] {
|
||||
fn eq(&self, other: &Bytes) -> bool {
|
||||
*other == *self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PartialEq<Bytes> for &'a str {
|
||||
fn eq(&self, other: &Bytes) -> bool {
|
||||
*other == *self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> PartialEq<&'a T> for Bytes
|
||||
where Bytes: PartialEq<T>
|
||||
{
|
||||
|
||||
+63
@@ -1,4 +1,67 @@
|
||||
//! Provides abstractions for working with bytes.
|
||||
//!
|
||||
//! The `bytes` crate provides an efficient byte buffer structure
|
||||
//! ([`Bytes`](struct.Bytes.html)) and traits for working with buffer
|
||||
//! implementations ([`Buf`](trait.Buf.html), [`BufMut`](trait.BufMut.html)).
|
||||
//!
|
||||
//! # `Bytes`
|
||||
//!
|
||||
//! `Bytes` is an efficient container for storing and operating on continguous
|
||||
//! slices of memory. It is intended for use primarily in networking code, but
|
||||
//! could have applications elsewhere as well.
|
||||
//!
|
||||
//! `Bytes` values facilitate zero-copy network programming by allowing multiple
|
||||
//! `Bytes` objects to point to the same underlying memory. This is managed by
|
||||
//! using a reference count to track when the memory is no longer needed and can
|
||||
//! be freed.
|
||||
//!
|
||||
//! See the [struct docs](struct.Bytes.html) for more details.
|
||||
//!
|
||||
//! # `Buf`, `BufMut`
|
||||
//!
|
||||
//! These two traits provide read and write access to buffers. The underlying
|
||||
//! storage may or may not be in contiguous memory. For example, `Bytes` is a
|
||||
//! buffer that guarantees contiguous memory, but a
|
||||
//! [rope](https://en.wikipedia.org/wiki/Rope_(data_structure)) stores the bytes
|
||||
//! in disjoint chunks. `Buf` and `BufMut` maintain cursors tracking the current
|
||||
//! position in the underlying byte storage. When bytes are read or written, the
|
||||
//! cursor is advanced.
|
||||
//!
|
||||
//! ## Relation with `Read` and `Write`
|
||||
//!
|
||||
//! At first glance, it may seem that `Buf` and `BufMut` overlap in
|
||||
//! functionality with `std::io::Ready` and `std::io::Write`. However, they
|
||||
//! serve different purposes. A buffer is the value that is provided as an
|
||||
//! argument to `Read::read` and `Write::write`. `Read` and `Write` may then
|
||||
//! perform a syscall, which has the potential of failing. Operations on `Buf`
|
||||
//! and `BufMut` are infallible.
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
//! ```
|
||||
//! use bytes::{BytesMut, Buf, BufMut};
|
||||
//! use std::io::Cursor;
|
||||
//! use std::thread;
|
||||
//!
|
||||
//! // Allocate a buffer capable of holding 1024 bytes.
|
||||
//! let mut buf = BytesMut::with_capacity(1024);
|
||||
//!
|
||||
//! // Write some data
|
||||
//! buf.put("Hello world");
|
||||
//! buf.put(b'-');
|
||||
//! buf.put("goodbye");
|
||||
//!
|
||||
//! // Freeze the buffer, enabling concurrent access
|
||||
//! let b1 = buf.freeze();
|
||||
//! let b2 = b1.clone();
|
||||
//!
|
||||
//! thread::spawn(move || {
|
||||
//! assert_eq!(&b1[..], b"Hello world-goodbye");
|
||||
//! });
|
||||
//!
|
||||
//! let mut buf = Cursor::new(b2);
|
||||
//! assert_eq!(b'H', buf.get_u8());
|
||||
//! ```
|
||||
|
||||
#![deny(warnings, missing_docs)]
|
||||
|
||||
|
||||
+70
-2
@@ -1,10 +1,16 @@
|
||||
extern crate bytes;
|
||||
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use bytes::{Bytes, BytesMut, BufMut};
|
||||
|
||||
const LONG: &'static [u8] = b"mary had a little lamb, little lamb, little lamb";
|
||||
const SHORT: &'static [u8] = b"hello world";
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
const INLINE_CAP: usize = 8 * 3;
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
const INNER_CAP: usize = 4 * 3;
|
||||
|
||||
fn is_sync<T: Sync>() {}
|
||||
fn is_send<T: Send>() {}
|
||||
|
||||
@@ -193,5 +199,67 @@ fn fns_defined_for_bytes_mut() {
|
||||
|
||||
// Iterator
|
||||
let v: Vec<u8> = bytes.iter().map(|b| *b).collect();
|
||||
assert_eq!(&v[..], &bytes[..]);
|
||||
assert_eq!(&v[..], bytes);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reserve() {
|
||||
// Inline -> Vec
|
||||
let mut bytes = BytesMut::with_capacity(8);
|
||||
bytes.put("hello");
|
||||
bytes.reserve(40);
|
||||
assert_eq!(bytes.capacity(), 45);
|
||||
assert_eq!(bytes, "hello");
|
||||
|
||||
// Inline -> Inline
|
||||
let mut bytes = BytesMut::with_capacity(INLINE_CAP);
|
||||
bytes.put("abcdefghijkl");
|
||||
|
||||
let a = bytes.drain_to(10);
|
||||
bytes.reserve(INLINE_CAP - 3);
|
||||
assert_eq!(INLINE_CAP, bytes.capacity());
|
||||
|
||||
assert_eq!(bytes, "kl");
|
||||
assert_eq!(a, "abcdefghij");
|
||||
|
||||
// Vec -> Vec
|
||||
let mut bytes = BytesMut::from(LONG);
|
||||
bytes.reserve(64);
|
||||
assert_eq!(bytes.capacity(), LONG.len() + 64);
|
||||
|
||||
// Arc -> Vec
|
||||
let mut bytes = BytesMut::from(LONG);
|
||||
let a = bytes.drain_to(30);
|
||||
|
||||
bytes.reserve(128);
|
||||
assert_eq!(bytes.capacity(), bytes.len() + 128);
|
||||
|
||||
drop(a);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_reclaim() {
|
||||
// Inline w/ start at zero
|
||||
let mut bytes = BytesMut::from(&SHORT[..]);
|
||||
assert!(bytes.try_reclaim());
|
||||
assert_eq!(bytes.capacity(), INLINE_CAP);
|
||||
assert_eq!(bytes, SHORT);
|
||||
|
||||
// Inline w/ start not at zero
|
||||
let mut bytes = BytesMut::from(&SHORT[..]);
|
||||
let _ = bytes.drain_to(2);
|
||||
assert_eq!(bytes.capacity(), INLINE_CAP - 2);
|
||||
assert!(bytes.try_reclaim());
|
||||
assert_eq!(bytes.capacity(), INLINE_CAP);
|
||||
assert_eq!(bytes, &SHORT[2..]);
|
||||
|
||||
// Arc
|
||||
let mut bytes = BytesMut::from(&LONG[..]);
|
||||
let a = bytes.drain_to(2);
|
||||
assert!(!bytes.try_reclaim());
|
||||
assert_eq!(bytes.capacity(), LONG.len() - 2);
|
||||
|
||||
drop(a);
|
||||
assert!(bytes.try_reclaim());
|
||||
assert_eq!(bytes.capacity(), LONG.len());
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ fn test_vec_as_mut_buf() {
|
||||
assert!(buf.bytes_mut().len() >= 64);
|
||||
}
|
||||
|
||||
buf.copy_from(&b"zomg"[..]);
|
||||
buf.put(&b"zomg"[..]);
|
||||
|
||||
assert_eq!(&buf, b"zomg");
|
||||
|
||||
@@ -23,7 +23,7 @@ fn test_vec_as_mut_buf() {
|
||||
assert_eq!(buf.capacity(), 64);
|
||||
|
||||
for _ in 0..16 {
|
||||
buf.copy_from(&b"zomg"[..]);
|
||||
buf.put(&b"zomg"[..]);
|
||||
}
|
||||
|
||||
assert_eq!(buf.len(), 68);
|
||||
@@ -32,7 +32,7 @@ fn test_vec_as_mut_buf() {
|
||||
#[test]
|
||||
fn test_put_u8() {
|
||||
let mut buf = Vec::with_capacity(8);
|
||||
buf.put_u8(33);
|
||||
buf.put::<u8>(33);
|
||||
assert_eq!(b"\x21", &buf[..]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user