mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-23 00:00:13 +02:00
Add vectored support to Buf and BufMut
This commit is contained in:
@@ -21,6 +21,7 @@ categories = ["network-programming", "data-structures"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "1.0.0"
|
byteorder = "1.0.0"
|
||||||
|
iovec = { git = "https://github.com/carllerche/iovec" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio-core = "0.1.0"
|
tokio-core = "0.1.0"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use super::{Take, Reader, Iter, FromBuf};
|
use super::{Take, Reader, Iter, FromBuf};
|
||||||
use byteorder::ByteOrder;
|
use byteorder::ByteOrder;
|
||||||
|
use iovec::IoVec;
|
||||||
|
|
||||||
use std::{cmp, io, ptr};
|
use std::{cmp, io, ptr};
|
||||||
|
|
||||||
@@ -72,6 +73,34 @@ pub trait Buf {
|
|||||||
/// ```
|
/// ```
|
||||||
fn bytes(&self) -> &[u8];
|
fn bytes(&self) -> &[u8];
|
||||||
|
|
||||||
|
/// Fills `dst` with potentially multiple slices starting at `self`'s
|
||||||
|
/// current position.
|
||||||
|
///
|
||||||
|
/// If the `Buf` is backed by disjoint slices of bytes, `bytes_vec` enables
|
||||||
|
/// fetching more than one slice at once. `dst` is a slice of `IoVec`
|
||||||
|
/// references, enabling the slice to be directly used with [`writev`]
|
||||||
|
/// without any further conversion. The sum of the lengths of all the
|
||||||
|
/// buffers in `dst` will be less than or equal to `Buf::remaining()`.
|
||||||
|
///
|
||||||
|
/// The entries in `dst` will be overwritten, but the data **contained** by
|
||||||
|
/// the slices **will not** be modified. If `bytes_vec` does not fill every
|
||||||
|
/// entry in `dst`, then `dst` is guaranteed to contain all remaining slices
|
||||||
|
/// in `self.
|
||||||
|
///
|
||||||
|
/// This is a lower level function. Most operations are done with other
|
||||||
|
/// functions.
|
||||||
|
///
|
||||||
|
/// [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html
|
||||||
|
fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize {
|
||||||
|
if dst.is_empty() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst[0] = self.bytes().into();
|
||||||
|
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
/// Advance the internal cursor of the Buf
|
/// Advance the internal cursor of the Buf
|
||||||
///
|
///
|
||||||
/// The next call to `bytes` will return a slice starting `cnt` bytes
|
/// The next call to `bytes` will return a slice starting `cnt` bytes
|
||||||
@@ -576,6 +605,10 @@ impl<'a, T: Buf + ?Sized> Buf for &'a mut T {
|
|||||||
(**self).bytes()
|
(**self).bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bytes_vec<'b>(&'b self, dst: &mut [&'b IoVec]) -> usize {
|
||||||
|
(**self).bytes_vec(dst)
|
||||||
|
}
|
||||||
|
|
||||||
fn advance(&mut self, cnt: usize) {
|
fn advance(&mut self, cnt: usize) {
|
||||||
(**self).advance(cnt)
|
(**self).advance(cnt)
|
||||||
}
|
}
|
||||||
@@ -590,6 +623,10 @@ impl<T: Buf + ?Sized> Buf for Box<T> {
|
|||||||
(**self).bytes()
|
(**self).bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bytes_vec<'b>(&'b self, dst: &mut [&'b IoVec]) -> usize {
|
||||||
|
(**self).bytes_vec(dst)
|
||||||
|
}
|
||||||
|
|
||||||
fn advance(&mut self, cnt: usize) {
|
fn advance(&mut self, cnt: usize) {
|
||||||
(**self).advance(cnt)
|
(**self).advance(cnt)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use super::{Source, Writer};
|
use super::{Source, Writer};
|
||||||
use byteorder::ByteOrder;
|
use byteorder::ByteOrder;
|
||||||
|
use iovec::IoVec;
|
||||||
|
|
||||||
use std::{cmp, io, ptr, usize};
|
use std::{cmp, io, ptr, usize};
|
||||||
|
|
||||||
@@ -137,6 +138,35 @@ pub trait BufMut {
|
|||||||
/// ```
|
/// ```
|
||||||
unsafe fn bytes_mut(&mut self) -> &mut [u8];
|
unsafe fn bytes_mut(&mut self) -> &mut [u8];
|
||||||
|
|
||||||
|
/// Fills `dst` with potentially multiple mutable slices starting at `self`'s
|
||||||
|
/// current position.
|
||||||
|
///
|
||||||
|
/// If the `BufMut` is backed by disjoint slices of bytes, `bytes_vec_mut`
|
||||||
|
/// enables fetching more than one slice at once. `dst` is a slice of
|
||||||
|
/// mutable `IoVec` references, enabling the slice to be directly used with
|
||||||
|
/// [`readv`] without any further conversion. The sum of the lengths of all
|
||||||
|
/// the buffers in `dst` will be less than or equal to
|
||||||
|
/// `Buf::remaining_mut()`.
|
||||||
|
///
|
||||||
|
/// The entries in `dst` will be overwritten, but the data **contained** by
|
||||||
|
/// the slices **will not** be modified. If `bytes_vec_mut` does not fill every
|
||||||
|
/// entry in `dst`, then `dst` is guaranteed to contain all remaining slices
|
||||||
|
/// in `self.
|
||||||
|
///
|
||||||
|
/// This is a lower level function. Most operations are done with other
|
||||||
|
/// functions.
|
||||||
|
///
|
||||||
|
/// [`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 {
|
||||||
|
if dst.is_empty() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst[0] = self.bytes_mut().into();
|
||||||
|
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
/// Transfer bytes into `self` from `src` and advance the cursor by the
|
/// Transfer bytes into `self` from `src` and advance the cursor by the
|
||||||
/// number of bytes written.
|
/// number of bytes written.
|
||||||
///
|
///
|
||||||
@@ -513,6 +543,10 @@ impl<'a, T: BufMut + ?Sized> BufMut for &'a mut T {
|
|||||||
(**self).bytes_mut()
|
(**self).bytes_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn bytes_vec_mut<'b>(&'b mut self, dst: &mut [&'b mut IoVec]) -> usize {
|
||||||
|
(**self).bytes_vec_mut(dst)
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn advance_mut(&mut self, cnt: usize) {
|
unsafe fn advance_mut(&mut self, cnt: usize) {
|
||||||
(**self).advance_mut(cnt)
|
(**self).advance_mut(cnt)
|
||||||
}
|
}
|
||||||
@@ -527,6 +561,10 @@ impl<T: BufMut + ?Sized> BufMut for Box<T> {
|
|||||||
(**self).bytes_mut()
|
(**self).bytes_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn bytes_vec_mut<'b>(&'b mut self, dst: &mut [&'b mut IoVec]) -> usize {
|
||||||
|
(**self).bytes_vec_mut(dst)
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn advance_mut(&mut self, cnt: usize) {
|
unsafe fn advance_mut(&mut self, cnt: usize) {
|
||||||
(**self).advance_mut(cnt)
|
(**self).advance_mut(cnt)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -1229,7 +1229,8 @@ impl<'a> From<&'a [u8]> for BytesMut {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut buf = BytesMut::with_capacity(src.len());
|
let mut buf = BytesMut::with_capacity(src.len());
|
||||||
buf.put(src.as_ref());
|
let src: &[u8] = src.as_ref();
|
||||||
|
buf.put(src);
|
||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,7 @@
|
|||||||
#![doc(html_root_url = "https://docs.rs/bytes/0.4")]
|
#![doc(html_root_url = "https://docs.rs/bytes/0.4")]
|
||||||
|
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
extern crate iovec;
|
||||||
|
|
||||||
pub mod buf;
|
pub mod buf;
|
||||||
pub use buf::{
|
pub use buf::{
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
extern crate bytes;
|
extern crate bytes;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
extern crate iovec;
|
||||||
|
|
||||||
use bytes::Buf;
|
use bytes::Buf;
|
||||||
|
use iovec::IoVec;
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -46,3 +48,11 @@ fn test_get_u16_buffer_underflow() {
|
|||||||
let mut buf = Cursor::new(b"\x21");
|
let mut buf = Cursor::new(b"\x21");
|
||||||
buf.get_u16::<byteorder::BigEndian>();
|
buf.get_u16::<byteorder::BigEndian>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bufs_vec() {
|
||||||
|
let buf = Cursor::new(b"hello world");
|
||||||
|
let mut dst: [&IoVec; 2] = Default::default();
|
||||||
|
|
||||||
|
assert_eq!(1, buf.bytes_vec(&mut dst[..]));
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
extern crate bytes;
|
extern crate bytes;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
extern crate iovec;
|
||||||
|
|
||||||
use bytes::{BufMut, BytesMut};
|
use bytes::{BufMut, BytesMut};
|
||||||
|
use iovec::IoVec;
|
||||||
use std::usize;
|
use std::usize;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
@@ -56,3 +58,15 @@ fn test_clone() {
|
|||||||
buf.write_str(" of our emergecy broadcast system").unwrap();
|
buf.write_str(" of our emergecy broadcast system").unwrap();
|
||||||
assert!(buf != buf2);
|
assert!(buf != buf2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bufs_vec_mut() {
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
|
let mut buf = BytesMut::from(&b"hello world"[..]);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let mut dst: [&mut IoVec; 2] = mem::zeroed();
|
||||||
|
assert_eq!(1, buf.bytes_vec_mut(&mut dst[..]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user