aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rw-r--r--CHANGELOG.md3
-rw-r--r--Cargo.toml11
-rw-r--r--README.md4
-rw-r--r--benches/buf.rs188
-rw-r--r--src/buf/buf.rs140
-rw-r--r--src/buf/buf_mut.rs138
-rw-r--r--src/buf/chain.rs6
-rw-r--r--src/buf/into_buf.rs8
-rw-r--r--src/bytes.rs133
-rw-r--r--src/either.rs6
-rw-r--r--src/lib.rs9
-rw-r--r--tests/test_buf.rs6
-rw-r--r--tests/test_buf_mut.rs6
-rw-r--r--tests/test_bytes.rs152
-rw-r--r--tests/test_chain.rs8
16 files changed, 534 insertions, 286 deletions
diff --git a/.travis.yml b/.travis.yml
index 2e8ab18..7acf37f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,7 +19,7 @@ matrix:
#
# This job will also build and deploy the docs to gh-pages.
- env: TARGET=x86_64-unknown-linux-gnu
- rust: 1.15.0
+ rust: 1.26.0
after_success:
- |
pip install 'travis-cargo<0.2' --user &&
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f846427..b538415 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,5 @@
+# 0.5.0 (unreleased)
+
# 0.4.12 (March 6, 2019)
### Added
@@ -19,6 +21,7 @@
* Add 128 bit number support behind a feature flag (#209).
* Implement `IntoBuf` for `&mut [u8]`
+>>>>>>> v0.4.x
# 0.4.8 (May 25, 2018)
diff --git a/Cargo.toml b/Cargo.toml
index 99331b6..22e48c2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,13 +6,12 @@ name = "bytes"
# - Update CHANGELOG.md.
# - Update doc URL.
# - Create "v0.4.x" git tag.
-version = "0.4.12"
+version = "0.5.0"
license = "MIT"
authors = ["Carl Lerche <me@carllerche.com>"]
description = "Types and traits for working with bytes"
-documentation = "https://docs.rs/bytes/0.4.12/bytes"
-homepage = "https://github.com/carllerche/bytes"
-repository = "https://github.com/carllerche/bytes"
+documentation = "https://docs.rs/bytes"
+repository = "https://github.com/tokio-rs/bytes"
readme = "README.md"
keywords = ["buffers", "zero-copy", "io"]
exclude = [
@@ -24,12 +23,14 @@ exclude = [
]
categories = ["network-programming", "data-structures"]
+publish = false
+
[package.metadata.docs.rs]
features = ["i128"]
[dependencies]
byteorder = "1.1.0"
-iovec = "0.1"
+iovec = { git = "https://github.com/carllerche/iovec" }
serde = { version = "1.0", optional = true }
either = { version = "1.5", default-features = false, optional = true }
diff --git a/README.md b/README.md
index 0135974..09ebfe9 100644
--- a/README.md
+++ b/README.md
@@ -3,9 +3,9 @@
A utility library for working with bytes.
[![Crates.io](https://img.shields.io/crates/v/bytes.svg?maxAge=2592000)](https://crates.io/crates/bytes)
-[![Build Status](https://travis-ci.org/carllerche/bytes.svg?branch=master)](https://travis-ci.org/carllerche/bytes)
+[![Build Status](https://travis-ci.org/tokio-rs/bytes.svg?branch=master)](https://travis-ci.org/tokio-rs/bytes)
-[Documentation](https://docs.rs/bytes/0.4.12/bytes/)
+[Documentation](https://docs.rs/bytes)
## Usage
diff --git a/benches/buf.rs b/benches/buf.rs
new file mode 100644
index 0000000..640f9ca
--- /dev/null
+++ b/benches/buf.rs
@@ -0,0 +1,188 @@
+#![feature(test)]
+
+extern crate bytes;
+extern crate test;
+
+use test::Bencher;
+use bytes::Buf;
+use std::io::Cursor;
+
+/// Dummy Buf implementation
+struct TestBuf {
+ buf: &'static [u8],
+ readlens: &'static [usize],
+ init_pos: usize,
+ pos: usize,
+ readlen_pos: usize,
+ readlen: usize,
+}
+impl TestBuf {
+ fn new(buf: &'static [u8], readlens: &'static [usize], init_pos: usize) -> TestBuf {
+ let mut buf = TestBuf {
+ buf,
+ readlens,
+ init_pos,
+ pos: 0,
+ readlen_pos: 0,
+ readlen: 0,
+ };
+ buf.reset();
+ buf
+ }
+ fn reset(&mut self) {
+ self.pos = self.init_pos;
+ self.readlen_pos = 0;
+ self.next_readlen();
+ }
+ /// Compute the length of the next read :
+ /// - use the next value specified in readlens (capped by remaining) if any
+ /// - else the remaining
+ fn next_readlen(&mut self) {
+ self.readlen = self.buf.len() - self.pos;
+ if let Some(readlen) = self.readlens.get(self.readlen_pos) {
+ self.readlen = std::cmp::min(self.readlen, *readlen);
+ self.readlen_pos += 1;
+ }
+ }
+}
+impl Buf for TestBuf {
+ fn remaining(&self) -> usize {
+ return self.buf.len() - self.pos;
+ }
+ fn advance(&mut self, cnt: usize) {
+ self.pos += cnt;
+ assert!(self.pos <= self.buf.len());
+ self.next_readlen();
+ }
+ fn bytes(&self) -> &[u8] {
+ if self.readlen == 0 {
+ Default::default()
+ } else {
+ &self.buf[self.pos..self.pos + self.readlen]
+ }
+ }
+}
+
+/// Dummy Buf implementation
+/// version with methods forced to not be inlined (to simulate costly calls)
+struct TestBufC {
+ inner: TestBuf,
+}
+impl TestBufC {
+ fn new(buf: &'static [u8], readlens: &'static [usize], init_pos: usize) -> TestBufC {
+ TestBufC {
+ inner: TestBuf::new(buf, readlens, init_pos),
+ }
+ }
+ fn reset(&mut self) {
+ self.inner.reset()
+ }
+}
+impl Buf for TestBufC {
+ #[inline(never)]
+ fn remaining(&self) -> usize {
+ self.inner.remaining()
+ }
+ #[inline(never)]
+ fn advance(&mut self, cnt: usize) {
+ self.inner.advance(cnt)
+ }
+ #[inline(never)]
+ fn bytes(&self) -> &[u8] {
+ self.inner.bytes()
+ }
+}
+
+macro_rules! bench {
+ ($fname:ident, testbuf $testbuf:ident $readlens:expr, $method:ident $(,$arg:expr)*) => (
+ #[bench]
+ fn $fname(b: &mut Bencher) {
+ let mut bufs = [
+ $testbuf::new(&[1u8; 8+0], $readlens, 0),
+ $testbuf::new(&[1u8; 8+1], $readlens, 1),
+ $testbuf::new(&[1u8; 8+2], $readlens, 2),
+ $testbuf::new(&[1u8; 8+3], $readlens, 3),
+ $testbuf::new(&[1u8; 8+4], $readlens, 4),
+ $testbuf::new(&[1u8; 8+5], $readlens, 5),
+ $testbuf::new(&[1u8; 8+6], $readlens, 6),
+ $testbuf::new(&[1u8; 8+7], $readlens, 7),
+ ];
+ b.iter(|| {
+ for i in 0..8 {
+ bufs[i].reset();
+ let mut buf: &mut Buf = &mut bufs[i]; // type erasure
+ test::black_box(buf.$method($($arg,)*));
+ }
+ })
+ }
+ );
+ ($fname:ident, cursor, $method:ident $(,$arg:expr)*) => (
+ #[bench]
+ fn $fname(b: &mut Bencher) {
+ // buf must be long enough for one read of 8 bytes starting at pos 7
+ let mut buf = Cursor::new(vec![1u8; 8+7]);
+ b.iter(|| {
+ for i in 0..8 {
+ buf.set_position(i);
+ let buf = &mut buf as &mut Buf; // type erasure
+ test::black_box(buf.$method($($arg,)*));
+ }
+ })
+ }
+ );
+ ($fname:ident, option) => (
+ #[bench]
+ fn $fname(b: &mut Bencher) {
+ let data = [1u8; 1];
+ b.iter(|| {
+ for _ in 0..8 {
+ let mut buf = Some(data);
+ let buf = &mut buf as &mut Buf; // type erasure
+ test::black_box(buf.get_u8());
+ }
+ })
+ }
+ );
+}
+
+macro_rules! bench_group {
+ ($method:ident $(,$arg:expr)*) => (
+ bench!(cursor, cursor, $method $(,$arg)*);
+ bench!(tbuf_1, testbuf TestBuf &[], $method $(,$arg)*);
+ bench!(tbuf_1_costly, testbuf TestBufC &[], $method $(,$arg)*);
+ bench!(tbuf_2, testbuf TestBuf &[1], $method $(,$arg)*);
+ bench!(tbuf_2_costly, testbuf TestBufC &[1], $method $(,$arg)*);
+ // bench!(tbuf_onebyone, testbuf TestBuf &[1,1,1,1,1,1,1,1], $method $(,$arg)*);
+ // bench!(tbuf_onebyone_costly, testbuf TestBufC &[1,1,1,1,1,1,1,1], $method $(,$arg)*);
+ );
+}
+
+mod get_u8 {
+ use super::*;
+ bench_group!(get_u8);
+ bench!(option, option);
+}
+mod get_u16 {
+ use super::*;
+ bench_group!(get_u16);
+}
+mod get_u32 {
+ use super::*;
+ bench_group!(get_u32);
+}
+mod get_u64 {
+ use super::*;
+ bench_group!(get_u64);
+}
+mod get_f32 {
+ use super::*;
+ bench_group!(get_f32);
+}
+mod get_f64 {
+ use super::*;
+ bench_group!(get_f64);
+}
+mod get_uint24 {
+ use super::*;
+ bench_group!(get_uint, 3);
+}
diff --git a/src/buf/buf.rs b/src/buf/buf.rs
index dc20567..3b4096f 100644
--- a/src/buf/buf.rs
+++ b/src/buf/buf.rs
@@ -146,7 +146,7 @@ pub trait Buf {
/// with `dst` being a zero length slice.
///
/// [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html
- fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize {
+ fn bytes_vec<'a>(&'a self, dst: &mut [IoVec<'a>]) -> usize {
if dst.is_empty() {
return 0;
}
@@ -251,7 +251,7 @@ pub trait Buf {
ptr::copy_nonoverlapping(
src.as_ptr(), dst[off..].as_mut_ptr(), cnt);
- off += src.len();
+ off += cnt;
}
self.advance(cnt);
@@ -306,14 +306,6 @@ pub trait Buf {
ret
}
- #[doc(hidden)]
- #[deprecated(note="use get_u16_be or get_u16_le")]
- fn get_u16<T: ByteOrder>(&mut self) -> u16 where Self: Sized {
- let mut buf = [0; 2];
- self.copy_to_slice(&mut buf);
- T::read_u16(&buf)
- }
-
/// Gets an unsigned 16 bit integer from `self` in big-endian byte order.
///
/// The current position is advanced by 2.
@@ -325,13 +317,13 @@ pub trait Buf {
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x08\x09 hello");
- /// assert_eq!(0x0809, buf.get_u16_be());
+ /// assert_eq!(0x0809, buf.get_u16());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
- fn get_u16_be(&mut self) -> u16 {
+ fn get_u16(&mut self) -> u16 {
buf_get_impl!(self, 2, BigEndian::read_u16);
}
@@ -356,14 +348,6 @@ pub trait Buf {
buf_get_impl!(self, 2, LittleEndian::read_u16);
}
- #[doc(hidden)]
- #[deprecated(note="use get_i16_be or get_i16_le")]
- fn get_i16<T: ByteOrder>(&mut self) -> i16 where Self: Sized {
- let mut buf = [0; 2];
- self.copy_to_slice(&mut buf);
- T::read_i16(&buf)
- }
-
/// Gets a signed 16 bit integer from `self` in big-endian byte order.
///
/// The current position is advanced by 2.
@@ -375,13 +359,13 @@ pub trait Buf {
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x08\x09 hello");
- /// assert_eq!(0x0809, buf.get_i16_be());
+ /// assert_eq!(0x0809, buf.get_i16());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
- fn get_i16_be(&mut self) -> i16 {
+ fn get_i16(&mut self) -> i16 {
buf_get_impl!(self, 2, BigEndian::read_i16);
}
@@ -406,14 +390,6 @@ pub trait Buf {
buf_get_impl!(self, 2, LittleEndian::read_i16);
}
- #[doc(hidden)]
- #[deprecated(note="use get_u32_be or get_u32_le")]
- fn get_u32<T: ByteOrder>(&mut self) -> u32 where Self: Sized {
- let mut buf = [0; 4];
- self.copy_to_slice(&mut buf);
- T::read_u32(&buf)
- }
-
/// Gets an unsigned 32 bit integer from `self` in the big-endian byte order.
///
/// The current position is advanced by 4.
@@ -425,13 +401,13 @@ pub trait Buf {
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x08\x09\xA0\xA1 hello");
- /// assert_eq!(0x0809A0A1, buf.get_u32_be());
+ /// assert_eq!(0x0809A0A1, buf.get_u32());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
- fn get_u32_be(&mut self) -> u32 {
+ fn get_u32(&mut self) -> u32 {
buf_get_impl!(self, 4, BigEndian::read_u32);
}
@@ -456,14 +432,6 @@ pub trait Buf {
buf_get_impl!(self, 4, LittleEndian::read_u32);
}
- #[doc(hidden)]
- #[deprecated(note="use get_i32_be or get_i32_le")]
- fn get_i32<T: ByteOrder>(&mut self) -> i32 where Self: Sized {
- let mut buf = [0; 4];
- self.copy_to_slice(&mut buf);
- T::read_i32(&buf)
- }
-
/// Gets a signed 32 bit integer from `self` in big-endian byte order.
///
/// The current position is advanced by 4.
@@ -475,13 +443,13 @@ pub trait Buf {
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x08\x09\xA0\xA1 hello");
- /// assert_eq!(0x0809A0A1, buf.get_i32_be());
+ /// assert_eq!(0x0809A0A1, buf.get_i32());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
- fn get_i32_be(&mut self) -> i32 {
+ fn get_i32(&mut self) -> i32 {
buf_get_impl!(self, 4, BigEndian::read_i32);
}
@@ -506,14 +474,6 @@ pub trait Buf {
buf_get_impl!(self, 4, LittleEndian::read_i32);
}
- #[doc(hidden)]
- #[deprecated(note="use get_u64_be or get_u64_le")]
- fn get_u64<T: ByteOrder>(&mut self) -> u64 where Self: Sized {
- let mut buf = [0; 8];
- self.copy_to_slice(&mut buf);
- T::read_u64(&buf)
- }
-
/// Gets an unsigned 64 bit integer from `self` in big-endian byte order.
///
/// The current position is advanced by 8.
@@ -525,13 +485,13 @@ pub trait Buf {
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08 hello");
- /// assert_eq!(0x0102030405060708, buf.get_u64_be());
+ /// assert_eq!(0x0102030405060708, buf.get_u64());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
- fn get_u64_be(&mut self) -> u64 {
+ fn get_u64(&mut self) -> u64 {
buf_get_impl!(self, 8, BigEndian::read_u64);
}
@@ -556,14 +516,6 @@ pub trait Buf {
buf_get_impl!(self, 8, LittleEndian::read_u64);
}
- #[doc(hidden)]
- #[deprecated(note="use get_i64_be or get_i64_le")]
- fn get_i64<T: ByteOrder>(&mut self) -> i64 where Self: Sized {
- let mut buf = [0; 8];
- self.copy_to_slice(&mut buf);
- T::read_i64(&buf)
- }
-
/// Gets a signed 64 bit integer from `self` in big-endian byte order.
///
/// The current position is advanced by 8.
@@ -575,13 +527,13 @@ pub trait Buf {
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08 hello");
- /// assert_eq!(0x0102030405060708, buf.get_i64_be());
+ /// assert_eq!(0x0102030405060708, buf.get_i64());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
- fn get_i64_be(&mut self) -> i64 {
+ fn get_i64(&mut self) -> i64 {
buf_get_impl!(self, 8, BigEndian::read_i64);
}
@@ -618,14 +570,14 @@ pub trait Buf {
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello");
- /// assert_eq!(0x01020304050607080910111213141516, buf.get_u128_be());
+ /// assert_eq!(0x01020304050607080910111213141516, buf.get_u128());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
#[cfg(feature = "i128")]
- fn get_u128_be(&mut self) -> u128 {
+ fn get_u128(&mut self) -> u128 {
buf_get_impl!(self, 16, BigEndian::read_u128);
}
@@ -664,14 +616,14 @@ pub trait Buf {
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello");
- /// assert_eq!(0x01020304050607080910111213141516, buf.get_i128_be());
+ /// assert_eq!(0x01020304050607080910111213141516, buf.get_i128());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
#[cfg(feature = "i128")]
- fn get_i128_be(&mut self) -> i128 {
+ fn get_i128(&mut self) -> i128 {
buf_get_impl!(self, 16, BigEndian::read_i128);
}
@@ -698,14 +650,6 @@ pub trait Buf {
buf_get_impl!(self, 16, LittleEndian::read_i128);
}
- #[doc(hidden)]
- #[deprecated(note="use get_uint_be or get_uint_le")]
- fn get_uint<T: ByteOrder>(&mut self, nbytes: usize) -> u64 where Self: Sized {
- let mut buf = [0; 8];
- self.copy_to_slice(&mut buf[..nbytes]);
- T::read_uint(&buf[..nbytes], nbytes)
- }
-
/// Gets an unsigned n-byte integer from `self` in big-endian byte order.
///
/// The current position is advanced by `nbytes`.
@@ -713,17 +657,17 @@ pub trait Buf {
/// # Examples
///
/// ```
- /// use bytes::{Buf, BigEndian};
+ /// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x01\x02\x03 hello");
- /// assert_eq!(0x010203, buf.get_uint_be(3));
+ /// assert_eq!(0x010203, buf.get_uint(3));
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
- fn get_uint_be(&mut self, nbytes: usize) -> u64 {
+ fn get_uint(&mut self, nbytes: usize) -> u64 {
buf_get_impl!(self, 8, BigEndian::read_uint, nbytes);
}
@@ -748,14 +692,6 @@ pub trait Buf {
buf_get_impl!(self, 8, LittleEndian::read_uint, nbytes);
}
- #[doc(hidden)]
- #[deprecated(note="use get_int_be or get_int_le")]
- fn get_int<T: ByteOrder>(&mut self, nbytes: usize) -> i64 where Self: Sized {
- let mut buf = [0; 8];
- self.copy_to_slice(&mut buf[..nbytes]);
- T::read_int(&buf[..nbytes], nbytes)
- }
-
/// Gets a signed n-byte integer from `self` in big-endian byte order.
///
/// The current position is advanced by `nbytes`.
@@ -767,13 +703,13 @@ pub trait Buf {
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x01\x02\x03 hello");
- /// assert_eq!(0x010203, buf.get_int_be(3));
+ /// assert_eq!(0x010203, buf.get_int(3));
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
- fn get_int_be(&mut self, nbytes: usize) -> i64 {
+ fn get_int(&mut self, nbytes: usize) -> i64 {
buf_get_impl!(self, 8, BigEndian::read_int, nbytes);
}
@@ -798,14 +734,6 @@ pub trait Buf {
buf_get_impl!(self, 8, LittleEndian::read_int, nbytes);
}
- #[doc(hidden)]
- #[deprecated(note="use get_f32_be or get_f32_le")]
- fn get_f32<T: ByteOrder>(&mut self) -> f32 where Self: Sized {
- let mut buf = [0; 4];
- self.copy_to_slice(&mut buf);
- T::read_f32(&buf)
- }
-
/// Gets an IEEE754 single-precision (4 bytes) floating point number from
/// `self` in big-endian byte order.
///
@@ -818,13 +746,13 @@ pub trait Buf {
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x3F\x99\x99\x9A hello");
- /// assert_eq!(1.2f32, buf.get_f32_be());
+ /// assert_eq!(1.2f32, buf.get_f32());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
- fn get_f32_be(&mut self) -> f32 {
+ fn get_f32(&mut self) -> f32 {
buf_get_impl!(self, 4, BigEndian::read_f32);
}
@@ -850,14 +778,6 @@ pub trait Buf {
buf_get_impl!(self, 4, LittleEndian::read_f32);
}
- #[doc(hidden)]
- #[deprecated(note="use get_f64_be or get_f64_le")]
- fn get_f64<T: ByteOrder>(&mut self) -> f64 where Self: Sized {
- let mut buf = [0; 8];
- self.copy_to_slice(&mut buf);
- T::read_f64(&buf)
- }
-
/// Gets an IEEE754 double-precision (8 bytes) floating point number from
/// `self` in big-endian byte order.
///
@@ -870,13 +790,13 @@ pub trait Buf {
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello");
- /// assert_eq!(1.2f64, buf.get_f64_be());
+ /// assert_eq!(1.2f64, buf.get_f64());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
- fn get_f64_be(&mut self) -> f64 {
+ fn get_f64(&mut self) -> f64 {
buf_get_impl!(self, 8, BigEndian::read_f64);
}
@@ -1061,7 +981,7 @@ impl<'a, T: Buf + ?Sized> Buf for &'a mut T {
(**self).bytes()
}
- fn bytes_vec<'b>(&'b self, dst: &mut [&'b IoVec]) -> usize {
+ fn bytes_vec<'b>(&'b self, dst: &mut [IoVec<'b>]) -> usize {
(**self).bytes_vec(dst)
}
@@ -1079,7 +999,7 @@ impl<T: Buf + ?Sized> Buf for Box<T> {
(**self).bytes()
}
- fn bytes_vec<'b>(&'b self, dst: &mut [&'b IoVec]) -> usize {
+ fn bytes_vec<'b>(&'b self, dst: &mut [IoVec<'b>]) -> usize {
(**self).bytes_vec(dst)
}
@@ -1151,4 +1071,4 @@ impl Buf for Option<[u8; 1]> {
// The existance of this function makes the compiler catch if the Buf
// trait is "object-safe" or not.
-fn _assert_trait_object(_b: &Buf) {}
+fn _assert_trait_object(_b: &dyn Buf) {}
diff --git a/src/buf/buf_mut.rs b/src/buf/buf_mut.rs
index 7f3c1f7..29774b9 100644
--- a/src/buf/buf_mut.rs
+++ b/src/buf/buf_mut.rs
@@ -1,6 +1,6 @@
use super::{IntoBuf, Writer};
use byteorder::{LittleEndian, ByteOrder, BigEndian};
-use iovec::IoVec;
+use iovec::IoVecMut;
use std::{cmp, io, ptr, usize};
@@ -189,7 +189,7 @@ pub trait BufMut {
/// with `dst` being a zero length slice.
///
/// [`readv`]: http://man7.org/linux/man-pages/man2/readv.2.html
- unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize {
+ unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [IoVecMut<'a>]) -> usize {
if dst.is_empty() {
return 0;
}
@@ -339,14 +339,6 @@ pub trait BufMut {
self.put_slice(&src)
}
- #[doc(hidden)]
- #[deprecated(note="use put_u16_be or put_u16_le")]
- fn put_u16<T: ByteOrder>(&mut self, n: u16) where Self: Sized {
- let mut buf = [0; 2];
- T::write_u16(&mut buf, n);
- self.put_slice(&buf)
- }
-
/// Writes an unsigned 16 bit integer to `self` in big-endian byte order.
///
/// The current position is advanced by 2.
@@ -357,7 +349,7 @@ pub trait BufMut {
/// use bytes::BufMut;
///
/// let mut buf = vec![];
- /// buf.put_u16_be(0x0809);
+ /// buf.put_u16(0x0809);
/// assert_eq!(buf, b"\x08\x09");
/// ```
///
@@ -365,7 +357,7 @@ pub trait BufMut {
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
- fn put_u16_be(&mut self, n: u16) {
+ fn put_u16(&mut self, n: u16) {
let mut buf = [0; 2];
BigEndian::write_u16(&mut buf, n);
self.put_slice(&buf)
@@ -395,14 +387,6 @@ pub trait BufMut {
self.put_slice(&buf)
}
- #[doc(hidden)]
- #[deprecated(note="use put_i16_be or put_i16_le")]
- fn put_i16<T: ByteOrder>(&mut self, n: i16) where Self: Sized {
- let mut buf = [0; 2];
- T::write_i16(&mut buf, n);
- self.put_slice(&buf)
- }
-
/// Writes a signed 16 bit integer to `self` in big-endian byte order.
///
/// The current position is advanced by 2.
@@ -413,7 +397,7 @@ pub trait BufMut {
/// use bytes::BufMut;
///
/// let mut buf = vec![];
- /// buf.put_i16_be(0x0809);
+ /// buf.put_i16(0x0809);
/// assert_eq!(buf, b"\x08\x09");
/// ```
///
@@ -421,7 +405,7 @@ pub trait BufMut {
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
- fn put_i16_be(&mut self, n: i16) {
+ fn put_i16(&mut self, n: i16) {
let mut buf = [0; 2];
BigEndian::write_i16(&mut buf, n);
self.put_slice(&buf)
@@ -451,14 +435,6 @@ pub trait BufMut {
self.put_slice(&buf)
}
- #[doc(hidden)]
- #[deprecated(note="use put_u32_be or put_u32_le")]
- fn put_u32<T: ByteOrder>(&mut self, n: u32) where Self: Sized {
- let mut buf = [0; 4];
- T::write_u32(&mut buf, n);
- self.put_slice(&buf)
- }
-
/// Writes an unsigned 32 bit integer to `self` in big-endian byte order.
///
/// The current position is advanced by 4.
@@ -469,7 +445,7 @@ pub trait BufMut {
/// use bytes::BufMut;
///
/// let mut buf = vec![];
- /// buf.put_u32_be(0x0809A0A1);
+ /// buf.put_u32(0x0809A0A1);
/// assert_eq!(buf, b"\x08\x09\xA0\xA1");
/// ```
///
@@ -477,7 +453,7 @@ pub trait BufMut {
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
- fn put_u32_be(&mut self, n: u32) {
+ fn put_u32(&mut self, n: u32) {
let mut buf = [0; 4];
BigEndian::write_u32(&mut buf, n);
self.put_slice(&buf)
@@ -507,14 +483,6 @@ pub trait BufMut {
self.put_slice(&buf)
}
- #[doc(hidden)]
- #[deprecated(note="use put_i32_be or put_i32_le")]
- fn put_i32<T: ByteOrder>(&mut self, n: i32) where Self: Sized {
- let mut buf = [0; 4];
- T::write_i32(&mut buf, n);
- self.put_slice(&buf)
- }
-
/// Writes a signed 32 bit integer to `self` in big-endian byte order.
///
/// The current position is advanced by 4.
@@ -525,7 +493,7 @@ pub trait BufMut {
/// use bytes::BufMut;
///
/// let mut buf = vec![];
- /// buf.put_i32_be(0x0809A0A1);
+ /// buf.put_i32(0x0809A0A1);
/// assert_eq!(buf, b"\x08\x09\xA0\xA1");
/// ```
///
@@ -533,7 +501,7 @@ pub trait BufMut {
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
- fn put_i32_be(&mut self, n: i32) {
+ fn put_i32(&mut self, n: i32) {
let mut buf = [0; 4];
BigEndian::write_i32(&mut buf, n);
self.put_slice(&buf)
@@ -563,14 +531,6 @@ pub trait BufMut {
self.put_slice(&buf)
}
- #[doc(hidden)]
- #[deprecated(note="use put_u64_be or put_u64_le")]
- fn put_u64<T: ByteOrder>(&mut self, n: u64) where Self: Sized {
- let mut buf = [0; 8];
- T::write_u64(&mut buf, n);
- self.put_slice(&buf)
- }
-
/// Writes an unsigned 64 bit integer to `self` in the big-endian byte order.
///
/// The current position is advanced by 8.
@@ -581,7 +541,7 @@ pub trait BufMut {
/// use bytes::BufMut;
///
/// let mut buf = vec![];
- /// buf.put_u64_be(0x0102030405060708);
+ /// buf.put_u64(0x0102030405060708);
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
/// ```
///
@@ -589,7 +549,7 @@ pub trait BufMut {
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
- fn put_u64_be(&mut self, n: u64) {
+ fn put_u64(&mut self, n: u64) {
let mut buf = [0; 8];
BigEndian::write_u64(&mut buf, n);
self.put_slice(&buf)
@@ -619,14 +579,6 @@ pub trait BufMut {
self.put_slice(&buf)
}
- #[doc(hidden)]
- #[deprecated(note="use put_i64_be or put_i64_le")]
- fn put_i64<T: ByteOrder>(&mut self, n: i64) where Self: Sized {
- let mut buf = [0; 8];
- T::write_i64(&mut buf, n);
- self.put_slice(&buf)
- }
-
/// Writes a signed 64 bit integer to `self` in the big-endian byte order.
///
/// The current position is advanced by 8.
@@ -637,7 +589,7 @@ pub trait BufMut {
/// use bytes::BufMut;
///
/// let mut buf = vec![];
- /// buf.put_i64_be(0x0102030405060708);
+ /// buf.put_i64(0x0102030405060708);
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
/// ```
///
@@ -645,7 +597,7 @@ pub trait BufMut {
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
- fn put_i64_be(&mut self, n: i64) {
+ fn put_i64(&mut self, n: i64) {
let mut buf = [0; 8];
BigEndian::write_i64(&mut buf, n);
self.put_slice(&buf)
@@ -686,7 +638,7 @@ pub trait BufMut {
/// use bytes::BufMut;
///
/// let mut buf = vec![];
- /// buf.put_u128_be(0x01020304050607080910111213141516);
+ /// buf.put_u128(0x01020304050607080910111213141516);
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
/// ```
///
@@ -695,7 +647,7 @@ pub trait BufMut {
/// This function panics if there is not enough remaining capacity in
/// `self`.
#[cfg(feature = "i128")]
- fn put_u128_be(&mut self, n: u128) {
+ fn put_u128(&mut self, n: u128) {
let mut buf = [0; 16];
BigEndian::write_u128(&mut buf, n);
self.put_slice(&buf)
@@ -738,7 +690,7 @@ pub trait BufMut {
/// use bytes::BufMut;
///
/// let mut buf = vec![];
- /// buf.put_i128_be(0x01020304050607080910111213141516);
+ /// buf.put_i128(0x01020304050607080910111213141516);
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
/// ```
///
@@ -747,7 +699,7 @@ pub trait BufMut {
/// This function panics if there is not enough remaining capacity in
/// `self`.
#[cfg(feature = "i128")]
- fn put_i128_be(&mut self, n: i128) {
+ fn put_i128(&mut self, n: i128) {
let mut buf = [0; 16];
BigEndian::write_i128(&mut buf, n);
self.put_slice(&buf)
@@ -779,14 +731,6 @@ pub trait BufMut {
self.put_slice(&buf)
}
- #[doc(hidden)]
- #[deprecated(note="use put_uint_be or put_uint_le")]
- fn put_uint<T: ByteOrder>(&mut self, n: u64, nbytes: usize) where Self: Sized {
- let mut buf = [0; 8];
- T::write_uint(&mut buf, n, nbytes);
- self.put_slice(&buf[0..nbytes])
- }
-
/// Writes an unsigned n-byte integer to `self` in big-endian byte order.
///
/// The current position is advanced by `nbytes`.
@@ -797,7 +741,7 @@ pub trait BufMut {
/// use bytes::BufMut;
///
/// let mut buf = vec![];
- /// buf.put_uint_be(0x010203, 3);
+ /// buf.put_uint(0x010203, 3);
/// assert_eq!(buf, b"\x01\x02\x03");
/// ```
///
@@ -805,7 +749,7 @@ pub trait BufMut {
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
- fn put_uint_be(&mut self, n: u64, nbytes: usize) {
+ fn put_uint(&mut self, n: u64, nbytes: usize) {
let mut buf = [0; 8];
BigEndian::write_uint(&mut buf, n, nbytes);
self.put_slice(&buf[0..nbytes])
@@ -835,14 +779,6 @@ pub trait BufMut {
self.put_slice(&buf[0..nbytes])
}
- #[doc(hidden)]
- #[deprecated(note="use put_int_be or put_int_le")]
- fn put_int<T: ByteOrder>(&mut self, n: i64, nbytes: usize) where Self: Sized {
- let mut buf = [0; 8];
- T::write_int(&mut buf, n, nbytes);
- self.put_slice(&buf[0..nbytes])
- }
-
/// Writes a signed n-byte integer to `self` in big-endian byte order.
///
/// The current position is advanced by `nbytes`.
@@ -853,7 +789,7 @@ pub trait BufMut {
/// use bytes::BufMut;
///
/// let mut buf = vec![];
- /// buf.put_int_be(0x010203, 3);
+ /// buf.put_int(0x010203, 3);
/// assert_eq!(buf, b"\x01\x02\x03");
/// ```
///
@@ -861,7 +797,7 @@ pub trait BufMut {
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
- fn put_int_be(&mut self, n: i64, nbytes: usize) {
+ fn put_int(&mut self, n: i64, nbytes: usize) {
let mut buf = [0; 8];
BigEndian::write_int(&mut buf, n, nbytes);
self.put_slice(&buf[0..nbytes])
@@ -891,14 +827,6 @@ pub trait BufMut {
self.put_slice(&buf[0..nbytes])
}
- #[doc(hidden)]
- #[deprecated(note="use put_f32_be or put_f32_le")]
- fn put_f32<T: ByteOrder>(&mut self, n: f32) where Self: Sized {
- let mut buf = [0; 4];
- T::write_f32(&mut buf, n);
- self.put_slice(&buf)
- }
-
/// Writes an IEEE754 single-precision (4 bytes) floating point number to
/// `self` in big-endian byte order.
///
@@ -910,7 +838,7 @@ pub trait BufMut {
/// use bytes::BufMut;
///
/// let mut buf = vec![];
- /// buf.put_f32_be(1.2f32);
+ /// buf.put_f32(1.2f32);
/// assert_eq!(buf, b"\x3F\x99\x99\x9A");
/// ```
///
@@ -918,7 +846,7 @@ pub trait BufMut {
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
- fn put_f32_be(&mut self, n: f32) {
+ fn put_f32(&mut self, n: f32) {
let mut buf = [0; 4];
BigEndian::write_f32(&mut buf, n);
self.put_slice(&buf)
@@ -949,14 +877,6 @@ pub trait BufMut {
self.put_slice(&buf)
}
- #[doc(hidden)]
- #[deprecated(note="use put_f64_be or put_f64_le")]
- fn put_f64<T: ByteOrder>(&mut self, n: f64) where Self: Sized {
- let mut buf = [0; 8];
- T::write_f64(&mut buf, n);
- self.put_slice(&buf)
- }
-
/// Writes an IEEE754 double-precision (8 bytes) floating point number to
/// `self` in big-endian byte order.
///
@@ -968,7 +888,7 @@ pub trait BufMut {
/// use bytes::BufMut;
///
/// let mut buf = vec![];
- /// buf.put_f64_be(1.2f64);
+ /// buf.put_f64(1.2f64);
/// assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
/// ```
///
@@ -976,7 +896,7 @@ pub trait BufMut {
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
- fn put_f64_be(&mut self, n: f64) {
+ fn put_f64(&mut self, n: f64) {
let mut buf = [0; 8];
BigEndian::write_f64(&mut buf, n);
self.put_slice(&buf)
@@ -1072,7 +992,7 @@ impl<'a, T: BufMut + ?Sized> BufMut for &'a mut T {
(**self).bytes_mut()
}
- unsafe fn bytes_vec_mut<'b>(&'b mut self, dst: &mut [&'b mut IoVec]) -> usize {
+ unsafe fn bytes_vec_mut<'b>(&'b mut self, dst: &mut [IoVecMut<'b>]) -> usize {
(**self).bytes_vec_mut(dst)
}
@@ -1090,7 +1010,7 @@ impl<T: BufMut + ?Sized> BufMut for Box<T> {
(**self).bytes_mut()
}
- unsafe fn bytes_vec_mut<'b>(&'b mut self, dst: &mut [&'b mut IoVec]) -> usize {
+ unsafe fn bytes_vec_mut<'b>(&'b mut self, dst: &mut [IoVecMut<'b>]) -> usize {
(**self).bytes_vec_mut(dst)
}
@@ -1164,4 +1084,4 @@ impl BufMut for Vec<u8> {
// The existance of this function makes the compiler catch if the BufMut
// trait is "object-safe" or not.
-fn _assert_trait_object(_b: &BufMut) {}
+fn _assert_trait_object(_b: &dyn BufMut) {}
diff --git a/src/buf/chain.rs b/src/buf/chain.rs
index 7dd44ab..76f1045 100644
--- a/src/buf/chain.rs
+++ b/src/buf/chain.rs
@@ -1,5 +1,5 @@
use {Buf, BufMut};
-use iovec::IoVec;
+use iovec::{IoVec, IoVecMut};
/// A `Chain` sequences two buffers.
///
@@ -177,7 +177,7 @@ impl<T, U> Buf for Chain<T, U>
self.b.advance(cnt);
}
- fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize {
+ fn bytes_vec<'a>(&'a self, dst: &mut [IoVec<'a>]) -> usize {
let mut n = self.a.bytes_vec(dst);
n += self.b.bytes_vec(&mut dst[n..]);
n
@@ -218,7 +218,7 @@ impl<T, U> BufMut for Chain<T, U>
self.b.advance_mut(cnt);
}
- unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize {
+ unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [IoVecMut<'a>]) -> usize {
let mut n = self.a.bytes_vec_mut(dst);
n += self.b.bytes_vec_mut(&mut dst[n..]);
n
diff --git a/src/buf/into_buf.rs b/src/buf/into_buf.rs
index 4c3b420..d43f95b 100644
--- a/src/buf/into_buf.rs
+++ b/src/buf/into_buf.rs
@@ -11,12 +11,12 @@ use std::io;
/// # Examples
///
/// ```
-/// use bytes::{Buf, IntoBuf, BigEndian};
+/// use bytes::{Buf, IntoBuf};
///
/// let bytes = b"\x00\x01hello world";
/// let mut buf = bytes.into_buf();
///
-/// assert_eq!(1, buf.get_u16::<BigEndian>());
+/// assert_eq!(1, buf.get_u16());
///
/// let mut rest = [0; 11];
/// buf.copy_to_slice(&mut rest);
@@ -32,12 +32,12 @@ pub trait IntoBuf {
/// # Examples
///
/// ```
- /// use bytes::{Buf, IntoBuf, BigEndian};
+ /// use bytes::{Buf, IntoBuf};
///
/// let bytes = b"\x00\x01hello world";
/// let mut buf = bytes.into_buf();
///
- /// assert_eq!(1, buf.get_u16::<BigEndian>());
+ /// assert_eq!(1, buf.get_u16());
///
/// let mut rest = [0; 11];
/// buf.copy_to_slice(&mut rest);
diff --git a/src/bytes.rs b/src/bytes.rs
index a9aefa9..3343741 100644
--- a/src/bytes.rs
+++ b/src/bytes.rs
@@ -95,8 +95,8 @@ use std::iter::{FromIterator, Iterator};
/// # Inline bytes
///
/// As an optimization, when the slice referenced by a `Bytes` or `BytesMut`
-/// handle is small enough [^1], `with_capacity` will avoid the allocation by
-/// inlining the slice directly in the handle. In this case, a clone is no
+/// handle is small enough [^1], `with_capacity` will avoid the allocation
+/// by inlining the slice directly in the handle. In this case, a clone is no
/// longer "shallow" and the data will be copied. Converting from a `Vec` will
/// never use inlining.
///
@@ -485,6 +485,20 @@ impl Bytes {
self.inner.is_empty()
}
+ /// Return true if the `Bytes` uses inline allocation
+ ///
+ /// # Examples
+ /// ```
+ /// use bytes::Bytes;
+ ///
+ /// assert!(Bytes::with_capacity(4).is_inline());
+ /// assert!(!Bytes::from(Vec::with_capacity(4)).is_inline());
+ /// assert!(!Bytes::with_capacity(1024).is_inline());
+ /// ```
+ pub fn is_inline(&self) -> bool {
+ self.inner.is_inline()
+ }
+
/// Returns a slice of self for the index range `[begin..end)`.
///
/// This will increment the reference count for the underlying memory and
@@ -791,6 +805,17 @@ impl Bytes {
}
}
+ /// Acquires a mutable reference to the owned form of the data.
+ ///
+ /// Clones the data if it is not already owned.
+ pub fn to_mut(&mut self) -> &mut BytesMut {
+ if !self.inner.is_mut_safe() {
+ let new = Bytes::from(&self[..]);
+ *self = new;
+ }
+ unsafe { &mut *(self as *mut Bytes as *mut BytesMut) }
+ }
+
/// Appends given bytes to this object.
///
/// If this `Bytes` object has not enough capacity, it is resized first.
@@ -832,6 +857,36 @@ impl Bytes {
mem::replace(self, result.freeze());
}
+
+ /// Combine splitted Bytes objects back as contiguous.
+ ///
+ /// If `Bytes` objects were not contiguous originally, they will be extended.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use bytes::Bytes;
+ ///
+ /// let mut buf = Bytes::with_capacity(64);
+ /// buf.extend_from_slice(b"aaabbbcccddd");
+ ///
+ /// let splitted = buf.split_off(6);
+ /// assert_eq!(b"aaabbb", &buf[..]);
+ /// assert_eq!(b"cccddd", &splitted[..]);
+ ///
+ /// buf.unsplit(splitted);
+ /// assert_eq!(b"aaabbbcccddd", &buf[..]);
+ /// ```
+ pub fn unsplit(&mut self, other: Bytes) {
+ if self.is_empty() {
+ *self = other;
+ return;
+ }
+
+ if let Err(other_inner) = self.inner.try_unsplit(other.inner) {
+ self.extend_from_slice(other_inner.as_ref());
+ }
+ }
}
impl IntoBuf for Bytes {
@@ -881,6 +936,11 @@ impl From<BytesMut> for Bytes {
}
impl From<Vec<u8>> for Bytes {
+ /// Convert a `Vec` into a `Bytes`
+ ///
+ /// This constructor may be used to avoid the inlining optimization used by
+ /// `with_capacity`. A `Bytes` constructed this way will always store its
+ /// data on the heap.
fn from(src: Vec<u8>) -> Bytes {
BytesMut::from(src).freeze()
}
@@ -1123,7 +1183,21 @@ impl BytesMut {
/// ```
#[inline]
pub fn is_empty(&self) -> bool {
- self.len() == 0
+ self.inner.is_empty()
+ }
+
+ /// Return true if the `BytesMut` uses inline allocation
+ ///
+ /// # Examples
+ /// ```
+ /// use bytes::BytesMut;
+ ///
+ /// assert!(BytesMut::with_capacity(4).is_inline());
+ /// assert!(!BytesMut::from(Vec::with_capacity(4)).is_inline());
+ /// assert!(!BytesMut::with_capacity(1024).is_inline());
+ /// ```
+ pub fn is_inline(&self) -> bool {
+ self.inner.is_inline()
}
/// Returns the number of bytes the `BytesMut` can hold without reallocating.
@@ -1487,32 +1561,13 @@ impl BytesMut {
/// assert_eq!(b"aaabbbcccddd", &buf[..]);
/// ```
pub fn unsplit(&mut self, other: BytesMut) {
- let ptr;
-
- if other.is_empty() {
- return;
- }
-
if self.is_empty() {
*self = other;
return;
}
- unsafe {
- ptr = self.inner.ptr.offset(self.inner.len as isize);
- }
- if ptr == other.inner.ptr &&
- self.inner.kind() == KIND_ARC &&
- other.inner.kind() == KIND_ARC
- {
- debug_assert_eq!(self.inner.arc.load(Acquire),
- other.inner.arc.load(Acquire));
- // Contiguous blocks, just combine directly
- self.inner.len += other.inner.len;
- self.inner.cap += other.inner.cap;
- }
- else {
- self.extend_from_slice(&other);
+ if let Err(other_inner) = self.inner.try_unsplit(other.inner) {
+ self.extend_from_slice(other_inner.as_ref());
}
}
}
@@ -1608,6 +1663,11 @@ impl ops::DerefMut for BytesMut {
}
impl From<Vec<u8>> for BytesMut {
+ /// Convert a `Vec` into a `BytesMut`
+ ///
+ /// This constructor may be used to avoid the inlining optimization used by
+ /// `with_capacity`. A `BytesMut` constructed this way will always store
+ /// its data on the heap.
fn from(src: Vec<u8>) -> BytesMut {
BytesMut {
inner: Inner::from_vec(src),
@@ -1973,6 +2033,31 @@ impl Inner {
}
}
+ fn try_unsplit(&mut self, other: Inner) -> Result<(), Inner> {
+ let ptr;
+
+ if other.is_empty() {
+ return Ok(());
+ }
+
+ unsafe {
+ ptr = self.ptr.offset(self.len as isize);
+ }
+ if ptr == other.ptr &&
+ self.kind() == KIND_ARC &&
+ other.kind() == KIND_ARC
+ {
+ debug_assert_eq!(self.arc.load(Acquire),
+ other.arc.load(Acquire));
+ // Contiguous blocks, just combine directly
+ self.len += other.len;
+ self.cap += other.cap;
+ Ok(())
+ } else {
+ Err(other)
+ }
+ }
+
fn resize(&mut self, new_len: usize, value: u8) {
let len = self.len();
if new_len > len {
diff --git a/src/either.rs b/src/either.rs
index 53a2775..b3c7801 100644
--- a/src/either.rs
+++ b/src/either.rs
@@ -4,7 +4,7 @@ use {Buf, BufMut};
use self::either::Either;
use self::either::Either::*;
-use iovec::IoVec;
+use iovec::{IoVec, IoVecMut};
impl<L, R> Buf for Either<L, R>
where
@@ -25,7 +25,7 @@ where
}
}
- fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize {
+ fn bytes_vec<'a>(&'a self, dst: &mut [IoVec<'a>]) -> usize {
match *self {
Left(ref b) => b.bytes_vec(dst),
Right(ref b) => b.bytes_vec(dst),
@@ -66,7 +66,7 @@ where
}
}
- unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize {
+ unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [IoVecMut<'a>]) -> usize {
match *self {
Left(ref mut b) => b.bytes_vec_mut(dst),
Right(ref mut b) => b.bytes_vec_mut(dst),
diff --git a/src/lib.rs b/src/lib.rs
index a4f1573..04dae76 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -23,11 +23,11 @@
//! example:
//!
//! ```rust
-//! use bytes::{BytesMut, BufMut, BigEndian};
+//! use bytes::{BytesMut, BufMut};
//!
//! let mut buf = BytesMut::with_capacity(1024);
//! buf.put(&b"hello world"[..]);
-//! buf.put_u16::<BigEndian>(1234);
+//! buf.put_u16(1234);
//!
//! let a = buf.take();
//! assert_eq!(a, b"hello world\x04\xD2"[..]);
@@ -69,7 +69,7 @@
//! and `BufMut` are infallible.
#![deny(warnings, missing_docs, missing_debug_implementations)]
-#![doc(html_root_url = "https://docs.rs/bytes/0.4.12")]
+#![doc(html_root_url = "https://docs.rs/bytes/0.5.0")]
extern crate byteorder;
extern crate iovec;
@@ -92,9 +92,6 @@ mod bytes;
mod debug;
pub use bytes::{Bytes, BytesMut};
-#[deprecated]
-pub use byteorder::{ByteOrder, BigEndian, LittleEndian};
-
// Optional Serde support
#[cfg(feature = "serde")]
#[doc(hidden)]
diff --git a/tests/test_buf.rs b/tests/test_buf.rs
index f25c25f..93817ea 100644
--- a/tests/test_buf.rs
+++ b/tests/test_buf.rs
@@ -33,7 +33,7 @@ fn test_get_u8() {
#[test]
fn test_get_u16() {
let buf = b"\x21\x54zomg";
- assert_eq!(0x2154, Cursor::new(buf).get_u16_be());
+ assert_eq!(0x2154, Cursor::new(buf).get_u16());
assert_eq!(0x5421, Cursor::new(buf).get_u16_le());
}
@@ -41,7 +41,7 @@ fn test_get_u16() {
#[should_panic]
fn test_get_u16_buffer_underflow() {
let mut buf = Cursor::new(b"\x21");
- buf.get_u16_be();
+ buf.get_u16();
}
#[test]
@@ -51,7 +51,7 @@ fn test_bufs_vec() {
let b1: &[u8] = &mut [0];
let b2: &[u8] = &mut [0];
- let mut dst: [&IoVec; 2] =
+ let mut dst: [IoVec; 2] =
[b1.into(), b2.into()];
assert_eq!(1, buf.bytes_vec(&mut dst[..]));
diff --git a/tests/test_buf_mut.rs b/tests/test_buf_mut.rs
index 2c8faa1..0179259 100644
--- a/tests/test_buf_mut.rs
+++ b/tests/test_buf_mut.rs
@@ -3,7 +3,7 @@ extern crate byteorder;
extern crate iovec;
use bytes::{BufMut, BytesMut};
-use iovec::IoVec;
+use iovec::IoVecMut;
use std::usize;
use std::fmt::Write;
@@ -41,7 +41,7 @@ fn test_put_u8() {
#[test]
fn test_put_u16() {
let mut buf = Vec::with_capacity(8);
- buf.put_u16_be(8532);
+ buf.put_u16(8532);
assert_eq!(b"\x21\x54", &buf[..]);
buf.clear();
@@ -77,7 +77,7 @@ fn test_bufs_vec_mut() {
let mut buf = BytesMut::from(&b"hello world"[..]);
unsafe {
- let mut dst: [&mut IoVec; 2] = mem::zeroed();
+ let mut dst: [IoVecMut; 2] = mem::zeroed();
assert_eq!(1, buf.bytes_vec_mut(&mut dst[..]));
}
}
diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs
index e188354..5eaedd3 100644
--- a/tests/test_bytes.rs
+++ b/tests/test_bytes.rs
@@ -571,7 +571,141 @@ fn partial_eq_bytesmut() {
}
#[test]
-fn unsplit_basic() {
+fn bytes_unsplit_basic() {
+ let mut buf = Bytes::with_capacity(64);
+ buf.extend_from_slice(b"aaabbbcccddd");
+
+ let splitted = buf.split_off(6);
+ assert_eq!(b"aaabbb", &buf[..]);
+ assert_eq!(b"cccddd", &splitted[..]);
+
+ buf.unsplit(splitted);
+ assert_eq!(b"aaabbbcccddd", &buf[..]);
+}
+
+#[test]
+fn bytes_unsplit_empty_other() {
+ let mut buf = Bytes::with_capacity(64);
+ buf.extend_from_slice(b"aaabbbcccddd");
+
+ // empty other
+ let other = Bytes::new();
+
+ buf.unsplit(other);
+ assert_eq!(b"aaabbbcccddd", &buf[..]);
+}
+
+#[test]
+fn bytes_unsplit_empty_self() {
+ // empty self
+ let mut buf = Bytes::new();
+
+ let mut other = Bytes::with_capacity(64);
+ other.extend_from_slice(b"aaabbbcccddd");
+
+ buf.unsplit(other);
+ assert_eq!(b"aaabbbcccddd", &buf[..]);
+}
+
+#[test]
+fn bytes_unsplit_inline_arc() {
+ let mut buf = Bytes::with_capacity(8); //inline
+ buf.extend_from_slice(b"aaaabbbb");
+
+ let mut buf2 = Bytes::with_capacity(64);
+ buf2.extend_from_slice(b"ccccddddeeee");
+
+ buf2.split_off(8); //arc
+
+ buf.unsplit(buf2);
+ assert_eq!(b"aaaabbbbccccdddd", &buf[..]);
+}
+
+#[test]
+fn bytes_unsplit_arc_inline() {
+ let mut buf = Bytes::with_capacity(64);
+ buf.extend_from_slice(b"aaaabbbbeeee");
+
+ buf.split_off(8); //arc
+
+ let mut buf2 = Bytes::with_capacity(8); //inline
+ buf2.extend_from_slice(b"ccccdddd");
+
+ buf.unsplit(buf2);
+ assert_eq!(b"aaaabbbbccccdddd", &buf[..]);
+
+}
+
+#[test]
+fn bytes_unsplit_both_inline() {
+ let mut buf = Bytes::with_capacity(16); //inline
+ buf.extend_from_slice(b"aaaabbbbccccdddd");
+
+ let splitted = buf.split_off(8); // both inline
+ assert_eq!(b"aaaabbbb", &buf[..]);
+ assert_eq!(b"ccccdddd", &splitted[..]);
+
+ buf.unsplit(splitted);
+ assert_eq!(b"aaaabbbbccccdddd", &buf[..]);
+}
+
+
+#[test]
+fn bytes_unsplit_arc_different() {
+ let mut buf = Bytes::with_capacity(64);
+ buf.extend_from_slice(b"aaaabbbbeeee");
+
+ buf.split_off(8); //arc
+
+ let mut buf2 = Bytes::with_capacity(64);
+ buf2.extend_from_slice(b"ccccddddeeee");
+
+ buf2.split_off(8); //arc
+
+ buf.unsplit(buf2);
+ assert_eq!(b"aaaabbbbccccdddd", &buf[..]);
+}
+
+#[test]
+fn bytes_unsplit_arc_non_contiguous() {
+ let mut buf = Bytes::with_capacity(64);
+ buf.extend_from_slice(b"aaaabbbbeeeeccccdddd");
+
+ let mut buf2 = buf.split_off(8); //arc
+
+ let buf3 = buf2.split_off(4); //arc
+
+ buf.unsplit(buf3);
+ assert_eq!(b"aaaabbbbccccdddd", &buf[..]);
+}
+
+#[test]
+fn bytes_unsplit_two_split_offs() {
+ let mut buf = Bytes::with_capacity(64);
+ buf.extend_from_slice(b"aaaabbbbccccdddd");
+
+ let mut buf2 = buf.split_off(8); //arc
+ let buf3 = buf2.split_off(4); //arc
+
+ buf2.unsplit(buf3);
+ buf.unsplit(buf2);
+ assert_eq!(b"aaaabbbbccccdddd", &buf[..]);
+}
+
+#[test]
+fn bytes_unsplit_overlapping_references() {
+ let mut buf = Bytes::with_capacity(64);
+ buf.extend_from_slice(b"abcdefghijklmnopqrstuvwxyz");
+ let mut buf0010 = buf.slice(0, 10);
+ let buf1020 = buf.slice(10, 20);
+ let buf0515 = buf.slice(5, 15);
+ buf0010.unsplit(buf1020);
+ assert_eq!(b"abcdefghijklmnopqrst", &buf0010[..]);
+ assert_eq!(b"fghijklmno", &buf0515[..]);
+}
+
+#[test]
+fn bytes_mut_unsplit_basic() {
let mut buf = BytesMut::with_capacity(64);
buf.extend_from_slice(b"aaabbbcccddd");
@@ -584,7 +718,7 @@ fn unsplit_basic() {
}
#[test]
-fn unsplit_empty_other() {
+fn bytes_mut_unsplit_empty_other() {
let mut buf = BytesMut::with_capacity(64);
buf.extend_from_slice(b"aaabbbcccddd");
@@ -596,7 +730,7 @@ fn unsplit_empty_other() {
}
#[test]
-fn unsplit_empty_self() {
+fn bytes_mut_unsplit_empty_self() {
// empty self
let mut buf = BytesMut::new();
@@ -608,7 +742,7 @@ fn unsplit_empty_self() {
}
#[test]
-fn unsplit_inline_arc() {
+fn bytes_mut_unsplit_inline_arc() {
let mut buf = BytesMut::with_capacity(8); //inline
buf.extend_from_slice(b"aaaabbbb");
@@ -622,7 +756,7 @@ fn unsplit_inline_arc() {
}
#[test]
-fn unsplit_arc_inline() {
+fn bytes_mut_unsplit_arc_inline() {
let mut buf = BytesMut::with_capacity(64);
buf.extend_from_slice(b"aaaabbbbeeee");
@@ -637,7 +771,7 @@ fn unsplit_arc_inline() {
}
#[test]
-fn unsplit_both_inline() {
+fn bytes_mut_unsplit_both_inline() {
let mut buf = BytesMut::with_capacity(16); //inline
buf.extend_from_slice(b"aaaabbbbccccdddd");
@@ -651,7 +785,7 @@ fn unsplit_both_inline() {
#[test]
-fn unsplit_arc_different() {
+fn bytes_mut_unsplit_arc_different() {
let mut buf = BytesMut::with_capacity(64);
buf.extend_from_slice(b"aaaabbbbeeee");
@@ -667,7 +801,7 @@ fn unsplit_arc_different() {
}
#[test]
-fn unsplit_arc_non_contiguous() {
+fn bytes_mut_unsplit_arc_non_contiguous() {
let mut buf = BytesMut::with_capacity(64);
buf.extend_from_slice(b"aaaabbbbeeeeccccdddd");
@@ -680,7 +814,7 @@ fn unsplit_arc_non_contiguous() {
}
#[test]
-fn unsplit_two_split_offs() {
+fn bytes_mut_unsplit_two_split_offs() {
let mut buf = BytesMut::with_capacity(64);
buf.extend_from_slice(b"aaaabbbbccccdddd");
diff --git a/tests/test_chain.rs b/tests/test_chain.rs
index 2789e7c..049a8a2 100644
--- a/tests/test_chain.rs
+++ b/tests/test_chain.rs
@@ -59,7 +59,7 @@ fn vectored_read() {
let b2: &[u8] = &mut [0];
let b3: &[u8] = &mut [0];
let b4: &[u8] = &mut [0];
- let mut iovecs: [&IoVec; 4] =
+ let mut iovecs: [IoVec; 4] =
[b1.into(), b2.into(), b3.into(), b4.into()];
assert_eq!(2, buf.bytes_vec(&mut iovecs));
@@ -76,7 +76,7 @@ fn vectored_read() {
let b2: &[u8] = &mut [0];
let b3: &[u8] = &mut [0];
let b4: &[u8] = &mut [0];
- let mut iovecs: [&IoVec; 4] =
+ let mut iovecs: [IoVec; 4] =
[b1.into(), b2.into(), b3.into(), b4.into()];
assert_eq!(2, buf.bytes_vec(&mut iovecs));
@@ -93,7 +93,7 @@ fn vectored_read() {
let b2: &[u8] = &mut [0];
let b3: &[u8] = &mut [0];
let b4: &[u8] = &mut [0];
- let mut iovecs: [&IoVec; 4] =
+ let mut iovecs: [IoVec; 4] =
[b1.into(), b2.into(), b3.into(), b4.into()];
assert_eq!(1, buf.bytes_vec(&mut iovecs));
@@ -110,7 +110,7 @@ fn vectored_read() {
let b2: &[u8] = &mut [0];
let b3: &[u8] = &mut [0];
let b4: &[u8] = &mut [0];
- let mut iovecs: [&IoVec; 4] =
+ let mut iovecs: [IoVec; 4] =
[b1.into(), b2.into(), b3.into(), b4.into()];
assert_eq!(1, buf.bytes_vec(&mut iovecs));