Commit Graph
87 Commits
Author SHA1 Message Date
Artem Vorotnikov 2a66700a94 BytesMut::unsplit: rename to join 2020-11-29 06:33:09 +03:00
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 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 7daa7fe053 Change default lint level to warning and deny warnings in CI (#397) 2020-07-09 09:12:39 -07:00
Bryan DonlanandSean McArthur 81550da474 BytesMut: Reuse buffer when data fully consumed via Buf
Closes #412
2020-07-08 15:28:36 -07:00
Taiki EndoandGitHub 1fbf83816b Format with rustfmt (#389)
* Format with rustfmt

* Add rustfmt check to CI
2020-05-22 13:17:30 +09:00
Cheng XUandGitHub e8fa2511ff Fix tests for no_std build (#384)
This fixes `cargo test --no-default-features`.
2020-05-22 11:18:20 +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
Tim HambourgerandSean McArthur 8bbe9dd87b Fix #352 -- Make freeze respect the start offset for BytesMuts in Vec mode 2020-03-24 11:14:16 -07:00
Stepan KoltsovandSean McArthur f330ef6c4d Do not panic on Bytes::slice_ref on empty slice (#355)
Use case:

```
let bytes: Bytes = ...
let subbytes = bytes.slice(a..b); // where a == b
let slice = &subbytes[..];
let slice_bytes = bytes.slice_ref(slice);
```

Last line should not panic, because `slice` object is derived from
the original `Bytes` object.

Before this commit it panics, because `Bytes::slice` returns a fresh
`Bytes` object when `begin == end`.
2020-01-23 10:29:42 -08:00
Sean McArthurandCarl Lerche e0eebde993 Fix Bytes::truncate losing the original Vec's capacity (#361) 2020-01-22 16:37:53 -08:00
Sean McArthurandGitHub c7cf716180 Fix Bytes when Vec pointer's LSB is set (#346)
This separates the `SharedVtable` into 3:

- `PromotableEvenVtable`: The original `SharedVtable`, which will
  promote the `Vec` to `Shared` on the first clone, and is selected when
  the `Vec`'s pointer has the LSB unset.
- `PromotableOddVtable`: Similar to the `PromotableEvenVtable`, but
  selected when the `Vec`'s pointer has the LSB set. This vtable differs
  in the masking used when reconstructing the `Vec`.
- `SharedVtable`: This no longer checks if its current kind is `VEC` or
  `ARC`, and is only created by the "promotable" vtables.

This also adds a test using an "odd" global allocator that purposefully
bumps all pointers with alignment of 1.

Closes #343
2019-12-17 13:23:15 -08:00
Sean McArthur 8733f74d59 Assert the LSB is 0 when converting Vec into Bytes 2019-12-12 11:46:51 -08:00
Sean McArthur a7fc5274ad Make Deref impls of Buf and BufMut forward more methods 2019-12-10 13:35:26 -08:00
Sean McArthur a4908213a6 Add must_use to split, split_off, and split_to 2019-12-04 12:39:48 -08:00
Mikhail ZabaluevandCarl Lerche af606aab9b Fix regression in Bytes::truncate (#333)
When the length to truncate is greater than the buffer's current
length, do nothing instead of clearing the contents.
2019-12-01 14:00:42 -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 9a10addb44 Change loom tests to use cfg(loom) internally (#314) 2019-11-13 14:55:25 -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
Douman ae9991f3ba Make From only for static slices to Bytes 2019-08-27 22:17:26 +02: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
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 McArthur ac4e8f2fc5 Use RangeBounds trait for Bytes::slice
- Removes `slice_to` and `slice_from`.
2019-06-10 09:39:27 -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
Pavel StrakhovandCarl Lerche d43e283e5e Panic in BytesMut::split_to when out of bounds (#252) (#253) 2019-04-02 16:24:30 -07: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
Federico Mena QuinteroandCarl Lerche 79f05591c9 Add a subslice function for Bytes (#198) (#208)
This lets us take Bytes and a &[u8] slice that is contained in it, and
create a new Bytes that corresponds to that subset slice.

Closes #198
2018-09-01 19:57:31 -07: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
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
Carl Lerche c87739bb55 Merge branch 'v0.4.x' 2018-05-25 14:15:00 -07:00
Noah ZentzisandCarl Lerche dfce95b89d Recycle space when reserving from Vec-backed Bytes (#197)
* Recycle space when reserving from Vec-backed Bytes

BytesMut::reserve, when called on a BytesMut instance which is backed by
a non-shared Vec<u8>, would previously just delegate to Vec::reserve
regardless of the current location in the buffer. If the Bytes is
actually the trailing component of a larger Vec, then the unused space
won't be recycled. In applications which continually move the pointer
forward to consume data as it comes in, this can cause the underlying
buffer to get extremely large.

This commit checks whether there's extra space at the start of the
backing Vec in this case, and reuses the unused space if possible
instead of allocating.

* Avoid excessive copying when reusing Vec space

Only reuse space in a Vec-backed Bytes when doing so would gain back
more than half of the current capacity. This avoids excessive copy
operations when a large buffer is almost (but not completely) full.
2018-05-24 16:37:13 -07:00
Noah ZentzisandCarl Lerche 2d95683bd5 Recycle space when reserving from Vec-backed Bytes (#197)
* Recycle space when reserving from Vec-backed Bytes

BytesMut::reserve, when called on a BytesMut instance which is backed by
a non-shared Vec<u8>, would previously just delegate to Vec::reserve
regardless of the current location in the buffer. If the Bytes is
actually the trailing component of a larger Vec, then the unused space
won't be recycled. In applications which continually move the pointer
forward to consume data as it comes in, this can cause the underlying
buffer to get extremely large.

This commit checks whether there's extra space at the start of the
backing Vec in this case, and reuses the unused space if possible
instead of allocating.

* Avoid excessive copying when reusing Vec space

Only reuse space in a Vec-backed Bytes when doing so would gain back
more than half of the current capacity. This avoids excessive copy
operations when a large buffer is almost (but not completely) full.
2018-05-24 14:50:31 -07:00
Carl Lerche b68fa46e3d Fix panic in FromIterator for BytesMut 2018-05-11 08:45:04 -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
Alan SomersandCarl Lerche ff7c0a1d90 Bytes::unsplit (#182)
Add `Bytes::unsplit`, analogous to `BytesMut::unsplit`.
2018-02-26 09:19:20 -08: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
jq-rsandCarl Lerche ba9a975358 Unsplit improvements (#173)
* Handle empty self and other for unsplit.
* Change extend() to extend_from_slice().
2018-01-05 16:20:59 -08:00
jq-rsandCarl Lerche 2ca61d881d Add support for unsplit() to BytesMut (#162)
Add support for unsplit() to BytesMut which combines splitted contiguous memory blocks efficiently.
2018-01-03 09:54:51 -08:00
Carl LercheandGitHub 02891144be Add advance on Bytes and BytesMut (#166)
* Compact Bytes original capacity representation

In order to avoid unnecessary allocations, a `Bytes` structure remembers
the capacity with which it was first created. When a reserve operation
is issued, this original capacity value is used to as a baseline for
reallocating new storage.

Previously, this original capacity value was stored in its raw form. In
other words, the original capacity `usize` was stored as is. In order to
reclaim some `Bytes` internal storage space for additional features,
this original capacity value is compressed from requiring 16 bits to 3.

To do this, instead of storing the exact original capacity. The original
capacity is rounded down to the nearest power of two. If the original
capacity is less than 1024, then it is rounded down to zero. This
roughly means that the original capacity is now stored as a table:

0 => 0
1 => 1k
2 => 2k
3 => 4k
4 => 8k
5 => 16k
6 => 32k
7 => 64k

For the purposes that the original capacity feature was introduced, this
is sufficient granularity.

* Provide `advance` on Bytes and BytesMut

This is the `advance` function that would be part of a `Buf`
implementation. However, `Bytes` and `BytesMut` cannot impl `Buf` until
the next breaking release.

The implementation uses the additional storage made available by the
previous commit to store the number of bytes that the view was advanced.
The `ptr` pointer will point to the start of the window, avoiding any
pointer arithmetic when dereferencing the `Bytes` handle.
2017-12-13 13:30:03 -06:00