diff --git a/src/buf/byte.rs b/src/buf/byte.rs deleted file mode 100644 index 920299f34a79727fb21bebc28e6f5b9b3232afc5..0000000000000000000000000000000000000000 --- a/src/buf/byte.rs +++ /dev/null @@ -1,238 +0,0 @@ -use {Buf, BufMut, Bytes, BytesMut}; - -use std::{cmp, fmt}; - -/// A buffer backed by `BytesMut` -pub struct ByteBuf { - mem: BytesMut, - rd: usize, -} - -impl ByteBuf { - /// Create a new `ByteBuf` with 8kb capacity - #[inline] - pub fn new() -> ByteBuf { - ByteBuf::with_capacity(8 * 1024) - } - - /// Create a new `ByteBuf` with `cap` capacity - #[inline] - pub fn with_capacity(cap: usize) -> ByteBuf { - ByteBuf { - mem: BytesMut::with_capacity(cap), - rd: 0, - } - } - - /// Create a new `ByteBuf` backed by `bytes` - #[inline] - pub fn from_bytes(bytes: BytesMut) -> ByteBuf { - ByteBuf { - mem: bytes, - rd: 0, - } - } - - /// Create a new `ByteBuf` containing the given slice - #[inline] - pub fn from_slice<T: AsRef<[u8]>>(bytes: T) -> ByteBuf { - let mut buf = ByteBuf::with_capacity(bytes.as_ref().len()); - buf.copy_from_slice(bytes.as_ref()); - buf - } - - /// Return the number of bytes the buffer can contain - pub fn capacity(&self) -> usize { - self.mem.capacity() - } - - /// 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.mem.len(), "position out of bounds"); - self.rd = position - } - - /// Return the number of buffered bytes - pub fn len(&self) -> usize { - self.mem.len() - } - - /// Returns `true` if the buffer contains no unread bytes - pub fn is_empty(&self) -> bool { - self.mem.is_empty() - } - - /// Clears the buffer, removing any written data - pub fn clear(&mut self) { - self.rd = 0; - unsafe { self.mem.set_len(0); } - } - - /// Splits the buffer into two at the current read index. - pub fn drain_read(&mut self) -> BytesMut { - let drained = self.mem.drain_to_mut(self.rd); - self.rd = 0; - drained - } - - /// Splits the buffer into two at the given index. - pub fn drain_to(&mut self, at: usize) -> BytesMut { - let drained = self.mem.drain_to_mut(at); - - if at >= self.rd { - self.rd = 0; - } else { - self.rd -= at; - } - - drained - } - - /// Reserves capacity for at least additional more bytes to be written in - /// the given `ByteBuf`. The `ByteBuf` may reserve more space to avoid - /// frequent reallocations. - pub fn reserve(&mut self, additional: usize) { - if self.remaining_mut() < additional { - let cap = cmp::max(self.capacity() * 2, self.len() + additional); - let cap = cap.next_power_of_two(); - - let mut new = ByteBuf::with_capacity(cap); - - new.copy_from_slice(self.mem.as_ref()); - new.rd = self.rd; - - *self = new; - } - } - - /// Reserves the minimum capacity for exactly additional more bytes to be - /// written in the given `ByteBuf`. Does nothing if the capacity is already - /// sufficient. - /// - /// Note that the allocator may give the collection more space than it - /// requests. Therefore capacity can not be relied upon to be precisely - /// minimal. Prefer reserve if future insertions are expected. - pub fn reserve_exact(&mut self, additional: usize) { - if self.remaining_mut() < additional { - let cap = self.len() + additional; - let mut new = ByteBuf::with_capacity(cap); - - new.copy_from_slice(self.mem.as_ref()); - new.rd = self.rd; - - *self = new; - } - } - - /// Gets a reference to the underlying `BytesMut` - pub fn get_ref(&self) -> &BytesMut { - &self.mem - } - - /// Unwraps the `ByteBuf`, returning the underlying `BytesMut` - pub fn into_inner(self) -> BytesMut { - self.mem - } -} - -impl Buf for ByteBuf { - #[inline] - fn remaining(&self) -> usize { - self.len() - self.rd - } - - #[inline] - fn bytes(&self) -> &[u8] { - &self.mem[self.rd..] - } - - #[inline] - fn advance(&mut self, cnt: usize) { - assert!(cnt <= self.remaining(), "buffer overflow"); - self.rd += cnt; - } - - #[inline] - fn copy_to_slice(&mut self, dst: &mut [u8]) { - assert!(self.remaining() >= dst.len()); - - let len = dst.len(); - dst.copy_from_slice(&self.bytes()[..len]); - self.rd += len; - } -} - -impl BufMut for ByteBuf { - #[inline] - fn remaining_mut(&self) -> usize { - self.capacity() - self.len() - } - - #[inline] - unsafe fn advance_mut(&mut self, cnt: usize) { - let new_len = self.len() + cnt; - self.mem.set_len(new_len); - } - - #[inline] - unsafe fn bytes_mut(&mut self) -> &mut [u8] { - let len = self.len(); - &mut self.mem.as_raw()[len..] - } - - #[inline] - fn copy_from_slice(&mut self, src: &[u8]) { - assert!(self.remaining_mut() >= src.len()); - - let len = src.len(); - - unsafe { - self.bytes_mut()[..len].copy_from_slice(src); - self.advance_mut(len); - } - } -} - -impl From<ByteBuf> for Bytes { - fn from(src: ByteBuf) -> Bytes { - let bytes = BytesMut::from(src); - bytes.freeze() - } -} - -impl From<ByteBuf> for BytesMut { - fn from(src: ByteBuf) -> BytesMut { - src.mem - } -} - -impl fmt::Debug for ByteBuf { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - self.bytes().fmt(fmt) - } -} - -impl fmt::Write for ByteBuf { - 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 Clone for ByteBuf { - fn clone(&self) -> Self { - ByteBuf { - mem: self.mem.clone(), - rd: self.rd, - } - } -} diff --git a/src/buf/mod.rs b/src/buf/mod.rs index e280bfe35825489525b3cd92db76750ed45b7907..e32f438b2f54c1048e1a1c098b89399fb1491556 100644 --- a/src/buf/mod.rs +++ b/src/buf/mod.rs @@ -1,5 +1,3 @@ -pub mod byte; -pub mod slice; pub mod take; use {Bytes, Take, TakeMut}; diff --git a/src/buf/slice.rs b/src/buf/slice.rs deleted file mode 100644 index bb6c1c40b23c6bc12b7c97a9ddf3705f3d406968..0000000000000000000000000000000000000000 --- a/src/buf/slice.rs +++ /dev/null @@ -1,139 +0,0 @@ -//! A buffer backed by a contiguous region of memory. - -use {Buf, BufMut}; -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> { - // Contiguous memory - mem: T, - // Current read position - rd: usize, - // Current write position - wr: usize, -} - -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; - }} - -impl<T> Buf for SliceBuf<T> - where T: AsRef<[u8]>, -{ - fn remaining(&self) -> usize { - self.wr - self.rd - } - - 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 copy_to_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> BufMut for SliceBuf<T> - where T: AsRef<[u8]> + AsMut<[u8]>, -{ - fn remaining_mut(&self) -> usize { - self.capacity() - self.wr - } - - unsafe fn advance_mut(&mut self, cnt: usize) { - assert!(cnt <= self.remaining_mut()); - self.wr += cnt; - } - - unsafe fn bytes_mut(&mut self) -> &mut [u8] { - &mut self.mem.as_mut()[self.wr..] - } - - fn copy_from_slice(&mut self, src: &[u8]) { - assert!(self.remaining_mut() >= src.len()); - - 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) - } -} - -impl<T> fmt::Write for SliceBuf<T> - where T: AsRef<[u8]> + AsMut<[u8]> -{ - 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) - } -} diff --git a/src/bytes.rs b/src/bytes.rs index d4cf64445e5f85d8e5fda4daf02e3b9ee0882342..ed56618876bd2fe131fbfa0122d47c3897e1cd59 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -19,7 +19,7 @@ use std::sync::Arc; /// ``` /// use bytes::Bytes; /// -/// let mem = Bytes::from_slice(b"Hello world"); +/// let mem = Bytes::from(&b"Hello world"[..]); /// let a = mem.slice(0, 5); /// /// assert_eq!(&a[..], b"Hello"); @@ -186,6 +186,17 @@ const INLINE_LEN_MASK: usize = 0xff << INLINE_LEN_OFFSET; impl Bytes { /// Creates a new empty `Bytes` + /// + /// This will not allocate and the returned `Bytes` handle will be empty. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let b = Bytes::new(); + /// assert_eq!(&b[..], b""); + /// ``` #[inline] pub fn new() -> Bytes { Bytes { @@ -200,15 +211,19 @@ impl Bytes { } } - /// Creates a new `Bytes` and copy the given slice into it. - #[inline] - pub fn from_slice<T: AsRef<[u8]>>(bytes: T) -> Bytes { - BytesMut::from_slice(bytes).freeze() - } - /// Creates a new `Bytes` from a static slice. /// - /// This is a zero copy function + /// The returned `Bytes` will point directly to the static slice. There is + /// no allocating or copying. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let b = Bytes::from_static(b"hello"); + /// assert_eq!(&b[..], b"hello"); + /// ``` #[inline] pub fn from_static(bytes: &'static [u8]) -> Bytes { Bytes { @@ -224,44 +239,113 @@ impl Bytes { } /// Returns the number of bytes contained in this `Bytes`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let b = Bytes::from(&b"hello"[..]); + /// assert_eq!(b.len(), 5); + /// ``` pub fn len(&self) -> usize { self.inner.len() } - /// Returns the total byte capacity of this `Bytes` - #[inline] - pub fn capacity(&self) -> usize { - self.inner.capacity() - } - - /// Returns true if the value contains no bytes + /// Returns true if the `Bytes` has a length of 0. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let b = Bytes::new(); + /// assert!(b.is_empty()); + /// ``` pub fn is_empty(&self) -> bool { self.inner.is_empty() } - /// Returns the inner contents of this `Bytes` as a slice. - pub fn as_slice(&self) -> &[u8] { - self.as_ref() - } - - /// Extracts a new `Bytes` referencing the bytes from range [start, end). - pub fn slice(&self, start: usize, end: usize) -> Bytes { + /// Returns a slice of self for the index range `[begin..end)`. + /// + /// This will increment the reference count for the underlying memory and + /// return a new `Bytes` handle set to the slice. + /// + /// This operation is `O(1)`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let a = Bytes::from(&b"hello world"[..]); + /// let b = a.slice(2, 5); + /// + /// assert_eq!(&b[..], b"llo"); + /// ``` + /// + /// # Panics + /// + /// Requires that `begin <= end` and `end <= self.len()`, otherwise slicing + /// will panic. + pub fn slice(&self, begin: usize, end: usize) -> Bytes { let ret = self.clone(); unsafe { ret.inner.set_end(end); - ret.inner.set_start(start); + ret.inner.set_start(begin); } ret } - /// Extracts a new `Bytes` referencing the bytes from range [start, len). - pub fn slice_from(&self, start: usize) -> Bytes { - self.slice(start, self.len()) + /// Returns a slice of self for the index range `[begin..self.len())`. + /// + /// This will increment the reference count for the underlying memory and + /// return a new `Bytes` handle set to the slice. + /// + /// This operation is `O(1)` and is equivalent to `self.slice(begin, + /// self.len())`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let a = Bytes::from(&b"hello world"[..]); + /// let b = a.slice_from(6); + /// + /// assert_eq!(&b[..], b"world"); + /// ``` + /// + /// # Panics + /// + /// Requires that `begin <= self.len()`, otherwise slicing will panic. + pub fn slice_from(&self, begin: usize) -> Bytes { + self.slice(begin, self.len()) } - /// Extracts a new `Bytes` referencing the bytes from range [0, end). + /// Returns a slice of self for the index range `[0..end)`. + /// + /// This will increment the reference count for the underlying memory and + /// return a new `Bytes` handle set to the slice. + /// + /// This operation is `O(1)` and is equivalent to `self.slice(0, end)`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let a = Bytes::from(&b"hello world"[..]); + /// let b = a.slice_to(5); + /// + /// assert_eq!(&b[..], b"hello"); + /// ``` + /// + /// # Panics + /// + /// Requires that `end <= self.len()`, otherwise slicing will panic. pub fn slice_to(&self, end: usize) -> Bytes { self.slice(0, end) } @@ -274,6 +358,18 @@ impl Bytes { /// This is an O(1) operation that just increases the reference count and /// sets a few indexes. /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let a = Bytes::from(&b"hello world"[..]); + /// let b = a.split_off(5); + /// + /// assert_eq!(&a[..], b"hello"); + /// assert_eq!(&b[..], b" world"); + /// ``` + /// /// # Panics /// /// Panics if `at > len` @@ -281,7 +377,7 @@ impl Bytes { Bytes { inner: self.inner.split_off(at) } } - /// Splits the buffer into two at the given index. + /// Splits the bytes into two at the given index. /// /// Afterwards `self` contains elements `[at, len)`, and the returned /// `Bytes` contains elements `[0, at)`. @@ -289,6 +385,18 @@ impl Bytes { /// This is an O(1) operation that just increases the reference count and /// sets a few indexes. /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let a = Bytes::from(&b"hello world"[..]); + /// let b = a.drain_to(5); + /// + /// assert_eq!(&a[..], b" world"); + /// assert_eq!(&b[..], b"hello"); + /// ``` + /// /// # Panics /// /// Panics if `at > len` @@ -299,7 +407,31 @@ impl Bytes { /// Attempt to convert into a `BytesMut` handle. /// /// This will only succeed if there are no other outstanding references to - /// the underlying chunk of memory. + /// the underlying chunk of memory. `Bytes` handles that contain inlined + /// bytes will always be convertable to `BytesMut`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let a = Bytes::from(&b"Mary had a little lamb, little lamb, little lamb..."[..]); + /// + /// // Create a shallow clone + /// let b = a.clone(); + /// + /// // This will fail because `b` shares a reference with `a` + /// let a = a.try_mut().unwrap_err(); + /// + /// drop(b); + /// + /// // This will succeed + /// let mut a = a.try_mut().unwrap(); + /// + /// a[0] = b'b'; + /// + /// assert_eq!(&a[..4], b"bary"); + /// ``` pub fn try_mut(mut self) -> Result<BytesMut, Bytes> { if self.inner.is_mut_safe() { Ok(BytesMut { inner: self.inner }) @@ -307,15 +439,6 @@ impl Bytes { Err(self) } } - - /// Consumes handle, returning a new mutable handle - /// - /// The function attempts to avoid copying, however if it is unable to - /// obtain a unique reference to the underlying data, a new buffer is - /// allocated and the data is copied to it. - pub fn into_mut(self) -> BytesMut { - self.try_mut().unwrap_or_else(BytesMut::from_slice) - } } impl IntoBuf for Bytes { @@ -437,52 +560,75 @@ impl BytesMut { } } - /// Creates a new `BytesMut` and copy the given slice into it. - #[inline] - pub fn from_slice<T: AsRef<[u8]>>(bytes: T) -> BytesMut { - let b = bytes.as_ref(); - - if b.len() <= INLINE_CAP { - unsafe { - let len = b.len(); - let mut data: [u8; INLINE_CAP] = mem::uninitialized(); - data[0..len].copy_from_slice(b); - - let a = KIND_INLINE | (len << INLINE_LEN_OFFSET); - - BytesMut { - inner: Inner { - data: mem::transmute(data), - arc: Cell::new(a), - } - } - } - } else { - let mut buf = BytesMut::with_capacity(bytes.as_ref().len()); - buf.copy_from_slice(bytes.as_ref()); - buf - } - } - /// Returns the number of bytes contained in this `BytesMut`. + /// + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let b = BytesMut::from(&b"hello"[..]); + /// assert_eq!(b.len(), 5); + /// ``` #[inline] pub fn len(&self) -> usize { self.inner.len() } - /// Returns true if the value contains no bytes + /// Returns true if the `BytesMut` has a length of 0. + /// + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let b = BytesMut::with_capacity(64); + /// assert!(b.is_empty()); + /// ``` #[inline] pub fn is_empty(&self) -> bool { self.len() == 0 } - /// Returns the total byte capacity of this `BytesMut` + /// Returns the number of bytes the `BytesMut` can hold without reallocating. + /// + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let b = BytesMut::with_capacity(64); + /// assert_eq!(b.capacity(), 64); + /// ``` #[inline] pub fn capacity(&self) -> usize { self.inner.capacity() } - /// Return an immutable handle to the bytes + /// Convert `self` into an immutable `Bytes` + /// + /// The conversion is zero cost and is used to indicate that the slice + /// referenced by the handle will no longer be mutated. Once the conversion + /// is done, the handle can be cloned and shared across threads. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BytesMut, BufMut}; + /// use std::thread; + /// + /// let mut b = BytesMut::with_capacity(64); + /// b.put_str("hello world"); + /// let b1 = b.freeze(); + /// let b2 = b1.clone(); + /// + /// let th = thread::spawn(move || { + /// assert_eq!(&b1[..], b"hello world"); + /// }); + /// + /// assert_eq!(&b2[..], b"hello world"); + /// th.join().unwrap(); + /// ``` #[inline] pub fn freeze(self) -> Bytes { Bytes { inner: self.inner } @@ -493,10 +639,22 @@ impl BytesMut { /// Afterwards `self` contains elements `[0, at)`, and the returned /// `BytesMut` contains elements `[at, capacity)`. /// - /// This is an O(1) operation [1] that just increases the reference count - /// and sets a few indexes. + /// This is an O(1) operation that just increases the reference count and + /// sets a few indexes. + /// + /// # Examples /// - /// [1] Inlined bytes are copied + /// ``` + /// use bytes::BytesMut; + /// + /// let mut a = BytesMut::from(&b"hello world"[..]); + /// let b = a.split_off(5); + /// + /// a[0] = b'j'; + /// + /// assert_eq!(&a[..], b"jello"); + /// assert_eq!(&b[..], b" world"); + /// ``` /// /// # Panics /// @@ -510,10 +668,23 @@ impl BytesMut { /// Afterwards `self` contains elements `[0, at)`, and the returned /// `BytesMut` contains elements `[at, capacity)`. /// - /// This is an O(1) operation [1] that just increases the reference count + /// This is an O(1) operation that just increases the reference count /// and sets a few indexes. /// - /// [1] Inlined bytes are copied + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let mut a = BytesMut::from(&b"hello world"[..]); + /// let mut b = a.split_off_mut(5); + /// + /// a[0] = b'j'; + /// b[0] = b'!'; + /// + /// assert_eq!(&a[..], b"jello"); + /// assert_eq!(&b[..], b"!world"); + /// ``` /// /// # Panics /// @@ -527,10 +698,22 @@ impl BytesMut { /// Afterwards `self` contains elements `[at, len)`, and the returned `Bytes` /// contains elements `[0, at)`. /// - /// This is an O(1) operation [1] that just increases the reference count - /// and sets a few indexes. + /// This is an O(1) operation that just increases the reference count and + /// sets a few indexes. /// - /// [1] Inlined bytes are copied. + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let mut a = BytesMut::from(&b"hello world"[..]); + /// let b = a.drain_to(5); + /// + /// a[0] = b'!'; + /// + /// assert_eq!(&a[..], b"!world"); + /// assert_eq!(&b[..], b"hello"); + /// ``` /// /// # Panics /// @@ -544,10 +727,23 @@ impl BytesMut { /// Afterwards `self` contains elements `[at, len)`, and the returned `BytesMut` /// contains elements `[0, at)`. /// - /// This is an O(1) operation [1] that just increases the reference count and + /// This is an O(1) operation that just increases the reference count and /// sets a few indexes. /// - /// [1] Inlined bytes are copied. + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let mut a = BytesMut::from(&b"hello world"[..]); + /// let mut b = a.drain_to_mut(5); + /// + /// a[0] = b'!'; + /// b[0] = b'j'; + /// + /// assert_eq!(&a[..], b"!world"); + /// assert_eq!(&b[..], b"jello"); + /// ``` /// /// # Panics /// @@ -556,38 +752,38 @@ impl BytesMut { BytesMut { inner: self.inner.drain_to(at) } } - /// Returns the inner contents of this `BytesMut` as a slice. - pub fn as_slice(&self) -> &[u8] { - self.as_ref() - } - - /// Returns the inner contents of this `BytesMut` as a mutable slice - /// - /// This a slice of bytes that have been initialized - pub fn as_mut(&mut self) -> &mut [u8] { - self.inner.as_mut() - } - /// Sets the length of the buffer /// /// This will explicitly set the size of the buffer without actually /// modifying the data, so it is up to the caller to ensure that the data /// has been initialized. /// + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let mut b = BytesMut::from(&b"hello world"[..]); + /// + /// unsafe { + /// b.set_len(5); + /// } + /// + /// assert_eq!(&b[..], b"hello"); + /// + /// unsafe { + /// b.set_len(11); + /// } + /// + /// assert_eq!(&b[..], b"hello world"); + /// ``` + /// /// # Panics /// /// This method will panic if `len` is out of bounds for the underlying /// slice or if it comes after the `end` of the configured window. pub unsafe fn set_len(&mut self, len: usize) { - self.inner.set_len(len); - } - - /// Returns the inner contents of this `BytesMut` as a mutable slice - /// - /// This a slice of all bytes, including uninitialized memory - #[inline] - pub unsafe fn as_raw(&mut self) -> &mut [u8] { - self.inner.as_raw() + self.inner.set_len(len) } } @@ -600,13 +796,13 @@ impl BufMut for BytesMut { #[inline] unsafe fn advance_mut(&mut self, cnt: usize) { let new_len = self.len() + cnt; - self.set_len(new_len); + self.inner.set_len(new_len); } #[inline] unsafe fn bytes_mut(&mut self) -> &mut [u8] { let len = self.len(); - &mut self.as_raw()[len..] + &mut self.inner.as_raw()[len..] } #[inline] @@ -654,7 +850,7 @@ impl ops::Deref for BytesMut { impl ops::DerefMut for BytesMut { fn deref_mut(&mut self) -> &mut [u8] { - self.as_mut() + self.inner.as_mut() } } @@ -681,7 +877,33 @@ impl From<Vec<u8>> for BytesMut { impl<'a> From<&'a [u8]> for BytesMut { fn from(src: &'a [u8]) -> BytesMut { - BytesMut::from_slice(src) + if src.len() <= INLINE_CAP { + unsafe { + let len = src.len(); + let mut data: [u8; INLINE_CAP] = mem::uninitialized(); + data[0..len].copy_from_slice(src); + + let a = KIND_INLINE | (len << INLINE_LEN_OFFSET); + + BytesMut { + inner: Inner { + data: mem::transmute(data), + arc: Cell::new(a), + } + } + } + } else { + let mut buf = BytesMut::with_capacity(src.len()); + buf.copy_from_slice(src.as_ref()); + buf + } + } +} + +impl From<Bytes> for BytesMut { + fn from(src: Bytes) -> BytesMut { + src.try_mut() + .unwrap_or_else(|src| BytesMut::from(&src[..])) } } @@ -700,6 +922,17 @@ impl fmt::Debug for BytesMut { } } +impl fmt::Write for BytesMut { + 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) + } +} + /* * * ===== Inner ===== @@ -1122,6 +1355,6 @@ impl<'a, T: ?Sized> PartialEq<&'a T> for Bytes impl Clone for BytesMut { fn clone(&self) -> BytesMut { - BytesMut::from_slice(self.as_ref()) + BytesMut::from(&self[..]) } } diff --git a/src/lib.rs b/src/lib.rs index 98d63fa753022e9dfd9db61d9186ab003df84631..156120319ae8ed3bf6b78d72e649fc8acc16a544 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,7 +16,5 @@ pub use buf::{ Reader, Writer, }; -pub use buf::byte::{ByteBuf}; -pub use buf::slice::{SliceBuf}; pub use buf::take::{Take, TakeMut}; pub use bytes::{Bytes, BytesMut}; diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs index 083d92ac55cff979ee8a07d7d394ab554c42d787..521446e1930c8f8249d1d9209a70020706478f2f 100644 --- a/tests/test_bytes.rs +++ b/tests/test_bytes.rs @@ -17,7 +17,7 @@ fn test_bounds() { #[test] fn from_slice() { - let a = Bytes::from_slice(b"abcdefgh"); + let a = Bytes::from(&b"abcdefgh"[..]); assert_eq!(a, b"abcdefgh"[..]); assert_eq!(a, &b"abcdefgh"[..]); assert_eq!(a, Vec::from(&b"abcdefgh"[..])); @@ -25,7 +25,7 @@ fn from_slice() { assert_eq!(&b"abcdefgh"[..], a); assert_eq!(Vec::from(&b"abcdefgh"[..]), a); - let a = BytesMut::from_slice(b"abcdefgh"); + let a = BytesMut::from(&b"abcdefgh"[..]); assert_eq!(a, b"abcdefgh"[..]); assert_eq!(a, &b"abcdefgh"[..]); assert_eq!(a, Vec::from(&b"abcdefgh"[..])); @@ -36,39 +36,39 @@ fn from_slice() { #[test] fn fmt() { - let a = format!("{:?}", Bytes::from_slice(b"abcdefg")); + let a = format!("{:?}", Bytes::from(&b"abcdefg"[..])); let b = format!("{:?}", b"abcdefg"); assert_eq!(a, b); - let a = format!("{:?}", BytesMut::from_slice(b"abcdefg")); + let a = format!("{:?}", BytesMut::from(&b"abcdefg"[..])); assert_eq!(a, b); } #[test] fn len() { - let a = Bytes::from_slice(b"abcdefg"); + let a = Bytes::from(&b"abcdefg"[..]); assert_eq!(a.len(), 7); - let a = BytesMut::from_slice(b"abcdefg"); + let a = BytesMut::from(&b"abcdefg"[..]); assert_eq!(a.len(), 7); - let a = Bytes::from_slice(b""); + let a = Bytes::from(&b""[..]); assert!(a.is_empty()); - let a = BytesMut::from_slice(b""); + let a = BytesMut::from(&b""[..]); assert!(a.is_empty()); } #[test] fn index() { - let a = Bytes::from_slice(b"hello world"); + let a = Bytes::from(&b"hello world"[..]); assert_eq!(a[0..5], *b"hello"); } #[test] fn slice() { - let a = Bytes::from_slice(b"hello world"); + let a = Bytes::from(&b"hello world"[..]); let b = a.slice(3, 5); assert_eq!(b, b"lo"[..]); @@ -83,26 +83,26 @@ fn slice() { #[test] #[should_panic] fn slice_oob_1() { - let a = Bytes::from_slice(b"hello world"); + let a = Bytes::from(&b"hello world"[..]); a.slice(5, 25); } #[test] #[should_panic] fn slice_oob_2() { - let a = Bytes::from_slice(b"hello world"); + let a = Bytes::from(&b"hello world"[..]); a.slice(25, 30); } #[test] fn split_off() { - let hello = Bytes::from_slice(b"helloworld"); + let hello = Bytes::from(&b"helloworld"[..]); let world = hello.split_off(5); assert_eq!(hello, &b"hello"[..]); assert_eq!(world, &b"world"[..]); - let hello = BytesMut::from_slice(b"helloworld"); + let hello = BytesMut::from(&b"helloworld"[..]); let world = hello.split_off(5); assert_eq!(hello, &b"hello"[..]); @@ -112,21 +112,21 @@ fn split_off() { #[test] #[should_panic] fn split_off_oob() { - let hello = Bytes::from_slice(b"helloworld"); + let hello = Bytes::from(&b"helloworld"[..]); hello.split_off(25); } #[test] #[should_panic] fn split_off_oob_mut() { - let hello = BytesMut::from_slice(b"helloworld"); + let hello = BytesMut::from(&b"helloworld"[..]); hello.split_off(25); } #[test] fn split_off_uninitialized() { - let bytes = BytesMut::with_capacity(1024); - let other = bytes.split_off(128); + let mut bytes = BytesMut::with_capacity(1024); + let other = bytes.split_off_mut(128); assert_eq!(bytes.len(), 0); assert_eq!(bytes.capacity(), 128); @@ -138,20 +138,20 @@ fn split_off_uninitialized() { #[test] fn drain_to_1() { // Inline - let a = Bytes::from_slice(SHORT); + let a = Bytes::from(SHORT); let b = a.drain_to(4); assert_eq!(SHORT[4..], a); assert_eq!(SHORT[..4], b); // Allocated - let a = Bytes::from_slice(LONG); + let a = Bytes::from(LONG); let b = a.drain_to(4); assert_eq!(LONG[4..], a); assert_eq!(LONG[..4], b); - let a = Bytes::from_slice(LONG); + let a = Bytes::from(LONG); let b = a.drain_to(30); assert_eq!(LONG[30..], a); @@ -161,21 +161,21 @@ fn drain_to_1() { #[test] #[should_panic] fn drain_to_oob() { - let hello = Bytes::from_slice(b"helloworld"); + let hello = Bytes::from(&b"helloworld"[..]); hello.drain_to(30); } #[test] #[should_panic] fn drain_to_oob_mut() { - let hello = BytesMut::from_slice(b"helloworld"); + let hello = BytesMut::from(&b"helloworld"[..]); hello.drain_to(30); } #[test] fn drain_to_uninitialized() { - let bytes = BytesMut::with_capacity(1024); - let other = bytes.drain_to(128); + let mut bytes = BytesMut::with_capacity(1024); + let other = bytes.drain_to_mut(128); assert_eq!(bytes.len(), 0); assert_eq!(bytes.capacity(), 896); @@ -183,3 +183,15 @@ fn drain_to_uninitialized() { assert_eq!(other.len(), 0); assert_eq!(other.capacity(), 128); } + +#[test] +fn fns_defined_for_bytes_mut() { + let mut bytes = BytesMut::from(&b"hello world"[..]); + + bytes.as_ptr(); + bytes.as_mut_ptr(); + + // Iterator + let v: Vec<u8> = bytes.iter().map(|b| *b).collect(); + assert_eq!(&v[..], &bytes[..]); +} diff --git a/tests/test_mut_buf.rs b/tests/test_mut_buf.rs index 3cd88f3e46744283f9806205a9e8bbb1a0eba632..56660e8c69e1cd1d4ad08b466862e16a30e363c7 100644 --- a/tests/test_mut_buf.rs +++ b/tests/test_mut_buf.rs @@ -1,7 +1,7 @@ extern crate bytes; extern crate byteorder; -use bytes::{Buf, BufMut, ByteBuf}; +use bytes::{BufMut, BytesMut}; use std::usize; use std::fmt::Write; @@ -49,10 +49,10 @@ fn test_put_u16() { #[test] fn test_clone() { - let mut buf = ByteBuf::with_capacity(100); + let mut buf = BytesMut::with_capacity(100); buf.write_str("this is a test").unwrap(); let buf2 = buf.clone(); buf.write_str(" of our emergecy broadcast system").unwrap(); - assert!(buf.bytes() != buf2.bytes()); + assert!(buf != buf2); } diff --git a/tests/test_slice_buf.rs b/tests/test_slice_buf.rs deleted file mode 100644 index e712d14d55ee132428dddfba5f3bf24d1847e166..0000000000000000000000000000000000000000 --- a/tests/test_slice_buf.rs +++ /dev/null @@ -1,71 +0,0 @@ -extern crate bytes; - -use bytes::{Buf, BufMut, SliceBuf}; - -#[test] -fn test_initial_buf_empty() { - let mut mem = [0u8; 100]; - let buf = SliceBuf::new(&mut mem[..]); - - assert!(buf.capacity() == 100); - assert!(buf.remaining_mut() == 100); - assert!(buf.remaining() == 0); -} - -#[test] -fn test_slice_buf_bytes() { - let mut mem = [0u8; 32]; - let mut buf = SliceBuf::new(&mut mem[..]); - - buf.copy_from(&b"hello "[..]); - assert_eq!(&b"hello "[..], buf.bytes()); - - buf.copy_from(&b"world"[..]); - assert_eq!(&b"hello world"[..], buf.bytes()); -} - -#[test] -fn test_byte_buf_read_write() { - let mut mem = [0u8; 32]; - let mut buf = SliceBuf::new(&mut mem[..]); - - buf.copy_from(&b"hello world"[..]); - assert_eq!(21, buf.remaining_mut()); - - buf.copy_from(&b" goodbye"[..]); - assert_eq!(13, buf.remaining_mut()); - - let mut dst = [0; 5]; - - let pos = buf.position(); - buf.copy_to(&mut dst[..]); - assert_eq!(b"hello", &dst); - - buf.set_position(pos); - buf.copy_to(&mut dst[..]); - assert_eq!(b"hello", &dst); - - buf.copy_to(&mut dst[..]); - assert_eq!(b" worl", &dst); - - let mut dst = [0; 2]; - buf.copy_to(&mut dst[..]); - assert_eq!(b"d ", &dst); - - let mut dst = [0; 7]; - buf.copy_to(&mut dst[..]); - assert_eq!(b"goodbye", &dst); - - assert_eq!(13, buf.remaining_mut()); - - buf.copy_from(&b" have fun"[..]); - assert_eq!(4, buf.remaining_mut()); - - assert_eq!(buf.bytes(), b" have fun"); - - buf.set_position(0); - assert_eq!(buf.bytes(), b"hello world goodbye have fun"); - - buf.clear(); - assert_eq!(buf.bytes(), b""); -}