mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-08 00:00:26 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef09e98fbc | ||
|
|
51e435b7e0 | ||
|
|
15050b1da5 | ||
|
|
ce79f0a268 | ||
|
|
86c83959dc | ||
|
|
e5c4c6028d | ||
|
|
ba9a975358 | ||
|
|
6a3d20bb8d | ||
|
|
2ca61d881d | ||
|
|
8d6c2b61cc | ||
|
|
02891144be | ||
|
|
149922d7cf | ||
|
|
03d501b18d | ||
|
|
34540be54c | ||
|
|
cfca1c04fa |
@@ -36,6 +36,13 @@ matrix:
|
||||
# Serde implementation
|
||||
- env: EXTRA_ARGS="--features serde"
|
||||
|
||||
# WASM support
|
||||
- rust: beta
|
||||
script:
|
||||
- rustup target add wasm32-unknown-unknown
|
||||
- cargo build --target=wasm32-unknown-unknown
|
||||
|
||||
|
||||
before_install: set -e
|
||||
|
||||
install:
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
# 0.4.7 (April 27, 2018)
|
||||
|
||||
* Make `Buf` and `BufMut` usable as trait objects (#186).
|
||||
* impl BorrowMut for BytesMut (#185).
|
||||
* Improve accessor performance (#195).
|
||||
|
||||
# 0.4.6 (Janary 8, 2018)
|
||||
|
||||
* Implement FromIterator for Bytes/BytesMut (#148).
|
||||
* Add `advance` fn to Bytes/BytesMut (#166).
|
||||
* Add `unsplit` fn to `BytesMut` (#162, #173).
|
||||
* Improvements to Bytes split fns (#92).
|
||||
|
||||
# 0.4.5 (August 12, 2017)
|
||||
|
||||
* Fix range bug in `Take::bytes`
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
|
||||
name = "bytes"
|
||||
version = "0.4.5"
|
||||
version = "0.4.7" # don't forget to update html_root_url
|
||||
license = "MIT/Apache-2.0"
|
||||
authors = ["Carl Lerche <[email protected]>"]
|
||||
description = "Types and traits for working with bytes"
|
||||
|
||||
@@ -29,6 +29,18 @@ fn alloc_big(b: &mut Bencher) {
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn split_off_and_drop(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
for _ in 0..1024 {
|
||||
let v = vec![10; 200];
|
||||
let mut b = Bytes::from(v);
|
||||
test::black_box(b.split_off(100));
|
||||
test::black_box(b);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn deref_unique(b: &mut Bencher) {
|
||||
let mut buf = BytesMut::with_capacity(4096);
|
||||
|
||||
+455
-145
@@ -1,9 +1,41 @@
|
||||
use super::{IntoBuf, Take, Reader, Iter, FromBuf, Chain};
|
||||
use byteorder::ByteOrder;
|
||||
use byteorder::{BigEndian, ByteOrder, LittleEndian};
|
||||
use iovec::IoVec;
|
||||
|
||||
use std::{cmp, io, ptr};
|
||||
|
||||
macro_rules! buf_get_impl {
|
||||
($this:ident, $size:expr, $conv:path) => ({
|
||||
// try to convert directly from the bytes
|
||||
let ret = {
|
||||
// this Option<ret> trick is to avoid keeping a borrow on self
|
||||
// when advance() is called (mut borrow) and to call bytes() only once
|
||||
if let Some(src) = $this.bytes().get(..($size)) {
|
||||
Some($conv(src))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
if let Some(ret) = ret {
|
||||
// if the direct convertion was possible, advance and return
|
||||
$this.advance($size);
|
||||
return ret;
|
||||
} else {
|
||||
// if not we copy the bytes in a temp buffer then convert
|
||||
let mut buf = [0; ($size)];
|
||||
$this.copy_to_slice(&mut buf); // (do the advance)
|
||||
return $conv(&buf);
|
||||
}
|
||||
});
|
||||
($this:ident, $buf_size:expr, $conv:path, $len_to_read:expr) => ({
|
||||
// The same trick as above does not improve the best case speed.
|
||||
// It seems to be linked to the way the method is optimised by the compiler
|
||||
let mut buf = [0; ($buf_size)];
|
||||
$this.copy_to_slice(&mut buf[..($len_to_read)]);
|
||||
return $conv(&buf[..($len_to_read)], $len_to_read);
|
||||
});
|
||||
}
|
||||
|
||||
/// Read bytes from a buffer.
|
||||
///
|
||||
/// A buffer stores bytes in memory such that read operations are infallible.
|
||||
@@ -243,9 +275,10 @@ pub trait Buf {
|
||||
///
|
||||
/// This function panics if there is no more remaining data in `self`.
|
||||
fn get_u8(&mut self) -> u8 {
|
||||
let mut buf = [0; 1];
|
||||
self.copy_to_slice(&mut buf);
|
||||
buf[0]
|
||||
assert!(self.remaining() >= 1);
|
||||
let ret = self.bytes()[0];
|
||||
self.advance(1);
|
||||
ret
|
||||
}
|
||||
|
||||
/// Gets a signed 8 bit integer from `self`.
|
||||
@@ -266,243 +299,516 @@ pub trait Buf {
|
||||
///
|
||||
/// This function panics if there is no more remaining data in `self`.
|
||||
fn get_i8(&mut self) -> i8 {
|
||||
let mut buf = [0; 1];
|
||||
self.copy_to_slice(&mut buf);
|
||||
buf[0] as i8
|
||||
assert!(self.remaining() >= 1);
|
||||
let ret = self.bytes()[0] as i8;
|
||||
self.advance(1);
|
||||
ret
|
||||
}
|
||||
|
||||
/// Gets an unsigned 16 bit integer from `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x08\x09 hello");
|
||||
/// assert_eq!(0x0809, buf.get_u16::<BigEndian>());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_u16<T: ByteOrder>(&mut self) -> u16 {
|
||||
#[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 a signed 16 bit integer from `self` in the specified byte order.
|
||||
/// Gets an unsigned 16 bit integer from `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x08\x09 hello");
|
||||
/// assert_eq!(0x0809, buf.get_i16::<BigEndian>());
|
||||
/// assert_eq!(0x0809, buf.get_u16_be());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_i16<T: ByteOrder>(&mut self) -> i16 {
|
||||
fn get_u16_be(&mut self) -> u16 {
|
||||
buf_get_impl!(self, 2, BigEndian::read_u16);
|
||||
}
|
||||
|
||||
/// Gets an unsigned 16 bit integer from `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x09\x08 hello");
|
||||
/// assert_eq!(0x0809, buf.get_u16_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_u16_le(&mut self) -> u16 {
|
||||
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 an unsigned 32 bit integer from `self` in the specified byte order.
|
||||
/// Gets a signed 16 bit integer from `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x08\x09\xA0\xA1 hello");
|
||||
/// assert_eq!(0x0809A0A1, buf.get_u32::<BigEndian>());
|
||||
/// let mut buf = Cursor::new(b"\x08\x09 hello");
|
||||
/// assert_eq!(0x0809, buf.get_i16_be());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_u32<T: ByteOrder>(&mut self) -> u32 {
|
||||
fn get_i16_be(&mut self) -> i16 {
|
||||
buf_get_impl!(self, 2, BigEndian::read_i16);
|
||||
}
|
||||
|
||||
/// Gets a signed 16 bit integer from `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x09\x08 hello");
|
||||
/// assert_eq!(0x0809, buf.get_i16_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_i16_le(&mut self) -> i16 {
|
||||
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 a signed 32 bit integer from `self` in the specified byte order.
|
||||
/// Gets an unsigned 32 bit integer from `self` in the big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x08\x09\xA0\xA1 hello");
|
||||
/// assert_eq!(0x0809A0A1, buf.get_i32::<BigEndian>());
|
||||
/// assert_eq!(0x0809A0A1, buf.get_u32_be());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_i32<T: ByteOrder>(&mut self) -> i32 {
|
||||
fn get_u32_be(&mut self) -> u32 {
|
||||
buf_get_impl!(self, 4, BigEndian::read_u32);
|
||||
}
|
||||
|
||||
/// Gets an unsigned 32 bit integer from `self` in the little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\xA1\xA0\x09\x08 hello");
|
||||
/// assert_eq!(0x0809A0A1, buf.get_u32_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_u32_le(&mut self) -> u32 {
|
||||
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 an unsigned 64 bit integer from `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// 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::<BigEndian>());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_u64<T: ByteOrder>(&mut self) -> u64 {
|
||||
let mut buf = [0; 8];
|
||||
self.copy_to_slice(&mut buf);
|
||||
T::read_u64(&buf)
|
||||
}
|
||||
|
||||
/// Gets a signed 64 bit integer from `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// 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::<BigEndian>());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_i64<T: ByteOrder>(&mut self) -> i64 {
|
||||
let mut buf = [0; 8];
|
||||
self.copy_to_slice(&mut buf);
|
||||
T::read_i64(&buf)
|
||||
}
|
||||
|
||||
/// Gets an unsigned n-byte integer from `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x01\x02\x03 hello");
|
||||
/// assert_eq!(0x010203, buf.get_uint::<BigEndian>(3));
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_uint<T: ByteOrder>(&mut self, nbytes: usize) -> u64 {
|
||||
let mut buf = [0; 8];
|
||||
self.copy_to_slice(&mut buf[..nbytes]);
|
||||
T::read_uint(&buf[..nbytes], nbytes)
|
||||
}
|
||||
|
||||
/// Gets a signed n-byte integer from `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x01\x02\x03 hello");
|
||||
/// assert_eq!(0x010203, buf.get_int::<BigEndian>(3));
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_int<T: ByteOrder>(&mut self, nbytes: usize) -> i64 {
|
||||
let mut buf = [0; 8];
|
||||
self.copy_to_slice(&mut buf[..nbytes]);
|
||||
T::read_int(&buf[..nbytes], nbytes)
|
||||
}
|
||||
|
||||
/// Gets an IEEE754 single-precision (4 bytes) floating point number from
|
||||
/// `self` in the specified byte order.
|
||||
/// Gets a signed 32 bit integer from `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x3F\x99\x99\x9A hello");
|
||||
/// assert_eq!(1.2f32, buf.get_f32::<BigEndian>());
|
||||
/// let mut buf = Cursor::new(b"\x08\x09\xA0\xA1 hello");
|
||||
/// assert_eq!(0x0809A0A1, buf.get_i32_be());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_f32<T: ByteOrder>(&mut self) -> f32 {
|
||||
let mut buf = [0; 4];
|
||||
self.copy_to_slice(&mut buf);
|
||||
T::read_f32(&buf)
|
||||
fn get_i32_be(&mut self) -> i32 {
|
||||
buf_get_impl!(self, 4, BigEndian::read_i32);
|
||||
}
|
||||
|
||||
/// Gets an IEEE754 double-precision (8 bytes) floating point number from
|
||||
/// `self` in the specified byte order.
|
||||
/// Gets a signed 32 bit integer from `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\xA1\xA0\x09\x08 hello");
|
||||
/// assert_eq!(0x0809A0A1, buf.get_i32_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_i32_le(&mut self) -> i32 {
|
||||
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.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::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());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_u64_be(&mut self) -> u64 {
|
||||
buf_get_impl!(self, 8, BigEndian::read_u64);
|
||||
}
|
||||
|
||||
/// Gets an unsigned 64 bit integer from `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x08\x07\x06\x05\x04\x03\x02\x01 hello");
|
||||
/// assert_eq!(0x0102030405060708, buf.get_u64_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_u64_le(&mut self) -> u64 {
|
||||
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.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::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());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_i64_be(&mut self) -> i64 {
|
||||
buf_get_impl!(self, 8, BigEndian::read_i64);
|
||||
}
|
||||
|
||||
/// Gets a signed 64 bit integer from `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x08\x07\x06\x05\x04\x03\x02\x01 hello");
|
||||
/// assert_eq!(0x0102030405060708, buf.get_i64_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_i64_le(&mut self) -> i64 {
|
||||
buf_get_impl!(self, 8, LittleEndian::read_i64);
|
||||
}
|
||||
|
||||
#[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`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// 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::<BigEndian>());
|
||||
/// let mut buf = Cursor::new(b"\x01\x02\x03 hello");
|
||||
/// assert_eq!(0x010203, buf.get_uint_be(3));
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_f64<T: ByteOrder>(&mut self) -> f64 {
|
||||
fn get_uint_be(&mut self, nbytes: usize) -> u64 {
|
||||
buf_get_impl!(self, 8, BigEndian::read_uint, nbytes);
|
||||
}
|
||||
|
||||
/// Gets an unsigned n-byte integer from `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x03\x02\x01 hello");
|
||||
/// assert_eq!(0x010203, buf.get_uint_le(3));
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_uint_le(&mut self, nbytes: usize) -> u64 {
|
||||
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`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x01\x02\x03 hello");
|
||||
/// assert_eq!(0x010203, buf.get_int_be(3));
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_int_be(&mut self, nbytes: usize) -> i64 {
|
||||
buf_get_impl!(self, 8, BigEndian::read_int, nbytes);
|
||||
}
|
||||
|
||||
/// Gets a signed n-byte integer from `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x03\x02\x01 hello");
|
||||
/// assert_eq!(0x010203, buf.get_int_le(3));
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_int_le(&mut self, nbytes: usize) -> i64 {
|
||||
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.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x3F\x99\x99\x9A hello");
|
||||
/// assert_eq!(1.2f32, buf.get_f32_be());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_f32_be(&mut self) -> f32 {
|
||||
buf_get_impl!(self, 4, BigEndian::read_f32);
|
||||
}
|
||||
|
||||
/// Gets an IEEE754 single-precision (4 bytes) floating point number from
|
||||
/// `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x9A\x99\x99\x3F hello");
|
||||
/// assert_eq!(1.2f32, buf.get_f32_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_f32_le(&mut self) -> f32 {
|
||||
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.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::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());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_f64_be(&mut self) -> f64 {
|
||||
buf_get_impl!(self, 8, BigEndian::read_f64);
|
||||
}
|
||||
|
||||
/// Gets an IEEE754 double-precision (8 bytes) floating point number from
|
||||
/// `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello");
|
||||
/// assert_eq!(1.2f64, buf.get_f64_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_f64_le(&mut self) -> f64 {
|
||||
buf_get_impl!(self, 8, LittleEndian::read_f64);
|
||||
}
|
||||
|
||||
/// Transforms a `Buf` into a concrete buffer.
|
||||
///
|
||||
/// `collect()` can operate on any value that implements `Buf`, and turn it
|
||||
@@ -749,3 +1055,7 @@ 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) {}
|
||||
|
||||
+468
-142
@@ -1,5 +1,5 @@
|
||||
use super::{IntoBuf, Writer};
|
||||
use byteorder::ByteOrder;
|
||||
use byteorder::{LittleEndian, ByteOrder, BigEndian};
|
||||
use iovec::IoVec;
|
||||
|
||||
use std::{cmp, io, ptr, usize};
|
||||
@@ -338,41 +338,25 @@ pub trait BufMut {
|
||||
self.put_slice(&src)
|
||||
}
|
||||
|
||||
/// Writes an unsigned 16 bit integer to `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u16::<BigEndian>(0x0809);
|
||||
/// assert_eq!(buf, b"\x08\x09");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_u16<T: ByteOrder>(&mut self, n: u16) {
|
||||
#[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 a signed 16 bit integer to `self` in the specified byte order.
|
||||
/// Writes an unsigned 16 bit integer to `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i16::<BigEndian>(0x0809);
|
||||
/// buf.put_u16_be(0x0809);
|
||||
/// assert_eq!(buf, b"\x08\x09");
|
||||
/// ```
|
||||
///
|
||||
@@ -380,47 +364,111 @@ pub trait BufMut {
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i16<T: ByteOrder>(&mut self, n: i16) {
|
||||
fn put_u16_be(&mut self, n: u16) {
|
||||
let mut buf = [0; 2];
|
||||
BigEndian::write_u16(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an unsigned 16 bit integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u16_le(0x0809);
|
||||
/// assert_eq!(buf, b"\x09\x08");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_u16_le(&mut self, n: u16) {
|
||||
let mut buf = [0; 2];
|
||||
LittleEndian::write_u16(&mut buf, n);
|
||||
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 an unsigned 32 bit integer to `self` in the specified byte order.
|
||||
/// Writes a signed 16 bit integer to `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u32::<BigEndian>(0x0809A0A1);
|
||||
/// assert_eq!(buf, b"\x08\x09\xA0\xA1");
|
||||
/// buf.put_i16_be(0x0809);
|
||||
/// assert_eq!(buf, b"\x08\x09");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_u32<T: ByteOrder>(&mut self, n: u32) {
|
||||
fn put_i16_be(&mut self, n: i16) {
|
||||
let mut buf = [0; 2];
|
||||
BigEndian::write_i16(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 16 bit integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i16_le(0x0809);
|
||||
/// assert_eq!(buf, b"\x09\x08");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i16_le(&mut self, n: i16) {
|
||||
let mut buf = [0; 2];
|
||||
LittleEndian::write_i16(&mut buf, n);
|
||||
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 a signed 32 bit integer to `self` in the specified byte order.
|
||||
/// Writes an unsigned 32 bit integer to `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i32::<BigEndian>(0x0809A0A1);
|
||||
/// buf.put_u32_be(0x0809A0A1);
|
||||
/// assert_eq!(buf, b"\x08\x09\xA0\xA1");
|
||||
/// ```
|
||||
///
|
||||
@@ -428,120 +476,336 @@ pub trait BufMut {
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i32<T: ByteOrder>(&mut self, n: i32) {
|
||||
fn put_u32_be(&mut self, n: u32) {
|
||||
let mut buf = [0; 4];
|
||||
T::write_i32(&mut buf, n);
|
||||
BigEndian::write_u32(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an unsigned 64 bit integer to `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u64::<BigEndian>(0x0102030405060708);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_u64<T: ByteOrder>(&mut self, n: u64) {
|
||||
let mut buf = [0; 8];
|
||||
T::write_u64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 64 bit integer to `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i64::<BigEndian>(0x0102030405060708);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i64<T: ByteOrder>(&mut self, n: i64) {
|
||||
let mut buf = [0; 8];
|
||||
T::write_i64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an unsigned n-byte integer to `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_uint::<BigEndian>(0x010203, 3);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_uint<T: ByteOrder>(&mut self, n: u64, nbytes: usize) {
|
||||
let mut buf = [0; 8];
|
||||
T::write_uint(&mut buf, n, nbytes);
|
||||
self.put_slice(&buf[0..nbytes])
|
||||
}
|
||||
|
||||
/// Writes a signed n-byte integer to `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_int::<BigEndian>(0x010203, 3);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_int<T: ByteOrder>(&mut self, n: i64, nbytes: usize) {
|
||||
let mut buf = [0; 8];
|
||||
T::write_int(&mut buf, n, nbytes);
|
||||
self.put_slice(&buf[0..nbytes])
|
||||
}
|
||||
|
||||
/// Writes an IEEE754 single-precision (4 bytes) floating point number to
|
||||
/// `self` in the specified byte order.
|
||||
/// Writes an unsigned 32 bit integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_f32::<BigEndian>(1.2f32);
|
||||
/// buf.put_u32_le(0x0809A0A1);
|
||||
/// assert_eq!(buf, b"\xA1\xA0\x09\x08");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_u32_le(&mut self, n: u32) {
|
||||
let mut buf = [0; 4];
|
||||
LittleEndian::write_u32(&mut buf, n);
|
||||
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.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i32_be(0x0809A0A1);
|
||||
/// assert_eq!(buf, b"\x08\x09\xA0\xA1");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i32_be(&mut self, n: i32) {
|
||||
let mut buf = [0; 4];
|
||||
BigEndian::write_i32(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 32 bit integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i32_le(0x0809A0A1);
|
||||
/// assert_eq!(buf, b"\xA1\xA0\x09\x08");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i32_le(&mut self, n: i32) {
|
||||
let mut buf = [0; 4];
|
||||
LittleEndian::write_i32(&mut buf, n);
|
||||
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.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u64_be(0x0102030405060708);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_u64_be(&mut self, n: u64) {
|
||||
let mut buf = [0; 8];
|
||||
BigEndian::write_u64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an unsigned 64 bit integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u64_le(0x0102030405060708);
|
||||
/// assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_u64_le(&mut self, n: u64) {
|
||||
let mut buf = [0; 8];
|
||||
LittleEndian::write_u64(&mut buf, n);
|
||||
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.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i64_be(0x0102030405060708);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i64_be(&mut self, n: i64) {
|
||||
let mut buf = [0; 8];
|
||||
BigEndian::write_i64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 64 bit integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i64_le(0x0102030405060708);
|
||||
/// assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i64_le(&mut self, n: i64) {
|
||||
let mut buf = [0; 8];
|
||||
LittleEndian::write_i64(&mut buf, n);
|
||||
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`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_uint_be(0x010203, 3);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_uint_be(&mut self, n: u64, nbytes: usize) {
|
||||
let mut buf = [0; 8];
|
||||
BigEndian::write_uint(&mut buf, n, nbytes);
|
||||
self.put_slice(&buf[0..nbytes])
|
||||
}
|
||||
|
||||
/// Writes an unsigned n-byte integer to `self` in the little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_uint_le(0x010203, 3);
|
||||
/// assert_eq!(buf, b"\x03\x02\x01");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_uint_le(&mut self, n: u64, nbytes: usize) {
|
||||
let mut buf = [0; 8];
|
||||
LittleEndian::write_uint(&mut buf, n, nbytes);
|
||||
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`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_int_be(0x010203, 3);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_int_be(&mut self, n: i64, nbytes: usize) {
|
||||
let mut buf = [0; 8];
|
||||
BigEndian::write_int(&mut buf, n, nbytes);
|
||||
self.put_slice(&buf[0..nbytes])
|
||||
}
|
||||
|
||||
/// Writes a signed n-byte integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_int_le(0x010203, 3);
|
||||
/// assert_eq!(buf, b"\x03\x02\x01");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_int_le(&mut self, n: i64, nbytes: usize) {
|
||||
let mut buf = [0; 8];
|
||||
LittleEndian::write_int(&mut buf, n, nbytes);
|
||||
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.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_f32_be(1.2f32);
|
||||
/// assert_eq!(buf, b"\x3F\x99\x99\x9A");
|
||||
/// ```
|
||||
///
|
||||
@@ -549,24 +813,57 @@ pub trait BufMut {
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_f32<T: ByteOrder>(&mut self, n: f32) {
|
||||
fn put_f32_be(&mut self, n: f32) {
|
||||
let mut buf = [0; 4];
|
||||
T::write_f32(&mut buf, n);
|
||||
BigEndian::write_f32(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an IEEE754 single-precision (4 bytes) floating point number to
|
||||
/// `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_f32_le(1.2f32);
|
||||
/// assert_eq!(buf, b"\x9A\x99\x99\x3F");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_f32_le(&mut self, n: f32) {
|
||||
let mut buf = [0; 4];
|
||||
LittleEndian::write_f32(&mut buf, n);
|
||||
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 the specified byte order.
|
||||
/// `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_f64::<BigEndian>(1.2f64);
|
||||
/// buf.put_f64_be(1.2f64);
|
||||
/// assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
|
||||
/// ```
|
||||
///
|
||||
@@ -574,9 +871,34 @@ pub trait BufMut {
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_f64<T: ByteOrder>(&mut self, n: f64) {
|
||||
fn put_f64_be(&mut self, n: f64) {
|
||||
let mut buf = [0; 8];
|
||||
T::write_f64(&mut buf, n);
|
||||
BigEndian::write_f64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an IEEE754 double-precision (8 bytes) floating point number to
|
||||
/// `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_f64_le(1.2f64);
|
||||
/// assert_eq!(buf, b"\x33\x33\x33\x33\x33\x33\xF3\x3F");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_f64_le(&mut self, n: f64) {
|
||||
let mut buf = [0; 8];
|
||||
LittleEndian::write_f64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
@@ -734,3 +1056,7 @@ impl BufMut for Vec<u8> {
|
||||
&mut slice::from_raw_parts_mut(ptr, cap)[len..]
|
||||
}
|
||||
}
|
||||
|
||||
// The existance of this function makes the compiler catch if the BufMut
|
||||
// trait is "object-safe" or not.
|
||||
fn _assert_trait_object(_b: &BufMut) {}
|
||||
|
||||
+367
-173
@@ -3,10 +3,11 @@ use buf::Iter;
|
||||
use debug;
|
||||
|
||||
use std::{cmp, fmt, mem, hash, ops, slice, ptr, usize};
|
||||
use std::borrow::Borrow;
|
||||
use std::borrow::{Borrow, BorrowMut};
|
||||
use std::io::Cursor;
|
||||
use std::sync::atomic::{self, AtomicUsize, AtomicPtr};
|
||||
use std::sync::atomic::Ordering::{Relaxed, Acquire, Release, AcqRel};
|
||||
use std::iter::{FromIterator, Iterator};
|
||||
|
||||
/// A reference counted contiguous slice of memory.
|
||||
///
|
||||
@@ -101,7 +102,7 @@ use std::sync::atomic::Ordering::{Relaxed, Acquire, Release, AcqRel};
|
||||
/// [1] Small enough: 31 bytes on 64 bit systems, 15 on 32 bit systems.
|
||||
///
|
||||
pub struct Bytes {
|
||||
inner: Inner2,
|
||||
inner: Inner,
|
||||
}
|
||||
|
||||
/// A unique reference to a contiguous slice of memory.
|
||||
@@ -147,7 +148,7 @@ pub struct Bytes {
|
||||
/// assert_eq!(&b[..], b"hello");
|
||||
/// ```
|
||||
pub struct BytesMut {
|
||||
inner: Inner2,
|
||||
inner: Inner,
|
||||
}
|
||||
|
||||
// Both `Bytes` and `BytesMut` are backed by `Inner` and functions are delegated
|
||||
@@ -294,6 +295,8 @@ pub struct BytesMut {
|
||||
#[cfg(target_endian = "little")]
|
||||
#[repr(C)]
|
||||
struct Inner {
|
||||
// WARNING: Do not access the fields directly unless you know what you are
|
||||
// doing. Instead, use the fns. See implementation comment above.
|
||||
arc: AtomicPtr<Shared>,
|
||||
ptr: *mut u8,
|
||||
len: usize,
|
||||
@@ -303,22 +306,14 @@ struct Inner {
|
||||
#[cfg(target_endian = "big")]
|
||||
#[repr(C)]
|
||||
struct Inner {
|
||||
// WARNING: Do not access the fields directly unless you know what you are
|
||||
// doing. Instead, use the fns. See implementation comment above.
|
||||
ptr: *mut u8,
|
||||
len: usize,
|
||||
cap: usize,
|
||||
arc: AtomicPtr<Shared>,
|
||||
}
|
||||
|
||||
// This struct is only here to make older versions of Rust happy. In older
|
||||
// versions of `Rust`, `repr(C)` structs could not have drop functions. While
|
||||
// this is no longer the case for newer rust versions, a number of major Rust
|
||||
// libraries still support older versions of Rust for which it is the case. To
|
||||
// get around this, `Inner` (the actual struct) is wrapped by `Inner2` which has
|
||||
// the drop fn implementation.
|
||||
struct Inner2 {
|
||||
inner: Inner,
|
||||
}
|
||||
|
||||
// Thread-safe reference-counted container for the shared storage. This mostly
|
||||
// the same as `std::sync::Arc` but without the weak counter. The ref counting
|
||||
// fns are based on the ones found in `std`.
|
||||
@@ -330,7 +325,7 @@ struct Inner2 {
|
||||
// other shenanigans to make it work.
|
||||
struct Shared {
|
||||
vec: Vec<u8>,
|
||||
original_capacity: usize,
|
||||
original_capacity_repr: usize,
|
||||
ref_count: AtomicUsize,
|
||||
}
|
||||
|
||||
@@ -341,7 +336,24 @@ const KIND_STATIC: usize = 0b10;
|
||||
const KIND_VEC: usize = 0b11;
|
||||
const KIND_MASK: usize = 0b11;
|
||||
|
||||
const MAX_ORIGINAL_CAPACITY: usize = 1 << 16;
|
||||
// The max original capacity value. Any `Bytes` allocated with a greater initial
|
||||
// capacity will default to this.
|
||||
const MAX_ORIGINAL_CAPACITY_WIDTH: usize = 17;
|
||||
// The original capacity algorithm will not take effect unless the originally
|
||||
// allocated capacity was at least 1kb in size.
|
||||
const MIN_ORIGINAL_CAPACITY_WIDTH: usize = 10;
|
||||
// The original capacity is stored in powers of 2 starting at 1kb to a max of
|
||||
// 64kb. Representing it as such requires only 3 bits of storage.
|
||||
const ORIGINAL_CAPACITY_MASK: usize = 0b11100;
|
||||
const ORIGINAL_CAPACITY_OFFSET: usize = 2;
|
||||
|
||||
// When the storage is in the `Vec` representation, the pointer can be advanced
|
||||
// at most this value. This is due to the amount of storage available to track
|
||||
// the offset is usize - number of KIND bits and number of ORIGINAL_CAPACITY
|
||||
// bits.
|
||||
const VEC_POS_OFFSET: usize = 5;
|
||||
const MAX_VEC_POS: usize = usize::MAX >> VEC_POS_OFFSET;
|
||||
const NOT_VEC_POS_MASK: usize = 0b11111;
|
||||
|
||||
// Bit op constants for extracting the inline length value from the `arc` field.
|
||||
const INLINE_LEN_MASK: usize = 0b11111100;
|
||||
@@ -356,6 +368,11 @@ const INLINE_DATA_OFFSET: isize = 1;
|
||||
#[cfg(target_endian = "big")]
|
||||
const INLINE_DATA_OFFSET: isize = 0;
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
const PTR_WIDTH: usize = 64;
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
const PTR_WIDTH: usize = 32;
|
||||
|
||||
// Inline buffer capacity. This is the size of `Inner` minus 1 byte for the
|
||||
// metadata.
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
@@ -373,7 +390,7 @@ impl Bytes {
|
||||
/// Creates a new `Bytes` with the specified capacity.
|
||||
///
|
||||
/// The returned `Bytes` will be able to hold at least `capacity` bytes
|
||||
/// without reallocating. If `capacity` is under `3 * size_of::<usize>()`,
|
||||
/// without reallocating. If `capacity` is under `4 * size_of::<usize>() - 1`,
|
||||
/// then `BytesMut` will not allocate.
|
||||
///
|
||||
/// It is important to note that this function does not specify the length
|
||||
@@ -396,9 +413,7 @@ impl Bytes {
|
||||
#[inline]
|
||||
pub fn with_capacity(capacity: usize) -> Bytes {
|
||||
Bytes {
|
||||
inner: Inner2 {
|
||||
inner: Inner::with_capacity(capacity),
|
||||
},
|
||||
inner: Inner::with_capacity(capacity),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,9 +450,7 @@ impl Bytes {
|
||||
#[inline]
|
||||
pub fn from_static(bytes: &'static [u8]) -> Bytes {
|
||||
Bytes {
|
||||
inner: Inner2 {
|
||||
inner: Inner::from_static(bytes),
|
||||
}
|
||||
inner: Inner::from_static(bytes),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -595,9 +608,7 @@ impl Bytes {
|
||||
}
|
||||
|
||||
Bytes {
|
||||
inner: Inner2 {
|
||||
inner: self.inner.split_off(at),
|
||||
}
|
||||
inner: self.inner.split_off(at),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -636,9 +647,7 @@ impl Bytes {
|
||||
}
|
||||
|
||||
Bytes {
|
||||
inner: Inner2 {
|
||||
inner: self.inner.split_to(at),
|
||||
}
|
||||
inner: self.inner.split_to(at),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -672,6 +681,22 @@ impl Bytes {
|
||||
self.inner.truncate(len);
|
||||
}
|
||||
|
||||
/// Shortens the buffer, dropping the first `cnt` bytes and keeping the
|
||||
/// rest.
|
||||
///
|
||||
/// This is the same function as `Buf::advance`, and in the next breaking
|
||||
/// release of `bytes`, this implementation will be removed in favor of
|
||||
/// having `Bytes` implement `Buf`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if `cnt` is greater than `self.len()`
|
||||
#[inline]
|
||||
pub fn advance(&mut self, cnt: usize) {
|
||||
assert!(cnt <= self.len(), "cannot advance past `remaining`");
|
||||
unsafe { self.inner.set_start(cnt); }
|
||||
}
|
||||
|
||||
/// Clears the buffer, removing all data.
|
||||
///
|
||||
/// # Examples
|
||||
@@ -785,9 +810,7 @@ impl<'a> IntoBuf for &'a Bytes {
|
||||
impl Clone for Bytes {
|
||||
fn clone(&self) -> Bytes {
|
||||
Bytes {
|
||||
inner: Inner2 {
|
||||
inner: self.inner.shallow_clone(),
|
||||
}
|
||||
inner: unsafe { self.inner.shallow_clone(false) },
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -838,6 +861,27 @@ impl<'a> From<&'a str> for Bytes {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<u8> for BytesMut {
|
||||
fn from_iter<T: IntoIterator<Item = u8>>(into_iter: T) -> Self {
|
||||
let iter = into_iter.into_iter();
|
||||
let (min, maybe_max) = iter.size_hint();
|
||||
|
||||
let mut out = BytesMut::with_capacity(maybe_max.unwrap_or(min));
|
||||
|
||||
for i in iter {
|
||||
out.put(i);
|
||||
}
|
||||
|
||||
out
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<u8> for Bytes {
|
||||
fn from_iter<T: IntoIterator<Item = u8>>(into_iter: T) -> Self {
|
||||
BytesMut::from_iter(into_iter).freeze()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Bytes {
|
||||
fn eq(&self, other: &Bytes) -> bool {
|
||||
self.inner.as_ref() == other.inner.as_ref()
|
||||
@@ -945,7 +989,7 @@ impl BytesMut {
|
||||
/// Creates a new `BytesMut` with the specified capacity.
|
||||
///
|
||||
/// The returned `BytesMut` will be able to hold at least `capacity` bytes
|
||||
/// without reallocating. If `capacity` is under `3 * size_of::<usize>()`,
|
||||
/// without reallocating. If `capacity` is under `4 * size_of::<usize>() - 1`,
|
||||
/// then `BytesMut` will not allocate.
|
||||
///
|
||||
/// It is important to note that this function does not specify the length
|
||||
@@ -968,9 +1012,7 @@ impl BytesMut {
|
||||
#[inline]
|
||||
pub fn with_capacity(capacity: usize) -> BytesMut {
|
||||
BytesMut {
|
||||
inner: Inner2 {
|
||||
inner: Inner::with_capacity(capacity),
|
||||
},
|
||||
inner: Inner::with_capacity(capacity),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1100,9 +1142,7 @@ impl BytesMut {
|
||||
/// Panics if `at > capacity`.
|
||||
pub fn split_off(&mut self, at: usize) -> BytesMut {
|
||||
BytesMut {
|
||||
inner: Inner2 {
|
||||
inner: self.inner.split_off(at),
|
||||
}
|
||||
inner: self.inner.split_off(at),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1170,9 +1210,7 @@ impl BytesMut {
|
||||
/// Panics if `at > len`.
|
||||
pub fn split_to(&mut self, at: usize) -> BytesMut {
|
||||
BytesMut {
|
||||
inner: Inner2 {
|
||||
inner: self.inner.split_to(at),
|
||||
}
|
||||
inner: self.inner.split_to(at),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1206,6 +1244,22 @@ impl BytesMut {
|
||||
self.inner.truncate(len);
|
||||
}
|
||||
|
||||
/// Shortens the buffer, dropping the first `cnt` bytes and keeping the
|
||||
/// rest.
|
||||
///
|
||||
/// This is the same function as `Buf::advance`, and in the next breaking
|
||||
/// release of `bytes`, this implementation will be removed in favor of
|
||||
/// having `BytesMut` implement `Buf`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if `cnt` is greater than `self.len()`
|
||||
#[inline]
|
||||
pub fn advance(&mut self, cnt: usize) {
|
||||
assert!(cnt <= self.len(), "cannot advance past `remaining`");
|
||||
unsafe { self.inner.set_start(cnt); }
|
||||
}
|
||||
|
||||
/// Clears the buffer, removing all data.
|
||||
///
|
||||
/// # Examples
|
||||
@@ -1328,6 +1382,55 @@ impl BytesMut {
|
||||
self.reserve(extend.len());
|
||||
self.put_slice(extend);
|
||||
}
|
||||
|
||||
/// Combine splitted BytesMut objects back as contiguous.
|
||||
///
|
||||
/// If `BytesMut` objects were not contiguous originally, they will be extended.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BytesMut;
|
||||
///
|
||||
/// let mut buf = BytesMut::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: 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BufMut for BytesMut {
|
||||
@@ -1423,9 +1526,7 @@ impl ops::DerefMut for BytesMut {
|
||||
impl From<Vec<u8>> for BytesMut {
|
||||
fn from(src: Vec<u8>) -> BytesMut {
|
||||
BytesMut {
|
||||
inner: Inner2 {
|
||||
inner: Inner::from_vec(src),
|
||||
},
|
||||
inner: Inner::from_vec(src),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1452,9 +1553,7 @@ impl<'a> From<&'a [u8]> for BytesMut {
|
||||
inner.as_raw()[0..len].copy_from_slice(src);
|
||||
|
||||
BytesMut {
|
||||
inner: Inner2 {
|
||||
inner: inner,
|
||||
}
|
||||
inner: inner,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1523,6 +1622,12 @@ impl Borrow<[u8]> for BytesMut {
|
||||
}
|
||||
}
|
||||
|
||||
impl BorrowMut<[u8]> for BytesMut {
|
||||
fn borrow_mut(&mut self) -> &mut [u8] {
|
||||
self.as_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Write for BytesMut {
|
||||
#[inline]
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
@@ -1616,8 +1721,8 @@ impl Inner {
|
||||
|
||||
mem::forget(src);
|
||||
|
||||
let original_capacity = cmp::min(cap, MAX_ORIGINAL_CAPACITY);
|
||||
let arc = (original_capacity & !KIND_MASK) | KIND_VEC;
|
||||
let original_capacity_repr = original_capacity_to_repr(cap);
|
||||
let arc = (original_capacity_repr << ORIGINAL_CAPACITY_OFFSET) | KIND_VEC;
|
||||
|
||||
Inner {
|
||||
arc: AtomicPtr::new(arc as *mut Shared),
|
||||
@@ -1632,10 +1737,9 @@ impl Inner {
|
||||
if capacity <= INLINE_CAP {
|
||||
unsafe {
|
||||
// Using uninitialized memory is ~30% faster
|
||||
Inner {
|
||||
arc: AtomicPtr::new(KIND_INLINE as *mut Shared),
|
||||
.. mem::uninitialized()
|
||||
}
|
||||
let mut inner: Inner = mem::uninitialized();
|
||||
inner.arc = AtomicPtr::new(KIND_INLINE as *mut Shared);
|
||||
inner
|
||||
}
|
||||
} else {
|
||||
Inner::from_vec(Vec::with_capacity(capacity))
|
||||
@@ -1727,8 +1831,8 @@ impl Inner {
|
||||
#[inline]
|
||||
fn set_inline_len(&mut self, len: usize) {
|
||||
debug_assert!(len <= INLINE_CAP);
|
||||
let p: &mut usize = unsafe { mem::transmute(&mut self.arc) };
|
||||
*p = (*p & !INLINE_LEN_MASK) | (len << INLINE_LEN_OFFSET);
|
||||
let p = self.arc.get_mut();
|
||||
*p = ((*p as usize & !INLINE_LEN_MASK) | (len << INLINE_LEN_OFFSET)) as _;
|
||||
}
|
||||
|
||||
/// slice.
|
||||
@@ -1758,7 +1862,7 @@ impl Inner {
|
||||
}
|
||||
|
||||
fn split_off(&mut self, at: usize) -> Inner {
|
||||
let mut other = self.shallow_clone();
|
||||
let mut other = unsafe { self.shallow_clone(true) };
|
||||
|
||||
unsafe {
|
||||
other.set_start(at);
|
||||
@@ -1769,7 +1873,7 @@ impl Inner {
|
||||
}
|
||||
|
||||
fn split_to(&mut self, at: usize) -> Inner {
|
||||
let mut other = self.shallow_clone();
|
||||
let mut other = unsafe { self.shallow_clone(true) };
|
||||
|
||||
unsafe {
|
||||
other.set_end(at);
|
||||
@@ -1786,19 +1890,17 @@ impl Inner {
|
||||
}
|
||||
|
||||
unsafe fn set_start(&mut self, start: usize) {
|
||||
// This function should never be called when the buffer is still backed
|
||||
// by a `Vec<u8>`
|
||||
debug_assert!(self.is_shared());
|
||||
|
||||
// Setting the start to 0 is a no-op, so return early if this is the
|
||||
// case.
|
||||
if start == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let kind = self.kind();
|
||||
|
||||
// Always check `inline` first, because if the handle is using inline
|
||||
// data storage, all of the `Inner` struct fields will be gibberish.
|
||||
if self.is_inline() {
|
||||
if kind == KIND_INLINE {
|
||||
assert!(start <= INLINE_CAP);
|
||||
|
||||
let len = self.inline_len();
|
||||
@@ -1822,6 +1924,25 @@ impl Inner {
|
||||
} else {
|
||||
assert!(start <= self.cap);
|
||||
|
||||
if kind == KIND_VEC {
|
||||
// Setting the start when in vec representation is a little more
|
||||
// complicated. First, we have to track how far ahead the
|
||||
// "start" of the byte buffer from the beginning of the vec. We
|
||||
// also have to ensure that we don't exceed the maximum shift.
|
||||
let (mut pos, prev) = self.uncoordinated_get_vec_pos();
|
||||
pos += start;
|
||||
|
||||
if pos <= MAX_VEC_POS {
|
||||
self.uncoordinated_set_vec_pos(pos, prev);
|
||||
} else {
|
||||
// The repr must be upgraded to ARC. This will never happen
|
||||
// on 64 bit systems and will only happen on 32 bit systems
|
||||
// when shifting past 134,217,727 bytes. As such, we don't
|
||||
// worry too much about performance here.
|
||||
let _ = self.shallow_clone(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Updating the start of the view is setting `ptr` to point to the
|
||||
// new start and updating the `len` field to reflect the new length
|
||||
// of the view.
|
||||
@@ -1869,36 +1990,36 @@ impl Inner {
|
||||
} else if kind == KIND_STATIC {
|
||||
false
|
||||
} else {
|
||||
// The function requires `&mut self`, which guarantees a unique
|
||||
// reference to the current handle. This means that the `arc` field
|
||||
// *cannot* be concurrently mutated. As such, `Relaxed` ordering is
|
||||
// fine (since we aren't synchronizing with anything).
|
||||
let arc = self.arc.load(Relaxed);
|
||||
|
||||
// Otherwise, the underlying buffer is potentially shared with other
|
||||
// handles, so the ref_count needs to be checked.
|
||||
unsafe { (*arc).is_unique() }
|
||||
unsafe { (**self.arc.get_mut()).is_unique() }
|
||||
}
|
||||
}
|
||||
|
||||
/// Increments the ref count. This should only be done if it is known that
|
||||
/// it can be done safely. As such, this fn is not public, instead other
|
||||
/// fns will use this one while maintaining the guarantees.
|
||||
fn shallow_clone(&self) -> Inner {
|
||||
/// Parameter `mut_self` should only be set to `true` if caller holds
|
||||
/// `&mut self` reference.
|
||||
///
|
||||
/// "Safely" is defined as not exposing two `BytesMut` values that point to
|
||||
/// the same byte window.
|
||||
///
|
||||
/// This function is thread safe.
|
||||
unsafe fn shallow_clone(&self, mut_self: bool) -> Inner {
|
||||
// Always check `inline` first, because if the handle is using inline
|
||||
// data storage, all of the `Inner` struct fields will be gibberish.
|
||||
if self.is_inline() {
|
||||
// In this case, a shallow_clone still involves copying the data.
|
||||
unsafe {
|
||||
// TODO: Just copy the fields
|
||||
let mut inner: Inner = mem::uninitialized();
|
||||
let len = self.inline_len();
|
||||
//
|
||||
// TODO: Just copy the fields
|
||||
let mut inner: Inner = mem::uninitialized();
|
||||
let len = self.inline_len();
|
||||
|
||||
inner.arc = AtomicPtr::new(KIND_INLINE as *mut Shared);
|
||||
inner.set_inline_len(len);
|
||||
inner.as_raw()[0..len].copy_from_slice(self.as_ref());
|
||||
inner
|
||||
}
|
||||
inner.arc = AtomicPtr::new(KIND_INLINE as *mut Shared);
|
||||
inner.set_inline_len(len);
|
||||
inner.as_raw()[0..len].copy_from_slice(self.as_ref());
|
||||
inner
|
||||
} else {
|
||||
// The function requires `&self`, this means that `shallow_clone`
|
||||
// could be called concurrently.
|
||||
@@ -1914,59 +2035,74 @@ impl Inner {
|
||||
// promote the vec to an `Arc`. This could potentially be called
|
||||
// concurrently, so some care must be taken.
|
||||
if arc as usize & KIND_MASK == KIND_VEC {
|
||||
unsafe {
|
||||
// First, allocate a new `Shared` instance containing the
|
||||
// `Vec` fields. It's important to note that `ptr`, `len`,
|
||||
// and `cap` cannot be mutated without having `&mut self`.
|
||||
// This means that these fields will not be concurrently
|
||||
// updated and since the buffer hasn't been promoted to an
|
||||
// `Arc`, those three fields still are the components of the
|
||||
// vector.
|
||||
let shared = Box::new(Shared {
|
||||
vec: Vec::from_raw_parts(self.ptr, self.len, self.cap),
|
||||
original_capacity: arc as usize & !KIND_MASK,
|
||||
// Initialize refcount to 2. One for this reference, and one
|
||||
// for the new clone that will be returned from
|
||||
// `shallow_clone`.
|
||||
ref_count: AtomicUsize::new(2),
|
||||
});
|
||||
let original_capacity_repr =
|
||||
(arc as usize & ORIGINAL_CAPACITY_MASK) >> ORIGINAL_CAPACITY_OFFSET;
|
||||
|
||||
let shared = Box::into_raw(shared);
|
||||
// The vec offset cannot be concurrently mutated, so there
|
||||
// should be no danger reading it.
|
||||
let off = (arc as usize) >> VEC_POS_OFFSET;
|
||||
|
||||
// The pointer should be aligned, so this assert should
|
||||
// always succeed.
|
||||
debug_assert!(0 == (shared as usize & 0b11));
|
||||
// First, allocate a new `Shared` instance containing the
|
||||
// `Vec` fields. It's important to note that `ptr`, `len`,
|
||||
// and `cap` cannot be mutated without having `&mut self`.
|
||||
// This means that these fields will not be concurrently
|
||||
// updated and since the buffer hasn't been promoted to an
|
||||
// `Arc`, those three fields still are the components of the
|
||||
// vector.
|
||||
let shared = Box::new(Shared {
|
||||
vec: rebuild_vec(self.ptr, self.len, self.cap, off),
|
||||
original_capacity_repr: original_capacity_repr,
|
||||
// Initialize refcount to 2. One for this reference, and one
|
||||
// for the new clone that will be returned from
|
||||
// `shallow_clone`.
|
||||
ref_count: AtomicUsize::new(2),
|
||||
});
|
||||
|
||||
// Try compare & swapping the pointer into the `arc` field.
|
||||
// `Release` is used synchronize with other threads that
|
||||
// will load the `arc` field.
|
||||
//
|
||||
// If the `compare_and_swap` fails, then the thread lost the
|
||||
// race to promote the buffer to shared. The `Acquire`
|
||||
// ordering will synchronize with the `compare_and_swap`
|
||||
// that happened in the other thread and the `Shared`
|
||||
// pointed to by `actual` will be visible.
|
||||
let actual = self.arc.compare_and_swap(arc, shared, AcqRel);
|
||||
let shared = Box::into_raw(shared);
|
||||
|
||||
if actual == arc {
|
||||
// The upgrade was successful, the new handle can be
|
||||
// returned.
|
||||
return Inner {
|
||||
arc: AtomicPtr::new(shared),
|
||||
.. *self
|
||||
};
|
||||
}
|
||||
// The pointer should be aligned, so this assert should
|
||||
// always succeed.
|
||||
debug_assert!(0 == (shared as usize & 0b11));
|
||||
|
||||
// The upgrade failed, a concurrent clone happened. Release
|
||||
// the allocation that was made in this thread, it will not
|
||||
// be needed.
|
||||
let shared: Box<Shared> = mem::transmute(shared);
|
||||
mem::forget(*shared);
|
||||
|
||||
// Update the `arc` local variable and fall through to a ref
|
||||
// count update
|
||||
arc = actual;
|
||||
// If there are no references to self in other threads,
|
||||
// expensive atomic operations can be avoided.
|
||||
if mut_self {
|
||||
self.arc.store(shared, Relaxed);
|
||||
return Inner {
|
||||
arc: AtomicPtr::new(shared),
|
||||
.. *self
|
||||
};
|
||||
}
|
||||
|
||||
// Try compare & swapping the pointer into the `arc` field.
|
||||
// `Release` is used synchronize with other threads that
|
||||
// will load the `arc` field.
|
||||
//
|
||||
// If the `compare_and_swap` fails, then the thread lost the
|
||||
// race to promote the buffer to shared. The `Acquire`
|
||||
// ordering will synchronize with the `compare_and_swap`
|
||||
// that happened in the other thread and the `Shared`
|
||||
// pointed to by `actual` will be visible.
|
||||
let actual = self.arc.compare_and_swap(arc, shared, AcqRel);
|
||||
|
||||
if actual == arc {
|
||||
// The upgrade was successful, the new handle can be
|
||||
// returned.
|
||||
return Inner {
|
||||
arc: AtomicPtr::new(shared),
|
||||
.. *self
|
||||
};
|
||||
}
|
||||
|
||||
// The upgrade failed, a concurrent clone happened. Release
|
||||
// the allocation that was made in this thread, it will not
|
||||
// be needed.
|
||||
let shared = Box::from_raw(shared);
|
||||
mem::forget(*shared);
|
||||
|
||||
// Update the `arc` local variable and fall through to a ref
|
||||
// count update
|
||||
arc = actual;
|
||||
} else if arc as usize & KIND_MASK == KIND_STATIC {
|
||||
// Static buffer
|
||||
return Inner {
|
||||
@@ -1977,14 +2113,13 @@ impl Inner {
|
||||
|
||||
// Buffer already promoted to shared storage, so increment ref
|
||||
// count.
|
||||
unsafe {
|
||||
// Relaxed ordering is acceptable as the memory has already been
|
||||
// acquired via the `Acquire` load above.
|
||||
let old_size = (*arc).ref_count.fetch_add(1, Relaxed);
|
||||
//
|
||||
// Relaxed ordering is acceptable as the memory has already been
|
||||
// acquired via the `Acquire` load above.
|
||||
let old_size = (*arc).ref_count.fetch_add(1, Relaxed);
|
||||
|
||||
if old_size == usize::MAX {
|
||||
panic!(); // TODO: abort
|
||||
}
|
||||
if old_size == usize::MAX {
|
||||
panic!(); // TODO: abort
|
||||
}
|
||||
|
||||
Inner {
|
||||
@@ -2031,13 +2166,14 @@ impl Inner {
|
||||
if kind == KIND_VEC {
|
||||
// Currently backed by a vector, so just use `Vector::reserve`.
|
||||
unsafe {
|
||||
let mut v = Vec::from_raw_parts(self.ptr, self.len, self.cap);
|
||||
let (off, _) = self.uncoordinated_get_vec_pos();
|
||||
let mut v = rebuild_vec(self.ptr, self.len, self.cap, off);
|
||||
v.reserve(additional);
|
||||
|
||||
// Update the info
|
||||
self.ptr = v.as_mut_ptr();
|
||||
self.len = v.len();
|
||||
self.cap = v.capacity();
|
||||
self.ptr = v.as_mut_ptr().offset(off as isize);
|
||||
self.len = v.len() - off;
|
||||
self.cap = v.capacity() - off;
|
||||
|
||||
// Drop the vec reference
|
||||
mem::forget(v);
|
||||
@@ -2046,10 +2182,7 @@ impl Inner {
|
||||
}
|
||||
}
|
||||
|
||||
// `Relaxed` is Ok here (and really, no synchronization is necessary)
|
||||
// due to having a `&mut self` pointer. The `&mut self` pointer ensures
|
||||
// that there is no concurrent access on `self`.
|
||||
let arc = self.arc.load(Relaxed);
|
||||
let arc = *self.arc.get_mut();
|
||||
|
||||
debug_assert!(kind == KIND_ARC);
|
||||
|
||||
@@ -2059,9 +2192,11 @@ impl Inner {
|
||||
// Compute the new capacity
|
||||
let mut new_cap = len + additional;
|
||||
let original_capacity;
|
||||
let original_capacity_repr;
|
||||
|
||||
unsafe {
|
||||
original_capacity = (*arc).original_capacity;
|
||||
original_capacity_repr = (*arc).original_capacity_repr;
|
||||
original_capacity = original_capacity_from_repr(original_capacity_repr);
|
||||
|
||||
// First, try to reclaim the buffer. This is possible if the current
|
||||
// handle is the only outstanding handle pointing to the buffer.
|
||||
@@ -2114,7 +2249,7 @@ impl Inner {
|
||||
self.len = v.len();
|
||||
self.cap = v.capacity();
|
||||
|
||||
let arc = (original_capacity & !KIND_MASK) | KIND_VEC;
|
||||
let arc = (original_capacity_repr << ORIGINAL_CAPACITY_OFFSET) | KIND_VEC;
|
||||
|
||||
self.arc = AtomicPtr::new(arc as *mut Shared);
|
||||
|
||||
@@ -2187,21 +2322,56 @@ impl Inner {
|
||||
|
||||
imp(&self.arc)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn uncoordinated_get_vec_pos(&mut self) -> (usize, usize) {
|
||||
// Similar to above, this is a pretty crazed function. This should only
|
||||
// be called when in the KIND_VEC mode. This + the &mut self argument
|
||||
// guarantees that there is no possibility of concurrent calls to this
|
||||
// function.
|
||||
let prev = unsafe {
|
||||
let p: &AtomicPtr<Shared> = &self.arc;
|
||||
let p: &usize = mem::transmute(p);
|
||||
*p
|
||||
};
|
||||
|
||||
(prev >> VEC_POS_OFFSET, prev)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn uncoordinated_set_vec_pos(&mut self, pos: usize, prev: usize) {
|
||||
// Once more... crazy
|
||||
debug_assert!(pos <= MAX_VEC_POS);
|
||||
|
||||
unsafe {
|
||||
let p: &mut AtomicPtr<Shared> = &mut self.arc;
|
||||
let p: &mut usize = mem::transmute(p);
|
||||
*p = (pos << VEC_POS_OFFSET) | (prev & NOT_VEC_POS_MASK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Inner2 {
|
||||
fn rebuild_vec(ptr: *mut u8, mut len: usize, mut cap: usize, off: usize) -> Vec<u8> {
|
||||
unsafe {
|
||||
let ptr = ptr.offset(-(off as isize));
|
||||
len += off;
|
||||
cap += off;
|
||||
|
||||
Vec::from_raw_parts(ptr, len, cap)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Inner {
|
||||
fn drop(&mut self) {
|
||||
let kind = self.kind();
|
||||
|
||||
if kind == KIND_VEC {
|
||||
let (off, _) = self.uncoordinated_get_vec_pos();
|
||||
|
||||
// Vector storage, free the vector
|
||||
unsafe {
|
||||
let _ = Vec::from_raw_parts(self.ptr, self.len, self.cap);
|
||||
}
|
||||
let _ = rebuild_vec(self.ptr, self.len, self.cap, off);
|
||||
} else if kind == KIND_ARC {
|
||||
// &mut self guarantees correct ordering
|
||||
let arc = self.arc.load(Relaxed);
|
||||
release_shared(arc);
|
||||
release_shared(*self.arc.get_mut());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2233,7 +2403,7 @@ fn release_shared(ptr: *mut Shared) {
|
||||
atomic::fence(Acquire);
|
||||
|
||||
// Drop the data
|
||||
let _: Box<Shared> = mem::transmute(ptr);
|
||||
Box::from_raw(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2253,31 +2423,55 @@ impl Shared {
|
||||
}
|
||||
}
|
||||
|
||||
fn original_capacity_to_repr(cap: usize) -> usize {
|
||||
let width = PTR_WIDTH - ((cap >> MIN_ORIGINAL_CAPACITY_WIDTH).leading_zeros() as usize);
|
||||
cmp::min(width, MAX_ORIGINAL_CAPACITY_WIDTH - MIN_ORIGINAL_CAPACITY_WIDTH)
|
||||
}
|
||||
|
||||
fn original_capacity_from_repr(repr: usize) -> usize {
|
||||
if repr == 0 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
1 << (repr + (MIN_ORIGINAL_CAPACITY_WIDTH - 1))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_original_capacity_to_repr() {
|
||||
for &cap in &[0, 1, 16, 1000] {
|
||||
assert_eq!(0, original_capacity_to_repr(cap));
|
||||
}
|
||||
|
||||
for &cap in &[1024, 1025, 1100, 2000, 2047] {
|
||||
assert_eq!(1, original_capacity_to_repr(cap));
|
||||
}
|
||||
|
||||
for &cap in &[2048, 2049] {
|
||||
assert_eq!(2, original_capacity_to_repr(cap));
|
||||
}
|
||||
|
||||
// TODO: more
|
||||
|
||||
for &cap in &[65536, 65537, 68000, 1 << 17, 1 << 18, 1 << 20, 1 << 30] {
|
||||
assert_eq!(7, original_capacity_to_repr(cap), "cap={}", cap);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_original_capacity_from_repr() {
|
||||
assert_eq!(0, original_capacity_from_repr(0));
|
||||
assert_eq!(1024, original_capacity_from_repr(1));
|
||||
assert_eq!(1024 * 2, original_capacity_from_repr(2));
|
||||
assert_eq!(1024 * 4, original_capacity_from_repr(3));
|
||||
assert_eq!(1024 * 8, original_capacity_from_repr(4));
|
||||
assert_eq!(1024 * 16, original_capacity_from_repr(5));
|
||||
assert_eq!(1024 * 32, original_capacity_from_repr(6));
|
||||
assert_eq!(1024 * 64, original_capacity_from_repr(7));
|
||||
}
|
||||
|
||||
unsafe impl Send for Inner {}
|
||||
unsafe impl Sync for Inner {}
|
||||
|
||||
/*
|
||||
*
|
||||
* ===== impl Inner2 =====
|
||||
*
|
||||
*/
|
||||
|
||||
impl ops::Deref for Inner2 {
|
||||
type Target = Inner;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &Inner {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::DerefMut for Inner2 {
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut Inner {
|
||||
&mut self.inner
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* ===== PartialEq / PartialOrd =====
|
||||
|
||||
+2
-2
@@ -27,8 +27,8 @@ impl<'a> fmt::Debug for BsDebug<'a> {
|
||||
try!(write!(fmt, "\\{}", c as char));
|
||||
} else if c == b'\0' {
|
||||
try!(write!(fmt, "\\0"));
|
||||
// ASCII printable except space
|
||||
} else if c > 0x20 && c < 0x7f {
|
||||
// ASCII printable
|
||||
} else if c >= 0x20 && c < 0x7f {
|
||||
try!(write!(fmt, "{}", c as char));
|
||||
} else {
|
||||
try!(write!(fmt, "\\x{:02x}", c));
|
||||
|
||||
+2
-1
@@ -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")]
|
||||
#![doc(html_root_url = "https://docs.rs/bytes/0.4.7")]
|
||||
|
||||
extern crate byteorder;
|
||||
extern crate iovec;
|
||||
@@ -92,6 +92,7 @@ mod bytes;
|
||||
mod debug;
|
||||
pub use bytes::{Bytes, BytesMut};
|
||||
|
||||
#[deprecated]
|
||||
pub use byteorder::{ByteOrder, BigEndian, LittleEndian};
|
||||
|
||||
// Optional Serde support
|
||||
|
||||
+9
-4
@@ -33,21 +33,26 @@ fn test_get_u8() {
|
||||
#[test]
|
||||
fn test_get_u16() {
|
||||
let buf = b"\x21\x54zomg";
|
||||
assert_eq!(0x2154, Cursor::new(buf).get_u16::<byteorder::BigEndian>());
|
||||
assert_eq!(0x5421, Cursor::new(buf).get_u16::<byteorder::LittleEndian>());
|
||||
assert_eq!(0x2154, Cursor::new(buf).get_u16_be());
|
||||
assert_eq!(0x5421, Cursor::new(buf).get_u16_le());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_get_u16_buffer_underflow() {
|
||||
let mut buf = Cursor::new(b"\x21");
|
||||
buf.get_u16::<byteorder::BigEndian>();
|
||||
buf.get_u16_be();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bufs_vec() {
|
||||
let buf = Cursor::new(b"hello world");
|
||||
let mut dst: [&IoVec; 2] = Default::default();
|
||||
|
||||
let b1: &[u8] = &mut [0];
|
||||
let b2: &[u8] = &mut [0];
|
||||
|
||||
let mut dst: [&IoVec; 2] =
|
||||
[b1.into(), b2.into()];
|
||||
|
||||
assert_eq!(1, buf.bytes_vec(&mut dst[..]));
|
||||
}
|
||||
|
||||
@@ -41,11 +41,11 @@ fn test_put_u8() {
|
||||
#[test]
|
||||
fn test_put_u16() {
|
||||
let mut buf = Vec::with_capacity(8);
|
||||
buf.put_u16::<byteorder::BigEndian>(8532);
|
||||
buf.put_u16_be(8532);
|
||||
assert_eq!(b"\x21\x54", &buf[..]);
|
||||
|
||||
buf.clear();
|
||||
buf.put_u16::<byteorder::LittleEndian>(8532);
|
||||
buf.put_u16_le(8532);
|
||||
assert_eq!(b"\x54\x21", &buf[..]);
|
||||
}
|
||||
|
||||
|
||||
+163
-3
@@ -350,16 +350,16 @@ fn reserve_growth() {
|
||||
|
||||
#[test]
|
||||
fn reserve_allocates_at_least_original_capacity() {
|
||||
let mut bytes = BytesMut::with_capacity(128);
|
||||
let mut bytes = BytesMut::with_capacity(1024);
|
||||
|
||||
for i in 0..120 {
|
||||
for i in 0..1020 {
|
||||
bytes.put(i as u8);
|
||||
}
|
||||
|
||||
let _other = bytes.take();
|
||||
|
||||
bytes.reserve(16);
|
||||
assert_eq!(bytes.capacity(), 128);
|
||||
assert_eq!(bytes.capacity(), 1024);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -466,6 +466,44 @@ fn from_static() {
|
||||
assert_eq!(b, b"b"[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn advance_inline() {
|
||||
let mut a = Bytes::from(&b"hello world"[..]);
|
||||
a.advance(6);
|
||||
assert_eq!(a, &b"world"[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn advance_static() {
|
||||
let mut a = Bytes::from_static(b"hello world");
|
||||
a.advance(6);
|
||||
assert_eq!(a, &b"world"[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn advance_vec() {
|
||||
let mut a = BytesMut::from(b"hello world boooo yah world zomg wat wat".to_vec());
|
||||
a.advance(16);
|
||||
assert_eq!(a, b"o yah world zomg wat wat"[..]);
|
||||
|
||||
a.advance(4);
|
||||
assert_eq!(a, b"h world zomg wat wat"[..]);
|
||||
|
||||
// Reserve some space.
|
||||
a.reserve(1024);
|
||||
assert_eq!(a, b"h world zomg wat wat"[..]);
|
||||
|
||||
a.advance(6);
|
||||
assert_eq!(a, b"d zomg wat wat"[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn advance_past_len() {
|
||||
let mut a = BytesMut::from(b"hello world".to_vec());
|
||||
a.advance(20);
|
||||
}
|
||||
|
||||
#[test]
|
||||
// Only run these tests on little endian systems. CI uses qemu for testing
|
||||
// little endian... and qemu doesn't really support threading all that well.
|
||||
@@ -514,3 +552,125 @@ fn partial_eq_bytesmut() {
|
||||
assert!(bytes2 != bytesmut);
|
||||
assert!(bytesmut != bytes2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_basic() {
|
||||
let mut buf = BytesMut::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 unsplit_empty_other() {
|
||||
let mut buf = BytesMut::with_capacity(64);
|
||||
buf.extend_from_slice(b"aaabbbcccddd");
|
||||
|
||||
// empty other
|
||||
let other = BytesMut::new();
|
||||
|
||||
buf.unsplit(other);
|
||||
assert_eq!(b"aaabbbcccddd", &buf[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_empty_self() {
|
||||
// empty self
|
||||
let mut buf = BytesMut::new();
|
||||
|
||||
let mut other = BytesMut::with_capacity(64);
|
||||
other.extend_from_slice(b"aaabbbcccddd");
|
||||
|
||||
buf.unsplit(other);
|
||||
assert_eq!(b"aaabbbcccddd", &buf[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_inline_arc() {
|
||||
let mut buf = BytesMut::with_capacity(8); //inline
|
||||
buf.extend_from_slice(b"aaaabbbb");
|
||||
|
||||
let mut buf2 = BytesMut::with_capacity(64);
|
||||
buf2.extend_from_slice(b"ccccddddeeee");
|
||||
|
||||
buf2.split_off(8); //arc
|
||||
|
||||
buf.unsplit(buf2);
|
||||
assert_eq!(b"aaaabbbbccccdddd", &buf[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_arc_inline() {
|
||||
let mut buf = BytesMut::with_capacity(64);
|
||||
buf.extend_from_slice(b"aaaabbbbeeee");
|
||||
|
||||
buf.split_off(8); //arc
|
||||
|
||||
let mut buf2 = BytesMut::with_capacity(8); //inline
|
||||
buf2.extend_from_slice(b"ccccdddd");
|
||||
|
||||
buf.unsplit(buf2);
|
||||
assert_eq!(b"aaaabbbbccccdddd", &buf[..]);
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_both_inline() {
|
||||
let mut buf = BytesMut::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 unsplit_arc_different() {
|
||||
let mut buf = BytesMut::with_capacity(64);
|
||||
buf.extend_from_slice(b"aaaabbbbeeee");
|
||||
|
||||
buf.split_off(8); //arc
|
||||
|
||||
let mut buf2 = BytesMut::with_capacity(64);
|
||||
buf2.extend_from_slice(b"ccccddddeeee");
|
||||
|
||||
buf2.split_off(8); //arc
|
||||
|
||||
buf.unsplit(buf2);
|
||||
assert_eq!(b"aaaabbbbccccdddd", &buf[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_arc_non_contiguous() {
|
||||
let mut buf = BytesMut::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 unsplit_two_split_offs() {
|
||||
let mut buf = BytesMut::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[..]);
|
||||
}
|
||||
|
||||
+34
-14
@@ -55,48 +55,68 @@ fn vectored_read() {
|
||||
let mut buf = a.chain(b);
|
||||
|
||||
{
|
||||
let mut iovecs: [&IoVec; 4] = Default::default();
|
||||
let b1: &[u8] = &mut [0];
|
||||
let b2: &[u8] = &mut [0];
|
||||
let b3: &[u8] = &mut [0];
|
||||
let b4: &[u8] = &mut [0];
|
||||
let mut iovecs: [&IoVec; 4] =
|
||||
[b1.into(), b2.into(), b3.into(), b4.into()];
|
||||
|
||||
assert_eq!(2, buf.bytes_vec(&mut iovecs));
|
||||
assert_eq!(iovecs[0][..], b"hello"[..]);
|
||||
assert_eq!(iovecs[1][..], b"world"[..]);
|
||||
assert!(iovecs[2].is_empty());
|
||||
assert!(iovecs[3].is_empty());
|
||||
assert_eq!(iovecs[2][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[3][..], b"\0"[..]);
|
||||
}
|
||||
|
||||
buf.advance(2);
|
||||
|
||||
{
|
||||
let mut iovecs: [&IoVec; 4] = Default::default();
|
||||
let b1: &[u8] = &mut [0];
|
||||
let b2: &[u8] = &mut [0];
|
||||
let b3: &[u8] = &mut [0];
|
||||
let b4: &[u8] = &mut [0];
|
||||
let mut iovecs: [&IoVec; 4] =
|
||||
[b1.into(), b2.into(), b3.into(), b4.into()];
|
||||
|
||||
assert_eq!(2, buf.bytes_vec(&mut iovecs));
|
||||
assert_eq!(iovecs[0][..], b"llo"[..]);
|
||||
assert_eq!(iovecs[1][..], b"world"[..]);
|
||||
assert!(iovecs[2].is_empty());
|
||||
assert!(iovecs[3].is_empty());
|
||||
assert_eq!(iovecs[2][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[3][..], b"\0"[..]);
|
||||
}
|
||||
|
||||
buf.advance(3);
|
||||
|
||||
{
|
||||
let mut iovecs: [&IoVec; 4] = Default::default();
|
||||
let b1: &[u8] = &mut [0];
|
||||
let b2: &[u8] = &mut [0];
|
||||
let b3: &[u8] = &mut [0];
|
||||
let b4: &[u8] = &mut [0];
|
||||
let mut iovecs: [&IoVec; 4] =
|
||||
[b1.into(), b2.into(), b3.into(), b4.into()];
|
||||
|
||||
assert_eq!(1, buf.bytes_vec(&mut iovecs));
|
||||
assert_eq!(iovecs[0][..], b"world"[..]);
|
||||
assert!(iovecs[1].is_empty());
|
||||
assert!(iovecs[2].is_empty());
|
||||
assert!(iovecs[3].is_empty());
|
||||
assert_eq!(iovecs[1][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[2][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[3][..], b"\0"[..]);
|
||||
}
|
||||
|
||||
buf.advance(3);
|
||||
|
||||
{
|
||||
let mut iovecs: [&IoVec; 4] = Default::default();
|
||||
let b1: &[u8] = &mut [0];
|
||||
let b2: &[u8] = &mut [0];
|
||||
let b3: &[u8] = &mut [0];
|
||||
let b4: &[u8] = &mut [0];
|
||||
let mut iovecs: [&IoVec; 4] =
|
||||
[b1.into(), b2.into(), b3.into(), b4.into()];
|
||||
|
||||
assert_eq!(1, buf.bytes_vec(&mut iovecs));
|
||||
assert_eq!(iovecs[0][..], b"ld"[..]);
|
||||
assert!(iovecs[1].is_empty());
|
||||
assert!(iovecs[2].is_empty());
|
||||
assert!(iovecs[3].is_empty());
|
||||
assert_eq!(iovecs[1][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[2][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[3][..], b"\0"[..]);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ fn fmt() {
|
||||
\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\
|
||||
\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\
|
||||
\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f\
|
||||
\\x20!\\\"#$%&'()*+,-./0123456789:;<=>?\
|
||||
\x20!\\\"#$%&'()*+,-./0123456789:;<=>?\
|
||||
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_\
|
||||
`abcdefghijklmnopqrstuvwxyz{|}~\\x7f\
|
||||
\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\
|
||||
|
||||
Reference in New Issue
Block a user