Commit Graph
109 Commits
Author SHA1 Message Date
Carl LercheandGitHub 39de065a1e Add Buf::copy_to_bytes(len) (#439)
This method replaces `Buf::to_bytes()`, providing a method that copies a
subset of the remaining buffer into a `Bytes` value. As this is strictly
more flexible, `to_bytes()` is removed.

Fixes: #129, #398
2020-10-20 11:00:35 -07:00
Carl LercheandGitHub e0d8413d53 Switch BufMut::bytes_mut to&mut UninitSlice (#433)
The way BufMut uses MaybeUninit can lead to unsoundness. This replaces
MaybeUnit with a type owned by bytes so we can ensure the usage patterns
are sound.

Refs: #328
2020-10-19 15:48:23 -07:00
Carl LercheandGitHub 4724c7e8a0 remove new fns from combinator structs (#434)
This is not idiomatic.
2020-10-18 09:55:19 -07:00
Carl LercheandGitHub ced050730c Make BufMut an unsafe trait (#432)
Users of `BufMut` are unable to defend against incorrect implementations
of `BufMut`, this makes the trait unsafe to implement.

Fixes #329
2020-10-16 15:45:38 -07:00
Carl LercheandGitHub 94c543f74b remove ext traits (#431) 2020-10-16 15:16:23 -07:00
Carl LercheandGitHub 447530b8a6 Remove BufMut::bytes_vectored_mut() (#430)
There are issues with regard to uninitialized memory. We are avoiding
stabilizing this function for now.
2020-10-16 11:56:03 -07:00
Taiki EndoandGitHub e9877e7a3d Deny warnings for doc tests (#391) 2020-05-24 06:30:50 +09:00
Kirill FomichevandGitHub 08ec01d1e7 Fix reference in Take docs (#383) 2020-05-22 14:33:06 +09:00
Taiki EndoandGitHub 1fbf83816b Format with rustfmt (#389)
* Format with rustfmt

* Add rustfmt check to CI
2020-05-22 13:17:30 +09:00
Tim HambourgerandSean McArthur b4ebe8432e Fix #354 -- Make advance_mut impl of BufMut for Vec<u8> panic if cnt > remaining 2020-03-25 12:30:15 -07:00
Sean McArthur a7fc5274ad Make Deref impls of Buf and BufMut forward more methods 2019-12-10 13:35:26 -08:00
Sean McArthurandCarl Lerche 7e80f3b646 Optimize BufMut for Vec and BytesMut (#338) 2019-12-10 13:30:49 -08:00
Sean McArthurandCarl Lerche a642e1c075 Add accessors to Limit combinator (#325) 2019-11-26 18:08:39 -08:00
Sean McArthurandCarl Lerche cdd9fc09cd Export public the combinator types (#318) 2019-11-25 10:47:37 -08:00
Sean McArthurandCarl Lerche 44fb206148 add BufMutExt::limit (#309)
This type is the counterpart to BufExt::take. It limits how many bytes
some `BufMut` can actually be filled with.
2019-11-20 15:10:30 -08:00
Carl LercheandGitHub 8135c1f606 implicitly grow BytesMut; add BufMutExt::chain_mut (#316)
This brings `BytesMut` in line with `Vec<u8>` behavior.

This also fixes an existing bug in BytesMut::bytes_mut that exposes
invalid slices. The bug was recently introduced and was only on master
and never released to `crates.io`.

In order to fix a test, `BufMutExt::chain_mut` is provided. Withou this,
it is not possible to chain two `&mut [u8]`.

Closes #170
2019-11-20 12:11:40 -08:00
Sean McArthurandGitHub 856ed7c43d implement Buf for std::io::Cursor (#308) 2019-11-04 17:23:40 -08:00
Sean McArthurandGitHub 96268a80d4 Move "extra" methods to extension traits (#306) 2019-10-31 09:39:58 -07:00
Sean McArthurandGitHub 2ac72333fa Change BufMut methods that expose maybe-uninitialized bytes (#305)
- The return type of `BufMut::bytes_mut` is now
  `&mut [MaybeUninit<u8>]`.
- The argument type of `BufMut::bytes_vectored_mut` is now
  `&mut [bytes::buf::IoSliceMut]`.
- `bytes::buf::IoSliceMut` is a `repr(transparent)` wrapper around an
  `std::io::IoSliceMut`, but does not expose the inner bytes with a safe
  API, since they might be uninitialized.
- `BufMut::bytesMut` and `BufMut::bytes_vectored_mut` are no longer
  `unsafe fn`, since the types encapsulate the unsafety instead.
2019-10-24 14:40:45 -07:00
Sean McArthurandCarl Lerche 491ebbf79a Remove Buf impl for &str (#301)
A `&str` cannot arbitrarily advance bytes, since it will panic if
advanced to the middle of a Unicode segment.
2019-10-16 11:28:50 -07:00
Sean McArthurandGitHub 43ac8e5494 Refactor Bytes to use an internal vtable (#298)
Bytes is a useful tool for managing multiple slices into the same region
of memory, and the other things it used to have been removed to reduce
complexity. The exact strategy for managing the multiple references is
no longer hard-coded, but instead backing by a customizable vtable.

- Removed ability to mutate the underlying memory from the `Bytes` type.
- Removed the "inline" (SBO) mechanism in `Bytes`. The reduces a large
  amount of complexity, and improves performance when accessing the
  slice of bytes, since a branch is no longer needed to check if the
  data is inline.
- Removed `Bytes` knowledge of `BytesMut` (`BytesMut` may grow that
  knowledge back at a future point.)
2019-10-16 09:53:36 -07:00
Chris BeckandCarl Lerche c17e40115f Add no_std support, by adding an std feature (#281)
To make the library work as `no_std` we add an `std` feature which
is on by default. When it is off, we compile as `no_std` and make
parts of the API that require `std::io` conditional on the `std`
feature.
2019-09-05 14:00:23 -07:00
DoumanandCarl Lerche 4f5ed82b3c Fix clippy (#285) 2019-08-27 14:19:44 -07:00
DoumanandCarl Lerche b6cb346adf Remove IntoBuf/FromBuf (#288)
As consequence Buf::collect is removed as well, which is replaced with `Buf::into_bytes`. The advantage of `Buf::into_bytes` is that it can be optimized in cases where converting a `T: Buf` into a `Bytes` instance is efficient.
2019-08-27 13:09:43 -07:00
DoumanandCarl Lerche 234d814122 Remove byteorder dependency (#280) 2019-08-11 10:16:03 -07:00
Taiki EndoandCarl Lerche b5d4f87e7e Remove i128 feature (#276) 2019-07-30 11:19:46 -07:00
Taiki EndoandGitHub ae7d884582 Update Bytes to Rust 2018 (#274) 2019-07-26 05:01:22 +09:00
Bruce MitchenerandSean McArthur e25b75a28e Fix typos. 2019-07-16 11:18:49 -07:00
Sean McArthur dea868a4b0 Replace iovec with std::io::IoSlice
- Renames `bytes_vec` to `bytes_vectored` and `bytes_vec_mut` to
  `bytes_vectored_mut`.
2019-06-11 11:58:43 -07:00
Sean McArthurandCarl Lerche 55aa530dc1 Remove io::Cursor, and implement Buf/BufMut for slices instead (#261) 2019-06-07 12:31:10 -07:00
YetAnotherMinionandSean McArthur d8134903de feat: remove impl IntoBuf for Cursor<Self>, impl Buf for Bytes, BytesMut, refactor iterators 2019-06-06 16:59:44 -07:00
Sean McArthur 5759211ff8 Merge branch 'v0.4.x' into uplift-0.4-commits 2019-06-06 14:08:29 -07:00
Sean McArthurandCarl Lerche 60aceba2bb set publish to false, update meta links (#258) 2019-06-06 13:58:22 -07:00
Michal 'vorner' VanerandCarl Lerche 0e8b440650 Implementation of Buf for VecDeque (#249) 2019-03-06 11:46:42 -08:00
Michal 'vorner' VanerandCarl Lerche 7c3085aaec The Reader can implement BufReader naturally (#232)
There's no reason the user should be forced to wrap it in BufReader in
case the trait is needed, because the Reader has all the bits for
supporting it naturally.
2018-11-17 07:51:41 -08:00
Michal 'vorner' VanerandCarl Lerche e64a123d00 Bring more attention to short reads/slices on Buff/BuffMut (#231)
The property the Buff and BuffMut can return shorter slice is quite an
important detail. Nevertheless, while it is mentioned in the
documentation, the wording makes it relatively easy to overlook. This
tries to bring more attention to it.
2018-11-17 07:51:28 -08:00
Rafael Ávila de EspíndolaandCarl Lerche 052648c3f5 Implement IntoBuf for mut slices. (#214)
With this if foo is a mutable slice, it is possible to do

foo.into_buf().put_u32_le(42);

Before this patch into_buf would create a Cursor<&'a [u8]> and it
would not be possible to write into it.
2018-07-12 20:16:08 -07:00
Carl Lerche f4100841f8 Merge branch 'v0.4.x' 2018-07-12 20:11:51 -07:00
Rafael Ávila de EspíndolaandCarl Lerche 83f68a013e Implement IntoBuf for mut slices. (#214)
With this if foo is a mutable slice, it is possible to do

foo.into_buf().put_u32_le(42);

Before this patch into_buf would create a Cursor<&'a [u8]> and it
would not be possible to write into it.
2018-07-12 19:03:47 -07:00
Ashley MannixandCarl Lerche 7785cde587 add support for 128bit numbers (#209) 2018-06-18 17:37:51 -07:00
kohensuandCarl Lerche 51e435b7e0 Improve performance of Buf::get_*() (#195)
The new implementation tries to get the data directly from bytes() (this is
possible most of the time) and if there is not enough data in bytes() use the
previous code: copy the needed bytes in a temporary buffer before returning
the data

Here the bench results:
                               Before                After           x-faster
get_f32::cursor             64 ns/iter (+/- 0)    20 ns/iter (+/- 0)    3.2
get_f32::tbuf_1             77 ns/iter (+/- 1)    34 ns/iter (+/- 0)    2.3
get_f32::tbuf_1_costly      87 ns/iter (+/- 0)    62 ns/iter (+/- 0)    1.4
get_f32::tbuf_2            151 ns/iter (+/- 18)  160 ns/iter (+/- 1)    0.9
get_f32::tbuf_2_costly     180 ns/iter (+/- 2)   187 ns/iter (+/- 2)    1.0

get_f64::cursor             67 ns/iter (+/- 0)    21 ns/iter (+/- 0)    3.2
get_f64::tbuf_1             80 ns/iter (+/- 0)    35 ns/iter (+/- 0)    2.3
get_f64::tbuf_1_costly      82 ns/iter (+/- 3)    60 ns/iter (+/- 0)    1.4
get_f64::tbuf_2            154 ns/iter (+/- 1)   164 ns/iter (+/- 0)    0.9
get_f64::tbuf_2_costly     170 ns/iter (+/- 2)   187 ns/iter (+/- 1)    0.9

get_u16::cursor             66 ns/iter (+/- 0)    20 ns/iter (+/- 0)    3.3
get_u16::tbuf_1             77 ns/iter (+/- 0)    35 ns/iter (+/- 0)    2.2
get_u16::tbuf_1_costly      85 ns/iter (+/- 2)    62 ns/iter (+/- 0)    1.4
get_u16::tbuf_2            147 ns/iter (+/- 0)   154 ns/iter (+/- 0)    1.0
get_u16::tbuf_2_costly     160 ns/iter (+/- 1)   177 ns/iter (+/- 0)    0.9

get_u32::cursor             64 ns/iter (+/- 0)    20 ns/iter (+/- 0)    3.2
get_u32::tbuf_1             77 ns/iter (+/- 0)    35 ns/iter (+/- 0)    2.2
get_u32::tbuf_1_costly      91 ns/iter (+/- 2)    63 ns/iter (+/- 0)    1.4
get_u32::tbuf_2            151 ns/iter (+/- 40)  157 ns/iter (+/- 0)    1.0
get_u32::tbuf_2_costly     162 ns/iter (+/- 0)   180 ns/iter (+/- 0)    0.9

get_u64::cursor             67 ns/iter (+/- 0)    20 ns/iter (+/- 0)    3.4
get_u64::tbuf_1             78 ns/iter (+/- 0)    35 ns/iter (+/- 1)    2.2
get_u64::tbuf_1_costly      87 ns/iter (+/- 1)    59 ns/iter (+/- 1)    1.5
get_u64::tbuf_2            154 ns/iter (+/- 0)   160 ns/iter (+/- 0)    1.0
get_u64::tbuf_2_costly     168 ns/iter (+/- 0)   184 ns/iter (+/- 0)    0.9

get_u8::cursor              64 ns/iter (+/- 0)    19 ns/iter (+/- 0)    3.4
get_u8::tbuf_1              77 ns/iter (+/- 0)    35 ns/iter (+/- 0)    2.2
get_u8::tbuf_1_costly       68 ns/iter (+/- 0)    51 ns/iter (+/- 0)    1.3
get_u8::tbuf_2              85 ns/iter (+/- 0)    43 ns/iter (+/- 0)    2.0
get_u8::tbuf_2_costly       75 ns/iter (+/- 0)    61 ns/iter (+/- 0)    1.2
get_u8::option              77 ns/iter (+/- 0)    59 ns/iter (+/- 0)    1.3

Improvement on the basic std::Cursor implementation are clearly visible.

Other implementations are specific to the bench tests and just map a static
slice. Different variant are:
 - tbuf_1: only one call of 'bytes()' is needed.
 - tbuf_2: two calls of 'bytes()' is needed to read more than one byte.
 - _costly version are implemented with #[inline(never)] on 'bytes()',
   'remaining()' and 'advance()'.

The cases that are slower (slightly) correspond to implementations that are not
really realistic: more than one byte is never possible in one time
2018-04-27 10:18:52 -07:00
kohensuandCarl Lerche e444722098 Improve performance of Buf::get_*() (#195)
The new implementation tries to get the data directly from bytes() (this is
possible most of the time) and if there is not enough data in bytes() use the
previous code: copy the needed bytes in a temporary buffer before returning
the data

Here the bench results:
                               Before                After           x-faster
get_f32::cursor             64 ns/iter (+/- 0)    20 ns/iter (+/- 0)    3.2
get_f32::tbuf_1             77 ns/iter (+/- 1)    34 ns/iter (+/- 0)    2.3
get_f32::tbuf_1_costly      87 ns/iter (+/- 0)    62 ns/iter (+/- 0)    1.4
get_f32::tbuf_2            151 ns/iter (+/- 18)  160 ns/iter (+/- 1)    0.9
get_f32::tbuf_2_costly     180 ns/iter (+/- 2)   187 ns/iter (+/- 2)    1.0

get_f64::cursor             67 ns/iter (+/- 0)    21 ns/iter (+/- 0)    3.2
get_f64::tbuf_1             80 ns/iter (+/- 0)    35 ns/iter (+/- 0)    2.3
get_f64::tbuf_1_costly      82 ns/iter (+/- 3)    60 ns/iter (+/- 0)    1.4
get_f64::tbuf_2            154 ns/iter (+/- 1)   164 ns/iter (+/- 0)    0.9
get_f64::tbuf_2_costly     170 ns/iter (+/- 2)   187 ns/iter (+/- 1)    0.9

get_u16::cursor             66 ns/iter (+/- 0)    20 ns/iter (+/- 0)    3.3
get_u16::tbuf_1             77 ns/iter (+/- 0)    35 ns/iter (+/- 0)    2.2
get_u16::tbuf_1_costly      85 ns/iter (+/- 2)    62 ns/iter (+/- 0)    1.4
get_u16::tbuf_2            147 ns/iter (+/- 0)   154 ns/iter (+/- 0)    1.0
get_u16::tbuf_2_costly     160 ns/iter (+/- 1)   177 ns/iter (+/- 0)    0.9

get_u32::cursor             64 ns/iter (+/- 0)    20 ns/iter (+/- 0)    3.2
get_u32::tbuf_1             77 ns/iter (+/- 0)    35 ns/iter (+/- 0)    2.2
get_u32::tbuf_1_costly      91 ns/iter (+/- 2)    63 ns/iter (+/- 0)    1.4
get_u32::tbuf_2            151 ns/iter (+/- 40)  157 ns/iter (+/- 0)    1.0
get_u32::tbuf_2_costly     162 ns/iter (+/- 0)   180 ns/iter (+/- 0)    0.9

get_u64::cursor             67 ns/iter (+/- 0)    20 ns/iter (+/- 0)    3.4
get_u64::tbuf_1             78 ns/iter (+/- 0)    35 ns/iter (+/- 1)    2.2
get_u64::tbuf_1_costly      87 ns/iter (+/- 1)    59 ns/iter (+/- 1)    1.5
get_u64::tbuf_2            154 ns/iter (+/- 0)   160 ns/iter (+/- 0)    1.0
get_u64::tbuf_2_costly     168 ns/iter (+/- 0)   184 ns/iter (+/- 0)    0.9

get_u8::cursor              64 ns/iter (+/- 0)    19 ns/iter (+/- 0)    3.4
get_u8::tbuf_1              77 ns/iter (+/- 0)    35 ns/iter (+/- 0)    2.2
get_u8::tbuf_1_costly       68 ns/iter (+/- 0)    51 ns/iter (+/- 0)    1.3
get_u8::tbuf_2              85 ns/iter (+/- 0)    43 ns/iter (+/- 0)    2.0
get_u8::tbuf_2_costly       75 ns/iter (+/- 0)    61 ns/iter (+/- 0)    1.2
get_u8::option              77 ns/iter (+/- 0)    59 ns/iter (+/- 0)    1.3

Improvement on the basic std::Cursor implementation are clearly visible.

Other implementations are specific to the bench tests and just map a static
slice. Different variant are:
 - tbuf_1: only one call of 'bytes()' is needed.
 - tbuf_2: two calls of 'bytes()' is needed to read more than one byte.
 - _costly version are implemented with #[inline(never)] on 'bytes()',
   'remaining()' and 'advance()'.

The cases that are slower (slightly) correspond to implementations that are not
really realistic: more than one byte is never possible in one time
2018-04-27 10:07:27 -07:00
Carl Lerche ebe522731f Fix copy_to_slice to use correct increment var
This patch fixes the `copy_to_slice` function, rectifying the logic.
However, the incorrect code does not result in incorrect behavior as the
only case `cnt != src.len()` is during the final iteration, and since
`src.len()` is greater than `cnt` in that case, `off` will be
incremented by too much, but this will still trigger the `off <
dst.len()` condition.

The only danger is `src.len()` could cause an overflow.
2018-03-12 09:39:33 -07:00
Sean McArthurandCarl Lerche 025d53342e Remove ByteOrder generic methods from Buf and BufMut (#187)
* make Buf and BufMut usable as trait objects

- All the `get_*` and `put_*` methods that take `T: ByteOrder` have
  a `where Self: Sized` bound added, so that they are only usable from
  sized types. It was impossible to make `Buf` or `BufMut` into trait
  objects before, so this change doesn't break anyone.
- Add `get_n_be`/`get_n_le`/`put_n_be`/`put_n_le` methods that can be
  used on trait objects.
- Deprecate the export of `ByteOrder` and methods generic on it.

* remove deprecated ByteOrder methods

Removes the `_be` suffix from all methods, implying that the default
people should use is network endian.
2018-03-12 09:27:09 -07:00
Sean McArthurandCarl Lerche ce79f0a268 Make Buf and BufMut usable as trait objects (#186)
- All the `get_*` and `put_*` methods that take `T: ByteOrder` have
  a `where Self: Sized` bound added, so that they are only usable from
  sized types. It was impossible to make `Buf` or `BufMut` into trait
  objects before, so this change doesn't break anyone.
- Add `get_n_be`/`get_n_le`/`put_n_be`/`put_n_le` methods that can be
  used on trait objects.
- Deprecate the export of `ByteOrder` and methods generic on it.

Fixes #163
2018-03-12 09:25:59 -07:00
Carl LercheandGitHub 3d169f1f34 Update iovec dependency (#179)
Update to match master version of IoVec (0.2.0?), using
IoVec/IoVecMut instead of &IoVec and &mut IoVec.
2018-01-25 22:02:21 -08:00
Dan BurkertandCarl Lerche 7ed78cef47 Fix index-oob panic in Take::bytes (#138)
The panic happens when `inner.bytes()` returns a slice smaller than the
limit.
2017-06-27 11:23:29 -07:00
brianwpandCarl Lerche 2b0602e756 impl ExactSizeIterator for Iter<T: Buf> (#127) 2017-05-24 08:13:19 -07:00
Dan BurkertandCarl Lerche 30bd7c1f21 Vec::advance_mut can advance past the end of the buffer (#108) 2017-04-30 16:14:54 -07:00
Carl Lerche bed128b2c0 Clarify when BufMut::bytes_mut can return &[]
Closes #79
2017-03-19 13:58:44 -07:00