mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-08 00:00:26 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98951ba26c | ||
|
|
171cffa505 | ||
|
|
a642e1c075 | ||
|
|
3cf91283f8 | ||
|
|
1db67b4a87 | ||
|
|
b7c1f2a135 | ||
|
|
cdd9fc09cd | ||
|
|
44fb206148 | ||
|
|
b3f86d8654 | ||
|
|
8135c1f606 | ||
|
|
59aea9e871 | ||
|
|
9a10addb44 | ||
|
|
b32f6298e2 | ||
|
|
856ed7c43d | ||
|
|
96268a80d4 | ||
|
|
2ac72333fa | ||
|
|
fe2183dc2f | ||
|
|
491ebbf79a | ||
|
|
43ac8e5494 | ||
|
|
ebe96021b0 | ||
|
|
97c1338833 | ||
|
|
c17e40115f | ||
|
|
73426dfaa3 | ||
|
|
425432ba6c | ||
|
|
4f5ed82b3c | ||
|
|
ae9991f3ba | ||
|
|
b6cb346adf | ||
|
|
79e4b2847f | ||
|
|
b1c17169d9 | ||
|
|
234d814122 | ||
|
|
b5d4f87e7e | ||
|
|
e07a949665 | ||
|
|
ae7d884582 | ||
|
|
ecdde1a996 | ||
|
|
e25b75a28e | ||
|
|
9b5e33d6f0 | ||
|
|
dea868a4b0 | ||
|
|
ac4e8f2fc5 | ||
|
|
ed7c7b5c58 | ||
|
|
09772c4e77 | ||
|
|
47fdf06e34 | ||
|
|
55aa530dc1 | ||
|
|
d8134903de | ||
|
|
654a11c84c | ||
|
|
5759211ff8 | ||
|
|
60aceba2bb | ||
|
|
d43e283e5e | ||
|
|
e0e30f00a1 | ||
|
|
4948b1053b | ||
|
|
0e8b440650 | ||
|
|
e13d2a783e | ||
|
|
55dfea8c18 | ||
|
|
f3b363a385 | ||
|
|
42b669690a | ||
|
|
9504447adc | ||
|
|
b3248c8807 | ||
|
|
c6c5b8fb54 | ||
|
|
7c3085aaec | ||
|
|
e64a123d00 | ||
|
|
e5304410a4 | ||
|
|
456221d165 | ||
|
|
f09c51c34e | ||
|
|
ad35fbef03 | ||
|
|
79f05591c9 | ||
|
|
ed244d3b54 | ||
|
|
dc961c3e78 | ||
|
|
890812af1b | ||
|
|
052648c3f5 | ||
|
|
042aa9023b | ||
|
|
f4100841f8 | ||
|
|
cdfd25f314 | ||
|
|
1ba5266bd9 | ||
|
|
83f68a013e | ||
|
|
63211d8c82 | ||
|
|
886dda0962 | ||
|
|
6414efe83b | ||
|
|
7785cde587 | ||
|
|
d98f49e67b | ||
|
|
a6b9844296 | ||
|
|
8d5b46cd10 | ||
|
|
3557bafa5c | ||
|
|
c87739bb55 | ||
|
|
2d95683bd5 | ||
|
|
d656d37180 | ||
|
|
e444722098 | ||
|
|
d561006290 | ||
|
|
2c27ddaf7e | ||
|
|
ae1b45495b | ||
|
|
ebe522731f | ||
|
|
bd4630a321 | ||
|
|
025d53342e | ||
|
|
ff7c0a1d90 | ||
|
|
4b68ef407f | ||
|
|
355a662976 | ||
|
|
3d169f1f34 | ||
|
|
c316c2433d |
-85
@@ -1,85 +0,0 @@
|
||||
---
|
||||
dist: trusty
|
||||
language: rust
|
||||
services: docker
|
||||
sudo: required
|
||||
rust: stable
|
||||
|
||||
env:
|
||||
global:
|
||||
- CRATE_NAME=bytes
|
||||
# Default job
|
||||
- TARGET=x86_64-unknown-linux-gnu
|
||||
- secure: "f17G5kb6uAQlAG9+GknFFYAmngGBqy9h+3FtNbp3mXTI0FOLltz00Ul5kGPysE4eagypm/dWOuvBkNjN01jhE6fCbekmInEsobIuanatrk6TvXT6caJqykxhPJC2cUoq8pKnMqEOuucEqPPUH6Qy6Hz4/2cRu5JV22Uv9dtS29Q="
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# Run build on oldest supported rust version. Do not change the rust
|
||||
# version without a Github issue first.
|
||||
#
|
||||
# This job will also build and deploy the docs to gh-pages.
|
||||
- env: TARGET=x86_64-unknown-linux-gnu
|
||||
rust: 1.15.0
|
||||
after_success:
|
||||
- |
|
||||
pip install 'travis-cargo<0.2' --user &&
|
||||
export PATH=$HOME/.local/bin:$PATH
|
||||
- travis-cargo doc
|
||||
- travis-cargo doc-upload
|
||||
|
||||
# Run tests on some extra platforms
|
||||
- env: TARGET=i686-unknown-linux-gnu
|
||||
- env: TARGET=armv7-unknown-linux-gnueabihf
|
||||
- env: RUST_TEST_THREADS=1 TARGET=powerpc-unknown-linux-gnu
|
||||
- env: RUST_TEST_THREADS=1 TARGET=powerpc64-unknown-linux-gnu
|
||||
|
||||
# Serde implementation
|
||||
- env: EXTRA_ARGS="--features serde"
|
||||
|
||||
# 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:
|
||||
- sh ci/install.sh
|
||||
- source ~/.cargo/env || true
|
||||
|
||||
script:
|
||||
- bash ci/script.sh
|
||||
|
||||
after_script: set +e
|
||||
|
||||
before_deploy:
|
||||
- sh ci/before_deploy.sh
|
||||
|
||||
cache: cargo
|
||||
before_cache:
|
||||
# Travis can't cache files that are not readable by "others"
|
||||
- chmod -R a+r $HOME/.cargo
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_success: never
|
||||
@@ -1,3 +1,68 @@
|
||||
# 0.5.2 (November 27, 2019)
|
||||
|
||||
### Added
|
||||
- `Limit` methods `into_inner`, `get_ref`, `get_mut`, `limit`, and `set_limit` (#325).
|
||||
|
||||
# 0.5.1 (November 25, 2019)
|
||||
|
||||
### Fix
|
||||
- Growth documentation for `BytesMut` (#321)
|
||||
|
||||
# 0.5.0 (November 25, 2019)
|
||||
|
||||
### Fix
|
||||
- Potential overflow in `copy_to_slice`
|
||||
|
||||
### Changed
|
||||
- Increased minimum supported Rust version to 1.39.
|
||||
- `Bytes` is now a "trait object", allowing for custom allocation strategies (#298)
|
||||
- `BytesMut` implicitly grows internal storage. `remaining_mut()` returns
|
||||
`usize::MAX` (#316).
|
||||
- `BufMut::bytes_mut` returns `&mut [MaybeUninit<u8>]` to reflect the unknown
|
||||
initialization state (#305).
|
||||
- `Buf` / `BufMut` implementations for `&[u8]` and `&mut [u8]`
|
||||
respectively (#261).
|
||||
- Move `Buf` / `BufMut` "extra" functions to an extension trait (#306).
|
||||
- `BufMutExt::limit` (#309).
|
||||
- `Bytes::slice` takes a `RangeBounds` argument (#265).
|
||||
- `Bytes::from_static` is now a `const fn` (#311).
|
||||
- A multitude of smaller performance optimizations.
|
||||
|
||||
### Added
|
||||
- `no_std` support (#281).
|
||||
- `get_*`, `put_*`, `get_*_le`, and `put_*le` accessors for handling byte order.
|
||||
- `BorrowMut` implementation for `BytesMut` (#185).
|
||||
|
||||
### Removed
|
||||
- `IntoBuf` (#288).
|
||||
- `Buf` implementation for `&str` (#301).
|
||||
- `byteorder` dependency (#280).
|
||||
- `iovec` dependency, use `std::IoSlice` instead (#263).
|
||||
- optional `either` dependency (#315).
|
||||
- optional `i128` feature -- now available on stable. (#276).
|
||||
|
||||
# 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.
|
||||
|
||||
+20
-19
@@ -1,28 +1,29 @@
|
||||
[package]
|
||||
|
||||
name = "bytes"
|
||||
version = "0.4.8" # don't forget to update html_root_url
|
||||
license = "MIT/Apache-2.0"
|
||||
authors = ["Carl Lerche <[email protected]>"]
|
||||
description = "Types and traits for working with bytes"
|
||||
documentation = "https://carllerche.github.io/bytes/bytes"
|
||||
homepage = "https://github.com/carllerche/bytes"
|
||||
repository = "https://github.com/carllerche/bytes"
|
||||
readme = "README.md"
|
||||
keywords = ["buffers", "zero-copy", "io"]
|
||||
exclude = [
|
||||
".gitignore",
|
||||
".travis.yml",
|
||||
"deploy.sh",
|
||||
"bench/**/*",
|
||||
"test/**/*"
|
||||
]
|
||||
name = "bytes"
|
||||
# When releasing to crates.io:
|
||||
# - Update html_root_url.
|
||||
# - Update CHANGELOG.md.
|
||||
# - Update doc URL.
|
||||
# - Create "v0.5.x" git tag.
|
||||
version = "0.5.2"
|
||||
license = "MIT"
|
||||
authors = ["Carl Lerche <[email protected]>"]
|
||||
description = "Types and traits for working with bytes"
|
||||
documentation = "https://docs.rs/bytes"
|
||||
repository = "https://github.com/tokio-rs/bytes"
|
||||
readme = "README.md"
|
||||
keywords = ["buffers", "zero-copy", "io"]
|
||||
categories = ["network-programming", "data-structures"]
|
||||
edition = "2018"
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = []
|
||||
|
||||
[dependencies]
|
||||
byteorder = "1.0.0"
|
||||
iovec = "0.1"
|
||||
serde = { version = "1.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
loom = "0.2.10"
|
||||
serde_test = "1.0"
|
||||
|
||||
@@ -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
@@ -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.
|
||||
@@ -2,10 +2,15 @@
|
||||
|
||||
A utility library for working with bytes.
|
||||
|
||||
[](https://crates.io/crates/bytes)
|
||||
[](https://travis-ci.org/carllerche/bytes)
|
||||
[![Crates.io][crates-badge]][crates-url]
|
||||
[![Build Status][azure-badge]][azure-url]
|
||||
|
||||
[Documentation](https://carllerche.github.io/bytes/bytes/index.html)
|
||||
[crates-badge]: https://img.shields.io/crates/v/bytes.svg
|
||||
[crates-url]: https://crates.io/crates/bytes
|
||||
[azure-badge]: https://dev.azure.com/tokio-rs/bytes/_apis/build/status/tokio-rs.bytes?branchName=master
|
||||
[azure-url]: https://dev.azure.com/tokio-rs/bytes/_build/latest?definitionId=3&branchName=master
|
||||
|
||||
[Documentation](https://docs.rs/bytes)
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -13,14 +18,12 @@ To use `bytes`, first add this to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
bytes = "0.4"
|
||||
bytes = "0.5"
|
||||
```
|
||||
|
||||
Next, add this to your crate:
|
||||
|
||||
```rust
|
||||
extern crate bytes;
|
||||
|
||||
use bytes::{Bytes, BytesMut, Buf, BufMut};
|
||||
```
|
||||
|
||||
@@ -30,13 +33,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.5", 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.
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
trigger: ["master"]
|
||||
pr: ["master"]
|
||||
|
||||
jobs:
|
||||
# Check formatting
|
||||
# - template: ci/azure-rustfmt.yml
|
||||
# parameters:
|
||||
# name: rustfmt
|
||||
|
||||
# Apply clippy lints
|
||||
# - template: ci/azure-clippy.yml
|
||||
# parameters:
|
||||
# name: clippy
|
||||
|
||||
# This represents the minimum Rust version supported by
|
||||
# Bytes. Updating this should be done in a dedicated PR.
|
||||
#
|
||||
# Tests are not run as tests may require newer versions of
|
||||
# rust.
|
||||
- template: ci/azure-test-stable.yml
|
||||
parameters:
|
||||
name: minrust
|
||||
rust_version: 1.39.0
|
||||
cmd: check
|
||||
|
||||
# Stable
|
||||
- template: ci/azure-test-stable.yml
|
||||
parameters:
|
||||
name: stable
|
||||
cross: true
|
||||
features:
|
||||
- serde
|
||||
|
||||
# Nightly
|
||||
- template: ci/azure-test-stable.yml
|
||||
parameters:
|
||||
name: nightly
|
||||
# Pin nightly to avoid being impacted by breakage
|
||||
rust_version: nightly-2019-09-25
|
||||
benches: true
|
||||
|
||||
# Run tests on some extra platforms
|
||||
- template: ci/azure-cross-compile.yml
|
||||
parameters:
|
||||
name: cross
|
||||
|
||||
# Sanitizers
|
||||
- template: ci/azure-tsan.yml
|
||||
parameters:
|
||||
name: tsan
|
||||
rust_version: nightly
|
||||
|
||||
# Loom
|
||||
- template: ci/azure-loom.yml
|
||||
parameters:
|
||||
name: loom
|
||||
rust_version: stable
|
||||
|
||||
|
||||
- template: ci/azure-deploy-docs.yml
|
||||
parameters:
|
||||
dependsOn:
|
||||
# - rustfmt
|
||||
# - clippy
|
||||
- stable
|
||||
- nightly
|
||||
- minrust
|
||||
- cross
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
#![feature(test)]
|
||||
#![deny(warnings, rust_2018_idioms)]
|
||||
|
||||
extern crate test;
|
||||
|
||||
use test::Bencher;
|
||||
use bytes::Buf;
|
||||
|
||||
/// Dummy Buf implementation
|
||||
struct TestBuf {
|
||||
buf: &'static [u8],
|
||||
readlens: &'static [usize],
|
||||
init_pos: usize,
|
||||
pos: usize,
|
||||
readlen_pos: usize,
|
||||
readlen: usize,
|
||||
}
|
||||
impl TestBuf {
|
||||
fn new(buf: &'static [u8], readlens: &'static [usize], init_pos: usize) -> TestBuf {
|
||||
let mut buf = TestBuf {
|
||||
buf,
|
||||
readlens,
|
||||
init_pos,
|
||||
pos: 0,
|
||||
readlen_pos: 0,
|
||||
readlen: 0,
|
||||
};
|
||||
buf.reset();
|
||||
buf
|
||||
}
|
||||
fn reset(&mut self) {
|
||||
self.pos = self.init_pos;
|
||||
self.readlen_pos = 0;
|
||||
self.next_readlen();
|
||||
}
|
||||
/// Compute the length of the next read :
|
||||
/// - use the next value specified in readlens (capped by remaining) if any
|
||||
/// - else the remaining
|
||||
fn next_readlen(&mut self) {
|
||||
self.readlen = self.buf.len() - self.pos;
|
||||
if let Some(readlen) = self.readlens.get(self.readlen_pos) {
|
||||
self.readlen = std::cmp::min(self.readlen, *readlen);
|
||||
self.readlen_pos += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Buf for TestBuf {
|
||||
fn remaining(&self) -> usize {
|
||||
return self.buf.len() - self.pos;
|
||||
}
|
||||
fn advance(&mut self, cnt: usize) {
|
||||
self.pos += cnt;
|
||||
assert!(self.pos <= self.buf.len());
|
||||
self.next_readlen();
|
||||
}
|
||||
fn bytes(&self) -> &[u8] {
|
||||
if self.readlen == 0 {
|
||||
Default::default()
|
||||
} else {
|
||||
&self.buf[self.pos..self.pos + self.readlen]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Dummy Buf implementation
|
||||
/// version with methods forced to not be inlined (to simulate costly calls)
|
||||
struct TestBufC {
|
||||
inner: TestBuf,
|
||||
}
|
||||
impl TestBufC {
|
||||
fn new(buf: &'static [u8], readlens: &'static [usize], init_pos: usize) -> TestBufC {
|
||||
TestBufC {
|
||||
inner: TestBuf::new(buf, readlens, init_pos),
|
||||
}
|
||||
}
|
||||
fn reset(&mut self) {
|
||||
self.inner.reset()
|
||||
}
|
||||
}
|
||||
impl Buf for TestBufC {
|
||||
#[inline(never)]
|
||||
fn remaining(&self) -> usize {
|
||||
self.inner.remaining()
|
||||
}
|
||||
#[inline(never)]
|
||||
fn advance(&mut self, cnt: usize) {
|
||||
self.inner.advance(cnt)
|
||||
}
|
||||
#[inline(never)]
|
||||
fn bytes(&self) -> &[u8] {
|
||||
self.inner.bytes()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! bench {
|
||||
($fname:ident, testbuf $testbuf:ident $readlens:expr, $method:ident $(,$arg:expr)*) => (
|
||||
#[bench]
|
||||
fn $fname(b: &mut Bencher) {
|
||||
let mut bufs = [
|
||||
$testbuf::new(&[1u8; 8+0], $readlens, 0),
|
||||
$testbuf::new(&[1u8; 8+1], $readlens, 1),
|
||||
$testbuf::new(&[1u8; 8+2], $readlens, 2),
|
||||
$testbuf::new(&[1u8; 8+3], $readlens, 3),
|
||||
$testbuf::new(&[1u8; 8+4], $readlens, 4),
|
||||
$testbuf::new(&[1u8; 8+5], $readlens, 5),
|
||||
$testbuf::new(&[1u8; 8+6], $readlens, 6),
|
||||
$testbuf::new(&[1u8; 8+7], $readlens, 7),
|
||||
];
|
||||
b.iter(|| {
|
||||
for i in 0..8 {
|
||||
bufs[i].reset();
|
||||
let buf: &mut dyn Buf = &mut bufs[i]; // type erasure
|
||||
test::black_box(buf.$method($($arg,)*));
|
||||
}
|
||||
})
|
||||
}
|
||||
);
|
||||
($fname:ident, slice, $method:ident $(,$arg:expr)*) => (
|
||||
#[bench]
|
||||
fn $fname(b: &mut Bencher) {
|
||||
// buf must be long enough for one read of 8 bytes starting at pos 7
|
||||
let arr = [1u8; 8+7];
|
||||
b.iter(|| {
|
||||
for i in 0..8 {
|
||||
let mut buf = &arr[i..];
|
||||
let buf = &mut buf as &mut dyn Buf; // type erasure
|
||||
test::black_box(buf.$method($($arg,)*));
|
||||
}
|
||||
})
|
||||
}
|
||||
);
|
||||
($fname:ident, option) => (
|
||||
#[bench]
|
||||
fn $fname(b: &mut Bencher) {
|
||||
let data = [1u8; 1];
|
||||
b.iter(|| {
|
||||
for _ in 0..8 {
|
||||
let mut buf = Some(data);
|
||||
let buf = &mut buf as &mut dyn Buf; // type erasure
|
||||
test::black_box(buf.get_u8());
|
||||
}
|
||||
})
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
macro_rules! bench_group {
|
||||
($method:ident $(,$arg:expr)*) => (
|
||||
bench!(slice, slice, $method $(,$arg)*);
|
||||
bench!(tbuf_1, testbuf TestBuf &[], $method $(,$arg)*);
|
||||
bench!(tbuf_1_costly, testbuf TestBufC &[], $method $(,$arg)*);
|
||||
bench!(tbuf_2, testbuf TestBuf &[1], $method $(,$arg)*);
|
||||
bench!(tbuf_2_costly, testbuf TestBufC &[1], $method $(,$arg)*);
|
||||
// bench!(tbuf_onebyone, testbuf TestBuf &[1,1,1,1,1,1,1,1], $method $(,$arg)*);
|
||||
// bench!(tbuf_onebyone_costly, testbuf TestBufC &[1,1,1,1,1,1,1,1], $method $(,$arg)*);
|
||||
);
|
||||
}
|
||||
|
||||
mod get_u8 {
|
||||
use super::*;
|
||||
bench_group!(get_u8);
|
||||
bench!(option, option);
|
||||
}
|
||||
mod get_u16 {
|
||||
use super::*;
|
||||
bench_group!(get_u16);
|
||||
}
|
||||
mod get_u32 {
|
||||
use super::*;
|
||||
bench_group!(get_u32);
|
||||
}
|
||||
mod get_u64 {
|
||||
use super::*;
|
||||
bench_group!(get_u64);
|
||||
}
|
||||
mod get_f32 {
|
||||
use super::*;
|
||||
bench_group!(get_f32);
|
||||
}
|
||||
mod get_f64 {
|
||||
use super::*;
|
||||
bench_group!(get_f64);
|
||||
}
|
||||
mod get_uint24 {
|
||||
use super::*;
|
||||
bench_group!(get_uint, 3);
|
||||
}
|
||||
+84
-183
@@ -1,31 +1,107 @@
|
||||
#![feature(test)]
|
||||
#![deny(warnings, rust_2018_idioms)]
|
||||
|
||||
extern crate bytes;
|
||||
extern crate test;
|
||||
|
||||
use test::Bencher;
|
||||
use bytes::{Bytes, BytesMut, BufMut};
|
||||
use bytes::Bytes;
|
||||
|
||||
#[bench]
|
||||
fn alloc_small(b: &mut Bencher) {
|
||||
fn deref_unique(b: &mut Bencher) {
|
||||
let buf = Bytes::from(vec![0; 1024]);
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..1024 {
|
||||
test::black_box(BytesMut::with_capacity(12));
|
||||
test::black_box(&buf[..]);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn alloc_mid(b: &mut Bencher) {
|
||||
fn deref_shared(b: &mut Bencher) {
|
||||
let buf = Bytes::from(vec![0; 1024]);
|
||||
let _b2 = buf.clone();
|
||||
|
||||
b.iter(|| {
|
||||
test::black_box(BytesMut::with_capacity(128));
|
||||
for _ in 0..1024 {
|
||||
test::black_box(&buf[..]);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn alloc_big(b: &mut Bencher) {
|
||||
fn deref_static(b: &mut Bencher) {
|
||||
let buf = Bytes::from_static(b"hello world");
|
||||
|
||||
b.iter(|| {
|
||||
test::black_box(BytesMut::with_capacity(4096));
|
||||
for _ in 0..1024 {
|
||||
test::black_box(&buf[..]);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[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_shared(b: &mut Bencher) {
|
||||
let bytes = Bytes::from(b"hello world 1234567890 and have a good byte 0987654321".to_vec());
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..1024 {
|
||||
test::black_box(&bytes.clone());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn clone_arc_vec(b: &mut Bencher) {
|
||||
use std::sync::Arc;
|
||||
let bytes = Arc::new(b"hello world 1234567890 and have a good byte 0987654321".to_vec());
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..1024 {
|
||||
test::black_box(&bytes.clone());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn from_long_slice(b: &mut Bencher) {
|
||||
let data = [0u8; 128];
|
||||
b.bytes = data.len() as u64;
|
||||
b.iter(|| {
|
||||
let buf = Bytes::copy_from_slice(&data[..]);
|
||||
test::black_box(buf);
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn slice_empty(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let b = Bytes::from(vec![17; 1024]).clone();
|
||||
for i in 0..1000 {
|
||||
test::black_box(b.slice(i % 100..i % 100));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn slice_short_from_arc(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
// `clone` is to convert to ARC
|
||||
let b = Bytes::from(vec![17; 1024]).clone();
|
||||
for i in 0..1000 {
|
||||
test::black_box(b.slice(1..2 + i % 10));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -40,178 +116,3 @@ fn split_off_and_drop(b: &mut Bencher) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn deref_unique(b: &mut Bencher) {
|
||||
let mut buf = BytesMut::with_capacity(4096);
|
||||
buf.put(&[0u8; 1024][..]);
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..1024 {
|
||||
test::black_box(&buf[..]);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn deref_unique_unroll(b: &mut Bencher) {
|
||||
let mut buf = BytesMut::with_capacity(4096);
|
||||
buf.put(&[0u8; 1024][..]);
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..128 {
|
||||
test::black_box(&buf[..]);
|
||||
test::black_box(&buf[..]);
|
||||
test::black_box(&buf[..]);
|
||||
test::black_box(&buf[..]);
|
||||
test::black_box(&buf[..]);
|
||||
test::black_box(&buf[..]);
|
||||
test::black_box(&buf[..]);
|
||||
test::black_box(&buf[..]);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn deref_shared(b: &mut Bencher) {
|
||||
let mut buf = BytesMut::with_capacity(4096);
|
||||
buf.put(&[0u8; 1024][..]);
|
||||
let _b2 = buf.split_off(1024);
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..1024 {
|
||||
test::black_box(&buf[..]);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn deref_inline(b: &mut Bencher) {
|
||||
let mut buf = BytesMut::with_capacity(8);
|
||||
buf.put(&[0u8; 8][..]);
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..1024 {
|
||||
test::black_box(&buf[..]);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn deref_two(b: &mut Bencher) {
|
||||
let mut buf1 = BytesMut::with_capacity(8);
|
||||
buf1.put(&[0u8; 8][..]);
|
||||
|
||||
let mut buf2 = BytesMut::with_capacity(4096);
|
||||
buf2.put(&[0u8; 1024][..]);
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..512 {
|
||||
test::black_box(&buf1[..]);
|
||||
test::black_box(&buf2[..]);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn alloc_write_split_to_mid(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let mut buf = BytesMut::with_capacity(128);
|
||||
buf.put_slice(&[0u8; 64]);
|
||||
test::black_box(buf.split_to(64));
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn drain_write_drain(b: &mut Bencher) {
|
||||
let data = [0u8; 128];
|
||||
|
||||
b.iter(|| {
|
||||
let mut buf = BytesMut::with_capacity(1024);
|
||||
let mut parts = Vec::with_capacity(8);
|
||||
|
||||
for _ in 0..8 {
|
||||
buf.put(&data[..]);
|
||||
parts.push(buf.split_to(128));
|
||||
}
|
||||
|
||||
test::black_box(parts);
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn fmt_write(b: &mut Bencher) {
|
||||
use std::fmt::Write;
|
||||
let mut buf = BytesMut::with_capacity(128);
|
||||
let s = "foo bar baz quux lorem ipsum dolor et";
|
||||
|
||||
b.bytes = s.len() as u64;
|
||||
b.iter(|| {
|
||||
let _ = write!(buf, "{}", s);
|
||||
test::black_box(&buf);
|
||||
unsafe { buf.set_len(0); }
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn from_long_slice(b: &mut Bencher) {
|
||||
let data = [0u8; 128];
|
||||
b.bytes = data.len() as u64;
|
||||
b.iter(|| {
|
||||
let buf = BytesMut::from(&data[..]);
|
||||
test::black_box(buf);
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn slice_empty(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let b = Bytes::from(vec![17; 1024]).clone();
|
||||
for i in 0..1000 {
|
||||
test::black_box(b.slice(i % 100, i % 100));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn slice_short_from_arc(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
// `clone` is to convert to ARC
|
||||
let b = Bytes::from(vec![17; 1024]).clone();
|
||||
for i in 0..1000 {
|
||||
test::black_box(b.slice(1, 2 + i % 10));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Keep in sync with bytes.rs
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
const INLINE_CAP: usize = 4 * 8 - 1;
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
const INLINE_CAP: usize = 4 * 4 - 1;
|
||||
|
||||
#[bench]
|
||||
fn slice_avg_le_inline_from_arc(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
// `clone` is to convert to ARC
|
||||
let b = Bytes::from(vec![17; 1024]).clone();
|
||||
for i in 0..1000 {
|
||||
// [1, INLINE_CAP]
|
||||
let len = 1 + i % (INLINE_CAP - 1);
|
||||
test::black_box(b.slice(i % 10, i % 10 + len));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn slice_large_le_inline_from_arc(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
// `clone` is to convert to ARC
|
||||
let b = Bytes::from(vec![17; 1024]).clone();
|
||||
for i in 0..1000 {
|
||||
// [INLINE_CAP - 10, INLINE_CAP]
|
||||
let len = INLINE_CAP - 9 + i % 10;
|
||||
test::black_box(b.slice(i % 10, i % 10 + len));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
#![feature(test)]
|
||||
#![deny(warnings, rust_2018_idioms)]
|
||||
|
||||
extern crate test;
|
||||
|
||||
use test::Bencher;
|
||||
use bytes::{BufMut, BytesMut};
|
||||
|
||||
#[bench]
|
||||
fn alloc_small(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
for _ in 0..1024 {
|
||||
test::black_box(BytesMut::with_capacity(12));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn alloc_mid(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
test::black_box(BytesMut::with_capacity(128));
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn alloc_big(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
test::black_box(BytesMut::with_capacity(4096));
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
#[bench]
|
||||
fn deref_unique(b: &mut Bencher) {
|
||||
let mut buf = BytesMut::with_capacity(4096);
|
||||
buf.put(&[0u8; 1024][..]);
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..1024 {
|
||||
test::black_box(&buf[..]);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn deref_unique_unroll(b: &mut Bencher) {
|
||||
let mut buf = BytesMut::with_capacity(4096);
|
||||
buf.put(&[0u8; 1024][..]);
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..128 {
|
||||
test::black_box(&buf[..]);
|
||||
test::black_box(&buf[..]);
|
||||
test::black_box(&buf[..]);
|
||||
test::black_box(&buf[..]);
|
||||
test::black_box(&buf[..]);
|
||||
test::black_box(&buf[..]);
|
||||
test::black_box(&buf[..]);
|
||||
test::black_box(&buf[..]);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn deref_shared(b: &mut Bencher) {
|
||||
let mut buf = BytesMut::with_capacity(4096);
|
||||
buf.put(&[0u8; 1024][..]);
|
||||
let _b2 = buf.split_off(1024);
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..1024 {
|
||||
test::black_box(&buf[..]);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn deref_two(b: &mut Bencher) {
|
||||
let mut buf1 = BytesMut::with_capacity(8);
|
||||
buf1.put(&[0u8; 8][..]);
|
||||
|
||||
let mut buf2 = BytesMut::with_capacity(4096);
|
||||
buf2.put(&[0u8; 1024][..]);
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..512 {
|
||||
test::black_box(&buf1[..]);
|
||||
test::black_box(&buf2[..]);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn clone_frozen(b: &mut Bencher) {
|
||||
let bytes = BytesMut::from(&b"hello world 1234567890 and have a good byte 0987654321"[..]).split().freeze();
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..1024 {
|
||||
test::black_box(&bytes.clone());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn alloc_write_split_to_mid(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let mut buf = BytesMut::with_capacity(128);
|
||||
buf.put_slice(&[0u8; 64]);
|
||||
test::black_box(buf.split_to(64));
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn drain_write_drain(b: &mut Bencher) {
|
||||
let data = [0u8; 128];
|
||||
|
||||
b.iter(|| {
|
||||
let mut buf = BytesMut::with_capacity(1024);
|
||||
let mut parts = Vec::with_capacity(8);
|
||||
|
||||
for _ in 0..8 {
|
||||
buf.put(&data[..]);
|
||||
parts.push(buf.split_to(128));
|
||||
}
|
||||
|
||||
test::black_box(parts);
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn fmt_write(b: &mut Bencher) {
|
||||
use std::fmt::Write;
|
||||
let mut buf = BytesMut::with_capacity(128);
|
||||
let s = "foo bar baz quux lorem ipsum dolor et";
|
||||
|
||||
b.bytes = s.len() as u64;
|
||||
b.iter(|| {
|
||||
let _ = write!(buf, "{}", s);
|
||||
test::black_box(&buf);
|
||||
unsafe { buf.set_len(0); }
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bytes_mut_extend(b: &mut Bencher) {
|
||||
let mut buf = BytesMut::with_capacity(256);
|
||||
let data = [33u8; 32];
|
||||
|
||||
b.bytes = data.len() as u64 * 4;
|
||||
b.iter(|| {
|
||||
for _ in 0..4 {
|
||||
buf.extend(&data);
|
||||
}
|
||||
test::black_box(&buf);
|
||||
unsafe { buf.set_len(0); }
|
||||
});
|
||||
}
|
||||
|
||||
// BufMut for BytesMut vs Vec<u8>
|
||||
|
||||
#[bench]
|
||||
fn put_slice_bytes_mut(b: &mut Bencher) {
|
||||
let mut buf = BytesMut::with_capacity(256);
|
||||
let data = [33u8; 32];
|
||||
|
||||
b.bytes = data.len() as u64 * 4;
|
||||
b.iter(|| {
|
||||
for _ in 0..4 {
|
||||
buf.put_slice(&data);
|
||||
}
|
||||
test::black_box(&buf);
|
||||
unsafe { buf.set_len(0); }
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn put_u8_bytes_mut(b: &mut Bencher) {
|
||||
let mut buf = BytesMut::with_capacity(256);
|
||||
let cnt = 128;
|
||||
|
||||
b.bytes = cnt as u64;
|
||||
b.iter(|| {
|
||||
for _ in 0..cnt {
|
||||
buf.put_u8(b'x');
|
||||
}
|
||||
test::black_box(&buf);
|
||||
unsafe { buf.set_len(0); }
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn put_slice_vec(b: &mut Bencher) {
|
||||
let mut buf = Vec::<u8>::with_capacity(256);
|
||||
let data = [33u8; 32];
|
||||
|
||||
b.bytes = data.len() as u64 * 4;
|
||||
b.iter(|| {
|
||||
for _ in 0..4 {
|
||||
buf.put_slice(&data);
|
||||
}
|
||||
test::black_box(&buf);
|
||||
unsafe { buf.set_len(0); }
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn put_u8_vec(b: &mut Bencher) {
|
||||
let mut buf = Vec::<u8>::with_capacity(256);
|
||||
let cnt = 128;
|
||||
|
||||
b.bytes = cnt as u64;
|
||||
b.iter(|| {
|
||||
for _ in 0..cnt {
|
||||
buf.put_u8(b'x');
|
||||
}
|
||||
test::black_box(&buf);
|
||||
unsafe { buf.set_len(0); }
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn put_slice_vec_extend(b: &mut Bencher) {
|
||||
let mut buf = Vec::<u8>::with_capacity(256);
|
||||
let data = [33u8; 32];
|
||||
|
||||
b.bytes = data.len() as u64 * 4;
|
||||
b.iter(|| {
|
||||
for _ in 0..4 {
|
||||
buf.extend_from_slice(&data);
|
||||
}
|
||||
test::black_box(&buf);
|
||||
unsafe { buf.set_len(0); }
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn put_u8_vec_push(b: &mut Bencher) {
|
||||
let mut buf = Vec::<u8>::with_capacity(256);
|
||||
let cnt = 128;
|
||||
|
||||
b.bytes = cnt as u64;
|
||||
b.iter(|| {
|
||||
for _ in 0..cnt {
|
||||
buf.push(b'x');
|
||||
}
|
||||
test::black_box(&buf);
|
||||
unsafe { buf.set_len(0); }
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
parameters:
|
||||
cmd: build
|
||||
rust_version: stable
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.name }}
|
||||
displayName: Cross
|
||||
strategy:
|
||||
matrix:
|
||||
i686:
|
||||
vmImage: ubuntu-16.04
|
||||
target: i686-unknown-linux-gnu
|
||||
armv7:
|
||||
vmImage: ubuntu-16.04
|
||||
target: armv7-unknown-linux-gnueabihf
|
||||
powerpc:
|
||||
vmImage: ubuntu-16.04
|
||||
target: powerpc-unknown-linux-gnu
|
||||
powerpc64:
|
||||
vmImage: ubuntu-16.04
|
||||
target: powerpc64-unknown-linux-gnu
|
||||
wasm:
|
||||
vmImage: ubuntu-16.04
|
||||
target: wasm32-unknown-unknown
|
||||
pool:
|
||||
vmImage: $(vmImage)
|
||||
|
||||
steps:
|
||||
- template: azure-install-rust.yml
|
||||
parameters:
|
||||
rust_version: ${{parameters.rust_version}}
|
||||
|
||||
- script: cargo install cross
|
||||
displayName: Install cross
|
||||
condition: not(eq(variables['target'], 'wasm32-unknown-unknown'))
|
||||
|
||||
- script: cross ${{ parameters.cmd }} --target $(target)
|
||||
displayName: cross ${{ parameters.cmd }} --target $(target)
|
||||
condition: not(eq(variables['target'], 'wasm32-unknown-unknown'))
|
||||
|
||||
# WASM support
|
||||
- script: |
|
||||
rustup target add $(target)
|
||||
cargo build --target $(target)
|
||||
displayName: cargo build --target $(target)
|
||||
condition: eq(variables['target'], 'wasm32-unknown-unknown')
|
||||
@@ -0,0 +1,39 @@
|
||||
parameters:
|
||||
dependsOn: []
|
||||
|
||||
jobs:
|
||||
- job: documentation
|
||||
displayName: 'Deploy API Documentation'
|
||||
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
|
||||
pool:
|
||||
vmImage: 'Ubuntu 16.04'
|
||||
dependsOn:
|
||||
- ${{ parameters.dependsOn }}
|
||||
steps:
|
||||
- template: azure-install-rust.yml
|
||||
parameters:
|
||||
rust_version: stable
|
||||
- script: |
|
||||
cargo doc --no-deps
|
||||
cp -R target/doc '$(Build.BinariesDirectory)'
|
||||
displayName: 'Generate Documentation'
|
||||
- script: |
|
||||
set -e
|
||||
|
||||
git --version
|
||||
ls -la
|
||||
git init
|
||||
git config user.name 'Deployment Bot (from Azure Pipelines)'
|
||||
git config user.email '[email protected]'
|
||||
git config --global credential.helper 'store --file ~/.my-credentials'
|
||||
printf "protocol=https\nhost=github.com\nusername=carllerche\npassword=%s\n\n" "$GITHUB_TOKEN" | git credential-store --file ~/.my-credentials store
|
||||
git remote add origin https://github.com/tokio-rs/bytes
|
||||
git checkout -b gh-pages
|
||||
git add .
|
||||
git commit -m 'Deploy Bytes API documentation'
|
||||
git push -f origin gh-pages
|
||||
env:
|
||||
GITHUB_TOKEN: $(githubPersonalToken)
|
||||
workingDirectory: '$(Build.BinariesDirectory)'
|
||||
displayName: 'Deploy Documentation'
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
steps:
|
||||
# Linux and macOS.
|
||||
- script: |
|
||||
set -e
|
||||
curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none
|
||||
export PATH=$PATH:$HOME/.cargo/bin
|
||||
rustup toolchain install $RUSTUP_TOOLCHAIN
|
||||
rustup default $RUSTUP_TOOLCHAIN
|
||||
echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin"
|
||||
env:
|
||||
RUSTUP_TOOLCHAIN: ${{parameters.rust_version}}
|
||||
displayName: "Install rust (*nix)"
|
||||
condition: not(eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
||||
# Windows.
|
||||
- script: |
|
||||
curl -sSf -o rustup-init.exe https://win.rustup.rs
|
||||
rustup-init.exe -y --default-toolchain none
|
||||
set PATH=%PATH%;%USERPROFILE%\.cargo\bin
|
||||
rustup toolchain install %RUSTUP_TOOLCHAIN%
|
||||
rustup default %RUSTUP_TOOLCHAIN%
|
||||
echo "##vso[task.setvariable variable=PATH;]%PATH%;%USERPROFILE%\.cargo\bin"
|
||||
env:
|
||||
RUSTUP_TOOLCHAIN: ${{parameters.rust_version}}
|
||||
displayName: "Install rust (windows)"
|
||||
condition: eq(variables['Agent.OS'], 'Windows_NT')
|
||||
|
||||
# All platforms.
|
||||
- script: |
|
||||
rustup toolchain list
|
||||
rustc -Vv
|
||||
cargo -V
|
||||
displayName: Query rust and cargo versions
|
||||
@@ -0,0 +1,15 @@
|
||||
jobs:
|
||||
- job: ${{parameters.name}}
|
||||
displayName: Loom tests
|
||||
pool:
|
||||
vmImage: ubuntu-16.04
|
||||
|
||||
steps:
|
||||
- template: azure-install-rust.yml
|
||||
parameters:
|
||||
rust_version: ${{parameters.rust_version}}
|
||||
|
||||
- script: RUSTFLAGS="--cfg loom" cargo test --lib
|
||||
displayName: RUSTFLAGS="--cfg loom" cargo test --lib
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
parameters:
|
||||
cmd: test
|
||||
rust_version: stable
|
||||
features: []
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.name }}
|
||||
displayName: ${{ parameters.displayName }}
|
||||
strategy:
|
||||
matrix:
|
||||
Linux:
|
||||
vmImage: ubuntu-16.04
|
||||
|
||||
${{ if parameters.cross }}:
|
||||
MacOS:
|
||||
vmImage: macOS-10.13
|
||||
Windows:
|
||||
vmImage: vs2017-win2016
|
||||
pool:
|
||||
vmImage: $(vmImage)
|
||||
|
||||
steps:
|
||||
- template: azure-install-rust.yml
|
||||
parameters:
|
||||
rust_version: ${{parameters.rust_version}}
|
||||
|
||||
# Run with default crate features
|
||||
- script: cargo ${{ parameters.cmd }}
|
||||
displayName: cargo ${{ parameters.cmd }}
|
||||
|
||||
# Run with each specified feature
|
||||
- ${{ each feature in parameters.features }}:
|
||||
- script: cargo ${{ parameters.cmd }} --features ${{ feature }}
|
||||
displayName: cargo ${{ parameters.cmd }} --features ${{ feature }}
|
||||
|
||||
- ${{ if eq(parameters.cmd, 'test') }}:
|
||||
- script: cargo doc --no-deps
|
||||
displayName: cargo doc --no-deps
|
||||
|
||||
- ${{ if parameters.benches }}:
|
||||
- script: cargo check --benches
|
||||
displayName: Check benchmarks
|
||||
|
||||
# Run with all features
|
||||
- script: cargo ${{ parameters.cmd }} --all-features
|
||||
displayName: cargo ${{ parameters.cmd }} --all-features
|
||||
|
||||
# Run with no default features
|
||||
- script: cargo check --no-default-features
|
||||
displayName: cargo check --no-default-features
|
||||
@@ -0,0 +1,26 @@
|
||||
jobs:
|
||||
- job: ${{ parameters.name }}
|
||||
displayName: TSAN
|
||||
pool:
|
||||
vmImage: ubuntu-16.04
|
||||
|
||||
steps:
|
||||
- template: azure-install-rust.yml
|
||||
parameters:
|
||||
rust_version: ${{ parameters.rust_version }}
|
||||
|
||||
- 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 --target x86_64-unknown-linux-gnu --test test_bytes --test test_buf --test test_buf_mut
|
||||
|
||||
# Run thread sanitizer
|
||||
RUSTFLAGS="-Z sanitizer=thread" \
|
||||
cargo test --target x86_64-unknown-linux-gnu --test test_bytes --test test_buf --test test_buf_mut
|
||||
displayName: TSAN / MSAN
|
||||
@@ -1,23 +0,0 @@
|
||||
# This script takes care of packaging the build artifacts that will go in the
|
||||
# release zipfile
|
||||
|
||||
$SRC_DIR = $PWD.Path
|
||||
$STAGE = [System.Guid]::NewGuid().ToString()
|
||||
|
||||
Set-Location $ENV:Temp
|
||||
New-Item -Type Directory -Name $STAGE
|
||||
Set-Location $STAGE
|
||||
|
||||
$ZIP = "$SRC_DIR\$($Env:CRATE_NAME)-$($Env:APPVEYOR_REPO_TAG_NAME)-$($Env:TARGET).zip"
|
||||
|
||||
# TODO Update this to package the right artifacts
|
||||
Copy-Item "$SRC_DIR\target\$($Env:TARGET)\release\hello.exe" '.\'
|
||||
|
||||
7z a "$ZIP" *
|
||||
|
||||
Push-AppveyorArtifact "$ZIP"
|
||||
|
||||
Remove-Item *.* -Force
|
||||
Set-Location ..
|
||||
Remove-Item $STAGE
|
||||
Set-Location $SRC_DIR
|
||||
@@ -1,33 +0,0 @@
|
||||
# This script takes care of building your crate and packaging it for release
|
||||
|
||||
set -ex
|
||||
|
||||
main() {
|
||||
local src=$(pwd) \
|
||||
stage=
|
||||
|
||||
case $TRAVIS_OS_NAME in
|
||||
linux)
|
||||
stage=$(mktemp -d)
|
||||
;;
|
||||
osx)
|
||||
stage=$(mktemp -d -t tmp)
|
||||
;;
|
||||
esac
|
||||
|
||||
test -f Cargo.lock || cargo generate-lockfile
|
||||
|
||||
# TODO Update this to build the artifacts that matter to you
|
||||
cross rustc --bin hello --target $TARGET --release -- -C lto
|
||||
|
||||
# TODO Update this to package the right artifacts
|
||||
cp target/$TARGET/release/hello $stage/
|
||||
|
||||
cd $stage
|
||||
tar czf $src/$CRATE_NAME-$TRAVIS_TAG-$TARGET.tar.gz *
|
||||
cd $src
|
||||
|
||||
rm -rf $stage
|
||||
}
|
||||
|
||||
main
|
||||
@@ -1,31 +0,0 @@
|
||||
set -ex
|
||||
|
||||
main() {
|
||||
curl https://sh.rustup.rs -sSf | \
|
||||
sh -s -- -y --default-toolchain $TRAVIS_RUST_VERSION
|
||||
|
||||
local target=
|
||||
if [ $TRAVIS_OS_NAME = linux ]; then
|
||||
target=x86_64-unknown-linux-gnu
|
||||
sort=sort
|
||||
else
|
||||
target=x86_64-apple-darwin
|
||||
sort=gsort # for `sort --sort-version`, from brew's coreutils.
|
||||
fi
|
||||
|
||||
# This fetches latest stable release
|
||||
local tag=$(git ls-remote --tags --refs --exit-code https://github.com/japaric/cross \
|
||||
| cut -d/ -f3 \
|
||||
| grep -E '^v[0-9.]+$' \
|
||||
| $sort --version-sort \
|
||||
| tail -n1)
|
||||
echo cross version: $tag
|
||||
curl -LSfs https://japaric.github.io/trust/install.sh | \
|
||||
sh -s -- \
|
||||
--force \
|
||||
--git japaric/cross \
|
||||
--tag $tag \
|
||||
--target $target
|
||||
}
|
||||
|
||||
main
|
||||
@@ -1,18 +0,0 @@
|
||||
# This script takes care of testing your crate
|
||||
|
||||
set -ex
|
||||
|
||||
main() {
|
||||
cross build --target $TARGET $EXTRA_ARGS
|
||||
|
||||
if [ ! -z $DISABLE_TESTS ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
cross test --target $TARGET $EXTRA_ARGS
|
||||
}
|
||||
|
||||
# we don't run the "test phase" when doing deploys
|
||||
if [ -z $TRAVIS_TAG ]; then
|
||||
main
|
||||
fi
|
||||
@@ -9,6 +9,9 @@ race:arc*Weak*drop
|
||||
# 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
|
||||
@@ -16,6 +19,6 @@ race:test::run_tests_console::*closure
|
||||
# Probably more fences in std.
|
||||
race:__call_tls_dtors
|
||||
|
||||
# `is_inline` is explicitly called concurrently without synchronization. The
|
||||
# safety explanation can be found in a comment.
|
||||
race:Inner::is_inline
|
||||
# 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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+238
-288
@@ -1,8 +1,9 @@
|
||||
use super::{IntoBuf, Writer};
|
||||
use byteorder::{LittleEndian, ByteOrder, BigEndian};
|
||||
use iovec::IoVec;
|
||||
use core::{cmp, mem::{self, MaybeUninit}, ptr, usize};
|
||||
|
||||
use std::{cmp, io, ptr, usize};
|
||||
#[cfg(feature = "std")]
|
||||
use std::fmt;
|
||||
|
||||
use alloc::{vec::Vec, boxed::Box};
|
||||
|
||||
/// A trait for values that provide sequential write access to bytes.
|
||||
///
|
||||
@@ -20,7 +21,7 @@ use std::{cmp, io, ptr, usize};
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
///
|
||||
/// buf.put("hello world");
|
||||
/// buf.put(&b"hello world"[..]);
|
||||
///
|
||||
/// assert_eq!(buf, b"hello world");
|
||||
/// ```
|
||||
@@ -35,15 +36,14 @@ pub trait BufMut {
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut dst = [0; 10];
|
||||
/// let mut buf = Cursor::new(&mut dst[..]);
|
||||
/// let mut buf = &mut dst[..];
|
||||
///
|
||||
/// assert_eq!(10, buf.remaining_mut());
|
||||
/// buf.put("hello");
|
||||
/// let original_remaining = buf.remaining_mut();
|
||||
/// buf.put(&b"hello"[..]);
|
||||
///
|
||||
/// assert_eq!(5, buf.remaining_mut());
|
||||
/// assert_eq!(original_remaining - 5, buf.remaining_mut());
|
||||
/// ```
|
||||
///
|
||||
/// # Implementer notes
|
||||
@@ -69,13 +69,15 @@ pub trait BufMut {
|
||||
/// let mut buf = Vec::with_capacity(16);
|
||||
///
|
||||
/// unsafe {
|
||||
/// buf.bytes_mut()[0] = b'h';
|
||||
/// buf.bytes_mut()[1] = b'e';
|
||||
/// // MaybeUninit::as_mut_ptr
|
||||
/// buf.bytes_mut()[0].as_mut_ptr().write(b'h');
|
||||
/// buf.bytes_mut()[1].as_mut_ptr().write(b'e');
|
||||
///
|
||||
/// buf.advance_mut(2);
|
||||
///
|
||||
/// buf.bytes_mut()[0] = b'l';
|
||||
/// buf.bytes_mut()[1..3].copy_from_slice(b"lo");
|
||||
/// buf.bytes_mut()[0].as_mut_ptr().write(b'l');
|
||||
/// buf.bytes_mut()[1].as_mut_ptr().write(b'l');
|
||||
/// buf.bytes_mut()[2].as_mut_ptr().write(b'o');
|
||||
///
|
||||
/// buf.advance_mut(3);
|
||||
/// }
|
||||
@@ -105,14 +107,13 @@ pub trait BufMut {
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut dst = [0; 5];
|
||||
/// let mut buf = Cursor::new(&mut dst);
|
||||
/// let mut buf = &mut dst[..];
|
||||
///
|
||||
/// assert!(buf.has_remaining_mut());
|
||||
///
|
||||
/// buf.put("hello");
|
||||
/// buf.put(&b"hello"[..]);
|
||||
///
|
||||
/// assert!(!buf.has_remaining_mut());
|
||||
/// ```
|
||||
@@ -121,7 +122,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.
|
||||
@@ -136,13 +138,15 @@ pub trait BufMut {
|
||||
/// let mut buf = Vec::with_capacity(16);
|
||||
///
|
||||
/// unsafe {
|
||||
/// buf.bytes_mut()[0] = b'h';
|
||||
/// buf.bytes_mut()[1] = b'e';
|
||||
/// // MaybeUninit::as_mut_ptr
|
||||
/// buf.bytes_mut()[0].as_mut_ptr().write(b'h');
|
||||
/// buf.bytes_mut()[1].as_mut_ptr().write(b'e');
|
||||
///
|
||||
/// buf.advance_mut(2);
|
||||
///
|
||||
/// buf.bytes_mut()[0] = b'l';
|
||||
/// buf.bytes_mut()[1..3].copy_from_slice(b"lo");
|
||||
/// buf.bytes_mut()[0].as_mut_ptr().write(b'l');
|
||||
/// buf.bytes_mut()[1].as_mut_ptr().write(b'l');
|
||||
/// buf.bytes_mut()[2].as_mut_ptr().write(b'o');
|
||||
///
|
||||
/// buf.advance_mut(3);
|
||||
/// }
|
||||
@@ -158,20 +162,20 @@ pub trait BufMut {
|
||||
/// `bytes_mut` returning an empty slice implies that `remaining_mut` will
|
||||
/// return 0 and `remaining_mut` returning 0 implies that `bytes_mut` will
|
||||
/// return an empty slice.
|
||||
unsafe fn bytes_mut(&mut self) -> &mut [u8];
|
||||
fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>];
|
||||
|
||||
/// Fills `dst` with potentially multiple mutable slices starting at `self`'s
|
||||
/// current position.
|
||||
///
|
||||
/// If the `BufMut` is backed by disjoint slices of bytes, `bytes_vec_mut`
|
||||
/// If the `BufMut` is backed by disjoint slices of bytes, `bytes_vectored_mut`
|
||||
/// enables fetching more than one slice at once. `dst` is a slice of
|
||||
/// mutable `IoVec` references, enabling the slice to be directly used with
|
||||
/// mutable `IoSliceMut` references, enabling the slice to be directly used with
|
||||
/// [`readv`] without any further conversion. The sum of the lengths of all
|
||||
/// the buffers in `dst` will be less than or equal to
|
||||
/// `Buf::remaining_mut()`.
|
||||
///
|
||||
/// The entries in `dst` will be overwritten, but the data **contained** by
|
||||
/// the slices **will not** be modified. If `bytes_vec_mut` does not fill every
|
||||
/// the slices **will not** be modified. If `bytes_vectored_mut` does not fill every
|
||||
/// entry in `dst`, then `dst` is guaranteed to contain all remaining slices
|
||||
/// in `self.
|
||||
///
|
||||
@@ -181,20 +185,21 @@ pub trait BufMut {
|
||||
/// # Implementer notes
|
||||
///
|
||||
/// This function should never panic. Once the end of the buffer is reached,
|
||||
/// i.e., `BufMut::remaining_mut` returns 0, calls to `bytes_vec_mut` must
|
||||
/// i.e., `BufMut::remaining_mut` returns 0, calls to `bytes_vectored_mut` must
|
||||
/// return 0 without mutating `dst`.
|
||||
///
|
||||
/// Implementations should also take care to properly handle being called
|
||||
/// with `dst` being a zero length slice.
|
||||
///
|
||||
/// [`readv`]: http://man7.org/linux/man-pages/man2/readv.2.html
|
||||
unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize {
|
||||
#[cfg(feature = "std")]
|
||||
fn bytes_vectored_mut<'a>(&'a mut self, dst: &mut [IoSliceMut<'a>]) -> usize {
|
||||
if dst.is_empty() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if self.has_remaining_mut() {
|
||||
dst[0] = self.bytes_mut().into();
|
||||
dst[0] = IoSliceMut::from(self.bytes_mut());
|
||||
1
|
||||
} else {
|
||||
0
|
||||
@@ -211,9 +216,9 @@ pub trait BufMut {
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
///
|
||||
/// buf.put(b'h');
|
||||
/// buf.put_u8(b'h');
|
||||
/// buf.put(&b"ello"[..]);
|
||||
/// buf.put(" world");
|
||||
/// buf.put(&b" world"[..]);
|
||||
///
|
||||
/// assert_eq!(buf, b"hello world");
|
||||
/// ```
|
||||
@@ -221,11 +226,7 @@ pub trait BufMut {
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `self` does not have enough capacity to contain `src`.
|
||||
fn put<T: IntoBuf>(&mut self, src: T) where Self: Sized {
|
||||
use super::Buf;
|
||||
|
||||
let mut src = src.into_buf();
|
||||
|
||||
fn put<T: super::Buf>(&mut self, mut src: T) where Self: Sized {
|
||||
assert!(self.remaining_mut() >= src.remaining());
|
||||
|
||||
while src.has_remaining() {
|
||||
@@ -238,7 +239,7 @@ pub trait BufMut {
|
||||
|
||||
ptr::copy_nonoverlapping(
|
||||
s.as_ptr(),
|
||||
d.as_mut_ptr(),
|
||||
d.as_mut_ptr() as *mut u8,
|
||||
l);
|
||||
}
|
||||
|
||||
@@ -254,12 +255,11 @@ pub trait BufMut {
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut dst = [0; 6];
|
||||
///
|
||||
/// {
|
||||
/// let mut buf = Cursor::new(&mut dst);
|
||||
/// let mut buf = &mut dst[..];
|
||||
/// buf.put_slice(b"hello");
|
||||
///
|
||||
/// assert_eq!(1, buf.remaining_mut());
|
||||
@@ -270,7 +270,7 @@ pub trait BufMut {
|
||||
fn put_slice(&mut self, src: &[u8]) {
|
||||
let mut off = 0;
|
||||
|
||||
assert!(self.remaining_mut() >= src.len(), "buffer overflow");
|
||||
assert!(self.remaining_mut() >= src.len(), "buffer overflow; remaining = {}; src = {}", self.remaining_mut(), src.len());
|
||||
|
||||
while off < src.len() {
|
||||
let cnt;
|
||||
@@ -281,7 +281,7 @@ pub trait BufMut {
|
||||
|
||||
ptr::copy_nonoverlapping(
|
||||
src[off..].as_ptr(),
|
||||
dst.as_mut_ptr(),
|
||||
dst.as_mut_ptr() as *mut u8,
|
||||
cnt);
|
||||
|
||||
off += cnt;
|
||||
@@ -338,14 +338,6 @@ pub trait BufMut {
|
||||
self.put_slice(&src)
|
||||
}
|
||||
|
||||
#[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 an unsigned 16 bit integer to `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
@@ -356,7 +348,7 @@ pub trait BufMut {
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u16_be(0x0809);
|
||||
/// buf.put_u16(0x0809);
|
||||
/// assert_eq!(buf, b"\x08\x09");
|
||||
/// ```
|
||||
///
|
||||
@@ -364,10 +356,8 @@ pub trait BufMut {
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_u16_be(&mut self, n: u16) {
|
||||
let mut buf = [0; 2];
|
||||
BigEndian::write_u16(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
fn put_u16(&mut self, n: u16) {
|
||||
self.put_slice(&n.to_be_bytes())
|
||||
}
|
||||
|
||||
/// Writes an unsigned 16 bit integer to `self` in little-endian byte order.
|
||||
@@ -389,17 +379,7 @@ pub trait BufMut {
|
||||
/// 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)
|
||||
self.put_slice(&n.to_le_bytes())
|
||||
}
|
||||
|
||||
/// Writes a signed 16 bit integer to `self` in big-endian byte order.
|
||||
@@ -412,7 +392,7 @@ pub trait BufMut {
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i16_be(0x0809);
|
||||
/// buf.put_i16(0x0809);
|
||||
/// assert_eq!(buf, b"\x08\x09");
|
||||
/// ```
|
||||
///
|
||||
@@ -420,10 +400,8 @@ pub trait BufMut {
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i16_be(&mut self, n: i16) {
|
||||
let mut buf = [0; 2];
|
||||
BigEndian::write_i16(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
fn put_i16(&mut self, n: i16) {
|
||||
self.put_slice(&n.to_be_bytes())
|
||||
}
|
||||
|
||||
/// Writes a signed 16 bit integer to `self` in little-endian byte order.
|
||||
@@ -445,17 +423,7 @@ pub trait BufMut {
|
||||
/// 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)
|
||||
self.put_slice(&n.to_le_bytes())
|
||||
}
|
||||
|
||||
/// Writes an unsigned 32 bit integer to `self` in big-endian byte order.
|
||||
@@ -468,7 +436,7 @@ pub trait BufMut {
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u32_be(0x0809A0A1);
|
||||
/// buf.put_u32(0x0809A0A1);
|
||||
/// assert_eq!(buf, b"\x08\x09\xA0\xA1");
|
||||
/// ```
|
||||
///
|
||||
@@ -476,10 +444,8 @@ pub trait BufMut {
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_u32_be(&mut self, n: u32) {
|
||||
let mut buf = [0; 4];
|
||||
BigEndian::write_u32(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
fn put_u32(&mut self, n: u32) {
|
||||
self.put_slice(&n.to_be_bytes())
|
||||
}
|
||||
|
||||
/// Writes an unsigned 32 bit integer to `self` in little-endian byte order.
|
||||
@@ -501,17 +467,7 @@ pub trait BufMut {
|
||||
/// 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)
|
||||
self.put_slice(&n.to_le_bytes())
|
||||
}
|
||||
|
||||
/// Writes a signed 32 bit integer to `self` in big-endian byte order.
|
||||
@@ -524,7 +480,7 @@ pub trait BufMut {
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i32_be(0x0809A0A1);
|
||||
/// buf.put_i32(0x0809A0A1);
|
||||
/// assert_eq!(buf, b"\x08\x09\xA0\xA1");
|
||||
/// ```
|
||||
///
|
||||
@@ -532,10 +488,8 @@ pub trait BufMut {
|
||||
///
|
||||
/// 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)
|
||||
fn put_i32(&mut self, n: i32) {
|
||||
self.put_slice(&n.to_be_bytes())
|
||||
}
|
||||
|
||||
/// Writes a signed 32 bit integer to `self` in little-endian byte order.
|
||||
@@ -557,17 +511,7 @@ pub trait BufMut {
|
||||
/// 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)
|
||||
self.put_slice(&n.to_le_bytes())
|
||||
}
|
||||
|
||||
/// Writes an unsigned 64 bit integer to `self` in the big-endian byte order.
|
||||
@@ -580,7 +524,7 @@ pub trait BufMut {
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u64_be(0x0102030405060708);
|
||||
/// buf.put_u64(0x0102030405060708);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
|
||||
/// ```
|
||||
///
|
||||
@@ -588,10 +532,8 @@ pub trait BufMut {
|
||||
///
|
||||
/// 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)
|
||||
fn put_u64(&mut self, n: u64) {
|
||||
self.put_slice(&n.to_be_bytes())
|
||||
}
|
||||
|
||||
/// Writes an unsigned 64 bit integer to `self` in little-endian byte order.
|
||||
@@ -613,17 +555,7 @@ pub trait BufMut {
|
||||
/// 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)
|
||||
self.put_slice(&n.to_le_bytes())
|
||||
}
|
||||
|
||||
/// Writes a signed 64 bit integer to `self` in the big-endian byte order.
|
||||
@@ -636,7 +568,7 @@ pub trait BufMut {
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i64_be(0x0102030405060708);
|
||||
/// buf.put_i64(0x0102030405060708);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
|
||||
/// ```
|
||||
///
|
||||
@@ -644,10 +576,8 @@ pub trait BufMut {
|
||||
///
|
||||
/// 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)
|
||||
fn put_i64(&mut self, n: i64) {
|
||||
self.put_slice(&n.to_be_bytes())
|
||||
}
|
||||
|
||||
/// Writes a signed 64 bit integer to `self` in little-endian byte order.
|
||||
@@ -669,17 +599,95 @@ pub trait BufMut {
|
||||
/// 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)
|
||||
self.put_slice(&n.to_le_bytes())
|
||||
}
|
||||
|
||||
#[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 128 bit integer to `self` in the big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 16.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u128(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`.
|
||||
fn put_u128(&mut self, n: u128) {
|
||||
self.put_slice(&n.to_be_bytes())
|
||||
}
|
||||
|
||||
/// Writes an unsigned 128 bit integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// 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`.
|
||||
fn put_u128_le(&mut self, n: u128) {
|
||||
self.put_slice(&n.to_le_bytes())
|
||||
}
|
||||
|
||||
/// Writes a signed 128 bit integer to `self` in the big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 16.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i128(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`.
|
||||
fn put_i128(&mut self, n: i128) {
|
||||
self.put_slice(&n.to_be_bytes())
|
||||
}
|
||||
|
||||
/// Writes a signed 128 bit integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// 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`.
|
||||
fn put_i128_le(&mut self, n: i128) {
|
||||
self.put_slice(&n.to_le_bytes())
|
||||
}
|
||||
|
||||
/// Writes an unsigned n-byte integer to `self` in big-endian byte order.
|
||||
@@ -692,7 +700,7 @@ pub trait BufMut {
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_uint_be(0x010203, 3);
|
||||
/// buf.put_uint(0x010203, 3);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03");
|
||||
/// ```
|
||||
///
|
||||
@@ -700,10 +708,8 @@ pub trait BufMut {
|
||||
///
|
||||
/// 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])
|
||||
fn put_uint(&mut self, n: u64, nbytes: usize) {
|
||||
self.put_slice(&n.to_be_bytes()[mem::size_of_val(&n) - nbytes..]);
|
||||
}
|
||||
|
||||
/// Writes an unsigned n-byte integer to `self` in the little-endian byte order.
|
||||
@@ -725,17 +731,7 @@ pub trait BufMut {
|
||||
/// 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])
|
||||
self.put_slice(&n.to_le_bytes()[0..nbytes]);
|
||||
}
|
||||
|
||||
/// Writes a signed n-byte integer to `self` in big-endian byte order.
|
||||
@@ -748,7 +744,7 @@ pub trait BufMut {
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_int_be(0x010203, 3);
|
||||
/// buf.put_int(0x010203, 3);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03");
|
||||
/// ```
|
||||
///
|
||||
@@ -756,10 +752,8 @@ pub trait BufMut {
|
||||
///
|
||||
/// 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])
|
||||
fn put_int(&mut self, n: i64, nbytes: usize) {
|
||||
self.put_slice(&n.to_be_bytes()[mem::size_of_val(&n) - nbytes..]);
|
||||
}
|
||||
|
||||
/// Writes a signed n-byte integer to `self` in little-endian byte order.
|
||||
@@ -781,17 +775,7 @@ pub trait BufMut {
|
||||
/// 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)
|
||||
self.put_slice(&n.to_le_bytes()[0..nbytes]);
|
||||
}
|
||||
|
||||
/// Writes an IEEE754 single-precision (4 bytes) floating point number to
|
||||
@@ -805,7 +789,7 @@ pub trait BufMut {
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_f32_be(1.2f32);
|
||||
/// buf.put_f32(1.2f32);
|
||||
/// assert_eq!(buf, b"\x3F\x99\x99\x9A");
|
||||
/// ```
|
||||
///
|
||||
@@ -813,10 +797,8 @@ pub trait BufMut {
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_f32_be(&mut self, n: f32) {
|
||||
let mut buf = [0; 4];
|
||||
BigEndian::write_f32(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
fn put_f32(&mut self, n: f32) {
|
||||
self.put_u32(n.to_bits());
|
||||
}
|
||||
|
||||
/// Writes an IEEE754 single-precision (4 bytes) floating point number to
|
||||
@@ -839,17 +821,7 @@ pub trait BufMut {
|
||||
/// 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)
|
||||
self.put_u32_le(n.to_bits());
|
||||
}
|
||||
|
||||
/// Writes an IEEE754 double-precision (8 bytes) floating point number to
|
||||
@@ -863,7 +835,7 @@ pub trait BufMut {
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_f64_be(1.2f64);
|
||||
/// buf.put_f64(1.2f64);
|
||||
/// assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
|
||||
/// ```
|
||||
///
|
||||
@@ -871,10 +843,8 @@ pub trait BufMut {
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_f64_be(&mut self, n: f64) {
|
||||
let mut buf = [0; 8];
|
||||
BigEndian::write_f64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
fn put_f64(&mut self, n: f64) {
|
||||
self.put_u64(n.to_bits());
|
||||
}
|
||||
|
||||
/// Writes an IEEE754 double-precision (8 bytes) floating point number to
|
||||
@@ -897,78 +867,22 @@ pub trait BufMut {
|
||||
/// 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)
|
||||
}
|
||||
|
||||
/// Creates a "by reference" adaptor for this instance of `BufMut`.
|
||||
///
|
||||
/// The returned adapter also implements `BufMut` and will simply borrow
|
||||
/// `self`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
/// use std::io;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
///
|
||||
/// {
|
||||
/// let mut reference = buf.by_ref();
|
||||
///
|
||||
/// // Adapt reference to `std::io::Write`.
|
||||
/// let mut writer = reference.writer();
|
||||
///
|
||||
/// // Use the buffer as a writter
|
||||
/// io::Write::write(&mut writer, &b"hello world"[..]).unwrap();
|
||||
/// } // drop our &mut reference so that we can use `buf` again
|
||||
///
|
||||
/// assert_eq!(buf, &b"hello world"[..]);
|
||||
/// ```
|
||||
fn by_ref(&mut self) -> &mut Self where Self: Sized {
|
||||
self
|
||||
}
|
||||
|
||||
/// Creates an adaptor which implements the `Write` trait for `self`.
|
||||
///
|
||||
/// This function returns a new value which implements `Write` by adapting
|
||||
/// the `Write` trait functions to the `BufMut` trait functions. Given that
|
||||
/// `BufMut` operations are infallible, none of the `Write` functions will
|
||||
/// return with `Err`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
/// use std::io::Write;
|
||||
///
|
||||
/// let mut buf = vec![].writer();
|
||||
///
|
||||
/// let num = buf.write(&b"hello world"[..]).unwrap();
|
||||
/// assert_eq!(11, num);
|
||||
///
|
||||
/// let buf = buf.into_inner();
|
||||
///
|
||||
/// assert_eq!(*buf, b"hello world"[..]);
|
||||
/// ```
|
||||
fn writer(self) -> Writer<Self> where Self: Sized {
|
||||
super::writer::new(self)
|
||||
self.put_u64_le(n.to_bits());
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: BufMut + ?Sized> BufMut for &'a mut T {
|
||||
impl<T: BufMut + ?Sized> BufMut for &mut T {
|
||||
fn remaining_mut(&self) -> usize {
|
||||
(**self).remaining_mut()
|
||||
}
|
||||
|
||||
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
|
||||
fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
|
||||
(**self).bytes_mut()
|
||||
}
|
||||
|
||||
unsafe fn bytes_vec_mut<'b>(&'b mut self, dst: &mut [&'b mut IoVec]) -> usize {
|
||||
(**self).bytes_vec_mut(dst)
|
||||
#[cfg(feature = "std")]
|
||||
fn bytes_vectored_mut<'b>(&'b mut self, dst: &mut [IoSliceMut<'b>]) -> usize {
|
||||
(**self).bytes_vectored_mut(dst)
|
||||
}
|
||||
|
||||
unsafe fn advance_mut(&mut self, cnt: usize) {
|
||||
@@ -981,12 +895,13 @@ impl<T: BufMut + ?Sized> BufMut for Box<T> {
|
||||
(**self).remaining_mut()
|
||||
}
|
||||
|
||||
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
|
||||
fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
|
||||
(**self).bytes_mut()
|
||||
}
|
||||
|
||||
unsafe fn bytes_vec_mut<'b>(&'b mut self, dst: &mut [&'b mut IoVec]) -> usize {
|
||||
(**self).bytes_vec_mut(dst)
|
||||
#[cfg(feature = "std")]
|
||||
fn bytes_vectored_mut<'b>(&'b mut self, dst: &mut [IoSliceMut<'b>]) -> usize {
|
||||
(**self).bytes_vectored_mut(dst)
|
||||
}
|
||||
|
||||
unsafe fn advance_mut(&mut self, cnt: usize) {
|
||||
@@ -994,31 +909,23 @@ impl<T: BufMut + ?Sized> BufMut for Box<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsMut<[u8]> + AsRef<[u8]>> BufMut for io::Cursor<T> {
|
||||
impl BufMut for &mut [u8] {
|
||||
#[inline]
|
||||
fn remaining_mut(&self) -> usize {
|
||||
use Buf;
|
||||
self.remaining()
|
||||
self.len()
|
||||
}
|
||||
|
||||
/// Advance the internal cursor of the BufMut
|
||||
#[inline]
|
||||
fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
|
||||
// MaybeUninit is repr(transparent), so safe to transmute
|
||||
unsafe { mem::transmute(&mut **self) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn advance_mut(&mut self, cnt: usize) {
|
||||
use Buf;
|
||||
self.advance(cnt);
|
||||
}
|
||||
|
||||
/// Returns a mutable slice starting at the current BufMut position and of
|
||||
/// length between 0 and `BufMut::remaining()`.
|
||||
///
|
||||
/// The returned byte slice may represent uninitialized memory.
|
||||
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
|
||||
let len = self.get_ref().as_ref().len();
|
||||
let pos = self.position() as usize;
|
||||
|
||||
if pos >= len {
|
||||
return Default::default();
|
||||
}
|
||||
|
||||
&mut (self.get_mut().as_mut())[pos..]
|
||||
// Lifetime dance taken from `impl Write for &mut [u8]`.
|
||||
let (_, b) = core::mem::replace(self, &mut []).split_at_mut(cnt);
|
||||
*self = b;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1042,8 +949,8 @@ impl BufMut for Vec<u8> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
|
||||
use std::slice;
|
||||
fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
|
||||
use core::slice;
|
||||
|
||||
if self.capacity() == self.len() {
|
||||
self.reserve(64); // Grow the vec
|
||||
@@ -1052,11 +959,54 @@ impl BufMut for Vec<u8> {
|
||||
let cap = self.capacity();
|
||||
let len = self.len();
|
||||
|
||||
let ptr = self.as_mut_ptr();
|
||||
&mut slice::from_raw_parts_mut(ptr, cap)[len..]
|
||||
let ptr = self.as_mut_ptr() as *mut MaybeUninit<u8>;
|
||||
unsafe {
|
||||
&mut slice::from_raw_parts_mut(ptr, cap)[len..]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The existance of this function makes the compiler catch if the BufMut
|
||||
// The existence of this function makes the compiler catch if the BufMut
|
||||
// trait is "object-safe" or not.
|
||||
fn _assert_trait_object(_b: &BufMut) {}
|
||||
fn _assert_trait_object(_b: &dyn BufMut) {}
|
||||
|
||||
// ===== impl IoSliceMut =====
|
||||
|
||||
/// A buffer type used for `readv`.
|
||||
///
|
||||
/// This is a wrapper around an `std::io::IoSliceMut`, but does not expose
|
||||
/// the inner bytes in a safe API, as they may point at uninitialized memory.
|
||||
///
|
||||
/// This is `repr(transparent)` of the `std::io::IoSliceMut`, so it is valid to
|
||||
/// transmute them. However, as the memory might be uninitialized, care must be
|
||||
/// taken to not *read* the internal bytes, only *write* to them.
|
||||
#[repr(transparent)]
|
||||
#[cfg(feature = "std")]
|
||||
pub struct IoSliceMut<'a>(std::io::IoSliceMut<'a>);
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl fmt::Debug for IoSliceMut<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("IoSliceMut")
|
||||
.field("len", &self.0.len())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<'a> From<&'a mut [u8]> for IoSliceMut<'a> {
|
||||
fn from(buf: &'a mut [u8]) -> IoSliceMut<'a> {
|
||||
IoSliceMut(std::io::IoSliceMut::new(buf))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<'a> From<&'a mut [MaybeUninit<u8>]> for IoSliceMut<'a> {
|
||||
fn from(buf: &'a mut [MaybeUninit<u8>]) -> IoSliceMut<'a> {
|
||||
IoSliceMut(std::io::IoSliceMut::new(unsafe {
|
||||
// We don't look at the contents, and `std::io::IoSliceMut`
|
||||
// doesn't either.
|
||||
mem::transmute::<&'a mut [MaybeUninit<u8>], &'a mut [u8]>(buf)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
use {Buf, BufMut};
|
||||
use iovec::IoVec;
|
||||
use crate::{Buf, BufMut};
|
||||
use crate::buf::IntoIter;
|
||||
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use std::io::{IoSlice};
|
||||
#[cfg(feature = "std")]
|
||||
use crate::buf::IoSliceMut;
|
||||
|
||||
/// A `Chain` sequences two buffers.
|
||||
///
|
||||
/// `Chain` is an adapter that links two underlying buffers and provides a
|
||||
/// continous view across both buffers. It is able to sequence either immutable
|
||||
/// continuous view across both buffers. It is able to sequence either immutable
|
||||
/// buffers ([`Buf`] values) or mutable buffers ([`BufMut`] values).
|
||||
///
|
||||
/// This struct is generally created by calling [`Buf::chain`]. Please see that
|
||||
@@ -13,13 +20,12 @@ use iovec::IoVec;
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Bytes, Buf, IntoBuf};
|
||||
/// use bytes::buf::Chain;
|
||||
/// use bytes::{Bytes, Buf, buf::BufExt};
|
||||
///
|
||||
/// let buf = Bytes::from(&b"hello "[..]).into_buf()
|
||||
/// .chain(Bytes::from(&b"world"[..]));
|
||||
/// let mut buf = (&b"hello "[..])
|
||||
/// .chain(&b"world"[..]);
|
||||
///
|
||||
/// let full: Bytes = buf.collect();
|
||||
/// let full: Bytes = buf.to_bytes();
|
||||
/// assert_eq!(full[..], b"hello world"[..]);
|
||||
/// ```
|
||||
///
|
||||
@@ -34,23 +40,10 @@ pub struct Chain<T, U> {
|
||||
|
||||
impl<T, U> Chain<T, U> {
|
||||
/// Creates a new `Chain` sequencing the provided values.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BytesMut;
|
||||
/// use bytes::buf::Chain;
|
||||
///
|
||||
/// let buf = Chain::new(
|
||||
/// BytesMut::with_capacity(1024),
|
||||
/// BytesMut::with_capacity(1024));
|
||||
///
|
||||
/// // Use the chained buffer
|
||||
/// ```
|
||||
pub fn new(a: T, b: U) -> Chain<T, U> {
|
||||
Chain {
|
||||
a: a,
|
||||
b: b,
|
||||
a,
|
||||
b,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,12 +52,12 @@ impl<T, U> Chain<T, U> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Bytes, Buf, IntoBuf};
|
||||
/// use bytes::buf::BufExt;
|
||||
///
|
||||
/// let buf = Bytes::from(&b"hello"[..]).into_buf()
|
||||
/// .chain(Bytes::from(&b"world"[..]));
|
||||
/// let buf = (&b"hello"[..])
|
||||
/// .chain(&b"world"[..]);
|
||||
///
|
||||
/// assert_eq!(buf.first_ref().get_ref()[..], b"hello"[..]);
|
||||
/// assert_eq!(buf.first_ref()[..], b"hello"[..]);
|
||||
/// ```
|
||||
pub fn first_ref(&self) -> &T {
|
||||
&self.a
|
||||
@@ -75,15 +68,15 @@ impl<T, U> Chain<T, U> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Bytes, Buf, IntoBuf};
|
||||
/// use bytes::{Buf, buf::BufExt};
|
||||
///
|
||||
/// let mut buf = Bytes::from(&b"hello "[..]).into_buf()
|
||||
/// .chain(Bytes::from(&b"world"[..]));
|
||||
/// let mut buf = (&b"hello"[..])
|
||||
/// .chain(&b"world"[..]);
|
||||
///
|
||||
/// buf.first_mut().set_position(1);
|
||||
/// buf.first_mut().advance(1);
|
||||
///
|
||||
/// let full: Bytes = buf.collect();
|
||||
/// assert_eq!(full[..], b"ello world"[..]);
|
||||
/// let full = buf.to_bytes();
|
||||
/// assert_eq!(full, b"elloworld"[..]);
|
||||
/// ```
|
||||
pub fn first_mut(&mut self) -> &mut T {
|
||||
&mut self.a
|
||||
@@ -94,12 +87,12 @@ impl<T, U> Chain<T, U> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Bytes, Buf, IntoBuf};
|
||||
/// use bytes::buf::BufExt;
|
||||
///
|
||||
/// let buf = Bytes::from(&b"hello"[..]).into_buf()
|
||||
/// .chain(Bytes::from(&b"world"[..]));
|
||||
/// let buf = (&b"hello"[..])
|
||||
/// .chain(&b"world"[..]);
|
||||
///
|
||||
/// assert_eq!(buf.last_ref().get_ref()[..], b"world"[..]);
|
||||
/// assert_eq!(buf.last_ref()[..], b"world"[..]);
|
||||
/// ```
|
||||
pub fn last_ref(&self) -> &U {
|
||||
&self.b
|
||||
@@ -110,15 +103,15 @@ impl<T, U> Chain<T, U> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Bytes, Buf, IntoBuf};
|
||||
/// use bytes::{Buf, buf::BufExt};
|
||||
///
|
||||
/// let mut buf = Bytes::from(&b"hello "[..]).into_buf()
|
||||
/// .chain(Bytes::from(&b"world"[..]));
|
||||
/// let mut buf = (&b"hello "[..])
|
||||
/// .chain(&b"world"[..]);
|
||||
///
|
||||
/// buf.last_mut().set_position(1);
|
||||
/// buf.last_mut().advance(1);
|
||||
///
|
||||
/// let full: Bytes = buf.collect();
|
||||
/// assert_eq!(full[..], b"hello orld"[..]);
|
||||
/// let full = buf.to_bytes();
|
||||
/// assert_eq!(full, b"hello orld"[..]);
|
||||
/// ```
|
||||
pub fn last_mut(&mut self) -> &mut U {
|
||||
&mut self.b
|
||||
@@ -129,14 +122,14 @@ impl<T, U> Chain<T, U> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Bytes, Buf, IntoBuf};
|
||||
/// use bytes::buf::BufExt;
|
||||
///
|
||||
/// let buf = Bytes::from(&b"hello"[..]).into_buf()
|
||||
/// .chain(Bytes::from(&b"world"[..]));
|
||||
/// let chain = (&b"hello"[..])
|
||||
/// .chain(&b"world"[..]);
|
||||
///
|
||||
/// let (first, last) = buf.into_inner();
|
||||
/// assert_eq!(first.get_ref()[..], b"hello"[..]);
|
||||
/// assert_eq!(last.get_ref()[..], b"world"[..]);
|
||||
/// let (first, last) = chain.into_inner();
|
||||
/// assert_eq!(first[..], b"hello"[..]);
|
||||
/// assert_eq!(last[..], b"world"[..]);
|
||||
/// ```
|
||||
pub fn into_inner(self) -> (T, U) {
|
||||
(self.a, self.b)
|
||||
@@ -177,9 +170,10 @@ impl<T, U> Buf for Chain<T, U>
|
||||
self.b.advance(cnt);
|
||||
}
|
||||
|
||||
fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize {
|
||||
let mut n = self.a.bytes_vec(dst);
|
||||
n += self.b.bytes_vec(&mut dst[n..]);
|
||||
#[cfg(feature = "std")]
|
||||
fn bytes_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize {
|
||||
let mut n = self.a.bytes_vectored(dst);
|
||||
n += self.b.bytes_vectored(&mut dst[n..]);
|
||||
n
|
||||
}
|
||||
}
|
||||
@@ -192,7 +186,7 @@ impl<T, U> BufMut for Chain<T, U>
|
||||
self.a.remaining_mut() + self.b.remaining_mut()
|
||||
}
|
||||
|
||||
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
|
||||
fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
|
||||
if self.a.has_remaining_mut() {
|
||||
self.a.bytes_mut()
|
||||
} else {
|
||||
@@ -218,9 +212,23 @@ impl<T, U> BufMut for Chain<T, U>
|
||||
self.b.advance_mut(cnt);
|
||||
}
|
||||
|
||||
unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize {
|
||||
let mut n = self.a.bytes_vec_mut(dst);
|
||||
n += self.b.bytes_vec_mut(&mut dst[n..]);
|
||||
#[cfg(feature = "std")]
|
||||
fn bytes_vectored_mut<'a>(&'a mut self, dst: &mut [IoSliceMut<'a>]) -> usize {
|
||||
let mut n = self.a.bytes_vectored_mut(dst);
|
||||
n += self.b.bytes_vectored_mut(&mut dst[n..]);
|
||||
n
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> IntoIterator for Chain<T, U>
|
||||
where
|
||||
T: Buf,
|
||||
U: Buf,
|
||||
{
|
||||
type Item = u8;
|
||||
type IntoIter = IntoIter<Chain<T, U>>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
IntoIter::new(self)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
use crate::BufMut;
|
||||
|
||||
use core::{cmp, mem::MaybeUninit};
|
||||
|
||||
/// A `BufMut` adapter which limits the amount of bytes that can be written
|
||||
/// to an underlying buffer.
|
||||
#[derive(Debug)]
|
||||
pub struct Limit<T> {
|
||||
inner: T,
|
||||
limit: usize,
|
||||
}
|
||||
|
||||
pub(super) fn new<T>(inner: T, limit: usize) -> Limit<T> {
|
||||
Limit {
|
||||
inner,
|
||||
limit,
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Limit<T> {
|
||||
/// Consumes this `Limit`, returning the underlying value.
|
||||
pub fn into_inner(self) -> T {
|
||||
self.inner
|
||||
}
|
||||
|
||||
/// Gets a reference to the underlying `BufMut`.
|
||||
///
|
||||
/// It is inadvisable to directly write to the underlying `BufMut`.
|
||||
pub fn get_ref(&self) -> &T {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the underlying `BufMut`.
|
||||
///
|
||||
/// It is inadvisable to directly write to the underlying `BufMut`.
|
||||
pub fn get_mut(&mut self) -> &mut T {
|
||||
&mut self.inner
|
||||
}
|
||||
|
||||
/// Returns the maximum number of bytes that can be written
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// If the inner `BufMut` has fewer bytes than indicated by this method then
|
||||
/// that is the actual number of available bytes.
|
||||
pub fn limit(&self) -> usize {
|
||||
self.limit
|
||||
}
|
||||
|
||||
/// Sets the maximum number of bytes that can be written.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// If the inner `BufMut` has fewer bytes than `lim` then that is the actual
|
||||
/// number of available bytes.
|
||||
pub fn set_limit(&mut self, lim: usize) {
|
||||
self.limit = lim
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BufMut> BufMut for Limit<T> {
|
||||
fn remaining_mut(&self) -> usize {
|
||||
cmp::min(self.inner.remaining_mut(), self.limit)
|
||||
}
|
||||
|
||||
fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
|
||||
let bytes = self.inner.bytes_mut();
|
||||
let end = cmp::min(bytes.len(), self.limit);
|
||||
&mut bytes[..end]
|
||||
}
|
||||
|
||||
unsafe fn advance_mut(&mut self, cnt: usize) {
|
||||
assert!(cnt <= self.limit);
|
||||
self.inner.advance_mut(cnt);
|
||||
self.limit -= cnt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
//! Extra utilities for `Buf` and `BufMut` types.
|
||||
|
||||
use super::{Buf, BufMut};
|
||||
|
||||
mod chain;
|
||||
mod limit;
|
||||
#[cfg(feature = "std")]
|
||||
mod reader;
|
||||
mod take;
|
||||
#[cfg(feature = "std")]
|
||||
mod writer;
|
||||
|
||||
pub use self::limit::Limit;
|
||||
pub use self::take::Take;
|
||||
pub use self::chain::Chain;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use self::{reader::Reader, writer::Writer};
|
||||
|
||||
/// Extra methods for implementations of `Buf`.
|
||||
pub trait BufExt: Buf {
|
||||
/// Creates an adaptor which will read at most `limit` bytes from `self`.
|
||||
///
|
||||
/// This function returns a new instance of `Buf` which will read at most
|
||||
/// `limit` bytes.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BufMut, buf::BufExt};
|
||||
///
|
||||
/// let mut buf = b"hello world"[..].take(5);
|
||||
/// let mut dst = vec![];
|
||||
///
|
||||
/// dst.put(&mut buf);
|
||||
/// assert_eq!(dst, b"hello");
|
||||
///
|
||||
/// let mut buf = buf.into_inner();
|
||||
/// dst.clear();
|
||||
/// dst.put(&mut buf);
|
||||
/// assert_eq!(dst, b" world");
|
||||
/// ```
|
||||
fn take(self, limit: usize) -> Take<Self>
|
||||
where Self: Sized
|
||||
{
|
||||
take::new(self, limit)
|
||||
}
|
||||
|
||||
/// Creates an adaptor which will chain this buffer with another.
|
||||
///
|
||||
/// The returned `Buf` instance will first consume all bytes from `self`.
|
||||
/// Afterwards the output is equivalent to the output of next.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, buf::BufExt};
|
||||
///
|
||||
/// let mut chain = b"hello "[..].chain(&b"world"[..]);
|
||||
///
|
||||
/// let full = chain.to_bytes();
|
||||
/// assert_eq!(full.bytes(), b"hello world");
|
||||
/// ```
|
||||
fn chain<U: Buf>(self, next: U) -> Chain<Self, U>
|
||||
where Self: Sized
|
||||
{
|
||||
Chain::new(self, next)
|
||||
}
|
||||
|
||||
/// Creates an adaptor which implements the `Read` trait for `self`.
|
||||
///
|
||||
/// This function returns a new value which implements `Read` by adapting
|
||||
/// the `Read` trait functions to the `Buf` trait functions. Given that
|
||||
/// `Buf` operations are infallible, none of the `Read` functions will
|
||||
/// return with `Err`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, Bytes, buf::BufExt};
|
||||
/// use std::io::Read;
|
||||
///
|
||||
/// let buf = Bytes::from("hello world");
|
||||
///
|
||||
/// let mut reader = buf.reader();
|
||||
/// let mut dst = [0; 1024];
|
||||
///
|
||||
/// let num = reader.read(&mut dst).unwrap();
|
||||
///
|
||||
/// assert_eq!(11, num);
|
||||
/// assert_eq!(&dst[..11], &b"hello world"[..]);
|
||||
/// ```
|
||||
#[cfg(feature = "std")]
|
||||
fn reader(self) -> Reader<Self> where Self: Sized {
|
||||
reader::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Buf + ?Sized> BufExt for B {}
|
||||
|
||||
/// Extra methods for implementations of `BufMut`.
|
||||
pub trait BufMutExt: BufMut {
|
||||
/// Creates an adaptor which can write at most `limit` bytes to `self`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, buf::BufMutExt};
|
||||
///
|
||||
/// let arr = &mut [0u8; 128][..];
|
||||
/// assert_eq!(arr.remaining_mut(), 128);
|
||||
///
|
||||
/// let dst = arr.limit(10);
|
||||
/// assert_eq!(dst.remaining_mut(), 10);
|
||||
/// ```
|
||||
fn limit(self, limit: usize) -> Limit<Self>
|
||||
where Self: Sized
|
||||
{
|
||||
limit::new(self, limit)
|
||||
}
|
||||
|
||||
/// Creates an adaptor which implements the `Write` trait for `self`.
|
||||
///
|
||||
/// This function returns a new value which implements `Write` by adapting
|
||||
/// the `Write` trait functions to the `BufMut` trait functions. Given that
|
||||
/// `BufMut` operations are infallible, none of the `Write` functions will
|
||||
/// return with `Err`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, buf::BufMutExt};
|
||||
/// use std::io::Write;
|
||||
///
|
||||
/// let mut buf = vec![].writer();
|
||||
///
|
||||
/// let num = buf.write(&b"hello world"[..]).unwrap();
|
||||
/// assert_eq!(11, num);
|
||||
///
|
||||
/// let buf = buf.into_inner();
|
||||
///
|
||||
/// assert_eq!(*buf, b"hello world"[..]);
|
||||
/// ```
|
||||
#[cfg(feature = "std")]
|
||||
fn writer(self) -> Writer<Self> where Self: Sized {
|
||||
writer::new(self)
|
||||
}
|
||||
|
||||
/// Creates an adapter which will chain this buffer with another.
|
||||
///
|
||||
/// The returned `BufMut` instance will first write to all bytes from
|
||||
/// `self`. Afterwards, it will write to `next`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, buf::BufMutExt};
|
||||
///
|
||||
/// let mut a = [0u8; 5];
|
||||
/// let mut b = [0u8; 6];
|
||||
///
|
||||
/// let mut chain = (&mut a[..]).chain_mut(&mut b[..]);
|
||||
///
|
||||
/// chain.put_slice(b"hello world");
|
||||
///
|
||||
/// assert_eq!(&a[..], b"hello");
|
||||
/// assert_eq!(&b[..], b" world");
|
||||
/// ```
|
||||
fn chain_mut<U: BufMut>(self, next: U) -> Chain<Self, U>
|
||||
where Self: Sized
|
||||
{
|
||||
Chain::new(self, next)
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: BufMut + ?Sized> BufMutExt for B {}
|
||||
@@ -1,4 +1,4 @@
|
||||
use {Buf};
|
||||
use crate::{Buf};
|
||||
|
||||
use std::{cmp, io};
|
||||
|
||||
@@ -13,7 +13,7 @@ pub struct Reader<B> {
|
||||
}
|
||||
|
||||
pub fn new<B>(buf: B) -> Reader<B> {
|
||||
Reader { buf: buf }
|
||||
Reader { buf }
|
||||
}
|
||||
|
||||
impl<B: Buf> Reader<B> {
|
||||
@@ -24,12 +24,11 @@ impl<B: Buf> Reader<B> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::{self, Cursor};
|
||||
/// use bytes::buf::BufExt;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"hello world").reader();
|
||||
/// let mut buf = b"hello world".reader();
|
||||
///
|
||||
/// assert_eq!(0, buf.get_ref().position());
|
||||
/// assert_eq!(b"hello world", buf.get_ref());
|
||||
/// ```
|
||||
pub fn get_ref(&self) -> &B {
|
||||
&self.buf
|
||||
@@ -38,21 +37,6 @@ impl<B: Buf> Reader<B> {
|
||||
/// Gets a mutable reference to the underlying `Buf`.
|
||||
///
|
||||
/// It is inadvisable to directly read from the underlying `Buf`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::{self, Cursor};
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"hello world").reader();
|
||||
/// let mut dst = vec![];
|
||||
///
|
||||
/// buf.get_mut().set_position(2);
|
||||
/// io::copy(&mut buf, &mut dst).unwrap();
|
||||
///
|
||||
/// assert_eq!(*dst, b"llo world"[..]);
|
||||
/// ```
|
||||
pub fn get_mut(&mut self) -> &mut B {
|
||||
&mut self.buf
|
||||
}
|
||||
@@ -62,10 +46,10 @@ impl<B: Buf> Reader<B> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::{self, Cursor};
|
||||
/// use bytes::{Buf, buf::BufExt};
|
||||
/// use std::io;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"hello world").reader();
|
||||
/// let mut buf = b"hello world".reader();
|
||||
/// let mut dst = vec![];
|
||||
///
|
||||
/// io::copy(&mut buf, &mut dst).unwrap();
|
||||
@@ -86,3 +70,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)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
use {Buf};
|
||||
use crate::Buf;
|
||||
|
||||
use std::cmp;
|
||||
use core::cmp;
|
||||
|
||||
/// A `Buf` adapter which limits the bytes read from an underlying buffer.
|
||||
///
|
||||
@@ -14,8 +14,8 @@ pub struct Take<T> {
|
||||
|
||||
pub fn new<T>(inner: T, limit: usize) -> Take<T> {
|
||||
Take {
|
||||
inner: inner,
|
||||
limit: limit,
|
||||
inner,
|
||||
limit,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,9 @@ impl<T> Take<T> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::{Buf, BufMut};
|
||||
/// use std::io::Cursor;
|
||||
/// use bytes::buf::{Buf, BufMut, BufExt};
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"hello world").take(2);
|
||||
/// let mut buf = b"hello world".take(2);
|
||||
/// let mut dst = vec![];
|
||||
///
|
||||
/// dst.put(&mut buf);
|
||||
@@ -51,12 +50,11 @@ impl<T> Take<T> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::{Buf, BufMut};
|
||||
/// use std::io::Cursor;
|
||||
/// use bytes::{Buf, buf::BufExt};
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"hello world").take(2);
|
||||
/// let mut buf = b"hello world".take(2);
|
||||
///
|
||||
/// assert_eq!(0, buf.get_ref().position());
|
||||
/// assert_eq!(11, buf.get_ref().remaining());
|
||||
/// ```
|
||||
pub fn get_ref(&self) -> &T {
|
||||
&self.inner
|
||||
@@ -69,13 +67,12 @@ impl<T> Take<T> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::{Buf, BufMut};
|
||||
/// use std::io::Cursor;
|
||||
/// use bytes::{Buf, BufMut, buf::BufExt};
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"hello world").take(2);
|
||||
/// let mut buf = b"hello world".take(2);
|
||||
/// let mut dst = vec![];
|
||||
///
|
||||
/// buf.get_mut().set_position(2);
|
||||
/// buf.get_mut().advance(2);
|
||||
///
|
||||
/// dst.put(&mut buf);
|
||||
/// assert_eq!(*dst, b"ll"[..]);
|
||||
@@ -94,10 +91,9 @@ impl<T> Take<T> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
/// use bytes::{Buf, buf::BufExt};
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"hello world").take(2);
|
||||
/// let mut buf = b"hello world".take(2);
|
||||
///
|
||||
/// assert_eq!(2, buf.limit());
|
||||
/// assert_eq!(b'h', buf.get_u8());
|
||||
@@ -117,10 +113,9 @@ impl<T> Take<T> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::{Buf, BufMut};
|
||||
/// use std::io::Cursor;
|
||||
/// use bytes::{Buf, BufMut, buf::BufExt};
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"hello world").take(2);
|
||||
/// let mut buf = b"hello world".take(2);
|
||||
/// let mut dst = vec![];
|
||||
///
|
||||
/// dst.put(&mut buf);
|
||||
@@ -1,4 +1,4 @@
|
||||
use BufMut;
|
||||
use crate::BufMut;
|
||||
|
||||
use std::{cmp, io};
|
||||
|
||||
@@ -13,7 +13,7 @@ pub struct Writer<B> {
|
||||
}
|
||||
|
||||
pub fn new<B>(buf: B) -> Writer<B> {
|
||||
Writer { buf: buf }
|
||||
Writer { buf }
|
||||
}
|
||||
|
||||
impl<B: BufMut> Writer<B> {
|
||||
@@ -24,7 +24,7 @@ impl<B: BufMut> Writer<B> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::BufMut;
|
||||
/// use bytes::buf::BufMutExt;
|
||||
///
|
||||
/// let mut buf = Vec::with_capacity(1024).writer();
|
||||
///
|
||||
@@ -41,7 +41,7 @@ impl<B: BufMut> Writer<B> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::BufMut;
|
||||
/// use bytes::buf::BufMutExt;
|
||||
///
|
||||
/// let mut buf = vec![].writer();
|
||||
///
|
||||
@@ -58,11 +58,11 @@ impl<B: BufMut> Writer<B> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::BufMut;
|
||||
/// use std::io::{self, Cursor};
|
||||
/// use bytes::buf::BufMutExt;
|
||||
/// use std::io;
|
||||
///
|
||||
/// let mut buf = vec![].writer();
|
||||
/// let mut src = Cursor::new(b"hello world");
|
||||
/// let mut src = &b"hello world"[..];
|
||||
///
|
||||
/// io::copy(&mut src, &mut buf).unwrap();
|
||||
///
|
||||
@@ -1,117 +0,0 @@
|
||||
use {Buf, BufMut, IntoBuf, Bytes, BytesMut};
|
||||
|
||||
/// Conversion from a [`Buf`]
|
||||
///
|
||||
/// Implementing `FromBuf` for a type defines how it is created from a buffer.
|
||||
/// This is common for types which represent byte storage of some kind.
|
||||
///
|
||||
/// [`FromBuf::from_buf`] is rarely called explicitly, and it is instead used
|
||||
/// through [`Buf::collect`]. See [`Buf::collect`] documentation for more examples.
|
||||
///
|
||||
/// See also [`IntoBuf`].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Bytes, IntoBuf};
|
||||
/// use bytes::buf::FromBuf;
|
||||
///
|
||||
/// let buf = Bytes::from(&b"hello world"[..]).into_buf();
|
||||
/// let vec = Vec::from_buf(buf);
|
||||
///
|
||||
/// assert_eq!(vec, &b"hello world"[..]);
|
||||
/// ```
|
||||
///
|
||||
/// Using [`Buf::collect`] to implicitly use `FromBuf`:
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, Bytes, IntoBuf};
|
||||
///
|
||||
/// let buf = Bytes::from(&b"hello world"[..]).into_buf();
|
||||
/// let vec: Vec<u8> = buf.collect();
|
||||
///
|
||||
/// assert_eq!(vec, &b"hello world"[..]);
|
||||
/// ```
|
||||
///
|
||||
/// Implementing `FromBuf` for your type:
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, Bytes};
|
||||
/// use bytes::buf::{IntoBuf, FromBuf};
|
||||
///
|
||||
/// // A sample buffer, that's just a wrapper over Vec<u8>
|
||||
/// struct MyBuffer(Vec<u8>);
|
||||
///
|
||||
/// impl FromBuf for MyBuffer {
|
||||
/// fn from_buf<B>(buf: B) -> Self where B: IntoBuf {
|
||||
/// let mut v = Vec::new();
|
||||
/// v.put(buf.into_buf());
|
||||
/// MyBuffer(v)
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // Now we can make a new buf
|
||||
/// let buf = Bytes::from(&b"hello world"[..]);
|
||||
///
|
||||
/// // And make a MyBuffer out of it
|
||||
/// let my_buf = MyBuffer::from_buf(buf);
|
||||
///
|
||||
/// assert_eq!(my_buf.0, &b"hello world"[..]);
|
||||
/// ```
|
||||
///
|
||||
/// [`Buf`]: trait.Buf.html
|
||||
/// [`FromBuf::from_buf`]: #method.from_buf
|
||||
/// [`Buf::collect`]: trait.Buf.html#method.collect
|
||||
/// [`IntoBuf`]: trait.IntoBuf.html
|
||||
pub trait FromBuf {
|
||||
/// Creates a value from a buffer.
|
||||
///
|
||||
/// See the [type-level documentation](#) for more details.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Bytes, IntoBuf};
|
||||
/// use bytes::buf::FromBuf;
|
||||
///
|
||||
/// let buf = Bytes::from(&b"hello world"[..]).into_buf();
|
||||
/// let vec = Vec::from_buf(buf);
|
||||
///
|
||||
/// assert_eq!(vec, &b"hello world"[..]);
|
||||
/// ```
|
||||
fn from_buf<T>(buf: T) -> Self where T: IntoBuf;
|
||||
}
|
||||
|
||||
impl FromBuf for Vec<u8> {
|
||||
fn from_buf<T>(buf: T) -> Self
|
||||
where T: IntoBuf
|
||||
{
|
||||
let buf = buf.into_buf();
|
||||
let mut ret = Vec::with_capacity(buf.remaining());
|
||||
ret.put(buf);
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
impl FromBuf for Bytes {
|
||||
fn from_buf<T>(buf: T) -> Self
|
||||
where T: IntoBuf
|
||||
{
|
||||
BytesMut::from_buf(buf).freeze()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromBuf for BytesMut {
|
||||
fn from_buf<T>(buf: T) -> Self
|
||||
where T: IntoBuf
|
||||
{
|
||||
let buf = buf.into_buf();
|
||||
let mut ret = BytesMut::with_capacity(buf.remaining());
|
||||
ret.put(buf);
|
||||
ret
|
||||
}
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
use super::{Buf};
|
||||
|
||||
use std::io;
|
||||
|
||||
/// Conversion into a `Buf`
|
||||
///
|
||||
/// An `IntoBuf` implementation defines how to convert a value into a `Buf`.
|
||||
/// This is common for types that represent byte storage of some kind. `IntoBuf`
|
||||
/// may be implemented directly for types or on references for those types.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, IntoBuf, BigEndian};
|
||||
///
|
||||
/// let bytes = b"\x00\x01hello world";
|
||||
/// let mut buf = bytes.into_buf();
|
||||
///
|
||||
/// assert_eq!(1, buf.get_u16::<BigEndian>());
|
||||
///
|
||||
/// let mut rest = [0; 11];
|
||||
/// buf.copy_to_slice(&mut rest);
|
||||
///
|
||||
/// assert_eq!(b"hello world", &rest);
|
||||
/// ```
|
||||
pub trait IntoBuf {
|
||||
/// The `Buf` type that `self` is being converted into
|
||||
type Buf: Buf;
|
||||
|
||||
/// Creates a `Buf` from a value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, IntoBuf, BigEndian};
|
||||
///
|
||||
/// let bytes = b"\x00\x01hello world";
|
||||
/// let mut buf = bytes.into_buf();
|
||||
///
|
||||
/// assert_eq!(1, buf.get_u16::<BigEndian>());
|
||||
///
|
||||
/// let mut rest = [0; 11];
|
||||
/// buf.copy_to_slice(&mut rest);
|
||||
///
|
||||
/// assert_eq!(b"hello world", &rest);
|
||||
/// ```
|
||||
fn into_buf(self) -> Self::Buf;
|
||||
}
|
||||
|
||||
impl<T: Buf> IntoBuf for T {
|
||||
type Buf = Self;
|
||||
|
||||
fn into_buf(self) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoBuf for &'a [u8] {
|
||||
type Buf = io::Cursor<&'a [u8]>;
|
||||
|
||||
fn into_buf(self) -> Self::Buf {
|
||||
io::Cursor::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoBuf for &'a str {
|
||||
type Buf = io::Cursor<&'a [u8]>;
|
||||
|
||||
fn into_buf(self) -> Self::Buf {
|
||||
self.as_bytes().into_buf()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoBuf for Vec<u8> {
|
||||
type Buf = io::Cursor<Vec<u8>>;
|
||||
|
||||
fn into_buf(self) -> Self::Buf {
|
||||
io::Cursor::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoBuf for &'a Vec<u8> {
|
||||
type Buf = io::Cursor<&'a [u8]>;
|
||||
|
||||
fn into_buf(self) -> Self::Buf {
|
||||
io::Cursor::new(&self[..])
|
||||
}
|
||||
}
|
||||
|
||||
// Kind of annoying... but this impl is required to allow passing `&'static
|
||||
// [u8]` where for<'a> &'a T: IntoBuf is required.
|
||||
impl<'a> IntoBuf for &'a &'static [u8] {
|
||||
type Buf = io::Cursor<&'static [u8]>;
|
||||
|
||||
fn into_buf(self) -> Self::Buf {
|
||||
io::Cursor::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoBuf for &'a &'static str {
|
||||
type Buf = io::Cursor<&'static [u8]>;
|
||||
|
||||
fn into_buf(self) -> Self::Buf {
|
||||
self.as_bytes().into_buf()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoBuf for String {
|
||||
type Buf = io::Cursor<Vec<u8>>;
|
||||
|
||||
fn into_buf(self) -> Self::Buf {
|
||||
self.into_bytes().into_buf()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoBuf for &'a String {
|
||||
type Buf = io::Cursor<&'a [u8]>;
|
||||
|
||||
fn into_buf(self) -> Self::Buf {
|
||||
self.as_bytes().into_buf()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoBuf for u8 {
|
||||
type Buf = Option<[u8; 1]>;
|
||||
|
||||
fn into_buf(self) -> Self::Buf {
|
||||
Some([self])
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoBuf for i8 {
|
||||
type Buf = Option<[u8; 1]>;
|
||||
|
||||
fn into_buf(self) -> Self::Buf {
|
||||
Some([self as u8; 1])
|
||||
}
|
||||
}
|
||||
+40
-23
@@ -1,4 +1,4 @@
|
||||
use Buf;
|
||||
use crate::Buf;
|
||||
|
||||
/// Iterator over the bytes contained by the buffer.
|
||||
///
|
||||
@@ -9,10 +9,10 @@ use Buf;
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, IntoBuf, Bytes};
|
||||
/// use bytes::{Buf, Bytes};
|
||||
///
|
||||
/// let buf = Bytes::from(&b"abc"[..]).into_buf();
|
||||
/// let mut iter = buf.iter();
|
||||
/// let buf = Bytes::from(&b"abc"[..]);
|
||||
/// let mut iter = buf.into_iter();
|
||||
///
|
||||
/// assert_eq!(iter.next(), Some(b'a'));
|
||||
/// assert_eq!(iter.next(), Some(b'b'));
|
||||
@@ -23,20 +23,39 @@ use Buf;
|
||||
/// [`iter`]: trait.Buf.html#method.iter
|
||||
/// [`Buf`]: trait.Buf.html
|
||||
#[derive(Debug)]
|
||||
pub struct Iter<T> {
|
||||
pub struct IntoIter<T> {
|
||||
inner: T,
|
||||
}
|
||||
|
||||
impl<T> Iter<T> {
|
||||
/// Consumes this `Iter`, returning the underlying value.
|
||||
impl<T> IntoIter<T> {
|
||||
/// Creates an iterator over the bytes contained by the buffer.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, Bytes};
|
||||
/// use bytes::buf::IntoIter;
|
||||
///
|
||||
/// let buf = Bytes::from_static(b"abc");
|
||||
/// let mut iter = IntoIter::new(buf);
|
||||
///
|
||||
/// assert_eq!(iter.next(), Some(b'a'));
|
||||
/// assert_eq!(iter.next(), Some(b'b'));
|
||||
/// assert_eq!(iter.next(), Some(b'c'));
|
||||
/// assert_eq!(iter.next(), None);
|
||||
/// ```
|
||||
pub fn new(inner: T) -> IntoIter<T> {
|
||||
IntoIter { inner }
|
||||
}
|
||||
/// Consumes this `IntoIter`, returning the underlying value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::{Buf, IntoBuf, Bytes};
|
||||
/// use bytes::{Buf, Bytes};
|
||||
///
|
||||
/// let buf = Bytes::from(&b"abc"[..]).into_buf();
|
||||
/// let mut iter = buf.iter();
|
||||
/// let buf = Bytes::from(&b"abc"[..]);
|
||||
/// let mut iter = buf.into_iter();
|
||||
///
|
||||
/// assert_eq!(iter.next(), Some(b'a'));
|
||||
///
|
||||
@@ -54,10 +73,10 @@ impl<T> Iter<T> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::{Buf, IntoBuf, Bytes};
|
||||
/// use bytes::{Buf, Bytes};
|
||||
///
|
||||
/// let buf = Bytes::from(&b"abc"[..]).into_buf();
|
||||
/// let mut iter = buf.iter();
|
||||
/// let buf = Bytes::from(&b"abc"[..]);
|
||||
/// let mut iter = buf.into_iter();
|
||||
///
|
||||
/// assert_eq!(iter.next(), Some(b'a'));
|
||||
///
|
||||
@@ -74,27 +93,24 @@ impl<T> Iter<T> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::{Buf, IntoBuf, BytesMut};
|
||||
/// use bytes::{Buf, BytesMut};
|
||||
///
|
||||
/// let buf = BytesMut::from(&b"abc"[..]).into_buf();
|
||||
/// let mut iter = buf.iter();
|
||||
/// let buf = BytesMut::from(&b"abc"[..]);
|
||||
/// let mut iter = buf.into_iter();
|
||||
///
|
||||
/// assert_eq!(iter.next(), Some(b'a'));
|
||||
///
|
||||
/// iter.get_mut().set_position(0);
|
||||
/// iter.get_mut().advance(1);
|
||||
///
|
||||
/// assert_eq!(iter.next(), Some(b'a'));
|
||||
/// assert_eq!(iter.next(), Some(b'c'));
|
||||
/// ```
|
||||
pub fn get_mut(&mut self) -> &mut T {
|
||||
&mut self.inner
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new<T>(inner: T) -> Iter<T> {
|
||||
Iter { inner: inner }
|
||||
}
|
||||
|
||||
impl<T: Buf> Iterator for Iter<T> {
|
||||
impl<T: Buf> Iterator for IntoIter<T> {
|
||||
type Item = u8;
|
||||
|
||||
fn next(&mut self) -> Option<u8> {
|
||||
@@ -104,6 +120,7 @@ impl<T: Buf> Iterator for Iter<T> {
|
||||
|
||||
let b = self.inner.bytes()[0];
|
||||
self.inner.advance(1);
|
||||
|
||||
Some(b)
|
||||
}
|
||||
|
||||
@@ -113,4 +130,4 @@ impl<T: Buf> Iterator for Iter<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Buf> ExactSizeIterator for Iter<T> { }
|
||||
impl<T: Buf> ExactSizeIterator for IntoIter<T> { }
|
||||
|
||||
+9
-15
@@ -16,22 +16,16 @@
|
||||
//! [`Buf`]: trait.Buf.html
|
||||
//! [`BufMut`]: trait.BufMut.html
|
||||
|
||||
mod buf;
|
||||
mod buf_impl;
|
||||
mod buf_mut;
|
||||
mod from_buf;
|
||||
mod chain;
|
||||
mod into_buf;
|
||||
pub mod ext;
|
||||
mod iter;
|
||||
mod reader;
|
||||
mod take;
|
||||
mod writer;
|
||||
mod vec_deque;
|
||||
|
||||
pub use self::buf::Buf;
|
||||
pub use self::buf_impl::Buf;
|
||||
pub use self::buf_mut::BufMut;
|
||||
pub use self::from_buf::FromBuf;
|
||||
pub use self::chain::Chain;
|
||||
pub use self::into_buf::IntoBuf;
|
||||
pub use self::iter::Iter;
|
||||
pub use self::reader::Reader;
|
||||
pub use self::take::Take;
|
||||
pub use self::writer::Writer;
|
||||
pub use self::ext::{BufExt, BufMutExt};
|
||||
#[cfg(feature = "std")]
|
||||
pub use self::buf_mut::IoSliceMut;
|
||||
pub use self::iter::IntoIter;
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
use alloc::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);
|
||||
}
|
||||
}
|
||||
+483
-2363
File diff suppressed because it is too large
Load Diff
+1464
File diff suppressed because it is too large
Load Diff
+12
-12
@@ -1,4 +1,4 @@
|
||||
use std::fmt;
|
||||
use core::fmt;
|
||||
|
||||
/// Alternative implementation of `fmt::Debug` for byte slice.
|
||||
///
|
||||
@@ -12,29 +12,29 @@ use std::fmt;
|
||||
/// `BsDebug` is not a part of public API of bytes crate.
|
||||
pub struct BsDebug<'a>(pub &'a [u8]);
|
||||
|
||||
impl<'a> fmt::Debug for BsDebug<'a> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
try!(write!(fmt, "b\""));
|
||||
impl fmt::Debug for BsDebug<'_> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||
write!(fmt, "b\"")?;
|
||||
for &c in self.0 {
|
||||
// https://doc.rust-lang.org/reference.html#byte-escapes
|
||||
if c == b'\n' {
|
||||
try!(write!(fmt, "\\n"));
|
||||
write!(fmt, "\\n")?;
|
||||
} else if c == b'\r' {
|
||||
try!(write!(fmt, "\\r"));
|
||||
write!(fmt, "\\r")?;
|
||||
} else if c == b'\t' {
|
||||
try!(write!(fmt, "\\t"));
|
||||
write!(fmt, "\\t")?;
|
||||
} else if c == b'\\' || c == b'"' {
|
||||
try!(write!(fmt, "\\{}", c as char));
|
||||
write!(fmt, "\\{}", c as char)?;
|
||||
} else if c == b'\0' {
|
||||
try!(write!(fmt, "\\0"));
|
||||
write!(fmt, "\\0")?;
|
||||
// ASCII printable
|
||||
} else if c >= 0x20 && c < 0x7f {
|
||||
try!(write!(fmt, "{}", c as char));
|
||||
write!(fmt, "{}", c as char)?;
|
||||
} else {
|
||||
try!(write!(fmt, "\\x{:02x}", c));
|
||||
write!(fmt, "\\x{:02x}", c)?;
|
||||
}
|
||||
}
|
||||
try!(write!(fmt, "\""));
|
||||
write!(fmt, "\"")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
use crate::{Bytes, BytesMut};
|
||||
use core::fmt::{Formatter, LowerHex, Result, UpperHex};
|
||||
|
||||
struct BytesRef<'a>(&'a [u8]);
|
||||
|
||||
impl<'a> LowerHex for BytesRef<'a> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
for b in self.0 {
|
||||
write!(f, "{:02x}", b)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> UpperHex for BytesRef<'a> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
for b in self.0 {
|
||||
write!(f, "{:02X}", b)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! hex_impl {
|
||||
($tr:ident, $ty:ty) => {
|
||||
impl $tr for $ty {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
$tr::fmt(&BytesRef(self.as_ref()), f)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
hex_impl!(LowerHex, Bytes);
|
||||
hex_impl!(LowerHex, BytesMut);
|
||||
hex_impl!(UpperHex, Bytes);
|
||||
hex_impl!(UpperHex, BytesMut);
|
||||
+43
-26
@@ -1,3 +1,7 @@
|
||||
#![deny(warnings, missing_docs, missing_debug_implementations, rust_2018_idioms)]
|
||||
#![doc(html_root_url = "https://docs.rs/bytes/0.5.2")]
|
||||
#![no_std]
|
||||
|
||||
//! Provides abstractions for working with bytes.
|
||||
//!
|
||||
//! The `bytes` crate provides an efficient byte buffer structure
|
||||
@@ -9,7 +13,7 @@
|
||||
//!
|
||||
//! # `Bytes`
|
||||
//!
|
||||
//! `Bytes` is an efficient container for storing and operating on continguous
|
||||
//! `Bytes` is an efficient container for storing and operating on contiguous
|
||||
//! slices of memory. It is intended for use primarily in networking code, but
|
||||
//! could have applications elsewhere as well.
|
||||
//!
|
||||
@@ -18,23 +22,23 @@
|
||||
//! 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
|
||||
//! use bytes::{BytesMut, BufMut, BigEndian};
|
||||
//! use bytes::{BytesMut, BufMut};
|
||||
//!
|
||||
//! let mut buf = BytesMut::with_capacity(1024);
|
||||
//! buf.put(&b"hello world"[..]);
|
||||
//! buf.put_u16::<BigEndian>(1234);
|
||||
//! buf.put_u16(1234);
|
||||
//!
|
||||
//! let a = buf.take();
|
||||
//! let a = buf.split();
|
||||
//! assert_eq!(a, b"hello world\x04\xD2"[..]);
|
||||
//!
|
||||
//! buf.put(&b"goodbye world"[..]);
|
||||
//!
|
||||
//! let b = buf.take();
|
||||
//! let b = buf.split();
|
||||
//! assert_eq!(b, b"goodbye world"[..]);
|
||||
//!
|
||||
//! assert_eq!(buf.capacity(), 998);
|
||||
@@ -68,34 +72,47 @@
|
||||
//! perform a syscall, which has the potential of failing. Operations on `Buf`
|
||||
//! and `BufMut` are infallible.
|
||||
|
||||
#![deny(warnings, missing_docs, missing_debug_implementations)]
|
||||
#![doc(html_root_url = "https://docs.rs/bytes/0.4.8")]
|
||||
|
||||
extern crate byteorder;
|
||||
extern crate iovec;
|
||||
extern crate alloc;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
extern crate std;
|
||||
|
||||
pub mod buf;
|
||||
pub use buf::{
|
||||
pub use crate::buf::{
|
||||
Buf,
|
||||
BufMut,
|
||||
IntoBuf,
|
||||
};
|
||||
#[deprecated(since = "0.4.1", note = "moved to `buf` module")]
|
||||
#[doc(hidden)]
|
||||
pub use buf::{
|
||||
Reader,
|
||||
Writer,
|
||||
Take,
|
||||
};
|
||||
|
||||
mod bytes_mut;
|
||||
mod bytes;
|
||||
mod debug;
|
||||
pub use bytes::{Bytes, BytesMut};
|
||||
|
||||
#[deprecated]
|
||||
pub use byteorder::{ByteOrder, BigEndian, LittleEndian};
|
||||
mod hex;
|
||||
mod loom;
|
||||
pub use crate::bytes_mut::BytesMut;
|
||||
pub use crate::bytes::Bytes;
|
||||
|
||||
// Optional Serde support
|
||||
#[cfg(feature = "serde")]
|
||||
#[doc(hidden)]
|
||||
pub mod serde;
|
||||
mod serde;
|
||||
|
||||
#[inline(never)]
|
||||
#[cold]
|
||||
fn abort() -> ! {
|
||||
#[cfg(feature = "std")]
|
||||
{
|
||||
std::process::abort();
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
{
|
||||
struct Abort;
|
||||
impl Drop for Abort {
|
||||
fn drop(&mut self) {
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
let _a = Abort;
|
||||
panic!("abort");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#[cfg(not(all(test, loom)))]
|
||||
pub(crate) mod sync {
|
||||
pub(crate) mod atomic {
|
||||
pub(crate) use core::sync::atomic::{fence, AtomicPtr, AtomicUsize, Ordering};
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, loom))]
|
||||
pub(crate) use ::loom::sync;
|
||||
+15
-15
@@ -1,11 +1,11 @@
|
||||
extern crate serde;
|
||||
|
||||
use std::{cmp, fmt};
|
||||
use self::serde::{Serialize, Serializer, Deserialize, Deserializer, de};
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use core::{cmp, fmt};
|
||||
use serde::{Serialize, Serializer, Deserialize, Deserializer, de};
|
||||
use super::{Bytes, BytesMut};
|
||||
|
||||
macro_rules! serde_impl {
|
||||
($ty:ident, $visitor_ty:ident) => (
|
||||
($ty:ident, $visitor_ty:ident, $from_slice:ident, $from_vec:ident) => (
|
||||
impl Serialize for $ty {
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -20,7 +20,7 @@ macro_rules! serde_impl {
|
||||
impl<'de> de::Visitor<'de> for $visitor_ty {
|
||||
type Value = $ty;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
formatter.write_str("byte array")
|
||||
}
|
||||
|
||||
@@ -29,41 +29,41 @@ macro_rules! serde_impl {
|
||||
where V: de::SeqAccess<'de>
|
||||
{
|
||||
let len = cmp::min(seq.size_hint().unwrap_or(0), 4096);
|
||||
let mut values = Vec::with_capacity(len);
|
||||
let mut values: Vec<u8> = Vec::with_capacity(len);
|
||||
|
||||
while let Some(value) = try!(seq.next_element()) {
|
||||
while let Some(value) = seq.next_element()? {
|
||||
values.push(value);
|
||||
}
|
||||
|
||||
Ok(values.into())
|
||||
Ok($ty::$from_vec(values))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||
where E: de::Error
|
||||
{
|
||||
Ok($ty::from(v))
|
||||
Ok($ty::$from_slice(v))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
|
||||
where E: de::Error
|
||||
{
|
||||
Ok($ty::from(v))
|
||||
Ok($ty::$from_vec(v))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where E: de::Error
|
||||
{
|
||||
Ok($ty::from(v))
|
||||
Ok($ty::$from_slice(v.as_bytes()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||
where E: de::Error
|
||||
{
|
||||
Ok($ty::from(v))
|
||||
Ok($ty::$from_vec(v.into_bytes()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,5 +78,5 @@ macro_rules! serde_impl {
|
||||
);
|
||||
}
|
||||
|
||||
serde_impl!(Bytes, BytesVisitor);
|
||||
serde_impl!(BytesMut, BytesMutVisitor);
|
||||
serde_impl!(Bytes, BytesVisitor, copy_from_slice, from);
|
||||
serde_impl!(BytesMut, BytesMutVisitor, from, from_vec);
|
||||
|
||||
+31
-18
@@ -1,14 +1,11 @@
|
||||
extern crate bytes;
|
||||
extern crate byteorder;
|
||||
extern crate iovec;
|
||||
#![deny(warnings, rust_2018_idioms)]
|
||||
|
||||
use bytes::Buf;
|
||||
use iovec::IoVec;
|
||||
use std::io::Cursor;
|
||||
use std::io::IoSlice;
|
||||
|
||||
#[test]
|
||||
fn test_fresh_cursor_vec() {
|
||||
let mut buf = Cursor::new(b"hello".to_vec());
|
||||
let mut buf = &b"hello"[..];
|
||||
|
||||
assert_eq!(buf.remaining(), 5);
|
||||
assert_eq!(buf.bytes(), b"hello");
|
||||
@@ -26,33 +23,49 @@ fn test_fresh_cursor_vec() {
|
||||
|
||||
#[test]
|
||||
fn test_get_u8() {
|
||||
let mut buf = Cursor::new(b"\x21zomg");
|
||||
let mut buf = &b"\x21zomg"[..];
|
||||
assert_eq!(0x21, buf.get_u8());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_u16() {
|
||||
let buf = b"\x21\x54zomg";
|
||||
assert_eq!(0x2154, Cursor::new(buf).get_u16_be());
|
||||
assert_eq!(0x5421, Cursor::new(buf).get_u16_le());
|
||||
let mut buf = &b"\x21\x54zomg"[..];
|
||||
assert_eq!(0x2154, buf.get_u16());
|
||||
let mut buf = &b"\x21\x54zomg"[..];
|
||||
assert_eq!(0x5421, buf.get_u16_le());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_get_u16_buffer_underflow() {
|
||||
let mut buf = Cursor::new(b"\x21");
|
||||
buf.get_u16_be();
|
||||
let mut buf = &b"\x21"[..];
|
||||
buf.get_u16();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bufs_vec() {
|
||||
let buf = Cursor::new(b"hello world");
|
||||
let buf = &b"hello world"[..];
|
||||
|
||||
let b1: &[u8] = &mut [0];
|
||||
let b2: &[u8] = &mut [0];
|
||||
let b1: &[u8] = &mut [];
|
||||
let b2: &[u8] = &mut [];
|
||||
|
||||
let mut dst: [&IoVec; 2] =
|
||||
[b1.into(), b2.into()];
|
||||
let mut dst = [IoSlice::new(b1), IoSlice::new(b2)];
|
||||
|
||||
assert_eq!(1, buf.bytes_vec(&mut dst[..]));
|
||||
assert_eq!(1, buf.bytes_vectored(&mut dst[..]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_deque() {
|
||||
use std::collections::VecDeque;
|
||||
|
||||
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");
|
||||
let mut out = [0; 11];
|
||||
buffer.copy_to_slice(&mut out);
|
||||
assert_eq!(b"world piece", &out[..]);
|
||||
}
|
||||
|
||||
+23
-17
@@ -1,9 +1,6 @@
|
||||
extern crate bytes;
|
||||
extern crate byteorder;
|
||||
extern crate iovec;
|
||||
#![deny(warnings, rust_2018_idioms)]
|
||||
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use iovec::IoVec;
|
||||
use bytes::{buf::IoSliceMut, BufMut, BytesMut};
|
||||
use std::usize;
|
||||
use std::fmt::Write;
|
||||
|
||||
@@ -13,9 +10,7 @@ fn test_vec_as_mut_buf() {
|
||||
|
||||
assert_eq!(buf.remaining_mut(), usize::MAX);
|
||||
|
||||
unsafe {
|
||||
assert!(buf.bytes_mut().len() >= 64);
|
||||
}
|
||||
assert!(buf.bytes_mut().len() >= 64);
|
||||
|
||||
buf.put(&b"zomg"[..]);
|
||||
|
||||
@@ -34,14 +29,14 @@ fn test_vec_as_mut_buf() {
|
||||
#[test]
|
||||
fn test_put_u8() {
|
||||
let mut buf = Vec::with_capacity(8);
|
||||
buf.put::<u8>(33);
|
||||
buf.put_u8(33);
|
||||
assert_eq!(b"\x21", &buf[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_put_u16() {
|
||||
let mut buf = Vec::with_capacity(8);
|
||||
buf.put_u16_be(8532);
|
||||
buf.put_u16(8532);
|
||||
assert_eq!(b"\x21\x54", &buf[..]);
|
||||
|
||||
buf.clear();
|
||||
@@ -66,18 +61,29 @@ fn test_clone() {
|
||||
buf.write_str("this is a test").unwrap();
|
||||
let buf2 = buf.clone();
|
||||
|
||||
buf.write_str(" of our emergecy broadcast system").unwrap();
|
||||
buf.write_str(" of our emergency broadcast system").unwrap();
|
||||
assert!(buf != buf2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bufs_vec_mut() {
|
||||
use std::mem;
|
||||
let b1: &mut [u8] = &mut [];
|
||||
let b2: &mut [u8] = &mut [];
|
||||
let mut dst = [IoSliceMut::from(b1), IoSliceMut::from(b2)];
|
||||
|
||||
let mut buf = BytesMut::from(&b"hello world"[..]);
|
||||
// with no capacity
|
||||
let mut buf = BytesMut::new();
|
||||
assert_eq!(buf.capacity(), 0);
|
||||
assert_eq!(1, buf.bytes_vectored_mut(&mut dst[..]));
|
||||
|
||||
unsafe {
|
||||
let mut dst: [&mut IoVec; 2] = mem::zeroed();
|
||||
assert_eq!(1, buf.bytes_vec_mut(&mut dst[..]));
|
||||
}
|
||||
// with capacity
|
||||
let mut buf = BytesMut::with_capacity(64);
|
||||
assert_eq!(1, buf.bytes_vectored_mut(&mut dst[..]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_slice() {
|
||||
let mut v = vec![0, 0, 0, 0];
|
||||
let mut s = &mut v[..];
|
||||
s.put_u32(42);
|
||||
}
|
||||
|
||||
+294
-151
@@ -1,15 +1,12 @@
|
||||
extern crate bytes;
|
||||
#![deny(warnings, rust_2018_idioms)]
|
||||
|
||||
use bytes::{Bytes, BytesMut, BufMut};
|
||||
use bytes::{Bytes, BytesMut, Buf, BufMut};
|
||||
|
||||
use std::usize;
|
||||
|
||||
const LONG: &'static [u8] = b"mary had a little lamb, little lamb, little lamb";
|
||||
const SHORT: &'static [u8] = b"hello world";
|
||||
|
||||
fn inline_cap() -> usize {
|
||||
use std::mem;
|
||||
4 * mem::size_of::<usize>() - 1
|
||||
}
|
||||
|
||||
fn is_sync<T: Sync>() {}
|
||||
fn is_send<T: Send>() {}
|
||||
|
||||
@@ -21,6 +18,35 @@ fn test_bounds() {
|
||||
is_send::<BytesMut>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_layout() {
|
||||
use std::mem;
|
||||
|
||||
assert_eq!(
|
||||
mem::size_of::<Bytes>(),
|
||||
mem::size_of::<usize>() * 4,
|
||||
"Bytes size should be 4 words",
|
||||
);
|
||||
assert_eq!(
|
||||
mem::size_of::<BytesMut>(),
|
||||
mem::size_of::<usize>() * 4,
|
||||
"BytesMut should be 4 words",
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
mem::size_of::<Bytes>(),
|
||||
mem::size_of::<Option<Bytes>>(),
|
||||
"Bytes should be same size as Option<Bytes>",
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
mem::size_of::<BytesMut>(),
|
||||
mem::size_of::<Option<BytesMut>>(),
|
||||
"BytesMut should be same size as Option<BytesMut>",
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_slice() {
|
||||
let a = Bytes::from(&b"abcdefgh"[..]);
|
||||
@@ -69,8 +95,8 @@ fn fmt_write() {
|
||||
|
||||
|
||||
let mut c = BytesMut::with_capacity(64);
|
||||
write!(c, "{}", s).unwrap_err();
|
||||
assert!(c.is_empty());
|
||||
write!(c, "{}", s).unwrap();
|
||||
assert_eq!(c, s[..].as_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -98,22 +124,22 @@ fn index() {
|
||||
fn slice() {
|
||||
let a = Bytes::from(&b"hello world"[..]);
|
||||
|
||||
let b = a.slice(3, 5);
|
||||
let b = a.slice(3..5);
|
||||
assert_eq!(b, b"lo"[..]);
|
||||
|
||||
let b = a.slice(0, 0);
|
||||
let b = a.slice(0..0);
|
||||
assert_eq!(b, b""[..]);
|
||||
|
||||
let b = a.slice(3, 3);
|
||||
let b = a.slice(3..3);
|
||||
assert_eq!(b, b""[..]);
|
||||
|
||||
let b = a.slice(a.len(), a.len());
|
||||
let b = a.slice(a.len()..a.len());
|
||||
assert_eq!(b, b""[..]);
|
||||
|
||||
let b = a.slice_to(5);
|
||||
let b = a.slice(..5);
|
||||
assert_eq!(b, b"hello"[..]);
|
||||
|
||||
let b = a.slice_from(3);
|
||||
let b = a.slice(3..);
|
||||
assert_eq!(b, b"lo world"[..]);
|
||||
}
|
||||
|
||||
@@ -121,14 +147,14 @@ fn slice() {
|
||||
#[should_panic]
|
||||
fn slice_oob_1() {
|
||||
let a = Bytes::from(&b"hello world"[..]);
|
||||
a.slice(5, inline_cap() + 1);
|
||||
a.slice(5..44);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn slice_oob_2() {
|
||||
let a = Bytes::from(&b"hello world"[..]);
|
||||
a.slice(inline_cap() + 1, inline_cap() + 5);
|
||||
a.slice(44..49);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -150,7 +176,7 @@ fn split_off() {
|
||||
#[should_panic]
|
||||
fn split_off_oob() {
|
||||
let mut hello = Bytes::from(&b"helloworld"[..]);
|
||||
hello.split_off(inline_cap() + 1);
|
||||
hello.split_off(44);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -175,8 +201,8 @@ fn split_off_to_loop() {
|
||||
let off = bytes.split_off(i);
|
||||
assert_eq!(i, bytes.len());
|
||||
let mut sum = Vec::new();
|
||||
sum.extend(&bytes);
|
||||
sum.extend(&off);
|
||||
sum.extend(bytes.iter());
|
||||
sum.extend(off.iter());
|
||||
assert_eq!(&s[..], &sum[..]);
|
||||
}
|
||||
{
|
||||
@@ -193,8 +219,8 @@ fn split_off_to_loop() {
|
||||
let off = bytes.split_to(i);
|
||||
assert_eq!(i, off.len());
|
||||
let mut sum = Vec::new();
|
||||
sum.extend(&off);
|
||||
sum.extend(&bytes);
|
||||
sum.extend(off.iter());
|
||||
sum.extend(bytes.iter());
|
||||
assert_eq!(&s[..], &sum[..]);
|
||||
}
|
||||
{
|
||||
@@ -211,21 +237,21 @@ fn split_off_to_loop() {
|
||||
|
||||
#[test]
|
||||
fn split_to_1() {
|
||||
// Inline
|
||||
let mut a = Bytes::from(SHORT);
|
||||
// Static
|
||||
let mut a = Bytes::from_static(SHORT);
|
||||
let b = a.split_to(4);
|
||||
|
||||
assert_eq!(SHORT[4..], a);
|
||||
assert_eq!(SHORT[..4], b);
|
||||
|
||||
// Allocated
|
||||
let mut a = Bytes::from(LONG);
|
||||
let mut a = Bytes::copy_from_slice(LONG);
|
||||
let b = a.split_to(4);
|
||||
|
||||
assert_eq!(LONG[4..], a);
|
||||
assert_eq!(LONG[..4], b);
|
||||
|
||||
let mut a = Bytes::from(LONG);
|
||||
let mut a = Bytes::copy_from_slice(LONG);
|
||||
let b = a.split_to(30);
|
||||
|
||||
assert_eq!(LONG[30..], a);
|
||||
@@ -247,26 +273,21 @@ fn split_to_2() {
|
||||
#[should_panic]
|
||||
fn split_to_oob() {
|
||||
let mut hello = Bytes::from(&b"helloworld"[..]);
|
||||
hello.split_to(inline_cap() + 1);
|
||||
hello.split_to(33);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn split_to_oob_mut() {
|
||||
let mut hello = BytesMut::from(&b"helloworld"[..]);
|
||||
hello.split_to(inline_cap() + 1);
|
||||
hello.split_to(33);
|
||||
}
|
||||
|
||||
#[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]
|
||||
@@ -291,6 +312,24 @@ fn split_off_to_at_gt_len() {
|
||||
}).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn freeze_clone_shared() {
|
||||
let s = &b"abcdefgh"[..];
|
||||
let b = BytesMut::from(s).split().freeze();
|
||||
assert_eq!(b, s);
|
||||
let c = b.clone();
|
||||
assert_eq!(c, s);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn freeze_clone_unique() {
|
||||
let s = &b"abcdefgh"[..];
|
||||
let b = BytesMut::from(s).freeze();
|
||||
assert_eq!(b, s);
|
||||
let c = b.clone();
|
||||
assert_eq!(c, s);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fns_defined_for_bytes_mut() {
|
||||
let mut bytes = BytesMut::from(&b"hello world"[..]);
|
||||
@@ -299,30 +338,12 @@ fn fns_defined_for_bytes_mut() {
|
||||
bytes.as_mut_ptr();
|
||||
|
||||
// Iterator
|
||||
let v: Vec<u8> = bytes.iter().map(|b| *b).collect();
|
||||
let v: Vec<u8> = bytes.as_ref().iter().cloned().collect();
|
||||
assert_eq!(&v[..], bytes);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reserve_convert() {
|
||||
// Inline -> Vec
|
||||
let mut bytes = BytesMut::with_capacity(8);
|
||||
bytes.put("hello");
|
||||
bytes.reserve(40);
|
||||
assert_eq!(bytes.capacity(), 45);
|
||||
assert_eq!(bytes, "hello");
|
||||
|
||||
// Inline -> Inline
|
||||
let mut bytes = BytesMut::with_capacity(inline_cap());
|
||||
bytes.put("abcdefghijkl");
|
||||
|
||||
let a = bytes.split_to(10);
|
||||
bytes.reserve(inline_cap() - 3);
|
||||
assert_eq!(inline_cap(), bytes.capacity());
|
||||
|
||||
assert_eq!(bytes, "kl");
|
||||
assert_eq!(a, "abcdefghij");
|
||||
|
||||
// Vec -> Vec
|
||||
let mut bytes = BytesMut::from(LONG);
|
||||
bytes.reserve(64);
|
||||
@@ -341,8 +362,8 @@ fn reserve_convert() {
|
||||
#[test]
|
||||
fn reserve_growth() {
|
||||
let mut bytes = BytesMut::with_capacity(64);
|
||||
bytes.put("hello world");
|
||||
let _ = bytes.take();
|
||||
bytes.put("hello world".as_bytes());
|
||||
let _ = bytes.split();
|
||||
|
||||
bytes.reserve(65);
|
||||
assert_eq!(bytes.capacity(), 128);
|
||||
@@ -353,10 +374,10 @@ fn reserve_allocates_at_least_original_capacity() {
|
||||
let mut bytes = BytesMut::with_capacity(1024);
|
||||
|
||||
for i in 0..1020 {
|
||||
bytes.put(i as u8);
|
||||
bytes.put_u8(i as u8);
|
||||
}
|
||||
|
||||
let _other = bytes.take();
|
||||
let _other = bytes.split();
|
||||
|
||||
bytes.reserve(16);
|
||||
assert_eq!(bytes.capacity(), 1024);
|
||||
@@ -369,34 +390,33 @@ fn reserve_max_original_capacity_value() {
|
||||
let mut bytes = BytesMut::with_capacity(SIZE);
|
||||
|
||||
for _ in 0..SIZE {
|
||||
bytes.put(0u8);
|
||||
bytes.put_u8(0u8);
|
||||
}
|
||||
|
||||
let _other = bytes.take();
|
||||
let _other = bytes.split();
|
||||
|
||||
bytes.reserve(16);
|
||||
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));
|
||||
let mut bytes = BytesMut::with_capacity(16);
|
||||
assert_eq!(bytes.capacity(), 16);
|
||||
bytes.put("0123456789012345");
|
||||
let addr = bytes.as_ptr() as usize;
|
||||
bytes.put("0123456789012345".as_bytes());
|
||||
assert_eq!(bytes.as_ptr() as usize, addr);
|
||||
bytes.advance(10);
|
||||
assert_eq!(bytes.capacity(), 6);
|
||||
bytes.reserve(8);
|
||||
assert_eq!(bytes.capacity(), 16);
|
||||
assert_eq!(bytes.as_ptr() as usize, addr);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reserve_in_arc_unique_does_not_overallocate() {
|
||||
let mut bytes = BytesMut::with_capacity(1000);
|
||||
bytes.take();
|
||||
bytes.split();
|
||||
|
||||
// now bytes is Arc and refcount == 1
|
||||
|
||||
@@ -408,7 +428,7 @@ fn reserve_in_arc_unique_does_not_overallocate() {
|
||||
#[test]
|
||||
fn reserve_in_arc_unique_doubles() {
|
||||
let mut bytes = BytesMut::with_capacity(1000);
|
||||
bytes.take();
|
||||
bytes.split();
|
||||
|
||||
// now bytes is Arc and refcount == 1
|
||||
|
||||
@@ -420,7 +440,7 @@ fn reserve_in_arc_unique_doubles() {
|
||||
#[test]
|
||||
fn reserve_in_arc_nonunique_does_not_overallocate() {
|
||||
let mut bytes = BytesMut::with_capacity(1000);
|
||||
let _copy = bytes.take();
|
||||
let _copy = bytes.split();
|
||||
|
||||
// now bytes is Arc and refcount == 2
|
||||
|
||||
@@ -429,15 +449,6 @@ fn reserve_in_arc_nonunique_does_not_overallocate() {
|
||||
assert_eq!(2001, bytes.capacity());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inline_storage() {
|
||||
let mut bytes = BytesMut::with_capacity(inline_cap());
|
||||
let zero = [0u8; 64];
|
||||
|
||||
bytes.put(&zero[0..inline_cap()]);
|
||||
assert_eq!(*bytes, zero[0..inline_cap()]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extend_mut() {
|
||||
let mut bytes = BytesMut::with_capacity(0);
|
||||
@@ -445,13 +456,6 @@ fn extend_mut() {
|
||||
assert_eq!(*bytes, LONG[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extend_shr() {
|
||||
let mut bytes = Bytes::new();
|
||||
bytes.extend(LONG);
|
||||
assert_eq!(*bytes, LONG[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extend_from_slice_mut() {
|
||||
for &i in &[3, 34] {
|
||||
@@ -463,13 +467,13 @@ fn extend_from_slice_mut() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extend_from_slice_shr() {
|
||||
for &i in &[3, 34] {
|
||||
let mut bytes = Bytes::new();
|
||||
bytes.extend_from_slice(&LONG[..i]);
|
||||
bytes.extend_from_slice(&LONG[i..]);
|
||||
assert_eq!(LONG[..], *bytes);
|
||||
}
|
||||
fn extend_mut_without_size_hint() {
|
||||
let mut bytes = BytesMut::with_capacity(0);
|
||||
let mut long_iter = LONG.iter();
|
||||
|
||||
// Use iter::from_fn since it doesn't know a size_hint
|
||||
bytes.extend(std::iter::from_fn(|| long_iter.next()));
|
||||
assert_eq!(*bytes, LONG[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -481,13 +485,6 @@ 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");
|
||||
@@ -497,7 +494,20 @@ fn advance_static() {
|
||||
|
||||
#[test]
|
||||
fn advance_vec() {
|
||||
let mut a = BytesMut::from(b"hello world boooo yah world zomg wat wat".to_vec());
|
||||
let mut a = Bytes::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"[..]);
|
||||
|
||||
a.advance(6);
|
||||
assert_eq!(a, b"d zomg wat wat"[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn advance_bytes_mut() {
|
||||
let mut a = BytesMut::from("hello world boooo yah world zomg wat wat");
|
||||
a.advance(16);
|
||||
assert_eq!(a, b"o yah world zomg wat wat"[..]);
|
||||
|
||||
@@ -515,7 +525,7 @@ fn advance_vec() {
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn advance_past_len() {
|
||||
let mut a = BytesMut::from(b"hello world".to_vec());
|
||||
let mut a = BytesMut::from("hello world");
|
||||
a.advance(20);
|
||||
}
|
||||
|
||||
@@ -533,7 +543,7 @@ fn stress() {
|
||||
|
||||
for i in 0..ITERS {
|
||||
let data = [i as u8; 256];
|
||||
let buf = Arc::new(Bytes::from(&data[..]));
|
||||
let buf = Arc::new(Bytes::copy_from_slice(&data[..]));
|
||||
|
||||
let barrier = Arc::new(Barrier::new(THREADS));
|
||||
let mut joins = Vec::with_capacity(THREADS);
|
||||
@@ -568,8 +578,99 @@ fn partial_eq_bytesmut() {
|
||||
assert!(bytesmut != bytes2);
|
||||
}
|
||||
|
||||
/*
|
||||
#[test]
|
||||
fn unsplit_basic() {
|
||||
fn bytes_unsplit_basic() {
|
||||
let buf = Bytes::from(&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 bytes_unsplit_empty_other() {
|
||||
let buf = Bytes::from(&b"aaabbbcccddd"[..]);
|
||||
|
||||
// empty other
|
||||
let other = Bytes::new();
|
||||
|
||||
buf.unsplit(other);
|
||||
assert_eq!(b"aaabbbcccddd", &buf[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bytes_unsplit_empty_self() {
|
||||
// empty self
|
||||
let mut buf = Bytes::new();
|
||||
|
||||
let mut other = Bytes::with_capacity(64);
|
||||
other.extend_from_slice(b"aaabbbcccddd");
|
||||
|
||||
buf.unsplit(other);
|
||||
assert_eq!(b"aaabbbcccddd", &buf[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bytes_unsplit_arc_different() {
|
||||
let mut buf = Bytes::with_capacity(64);
|
||||
buf.extend_from_slice(b"aaaabbbbeeee");
|
||||
|
||||
buf.split_off(8); //arc
|
||||
|
||||
let mut buf2 = Bytes::with_capacity(64);
|
||||
buf2.extend_from_slice(b"ccccddddeeee");
|
||||
|
||||
buf2.split_off(8); //arc
|
||||
|
||||
buf.unsplit(buf2);
|
||||
assert_eq!(b"aaaabbbbccccdddd", &buf[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bytes_unsplit_arc_non_contiguous() {
|
||||
let mut buf = Bytes::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 bytes_unsplit_two_split_offs() {
|
||||
let mut buf = Bytes::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 bytes_unsplit_overlapping_references() {
|
||||
let mut buf = Bytes::with_capacity(64);
|
||||
buf.extend_from_slice(b"abcdefghijklmnopqrstuvwxyz");
|
||||
let mut buf0010 = buf.slice(0..10);
|
||||
let buf1020 = buf.slice(10..20);
|
||||
let buf0515 = buf.slice(5..15);
|
||||
buf0010.unsplit(buf1020);
|
||||
assert_eq!(b"abcdefghijklmnopqrst", &buf0010[..]);
|
||||
assert_eq!(b"fghijklmno", &buf0515[..]);
|
||||
}
|
||||
*/
|
||||
|
||||
#[test]
|
||||
fn bytes_mut_unsplit_basic() {
|
||||
let mut buf = BytesMut::with_capacity(64);
|
||||
buf.extend_from_slice(b"aaabbbcccddd");
|
||||
|
||||
@@ -582,7 +683,7 @@ fn unsplit_basic() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_empty_other() {
|
||||
fn bytes_mut_unsplit_empty_other() {
|
||||
let mut buf = BytesMut::with_capacity(64);
|
||||
buf.extend_from_slice(b"aaabbbcccddd");
|
||||
|
||||
@@ -594,7 +695,7 @@ fn unsplit_empty_other() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_empty_self() {
|
||||
fn bytes_mut_unsplit_empty_self() {
|
||||
// empty self
|
||||
let mut buf = BytesMut::new();
|
||||
|
||||
@@ -606,50 +707,7 @@ fn unsplit_empty_self() {
|
||||
}
|
||||
|
||||
#[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() {
|
||||
fn bytes_mut_unsplit_arc_different() {
|
||||
let mut buf = BytesMut::with_capacity(64);
|
||||
buf.extend_from_slice(b"aaaabbbbeeee");
|
||||
|
||||
@@ -665,7 +723,7 @@ fn unsplit_arc_different() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_arc_non_contiguous() {
|
||||
fn bytes_mut_unsplit_arc_non_contiguous() {
|
||||
let mut buf = BytesMut::with_capacity(64);
|
||||
buf.extend_from_slice(b"aaaabbbbeeeeccccdddd");
|
||||
|
||||
@@ -678,7 +736,7 @@ fn unsplit_arc_non_contiguous() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_two_split_offs() {
|
||||
fn bytes_mut_unsplit_two_split_offs() {
|
||||
let mut buf = BytesMut::with_capacity(64);
|
||||
buf.extend_from_slice(b"aaaabbbbccccdddd");
|
||||
|
||||
@@ -710,3 +768,88 @@ fn from_iter_no_size_hint() {
|
||||
|
||||
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::copy_from_slice(&b""[..]);
|
||||
let slice = &b""[0..0];
|
||||
|
||||
bytes.slice_ref(slice);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bytes_buf_mut_advance() {
|
||||
let mut bytes = BytesMut::with_capacity(1024);
|
||||
|
||||
unsafe {
|
||||
let ptr = bytes.bytes_mut().as_ptr();
|
||||
assert_eq!(1024, bytes.bytes_mut().len());
|
||||
|
||||
bytes.advance_mut(10);
|
||||
|
||||
let next = bytes.bytes_mut().as_ptr();
|
||||
assert_eq!(1024 - 10, bytes.bytes_mut().len());
|
||||
assert_eq!(ptr.offset(10), next);
|
||||
|
||||
// advance to the end
|
||||
bytes.advance_mut(1024 - 10);
|
||||
|
||||
// The buffer size is doubled
|
||||
assert_eq!(1024, bytes.bytes_mut().len());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn bytes_reserve_overflow() {
|
||||
let mut bytes = BytesMut::with_capacity(1024);
|
||||
bytes.put_slice(b"hello world");
|
||||
|
||||
bytes.reserve(usize::MAX);
|
||||
}
|
||||
|
||||
+71
-60
@@ -1,36 +1,31 @@
|
||||
extern crate bytes;
|
||||
extern crate iovec;
|
||||
#![deny(warnings, rust_2018_idioms)]
|
||||
|
||||
use bytes::{Buf, BufMut, Bytes, BytesMut};
|
||||
use bytes::buf::Chain;
|
||||
use iovec::IoVec;
|
||||
use std::io::Cursor;
|
||||
use bytes::{Buf, BufMut, Bytes};
|
||||
use bytes::buf::{BufExt, BufMutExt};
|
||||
use std::io::IoSlice;
|
||||
|
||||
#[test]
|
||||
fn collect_two_bufs() {
|
||||
let a = Cursor::new(Bytes::from(&b"hello"[..]));
|
||||
let b = Cursor::new(Bytes::from(&b"world"[..]));
|
||||
let a = Bytes::from(&b"hello"[..]);
|
||||
let b = Bytes::from(&b"world"[..]);
|
||||
|
||||
let res: Vec<u8> = a.chain(b).collect();
|
||||
let res = a.chain(b).to_bytes();
|
||||
assert_eq!(res, &b"helloworld"[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn writing_chained() {
|
||||
let mut a = BytesMut::with_capacity(64);
|
||||
let mut b = BytesMut::with_capacity(64);
|
||||
let mut a = [0u8; 64];
|
||||
let mut b = [0u8; 64];
|
||||
|
||||
{
|
||||
let mut buf = Chain::new(&mut a, &mut b);
|
||||
let mut buf = (&mut a[..]).chain_mut(&mut b[..]);
|
||||
|
||||
for i in 0..128 {
|
||||
buf.put(i as u8);
|
||||
for i in 0u8..128 {
|
||||
buf.put_u8(i);
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(64, a.len());
|
||||
assert_eq!(64, b.len());
|
||||
|
||||
for i in 0..64 {
|
||||
let expect = i as u8;
|
||||
assert_eq!(expect, a[i]);
|
||||
@@ -40,83 +35,99 @@ fn writing_chained() {
|
||||
|
||||
#[test]
|
||||
fn iterating_two_bufs() {
|
||||
let a = Cursor::new(Bytes::from(&b"hello"[..]));
|
||||
let b = Cursor::new(Bytes::from(&b"world"[..]));
|
||||
let a = Bytes::from(&b"hello"[..]);
|
||||
let b = Bytes::from(&b"world"[..]);
|
||||
|
||||
let res: Vec<u8> = a.chain(b).iter().collect();
|
||||
let res: Vec<u8> = a.chain(b).into_iter().collect();
|
||||
assert_eq!(res, &b"helloworld"[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vectored_read() {
|
||||
let a = Cursor::new(Bytes::from(&b"hello"[..]));
|
||||
let b = Cursor::new(Bytes::from(&b"world"[..]));
|
||||
let a = Bytes::from(&b"hello"[..]);
|
||||
let b = Bytes::from(&b"world"[..]);
|
||||
|
||||
let mut buf = a.chain(b);
|
||||
|
||||
{
|
||||
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()];
|
||||
let b1: &[u8] = &mut [];
|
||||
let b2: &[u8] = &mut [];
|
||||
let b3: &[u8] = &mut [];
|
||||
let b4: &[u8] = &mut [];
|
||||
let mut iovecs = [
|
||||
IoSlice::new(b1),
|
||||
IoSlice::new(b2),
|
||||
IoSlice::new(b3),
|
||||
IoSlice::new(b4),
|
||||
];
|
||||
|
||||
assert_eq!(2, buf.bytes_vec(&mut iovecs));
|
||||
assert_eq!(2, buf.bytes_vectored(&mut iovecs));
|
||||
assert_eq!(iovecs[0][..], b"hello"[..]);
|
||||
assert_eq!(iovecs[1][..], b"world"[..]);
|
||||
assert_eq!(iovecs[2][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[3][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[2][..], b""[..]);
|
||||
assert_eq!(iovecs[3][..], b""[..]);
|
||||
}
|
||||
|
||||
buf.advance(2);
|
||||
|
||||
{
|
||||
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()];
|
||||
let b1: &[u8] = &mut [];
|
||||
let b2: &[u8] = &mut [];
|
||||
let b3: &[u8] = &mut [];
|
||||
let b4: &[u8] = &mut [];
|
||||
let mut iovecs = [
|
||||
IoSlice::new(b1),
|
||||
IoSlice::new(b2),
|
||||
IoSlice::new(b3),
|
||||
IoSlice::new(b4),
|
||||
];
|
||||
|
||||
assert_eq!(2, buf.bytes_vec(&mut iovecs));
|
||||
assert_eq!(2, buf.bytes_vectored(&mut iovecs));
|
||||
assert_eq!(iovecs[0][..], b"llo"[..]);
|
||||
assert_eq!(iovecs[1][..], b"world"[..]);
|
||||
assert_eq!(iovecs[2][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[3][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[2][..], b""[..]);
|
||||
assert_eq!(iovecs[3][..], b""[..]);
|
||||
}
|
||||
|
||||
buf.advance(3);
|
||||
|
||||
{
|
||||
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()];
|
||||
let b1: &[u8] = &mut [];
|
||||
let b2: &[u8] = &mut [];
|
||||
let b3: &[u8] = &mut [];
|
||||
let b4: &[u8] = &mut [];
|
||||
let mut iovecs = [
|
||||
IoSlice::new(b1),
|
||||
IoSlice::new(b2),
|
||||
IoSlice::new(b3),
|
||||
IoSlice::new(b4),
|
||||
];
|
||||
|
||||
assert_eq!(1, buf.bytes_vec(&mut iovecs));
|
||||
assert_eq!(1, buf.bytes_vectored(&mut iovecs));
|
||||
assert_eq!(iovecs[0][..], b"world"[..]);
|
||||
assert_eq!(iovecs[1][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[2][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[3][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[1][..], b""[..]);
|
||||
assert_eq!(iovecs[2][..], b""[..]);
|
||||
assert_eq!(iovecs[3][..], b""[..]);
|
||||
}
|
||||
|
||||
buf.advance(3);
|
||||
|
||||
{
|
||||
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()];
|
||||
let b1: &[u8] = &mut [];
|
||||
let b2: &[u8] = &mut [];
|
||||
let b3: &[u8] = &mut [];
|
||||
let b4: &[u8] = &mut [];
|
||||
let mut iovecs = [
|
||||
IoSlice::new(b1),
|
||||
IoSlice::new(b2),
|
||||
IoSlice::new(b3),
|
||||
IoSlice::new(b4),
|
||||
];
|
||||
|
||||
assert_eq!(1, buf.bytes_vec(&mut iovecs));
|
||||
assert_eq!(1, buf.bytes_vectored(&mut iovecs));
|
||||
assert_eq!(iovecs[0][..], b"ld"[..]);
|
||||
assert_eq!(iovecs[1][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[2][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[3][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[1][..], b""[..]);
|
||||
assert_eq!(iovecs[2][..], b""[..]);
|
||||
assert_eq!(iovecs[3][..], b""[..]);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
extern crate bytes;
|
||||
#![deny(warnings, rust_2018_idioms)]
|
||||
|
||||
use bytes::Bytes;
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
extern crate bytes;
|
||||
|
||||
use bytes::{Buf, Bytes, BytesMut};
|
||||
use std::io::Cursor;
|
||||
|
||||
const LONG: &'static [u8] = b"mary had a little lamb, little lamb, little lamb";
|
||||
const SHORT: &'static [u8] = b"hello world";
|
||||
|
||||
#[test]
|
||||
fn collect_to_vec() {
|
||||
let buf: Vec<u8> = Cursor::new(SHORT).collect();
|
||||
assert_eq!(buf, SHORT);
|
||||
|
||||
let buf: Vec<u8> = Cursor::new(LONG).collect();
|
||||
assert_eq!(buf, LONG);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn collect_to_bytes() {
|
||||
let buf: Bytes = Cursor::new(SHORT).collect();
|
||||
assert_eq!(buf, SHORT);
|
||||
|
||||
let buf: Bytes = Cursor::new(LONG).collect();
|
||||
assert_eq!(buf, LONG);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn collect_to_bytes_mut() {
|
||||
let buf: BytesMut = Cursor::new(SHORT).collect();
|
||||
assert_eq!(buf, SHORT);
|
||||
|
||||
let buf: BytesMut = Cursor::new(LONG).collect();
|
||||
assert_eq!(buf, LONG);
|
||||
}
|
||||
+4
-4
@@ -1,10 +1,10 @@
|
||||
extern crate bytes;
|
||||
#![deny(warnings, rust_2018_idioms)]
|
||||
|
||||
use bytes::{Buf, IntoBuf, Bytes};
|
||||
use bytes::Bytes;
|
||||
|
||||
#[test]
|
||||
fn iter_len() {
|
||||
let buf = Bytes::from(&b"hello world"[..]).into_buf();
|
||||
let buf = Bytes::from_static(b"hello world");
|
||||
let iter = buf.iter();
|
||||
|
||||
assert_eq!(iter.size_hint(), (11, Some(11)));
|
||||
@@ -14,7 +14,7 @@ fn iter_len() {
|
||||
|
||||
#[test]
|
||||
fn empty_iter_len() {
|
||||
let buf = Bytes::from(&b""[..]).into_buf();
|
||||
let buf = Bytes::from_static(b"");
|
||||
let iter = buf.iter();
|
||||
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#![deny(warnings, rust_2018_idioms)]
|
||||
|
||||
use std::io::{BufRead, Read};
|
||||
|
||||
use bytes::buf::{BufExt};
|
||||
|
||||
#[test]
|
||||
fn read() {
|
||||
let buf1 = &b"hello "[..];
|
||||
let buf2 = &b"world"[..];
|
||||
let buf = BufExt::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 = &b"hell"[..];
|
||||
let buf2 = &b"o\nworld"[..];
|
||||
let mut reader = BufExt::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);
|
||||
}
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
#![cfg(feature = "serde")]
|
||||
#![deny(warnings, rust_2018_idioms)]
|
||||
|
||||
extern crate bytes;
|
||||
extern crate serde_test;
|
||||
use serde_test::{Token, assert_tokens};
|
||||
|
||||
#[test]
|
||||
|
||||
+4
-5
@@ -1,13 +1,12 @@
|
||||
extern crate bytes;
|
||||
#![deny(warnings, rust_2018_idioms)]
|
||||
|
||||
use bytes::Buf;
|
||||
use std::io::Cursor;
|
||||
use bytes::buf::{Buf, BufExt};
|
||||
|
||||
#[test]
|
||||
fn long_take() {
|
||||
// Tests that take with a size greater than the buffer length will not
|
||||
// Tests that get a take with a size greater than the buffer length will not
|
||||
// overrun the buffer. Regression test for #138.
|
||||
let buf = Cursor::new(b"hello world").take(100);
|
||||
let buf = b"hello world".take(100);
|
||||
assert_eq!(11, buf.remaining());
|
||||
assert_eq!(b"hello world", buf.bytes());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user