Compare commits

...
47 Commits
Author SHA1 Message Date
Pavel StrakhovandCarl Lerche d43e283e5e Panic in BytesMut::split_to when out of bounds (#252) (#253) 2019-04-02 16:24:30 -07:00
南浦月andCarl Lerche e0e30f00a1 Fix a typo in CHANGELOG.md (#251) 2019-03-29 13:54:25 -07:00
Carl LercheandGitHub 4948b1053b Bump version to v0.4.12 (#250) 2019-03-06 12:42:20 -08:00
Michal 'vorner' VanerandCarl Lerche 0e8b440650 Implementation of Buf for VecDeque (#249) 2019-03-06 11:46:42 -08:00
Sangguk LeeandCarl Lerche e13d2a783e Use constants in bytes.rs test code (#247) 2019-02-27 10:41:11 -08:00
南浦月andCarl Lerche 55dfea8c18 Impl FromIterator<&'a u8> for BytesMut/Bytes (#244) 2019-01-30 11:05:15 -08:00
Dax HuibertsandCarl Lerche f3b363a385 Fix typo in bytes.rs (#243) 2019-01-28 10:06:28 -08:00
Ralf JungandCarl Lerche 42b669690a use raw ptr for potentially racy load (#240) 2018-12-21 11:07:20 -08:00
Ralf JungandCarl Lerche 9504447adc Be clear about Inner::kind being deliberate UB (#236) 2018-11-25 22:49:35 -08:00
Carl LercheandGitHub b3248c8807 Bump version to v0.4.11 (#235) 2018-11-17 14:33:25 -08:00
Ralf JungandCarl Lerche c6c5b8fb54 Use raw pointers for potentially racy loads (#233)
Shared references assert immutability, so any concurrent access would be UB
disregarding data race concerns.
2018-11-17 07:51:50 -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
Carl LercheandGitHub e5304410a4 Whitelist false positive std (#234) 2018-11-17 07:27:00 -08:00
Carl LercheandGitHub 456221d165 Bump version to v0.4.10 (#227) 2018-09-04 13:31:26 -07:00
Carl LercheandGitHub f09c51c34e White list allocation (#226) 2018-09-03 13:36:13 -07:00
Carl LercheandGitHub ad35fbef03 implement Buf and BufMut for Either (#225) 2018-09-03 10:23:00 -07: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
Carl LercheandGitHub ed244d3b54 Bump version to v0.4.9 (#220) 2018-07-22 19:30:41 -07:00
Sean McArthurandCarl Lerche 890812af1b inline Bytes::len and Bytes::is_empty (#211) 2018-07-12 20:17:27 -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
RomanandCarl Lerche 042aa9023b Fix cargo doc error on nightly caused by broken link to footnote (#218) 2018-07-12 20:15:53 -07:00
Sean McArthurandCarl Lerche 886dda0962 Optimize Inner::shallow_clone (#217)
- Clones when the kind is INLINE or STATIC are sped up by over double.
- Clones when the kind is ARC are spec up by about 1/3.
2018-07-03 15:21:26 -07:00
luben karavelovandCarl Lerche 6414efe83b Fix documentation (#219) 2018-07-02 12:10:16 -07:00
Ashley MannixandCarl Lerche 7785cde587 add support for 128bit numbers (#209) 2018-06-18 17:37:51 -07:00
Carl LercheandGitHub a6b9844296 Clarify license as MIT (#216)
The intent of the license was to dual license MIT & Apache 2.0. However,
the messaging was copy / pasted from rust-lang.

Clarify the license as exclusively MIT.

Fixes #215
2018-06-18 12:49:34 -07:00
Carl LercheandGitHub 406b048ae6 Bump version to v0.4.8 (#206) 2018-05-25 16:50:42 -07:00
Carl Lerche 8c041142a0 Filter out tsan warnings in test harness (#205) 2018-05-25 15:54:13 -07:00
Luke HorsleyandCarl Lerche e9a7098658 Added a resize function for BytesMut (#203) 2018-05-25 13:54:32 -07:00
Carl LercheandGitHub 32ea8281b3 Use sanitizers in CI (#204) 2018-05-25 12:40:37 -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
Carl Lerche b68fa46e3d Fix panic in FromIterator for BytesMut 2018-05-11 08:45:04 -07:00
Carl Lerche ef09e98fbc Bump version to v0.4.7 2018-04-27 10:51:09 -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
Alan SomersandCarl Lerche 15050b1da5 impl BorrowMut for BytesMut (#185) (#192) 2018-04-27 10:08:50 -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 86c83959dc Have Travis build WASM target (#180) 2018-01-29 10:18:52 -08:00
Carl Lerche e5c4c6028d Bump version to v0.4.6 2018-01-08 09:11:42 -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
Stepan KoltsovandCarl Lerche 6a3d20bb8d Optimize shallow_clone for Bytes::split_{off,to} (#92)
If `shallow_clone` is called with `&mut self`, and `Bytes` contains
`Vec`, then expensive CAS can be avoided, because no other thread
have references to this `Bytes` object.

Bench `split_off_and_drop` difference:

Before the diff:

```
test split_off_and_drop             ... bench:      91,858 ns/iter (+/- 17,401)
```

With the diff:

```
test split_off_and_drop             ... bench:      81,162 ns/iter (+/- 17,603)
```
2018-01-03 11:41:33 -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 8d6c2b61cc Document correct inline capacity in bytes.rs (#171)
Fixes #164
2017-12-15 18:10:30 -06: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
Carl Lerche 149922d7cf Get test passing again 2017-10-21 15:47:45 -07:00
Dan BurkertandCarl Lerche 03d501b18d small fixups in bytes.rs (#145)
* Inner: make uninitialized construction explicit
* Remove Inner2
* Remove unnecessary transmutes
* Use AtomicPtr::get_mut where possible
* Some minor tweaks
2017-08-18 08:33:28 -07:00
JefandCarl Lerche 34540be54c Add FromIterator impl (#148) 2017-08-17 10:32:59 -07:00
Sean McArthurandCarl Lerche cfca1c04fa print space normally in Debug for Bytes (#155) 2017-08-17 10:28:06 -07:00
24 changed files with 2391 additions and 764 deletions
+31
View File
@@ -36,6 +36,37 @@ matrix:
# Serde implementation
- env: EXTRA_ARGS="--features serde"
# 128 bit numbers
- env: EXTRA_ARGS="--features i128"
# `Either` impls
- env: EXTRA_ARGS="--features either"
# WASM support
- rust: beta
script:
- rustup target add wasm32-unknown-unknown
- cargo build --target=wasm32-unknown-unknown
# Sanitizers
- rust: nightly
os: linux
script:
- |
set -e
export RUST_TEST_THREADS=1
export ASAN_OPTIONS="detect_odr_violation=0 detect_leaks=0"
export TSAN_OPTIONS="suppressions=`pwd`/ci/tsan"
# Run address sanitizer
RUSTFLAGS="-Z sanitizer=address" \
cargo test --tests --target x86_64-unknown-linux-gnu
# Run thread sanitizer
RUSTFLAGS="-Z sanitizer=thread" \
cargo test --tests --target x86_64-unknown-linux-gnu
before_install: set -e
install:
+41
View File
@@ -1,3 +1,44 @@
# 0.4.12 (March 6, 2019)
### Added
- Implement `FromIterator<&'a u8>` for `BytesMut`/`Bytes` (#244).
- Implement `Buf` for `VecDeque` (#249).
# 0.4.11 (November 17, 2018)
* Use raw pointers for potentially racy loads (#233).
* Implement `BufRead` for `buf::Reader` (#232).
* Documentation tweaks (#234).
# 0.4.10 (September 4, 2018)
* impl `Buf` and `BufMut` for `Either` (#225).
* Add `Bytes::slice_ref` (#208).
# 0.4.9 (July 12, 2018)
* Add 128 bit number support behind a feature flag (#209).
* Implement `IntoBuf` for `&mut [u8]`
# 0.4.8 (May 25, 2018)
* Fix panic in `BytesMut` `FromIterator` implementation.
* Bytes: Recycle space when reserving space in vec mode (#197).
* Bytes: Add resize fn (#203).
# 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`
+16 -4
View File
@@ -1,11 +1,16 @@
[package]
name = "bytes"
version = "0.4.5"
license = "MIT/Apache-2.0"
# When releasing to crates.io:
# - Update html_root_url.
# - Update CHANGELOG.md.
# - Update doc URL.
# - Create "v0.4.x" git tag.
version = "0.4.12"
license = "MIT"
authors = ["Carl Lerche <[email protected]>"]
description = "Types and traits for working with bytes"
documentation = "https://carllerche.github.io/bytes/bytes"
documentation = "https://docs.rs/bytes/0.4.12/bytes"
homepage = "https://github.com/carllerche/bytes"
repository = "https://github.com/carllerche/bytes"
readme = "README.md"
@@ -19,10 +24,17 @@ exclude = [
]
categories = ["network-programming", "data-structures"]
[package.metadata.docs.rs]
features = ["i128"]
[dependencies]
byteorder = "1.0.0"
byteorder = "1.1.0"
iovec = "0.1"
serde = { version = "1.0", optional = true }
either = { version = "1.5", default-features = false, optional = true }
[dev-dependencies]
serde_test = "1.0"
[features]
i128 = ["byteorder/i128"]
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2017 Carl Lerche
Copyright (c) 2018 Carl Lerche
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
-201
View File
@@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2017 Carl Lerche
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+11 -8
View File
@@ -5,7 +5,7 @@ A utility library for working with bytes.
[![Crates.io](https://img.shields.io/crates/v/bytes.svg?maxAge=2592000)](https://crates.io/crates/bytes)
[![Build Status](https://travis-ci.org/carllerche/bytes.svg?branch=master)](https://travis-ci.org/carllerche/bytes)
[Documentation](https://carllerche.github.io/bytes/bytes/index.html)
[Documentation](https://docs.rs/bytes/0.4.12/bytes/)
## Usage
@@ -13,7 +13,7 @@ To use `bytes`, first add this to your `Cargo.toml`:
```toml
[dependencies]
bytes = "0.4"
bytes = "0.4.12"
```
Next, add this to your crate:
@@ -30,13 +30,16 @@ Serde support is optional and disabled by default. To enable use the feature `se
```toml
[dependencies]
bytes = { version = "0.4", features = ["serde"] }
bytes = { version = "0.4.12", features = ["serde"] }
```
# License
## License
`bytes` is primarily distributed under the terms of both the MIT license and the
Apache License (Version 2.0), with portions covered by various BSD-like
licenses.
This project is licensed under the [MIT license](LICENSE).
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in `bytes` by you, shall be licensed as MIT, without any additional
terms or conditions.
See LICENSE-APACHE, and LICENSE-MIT for details.
+45
View File
@@ -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);
@@ -101,6 +113,39 @@ fn deref_two(b: &mut Bencher) {
})
}
#[bench]
fn clone_inline(b: &mut Bencher) {
let bytes = Bytes::from_static(b"hello world");
b.iter(|| {
for _ in 0..1024 {
test::black_box(&bytes.clone());
}
})
}
#[bench]
fn clone_static(b: &mut Bencher) {
let bytes = Bytes::from_static("hello world 1234567890 and have a good byte 0987654321".as_bytes());
b.iter(|| {
for _ in 0..1024 {
test::black_box(&bytes.clone());
}
})
}
#[bench]
fn clone_arc(b: &mut Bencher) {
let bytes = Bytes::from("hello world 1234567890 and have a good byte 0987654321".as_bytes());
b.iter(|| {
for _ in 0..1024 {
test::black_box(&bytes.clone());
}
})
}
#[bench]
fn alloc_write_split_to_mid(b: &mut Bencher) {
b.iter(|| {
+28
View File
@@ -0,0 +1,28 @@
# TSAN suppressions file for `bytes`
# TSAN does not understand fences and `Arc::drop` is implemented using a fence.
# This causes many false positives.
race:Arc*drop
race:arc*Weak*drop
# `std` mpsc is not used in any Bytes code base. This race is triggered by some
# rust runtime logic.
race:std*mpsc_queue
# Some test runtime races. Allocation should be race free
race:alloc::alloc
# Not sure why this is warning, but it is in the test harness and not the library.
race:TestEvent*clone
race:test::run_tests_console::*closure
# Probably more fences in std.
race:__call_tls_dtors
# `is_inline_or_static` is explicitly called concurrently without synchronization.
# The safety explanation can be found in a comment.
race:Inner::is_inline_or_static
# This ignores a false positive caused by `thread::park()`/`thread::unpark()`.
# See: https://github.com/rust-lang/rust/pull/54806#issuecomment-436193353
race:pthread_cond_destroy
+549 -146
View File
@@ -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.
@@ -59,7 +91,8 @@ pub trait Buf {
fn remaining(&self) -> usize;
/// Returns a slice starting at the current position and of length between 0
/// and `Buf::remaining()`.
/// and `Buf::remaining()`. Note that this *can* return shorter slice (this allows
/// non-continuous internal representation).
///
/// This is a lower level function. Most operations are done with other
/// functions.
@@ -243,9 +276,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 +300,608 @@ 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);
}
/// Gets an unsigned 128 bit integer from `self` in big-endian byte order.
///
/// **NOTE:** This method requires the `i128` feature.
/// The current position is advanced by 16.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello");
/// assert_eq!(0x01020304050607080910111213141516, buf.get_u128_be());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
#[cfg(feature = "i128")]
fn get_u128_be(&mut self) -> u128 {
buf_get_impl!(self, 16, BigEndian::read_u128);
}
/// Gets an unsigned 128 bit integer from `self` in little-endian byte order.
///
/// **NOTE:** This method requires the `i128` feature.
/// The current position is advanced by 16.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello");
/// assert_eq!(0x01020304050607080910111213141516, buf.get_u128_le());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
#[cfg(feature = "i128")]
fn get_u128_le(&mut self) -> u128 {
buf_get_impl!(self, 16, LittleEndian::read_u128);
}
/// Gets a signed 128 bit integer from `self` in big-endian byte order.
///
/// **NOTE:** This method requires the `i128` feature.
/// The current position is advanced by 16.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello");
/// assert_eq!(0x01020304050607080910111213141516, buf.get_i128_be());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
#[cfg(feature = "i128")]
fn get_i128_be(&mut self) -> i128 {
buf_get_impl!(self, 16, BigEndian::read_i128);
}
/// Gets a signed 128 bit integer from `self` in little-endian byte order.
///
/// **NOTE:** This method requires the `i128` feature.
/// The current position is advanced by 16.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello");
/// assert_eq!(0x01020304050607080910111213141516, buf.get_i128_le());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
#[cfg(feature = "i128")]
fn get_i128_le(&mut self) -> i128 {
buf_get_impl!(self, 16, LittleEndian::read_i128);
}
#[doc(hidden)]
#[deprecated(note="use get_uint_be or get_uint_le")]
fn get_uint<T: ByteOrder>(&mut self, nbytes: usize) -> u64 where Self: Sized {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf[..nbytes]);
T::read_uint(&buf[..nbytes], nbytes)
}
/// Gets an unsigned n-byte integer from `self` in big-endian byte order.
///
/// The current position is advanced by `nbytes`.
///
/// # 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 +1148,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) {}
+574 -143
View File
@@ -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};
@@ -121,7 +121,8 @@ pub trait BufMut {
}
/// Returns a mutable slice starting at the current BufMut position and of
/// length between 0 and `BufMut::remaining_mut()`.
/// length between 0 and `BufMut::remaining_mut()`. Note that this *can* be shorter than the
/// whole remainder of the buffer (this allows non-continuous implementation).
///
/// This is a lower level function. Most operations are done with other
/// functions.
@@ -338,41 +339,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 +365,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 +477,440 @@ 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)
}
/// Writes an unsigned 128 bit integer to `self` in the big-endian byte order.
///
/// **NOTE:** This method requires the `i128` feature.
/// The current position is advanced by 16.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_u128_be(0x01020304050607080910111213141516);
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
#[cfg(feature = "i128")]
fn put_u128_be(&mut self, n: u128) {
let mut buf = [0; 16];
BigEndian::write_u128(&mut buf, n);
self.put_slice(&buf)
}
/// Writes an unsigned 128 bit integer to `self` in little-endian byte order.
///
/// **NOTE:** This method requires the `i128` feature.
/// The current position is advanced by 16.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_u128_le(0x01020304050607080910111213141516);
/// assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
#[cfg(feature = "i128")]
fn put_u128_le(&mut self, n: u128) {
let mut buf = [0; 16];
LittleEndian::write_u128(&mut buf, n);
self.put_slice(&buf)
}
/// Writes a signed 128 bit integer to `self` in the big-endian byte order.
///
/// **NOTE:** This method requires the `i128` feature.
/// The current position is advanced by 16.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_i128_be(0x01020304050607080910111213141516);
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
#[cfg(feature = "i128")]
fn put_i128_be(&mut self, n: i128) {
let mut buf = [0; 16];
BigEndian::write_i128(&mut buf, n);
self.put_slice(&buf)
}
/// Writes a signed 128 bit integer to `self` in little-endian byte order.
///
/// **NOTE:** This method requires the `i128` feature.
/// The current position is advanced by 16.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_i128_le(0x01020304050607080910111213141516);
/// assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
#[cfg(feature = "i128")]
fn put_i128_le(&mut self, n: i128) {
let mut buf = [0; 16];
LittleEndian::write_i128(&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 +918,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 +976,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 +1161,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) {}
+8
View File
@@ -63,6 +63,14 @@ impl<'a> IntoBuf for &'a [u8] {
}
}
impl<'a> IntoBuf for &'a mut [u8] {
type Buf = io::Cursor<&'a mut [u8]>;
fn into_buf(self) -> Self::Buf {
io::Cursor::new(self)
}
}
impl<'a> IntoBuf for &'a str {
type Buf = io::Cursor<&'a [u8]>;
+1
View File
@@ -24,6 +24,7 @@ mod into_buf;
mod iter;
mod reader;
mod take;
mod vec_deque;
mod writer;
pub use self::buf::Buf;
+9
View File
@@ -86,3 +86,12 @@ impl<B: Buf + Sized> io::Read for Reader<B> {
Ok(len)
}
}
impl<B: Buf + Sized> io::BufRead for Reader<B> {
fn fill_buf(&mut self) -> io::Result<&[u8]> {
Ok(self.buf.bytes())
}
fn consume(&mut self, amt: usize) {
self.buf.advance(amt)
}
}
+39
View File
@@ -0,0 +1,39 @@
use std::collections::VecDeque;
use super::Buf;
impl Buf for VecDeque<u8> {
fn remaining(&self) -> usize {
self.len()
}
fn bytes(&self) -> &[u8] {
let (s1, s2) = self.as_slices();
if s1.is_empty() {
s2
} else {
s1
}
}
fn advance(&mut self, cnt: usize) {
self.drain(..cnt);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn hello_world() {
let mut buffer: VecDeque<u8> = VecDeque::new();
buffer.extend(b"hello world");
assert_eq!(11, buffer.remaining());
assert_eq!(b"hello world", buffer.bytes());
buffer.advance(6);
assert_eq!(b"world", buffer.bytes());
buffer.extend(b" piece");
assert_eq!(b"world piece" as &[u8], &buffer.collect::<Vec<u8>>()[..]);
}
}
+602 -224
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -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));
+89
View File
@@ -0,0 +1,89 @@
extern crate either;
use {Buf, BufMut};
use self::either::Either;
use self::either::Either::*;
use iovec::IoVec;
impl<L, R> Buf for Either<L, R>
where
L: Buf,
R: Buf,
{
fn remaining(&self) -> usize {
match *self {
Left(ref b) => b.remaining(),
Right(ref b) => b.remaining(),
}
}
fn bytes(&self) -> &[u8] {
match *self {
Left(ref b) => b.bytes(),
Right(ref b) => b.bytes(),
}
}
fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize {
match *self {
Left(ref b) => b.bytes_vec(dst),
Right(ref b) => b.bytes_vec(dst),
}
}
fn advance(&mut self, cnt: usize) {
match *self {
Left(ref mut b) => b.advance(cnt),
Right(ref mut b) => b.advance(cnt),
}
}
fn copy_to_slice(&mut self, dst: &mut [u8]) {
match *self {
Left(ref mut b) => b.copy_to_slice(dst),
Right(ref mut b) => b.copy_to_slice(dst),
}
}
}
impl<L, R> BufMut for Either<L, R>
where
L: BufMut,
R: BufMut,
{
fn remaining_mut(&self) -> usize {
match *self {
Left(ref b) => b.remaining_mut(),
Right(ref b) => b.remaining_mut(),
}
}
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
match *self {
Left(ref mut b) => b.bytes_mut(),
Right(ref mut b) => b.bytes_mut(),
}
}
unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize {
match *self {
Left(ref mut b) => b.bytes_vec_mut(dst),
Right(ref mut b) => b.bytes_vec_mut(dst),
}
}
unsafe fn advance_mut(&mut self, cnt: usize) {
match *self {
Left(ref mut b) => b.advance_mut(cnt),
Right(ref mut b) => b.advance_mut(cnt),
}
}
fn put_slice(&mut self, src: &[u8]) {
match *self {
Left(ref mut b) => b.put_slice(src),
Right(ref mut b) => b.put_slice(src),
}
}
}
+8 -3
View File
@@ -18,8 +18,8 @@
//! using a reference count to track when the memory is no longer needed and can
//! be freed.
//!
//! A `Bytes` handle can be created directly from an existing byte store (such as &[u8]
//! or Vec<u8>), but usually a `BytesMut` is used first and written to. For
//! A `Bytes` handle can be created directly from an existing byte store (such as `&[u8]`
//! or `Vec<u8>`), but usually a `BytesMut` is used first and written to. For
//! example:
//!
//! ```rust
@@ -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.12")]
extern crate byteorder;
extern crate iovec;
@@ -92,9 +92,14 @@ mod bytes;
mod debug;
pub use bytes::{Bytes, BytesMut};
#[deprecated]
pub use byteorder::{ByteOrder, BigEndian, LittleEndian};
// Optional Serde support
#[cfg(feature = "serde")]
#[doc(hidden)]
pub mod serde;
// Optional `Either` support
#[cfg(feature = "either")]
mod either;
+9 -4
View File
@@ -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[..]));
}
+2 -2
View File
@@ -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[..]);
}
+263 -11
View File
@@ -1,6 +1,6 @@
extern crate bytes;
use bytes::{Bytes, BytesMut, BufMut};
use bytes::{Bytes, BytesMut, BufMut, IntoBuf};
const LONG: &'static [u8] = b"mary had a little lamb, little lamb, little lamb";
const SHORT: &'static [u8] = b"hello world";
@@ -258,15 +258,10 @@ fn split_to_oob_mut() {
}
#[test]
#[should_panic]
fn split_to_uninitialized() {
let mut bytes = BytesMut::with_capacity(1024);
let other = bytes.split_to(128);
assert_eq!(bytes.len(), 0);
assert_eq!(bytes.capacity(), 896);
assert_eq!(other.len(), 0);
assert_eq!(other.capacity(), 128);
let _other = bytes.split_to(128);
}
#[test]
@@ -303,6 +298,13 @@ fn fns_defined_for_bytes_mut() {
assert_eq!(&v[..], bytes);
}
#[test]
fn mut_into_buf() {
let mut v = vec![0, 0, 0, 0];
let s = &mut v[..];
s.into_buf().put_u32_le(42);
}
#[test]
fn reserve_convert() {
// Inline -> Vec
@@ -350,16 +352,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]
@@ -378,6 +380,21 @@ fn reserve_max_original_capacity_value() {
assert_eq!(bytes.capacity(), 64 * 1024);
}
// Without either looking at the internals of the BytesMut or doing weird stuff
// with the memory allocator, there's no good way to automatically verify from
// within the program that this actually recycles memory. Instead, just exercise
// the code path to ensure that the results are correct.
#[test]
fn reserve_vec_recycling() {
let mut bytes = BytesMut::from(Vec::with_capacity(16));
assert_eq!(bytes.capacity(), 16);
bytes.put("0123456789012345");
bytes.advance(10);
assert_eq!(bytes.capacity(), 6);
bytes.reserve(8);
assert_eq!(bytes.capacity(), 16);
}
#[test]
fn reserve_in_arc_unique_does_not_overallocate() {
let mut bytes = BytesMut::with_capacity(1000);
@@ -466,6 +483,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 +569,200 @@ 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[..]);
}
#[test]
fn from_iter_no_size_hint() {
use std::iter;
let mut expect = vec![];
let actual: Bytes = iter::repeat(b'x')
.scan(100, |cnt, item| {
if *cnt >= 1 {
*cnt -= 1;
expect.push(item);
Some(item)
} else {
None
}
})
.collect();
assert_eq!(&actual[..], &expect[..]);
}
fn test_slice_ref(bytes: &Bytes, start: usize, end: usize, expected: &[u8]) {
let slice = &(bytes.as_ref()[start..end]);
let sub = bytes.slice_ref(&slice);
assert_eq!(&sub[..], expected);
}
#[test]
fn slice_ref_works() {
let bytes = Bytes::from(&b"012345678"[..]);
test_slice_ref(&bytes, 0, 0, b"");
test_slice_ref(&bytes, 0, 3, b"012");
test_slice_ref(&bytes, 2, 6, b"2345");
test_slice_ref(&bytes, 7, 9, b"78");
test_slice_ref(&bytes, 9, 9, b"");
}
#[test]
fn slice_ref_empty() {
let bytes = Bytes::from(&b""[..]);
let slice = &(bytes.as_ref()[0..0]);
let sub = bytes.slice_ref(&slice);
assert_eq!(&sub[..], b"");
}
#[test]
#[should_panic]
fn slice_ref_catches_not_a_subset() {
let bytes = Bytes::from(&b"012345678"[..]);
let slice = &b"012345"[0..4];
bytes.slice_ref(slice);
}
#[test]
#[should_panic]
fn slice_ref_catches_not_an_empty_subset() {
let bytes = Bytes::from(&b"012345678"[..]);
let slice = &b""[0..0];
bytes.slice_ref(slice);
}
#[test]
#[should_panic]
fn empty_slice_ref_catches_not_an_empty_subset() {
let bytes = Bytes::from(&b""[..]);
let slice = &b""[0..0];
bytes.slice_ref(slice);
}
+34 -14
View File
@@ -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
View File
@@ -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\
+28
View File
@@ -0,0 +1,28 @@
extern crate bytes;
use std::io::{BufRead, Cursor, Read};
use bytes::Buf;
#[test]
fn read() {
let buf1 = Cursor::new(b"hello ");
let buf2 = Cursor::new(b"world");
let buf = Buf::chain(buf1, buf2); // Disambiguate with Read::chain
let mut buffer = Vec::new();
buf.reader().read_to_end(&mut buffer).unwrap();
assert_eq!(b"hello world", &buffer[..]);
}
#[test]
fn buf_read() {
let buf1 = Cursor::new(b"hell");
let buf2 = Cursor::new(b"o\nworld");
let mut reader = Buf::chain(buf1, buf2).reader();
let mut line = String::new();
reader.read_line(&mut line).unwrap();
assert_eq!("hello\n", &line);
line.clear();
reader.read_line(&mut line).unwrap();
assert_eq!("world", &line);
}