mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-08 00:00:26 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d43e283e5e | ||
|
|
e0e30f00a1 | ||
|
|
4948b1053b | ||
|
|
0e8b440650 | ||
|
|
e13d2a783e | ||
|
|
55dfea8c18 | ||
|
|
f3b363a385 | ||
|
|
42b669690a | ||
|
|
9504447adc | ||
|
|
b3248c8807 | ||
|
|
c6c5b8fb54 | ||
|
|
7c3085aaec | ||
|
|
e64a123d00 | ||
|
|
e5304410a4 | ||
|
|
456221d165 | ||
|
|
f09c51c34e | ||
|
|
ad35fbef03 | ||
|
|
79f05591c9 | ||
|
|
ed244d3b54 | ||
|
|
890812af1b | ||
|
|
052648c3f5 | ||
|
|
042aa9023b | ||
|
|
886dda0962 | ||
|
|
6414efe83b | ||
|
|
7785cde587 | ||
|
|
a6b9844296 | ||
|
|
406b048ae6 | ||
|
|
8c041142a0 | ||
|
|
e9a7098658 | ||
|
|
32ea8281b3 | ||
|
|
dfce95b89d | ||
|
|
b68fa46e3d | ||
|
|
ef09e98fbc | ||
|
|
51e435b7e0 | ||
|
|
15050b1da5 | ||
|
|
ce79f0a268 | ||
|
|
86c83959dc | ||
|
|
e5c4c6028d | ||
|
|
ba9a975358 | ||
|
|
6a3d20bb8d | ||
|
|
2ca61d881d | ||
|
|
8d6c2b61cc | ||
|
|
02891144be | ||
|
|
149922d7cf | ||
|
|
03d501b18d | ||
|
|
34540be54c | ||
|
|
cfca1c04fa |
+31
@@ -36,6 +36,37 @@ matrix:
|
||||
# Serde implementation
|
||||
- env: EXTRA_ARGS="--features serde"
|
||||
|
||||
# 128 bit numbers
|
||||
- env: EXTRA_ARGS="--features i128"
|
||||
|
||||
# `Either` impls
|
||||
- env: EXTRA_ARGS="--features either"
|
||||
|
||||
# WASM support
|
||||
- rust: beta
|
||||
script:
|
||||
- rustup target add wasm32-unknown-unknown
|
||||
- cargo build --target=wasm32-unknown-unknown
|
||||
|
||||
# Sanitizers
|
||||
- rust: nightly
|
||||
os: linux
|
||||
script:
|
||||
- |
|
||||
set -e
|
||||
|
||||
export RUST_TEST_THREADS=1
|
||||
export ASAN_OPTIONS="detect_odr_violation=0 detect_leaks=0"
|
||||
export TSAN_OPTIONS="suppressions=`pwd`/ci/tsan"
|
||||
|
||||
# Run address sanitizer
|
||||
RUSTFLAGS="-Z sanitizer=address" \
|
||||
cargo test --tests --target x86_64-unknown-linux-gnu
|
||||
|
||||
# Run thread sanitizer
|
||||
RUSTFLAGS="-Z sanitizer=thread" \
|
||||
cargo test --tests --target x86_64-unknown-linux-gnu
|
||||
|
||||
before_install: set -e
|
||||
|
||||
install:
|
||||
|
||||
@@ -1,3 +1,44 @@
|
||||
# 0.4.12 (March 6, 2019)
|
||||
|
||||
### Added
|
||||
- Implement `FromIterator<&'a u8>` for `BytesMut`/`Bytes` (#244).
|
||||
- Implement `Buf` for `VecDeque` (#249).
|
||||
|
||||
# 0.4.11 (November 17, 2018)
|
||||
|
||||
* Use raw pointers for potentially racy loads (#233).
|
||||
* Implement `BufRead` for `buf::Reader` (#232).
|
||||
* Documentation tweaks (#234).
|
||||
|
||||
# 0.4.10 (September 4, 2018)
|
||||
|
||||
* impl `Buf` and `BufMut` for `Either` (#225).
|
||||
* Add `Bytes::slice_ref` (#208).
|
||||
|
||||
# 0.4.9 (July 12, 2018)
|
||||
|
||||
* Add 128 bit number support behind a feature flag (#209).
|
||||
* Implement `IntoBuf` for `&mut [u8]`
|
||||
|
||||
# 0.4.8 (May 25, 2018)
|
||||
|
||||
* Fix panic in `BytesMut` `FromIterator` implementation.
|
||||
* Bytes: Recycle space when reserving space in vec mode (#197).
|
||||
* Bytes: Add resize fn (#203).
|
||||
|
||||
# 0.4.7 (April 27, 2018)
|
||||
|
||||
* Make `Buf` and `BufMut` usable as trait objects (#186).
|
||||
* impl BorrowMut for BytesMut (#185).
|
||||
* Improve accessor performance (#195).
|
||||
|
||||
# 0.4.6 (Janary 8, 2018)
|
||||
|
||||
* Implement FromIterator for Bytes/BytesMut (#148).
|
||||
* Add `advance` fn to Bytes/BytesMut (#166).
|
||||
* Add `unsplit` fn to `BytesMut` (#162, #173).
|
||||
* Improvements to Bytes split fns (#92).
|
||||
|
||||
# 0.4.5 (August 12, 2017)
|
||||
|
||||
* Fix range bug in `Take::bytes`
|
||||
|
||||
+16
-4
@@ -1,11 +1,16 @@
|
||||
[package]
|
||||
|
||||
name = "bytes"
|
||||
version = "0.4.5"
|
||||
license = "MIT/Apache-2.0"
|
||||
# When releasing to crates.io:
|
||||
# - Update html_root_url.
|
||||
# - Update CHANGELOG.md.
|
||||
# - Update doc URL.
|
||||
# - Create "v0.4.x" git tag.
|
||||
version = "0.4.12"
|
||||
license = "MIT"
|
||||
authors = ["Carl Lerche <[email protected]>"]
|
||||
description = "Types and traits for working with bytes"
|
||||
documentation = "https://carllerche.github.io/bytes/bytes"
|
||||
documentation = "https://docs.rs/bytes/0.4.12/bytes"
|
||||
homepage = "https://github.com/carllerche/bytes"
|
||||
repository = "https://github.com/carllerche/bytes"
|
||||
readme = "README.md"
|
||||
@@ -19,10 +24,17 @@ exclude = [
|
||||
]
|
||||
categories = ["network-programming", "data-structures"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["i128"]
|
||||
|
||||
[dependencies]
|
||||
byteorder = "1.0.0"
|
||||
byteorder = "1.1.0"
|
||||
iovec = "0.1"
|
||||
serde = { version = "1.0", optional = true }
|
||||
either = { version = "1.5", default-features = false, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
serde_test = "1.0"
|
||||
|
||||
[features]
|
||||
i128 = ["byteorder/i128"]
|
||||
|
||||
@@ -1,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.
|
||||
@@ -5,7 +5,7 @@ A utility library for working with bytes.
|
||||
[](https://crates.io/crates/bytes)
|
||||
[](https://travis-ci.org/carllerche/bytes)
|
||||
|
||||
[Documentation](https://carllerche.github.io/bytes/bytes/index.html)
|
||||
[Documentation](https://docs.rs/bytes/0.4.12/bytes/)
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -13,7 +13,7 @@ To use `bytes`, first add this to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
bytes = "0.4"
|
||||
bytes = "0.4.12"
|
||||
```
|
||||
|
||||
Next, add this to your crate:
|
||||
@@ -30,13 +30,16 @@ Serde support is optional and disabled by default. To enable use the feature `se
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
bytes = { version = "0.4", features = ["serde"] }
|
||||
bytes = { version = "0.4.12", features = ["serde"] }
|
||||
```
|
||||
|
||||
# License
|
||||
## License
|
||||
|
||||
`bytes` is primarily distributed under the terms of both the MIT license and the
|
||||
Apache License (Version 2.0), with portions covered by various BSD-like
|
||||
licenses.
|
||||
This project is licensed under the [MIT license](LICENSE).
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in `bytes` by you, shall be licensed as MIT, without any additional
|
||||
terms or conditions.
|
||||
|
||||
See LICENSE-APACHE, and LICENSE-MIT for details.
|
||||
|
||||
@@ -29,6 +29,18 @@ fn alloc_big(b: &mut Bencher) {
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn split_off_and_drop(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
for _ in 0..1024 {
|
||||
let v = vec![10; 200];
|
||||
let mut b = Bytes::from(v);
|
||||
test::black_box(b.split_off(100));
|
||||
test::black_box(b);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn deref_unique(b: &mut Bencher) {
|
||||
let mut buf = BytesMut::with_capacity(4096);
|
||||
@@ -101,6 +113,39 @@ fn deref_two(b: &mut Bencher) {
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn clone_inline(b: &mut Bencher) {
|
||||
let bytes = Bytes::from_static(b"hello world");
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..1024 {
|
||||
test::black_box(&bytes.clone());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn clone_static(b: &mut Bencher) {
|
||||
let bytes = Bytes::from_static("hello world 1234567890 and have a good byte 0987654321".as_bytes());
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..1024 {
|
||||
test::black_box(&bytes.clone());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn clone_arc(b: &mut Bencher) {
|
||||
let bytes = Bytes::from("hello world 1234567890 and have a good byte 0987654321".as_bytes());
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..1024 {
|
||||
test::black_box(&bytes.clone());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn alloc_write_split_to_mid(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# TSAN suppressions file for `bytes`
|
||||
|
||||
# TSAN does not understand fences and `Arc::drop` is implemented using a fence.
|
||||
# This causes many false positives.
|
||||
race:Arc*drop
|
||||
race:arc*Weak*drop
|
||||
|
||||
# `std` mpsc is not used in any Bytes code base. This race is triggered by some
|
||||
# rust runtime logic.
|
||||
race:std*mpsc_queue
|
||||
|
||||
# Some test runtime races. Allocation should be race free
|
||||
race:alloc::alloc
|
||||
|
||||
# Not sure why this is warning, but it is in the test harness and not the library.
|
||||
race:TestEvent*clone
|
||||
race:test::run_tests_console::*closure
|
||||
|
||||
# Probably more fences in std.
|
||||
race:__call_tls_dtors
|
||||
|
||||
# `is_inline_or_static` is explicitly called concurrently without synchronization.
|
||||
# The safety explanation can be found in a comment.
|
||||
race:Inner::is_inline_or_static
|
||||
|
||||
# This ignores a false positive caused by `thread::park()`/`thread::unpark()`.
|
||||
# See: https://github.com/rust-lang/rust/pull/54806#issuecomment-436193353
|
||||
race:pthread_cond_destroy
|
||||
+549
-146
@@ -1,9 +1,41 @@
|
||||
use super::{IntoBuf, Take, Reader, Iter, FromBuf, Chain};
|
||||
use byteorder::ByteOrder;
|
||||
use byteorder::{BigEndian, ByteOrder, LittleEndian};
|
||||
use iovec::IoVec;
|
||||
|
||||
use std::{cmp, io, ptr};
|
||||
|
||||
macro_rules! buf_get_impl {
|
||||
($this:ident, $size:expr, $conv:path) => ({
|
||||
// try to convert directly from the bytes
|
||||
let ret = {
|
||||
// this Option<ret> trick is to avoid keeping a borrow on self
|
||||
// when advance() is called (mut borrow) and to call bytes() only once
|
||||
if let Some(src) = $this.bytes().get(..($size)) {
|
||||
Some($conv(src))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
if let Some(ret) = ret {
|
||||
// if the direct convertion was possible, advance and return
|
||||
$this.advance($size);
|
||||
return ret;
|
||||
} else {
|
||||
// if not we copy the bytes in a temp buffer then convert
|
||||
let mut buf = [0; ($size)];
|
||||
$this.copy_to_slice(&mut buf); // (do the advance)
|
||||
return $conv(&buf);
|
||||
}
|
||||
});
|
||||
($this:ident, $buf_size:expr, $conv:path, $len_to_read:expr) => ({
|
||||
// The same trick as above does not improve the best case speed.
|
||||
// It seems to be linked to the way the method is optimised by the compiler
|
||||
let mut buf = [0; ($buf_size)];
|
||||
$this.copy_to_slice(&mut buf[..($len_to_read)]);
|
||||
return $conv(&buf[..($len_to_read)], $len_to_read);
|
||||
});
|
||||
}
|
||||
|
||||
/// Read bytes from a buffer.
|
||||
///
|
||||
/// A buffer stores bytes in memory such that read operations are infallible.
|
||||
@@ -59,7 +91,8 @@ pub trait Buf {
|
||||
fn remaining(&self) -> usize;
|
||||
|
||||
/// Returns a slice starting at the current position and of length between 0
|
||||
/// and `Buf::remaining()`.
|
||||
/// and `Buf::remaining()`. Note that this *can* return shorter slice (this allows
|
||||
/// non-continuous internal representation).
|
||||
///
|
||||
/// This is a lower level function. Most operations are done with other
|
||||
/// functions.
|
||||
@@ -243,9 +276,10 @@ pub trait Buf {
|
||||
///
|
||||
/// This function panics if there is no more remaining data in `self`.
|
||||
fn get_u8(&mut self) -> u8 {
|
||||
let mut buf = [0; 1];
|
||||
self.copy_to_slice(&mut buf);
|
||||
buf[0]
|
||||
assert!(self.remaining() >= 1);
|
||||
let ret = self.bytes()[0];
|
||||
self.advance(1);
|
||||
ret
|
||||
}
|
||||
|
||||
/// Gets a signed 8 bit integer from `self`.
|
||||
@@ -266,243 +300,608 @@ pub trait Buf {
|
||||
///
|
||||
/// This function panics if there is no more remaining data in `self`.
|
||||
fn get_i8(&mut self) -> i8 {
|
||||
let mut buf = [0; 1];
|
||||
self.copy_to_slice(&mut buf);
|
||||
buf[0] as i8
|
||||
assert!(self.remaining() >= 1);
|
||||
let ret = self.bytes()[0] as i8;
|
||||
self.advance(1);
|
||||
ret
|
||||
}
|
||||
|
||||
/// Gets an unsigned 16 bit integer from `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x08\x09 hello");
|
||||
/// assert_eq!(0x0809, buf.get_u16::<BigEndian>());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_u16<T: ByteOrder>(&mut self) -> u16 {
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use get_u16_be or get_u16_le")]
|
||||
fn get_u16<T: ByteOrder>(&mut self) -> u16 where Self: Sized {
|
||||
let mut buf = [0; 2];
|
||||
self.copy_to_slice(&mut buf);
|
||||
T::read_u16(&buf)
|
||||
}
|
||||
|
||||
/// Gets a signed 16 bit integer from `self` in the specified byte order.
|
||||
/// Gets an unsigned 16 bit integer from `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x08\x09 hello");
|
||||
/// assert_eq!(0x0809, buf.get_i16::<BigEndian>());
|
||||
/// assert_eq!(0x0809, buf.get_u16_be());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_i16<T: ByteOrder>(&mut self) -> i16 {
|
||||
fn get_u16_be(&mut self) -> u16 {
|
||||
buf_get_impl!(self, 2, BigEndian::read_u16);
|
||||
}
|
||||
|
||||
/// Gets an unsigned 16 bit integer from `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x09\x08 hello");
|
||||
/// assert_eq!(0x0809, buf.get_u16_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_u16_le(&mut self) -> u16 {
|
||||
buf_get_impl!(self, 2, LittleEndian::read_u16);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use get_i16_be or get_i16_le")]
|
||||
fn get_i16<T: ByteOrder>(&mut self) -> i16 where Self: Sized {
|
||||
let mut buf = [0; 2];
|
||||
self.copy_to_slice(&mut buf);
|
||||
T::read_i16(&buf)
|
||||
}
|
||||
|
||||
/// Gets an unsigned 32 bit integer from `self` in the specified byte order.
|
||||
/// Gets a signed 16 bit integer from `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x08\x09\xA0\xA1 hello");
|
||||
/// assert_eq!(0x0809A0A1, buf.get_u32::<BigEndian>());
|
||||
/// let mut buf = Cursor::new(b"\x08\x09 hello");
|
||||
/// assert_eq!(0x0809, buf.get_i16_be());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_u32<T: ByteOrder>(&mut self) -> u32 {
|
||||
fn get_i16_be(&mut self) -> i16 {
|
||||
buf_get_impl!(self, 2, BigEndian::read_i16);
|
||||
}
|
||||
|
||||
/// Gets a signed 16 bit integer from `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x09\x08 hello");
|
||||
/// assert_eq!(0x0809, buf.get_i16_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_i16_le(&mut self) -> i16 {
|
||||
buf_get_impl!(self, 2, LittleEndian::read_i16);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use get_u32_be or get_u32_le")]
|
||||
fn get_u32<T: ByteOrder>(&mut self) -> u32 where Self: Sized {
|
||||
let mut buf = [0; 4];
|
||||
self.copy_to_slice(&mut buf);
|
||||
T::read_u32(&buf)
|
||||
}
|
||||
|
||||
/// Gets a signed 32 bit integer from `self` in the specified byte order.
|
||||
/// Gets an unsigned 32 bit integer from `self` in the big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x08\x09\xA0\xA1 hello");
|
||||
/// assert_eq!(0x0809A0A1, buf.get_i32::<BigEndian>());
|
||||
/// assert_eq!(0x0809A0A1, buf.get_u32_be());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_i32<T: ByteOrder>(&mut self) -> i32 {
|
||||
fn get_u32_be(&mut self) -> u32 {
|
||||
buf_get_impl!(self, 4, BigEndian::read_u32);
|
||||
}
|
||||
|
||||
/// Gets an unsigned 32 bit integer from `self` in the little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\xA1\xA0\x09\x08 hello");
|
||||
/// assert_eq!(0x0809A0A1, buf.get_u32_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_u32_le(&mut self) -> u32 {
|
||||
buf_get_impl!(self, 4, LittleEndian::read_u32);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use get_i32_be or get_i32_le")]
|
||||
fn get_i32<T: ByteOrder>(&mut self) -> i32 where Self: Sized {
|
||||
let mut buf = [0; 4];
|
||||
self.copy_to_slice(&mut buf);
|
||||
T::read_i32(&buf)
|
||||
}
|
||||
|
||||
/// Gets an unsigned 64 bit integer from `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08 hello");
|
||||
/// assert_eq!(0x0102030405060708, buf.get_u64::<BigEndian>());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_u64<T: ByteOrder>(&mut self) -> u64 {
|
||||
let mut buf = [0; 8];
|
||||
self.copy_to_slice(&mut buf);
|
||||
T::read_u64(&buf)
|
||||
}
|
||||
|
||||
/// Gets a signed 64 bit integer from `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08 hello");
|
||||
/// assert_eq!(0x0102030405060708, buf.get_i64::<BigEndian>());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_i64<T: ByteOrder>(&mut self) -> i64 {
|
||||
let mut buf = [0; 8];
|
||||
self.copy_to_slice(&mut buf);
|
||||
T::read_i64(&buf)
|
||||
}
|
||||
|
||||
/// Gets an unsigned n-byte integer from `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x01\x02\x03 hello");
|
||||
/// assert_eq!(0x010203, buf.get_uint::<BigEndian>(3));
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_uint<T: ByteOrder>(&mut self, nbytes: usize) -> u64 {
|
||||
let mut buf = [0; 8];
|
||||
self.copy_to_slice(&mut buf[..nbytes]);
|
||||
T::read_uint(&buf[..nbytes], nbytes)
|
||||
}
|
||||
|
||||
/// Gets a signed n-byte integer from `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x01\x02\x03 hello");
|
||||
/// assert_eq!(0x010203, buf.get_int::<BigEndian>(3));
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_int<T: ByteOrder>(&mut self, nbytes: usize) -> i64 {
|
||||
let mut buf = [0; 8];
|
||||
self.copy_to_slice(&mut buf[..nbytes]);
|
||||
T::read_int(&buf[..nbytes], nbytes)
|
||||
}
|
||||
|
||||
/// Gets an IEEE754 single-precision (4 bytes) floating point number from
|
||||
/// `self` in the specified byte order.
|
||||
/// Gets a signed 32 bit integer from `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x3F\x99\x99\x9A hello");
|
||||
/// assert_eq!(1.2f32, buf.get_f32::<BigEndian>());
|
||||
/// let mut buf = Cursor::new(b"\x08\x09\xA0\xA1 hello");
|
||||
/// assert_eq!(0x0809A0A1, buf.get_i32_be());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_f32<T: ByteOrder>(&mut self) -> f32 {
|
||||
let mut buf = [0; 4];
|
||||
self.copy_to_slice(&mut buf);
|
||||
T::read_f32(&buf)
|
||||
fn get_i32_be(&mut self) -> i32 {
|
||||
buf_get_impl!(self, 4, BigEndian::read_i32);
|
||||
}
|
||||
|
||||
/// Gets an IEEE754 double-precision (8 bytes) floating point number from
|
||||
/// `self` in the specified byte order.
|
||||
/// Gets a signed 32 bit integer from `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\xA1\xA0\x09\x08 hello");
|
||||
/// assert_eq!(0x0809A0A1, buf.get_i32_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_i32_le(&mut self) -> i32 {
|
||||
buf_get_impl!(self, 4, LittleEndian::read_i32);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use get_u64_be or get_u64_le")]
|
||||
fn get_u64<T: ByteOrder>(&mut self) -> u64 where Self: Sized {
|
||||
let mut buf = [0; 8];
|
||||
self.copy_to_slice(&mut buf);
|
||||
T::read_u64(&buf)
|
||||
}
|
||||
|
||||
/// Gets an unsigned 64 bit integer from `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08 hello");
|
||||
/// assert_eq!(0x0102030405060708, buf.get_u64_be());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_u64_be(&mut self) -> u64 {
|
||||
buf_get_impl!(self, 8, BigEndian::read_u64);
|
||||
}
|
||||
|
||||
/// Gets an unsigned 64 bit integer from `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x08\x07\x06\x05\x04\x03\x02\x01 hello");
|
||||
/// assert_eq!(0x0102030405060708, buf.get_u64_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_u64_le(&mut self) -> u64 {
|
||||
buf_get_impl!(self, 8, LittleEndian::read_u64);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use get_i64_be or get_i64_le")]
|
||||
fn get_i64<T: ByteOrder>(&mut self) -> i64 where Self: Sized {
|
||||
let mut buf = [0; 8];
|
||||
self.copy_to_slice(&mut buf);
|
||||
T::read_i64(&buf)
|
||||
}
|
||||
|
||||
/// Gets a signed 64 bit integer from `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08 hello");
|
||||
/// assert_eq!(0x0102030405060708, buf.get_i64_be());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_i64_be(&mut self) -> i64 {
|
||||
buf_get_impl!(self, 8, BigEndian::read_i64);
|
||||
}
|
||||
|
||||
/// Gets a signed 64 bit integer from `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x08\x07\x06\x05\x04\x03\x02\x01 hello");
|
||||
/// assert_eq!(0x0102030405060708, buf.get_i64_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_i64_le(&mut self) -> i64 {
|
||||
buf_get_impl!(self, 8, LittleEndian::read_i64);
|
||||
}
|
||||
|
||||
/// Gets an unsigned 128 bit integer from `self` in big-endian byte order.
|
||||
///
|
||||
/// **NOTE:** This method requires the `i128` feature.
|
||||
/// The current position is advanced by 16.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello");
|
||||
/// assert_eq!(0x01020304050607080910111213141516, buf.get_u128_be());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
#[cfg(feature = "i128")]
|
||||
fn get_u128_be(&mut self) -> u128 {
|
||||
buf_get_impl!(self, 16, BigEndian::read_u128);
|
||||
}
|
||||
|
||||
/// Gets an unsigned 128 bit integer from `self` in little-endian byte order.
|
||||
///
|
||||
/// **NOTE:** This method requires the `i128` feature.
|
||||
/// The current position is advanced by 16.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello");
|
||||
/// assert_eq!(0x01020304050607080910111213141516, buf.get_u128_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
#[cfg(feature = "i128")]
|
||||
fn get_u128_le(&mut self) -> u128 {
|
||||
buf_get_impl!(self, 16, LittleEndian::read_u128);
|
||||
}
|
||||
|
||||
/// Gets a signed 128 bit integer from `self` in big-endian byte order.
|
||||
///
|
||||
/// **NOTE:** This method requires the `i128` feature.
|
||||
/// The current position is advanced by 16.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello");
|
||||
/// assert_eq!(0x01020304050607080910111213141516, buf.get_i128_be());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
#[cfg(feature = "i128")]
|
||||
fn get_i128_be(&mut self) -> i128 {
|
||||
buf_get_impl!(self, 16, BigEndian::read_i128);
|
||||
}
|
||||
|
||||
/// Gets a signed 128 bit integer from `self` in little-endian byte order.
|
||||
///
|
||||
/// **NOTE:** This method requires the `i128` feature.
|
||||
/// The current position is advanced by 16.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello");
|
||||
/// assert_eq!(0x01020304050607080910111213141516, buf.get_i128_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
#[cfg(feature = "i128")]
|
||||
fn get_i128_le(&mut self) -> i128 {
|
||||
buf_get_impl!(self, 16, LittleEndian::read_i128);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use get_uint_be or get_uint_le")]
|
||||
fn get_uint<T: ByteOrder>(&mut self, nbytes: usize) -> u64 where Self: Sized {
|
||||
let mut buf = [0; 8];
|
||||
self.copy_to_slice(&mut buf[..nbytes]);
|
||||
T::read_uint(&buf[..nbytes], nbytes)
|
||||
}
|
||||
|
||||
/// Gets an unsigned n-byte integer from `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BigEndian};
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello");
|
||||
/// assert_eq!(1.2f64, buf.get_f64::<BigEndian>());
|
||||
/// let mut buf = Cursor::new(b"\x01\x02\x03 hello");
|
||||
/// assert_eq!(0x010203, buf.get_uint_be(3));
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_f64<T: ByteOrder>(&mut self) -> f64 {
|
||||
fn get_uint_be(&mut self, nbytes: usize) -> u64 {
|
||||
buf_get_impl!(self, 8, BigEndian::read_uint, nbytes);
|
||||
}
|
||||
|
||||
/// Gets an unsigned n-byte integer from `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x03\x02\x01 hello");
|
||||
/// assert_eq!(0x010203, buf.get_uint_le(3));
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_uint_le(&mut self, nbytes: usize) -> u64 {
|
||||
buf_get_impl!(self, 8, LittleEndian::read_uint, nbytes);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use get_int_be or get_int_le")]
|
||||
fn get_int<T: ByteOrder>(&mut self, nbytes: usize) -> i64 where Self: Sized {
|
||||
let mut buf = [0; 8];
|
||||
self.copy_to_slice(&mut buf[..nbytes]);
|
||||
T::read_int(&buf[..nbytes], nbytes)
|
||||
}
|
||||
|
||||
/// Gets a signed n-byte integer from `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x01\x02\x03 hello");
|
||||
/// assert_eq!(0x010203, buf.get_int_be(3));
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_int_be(&mut self, nbytes: usize) -> i64 {
|
||||
buf_get_impl!(self, 8, BigEndian::read_int, nbytes);
|
||||
}
|
||||
|
||||
/// Gets a signed n-byte integer from `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x03\x02\x01 hello");
|
||||
/// assert_eq!(0x010203, buf.get_int_le(3));
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_int_le(&mut self, nbytes: usize) -> i64 {
|
||||
buf_get_impl!(self, 8, LittleEndian::read_int, nbytes);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use get_f32_be or get_f32_le")]
|
||||
fn get_f32<T: ByteOrder>(&mut self) -> f32 where Self: Sized {
|
||||
let mut buf = [0; 4];
|
||||
self.copy_to_slice(&mut buf);
|
||||
T::read_f32(&buf)
|
||||
}
|
||||
|
||||
/// Gets an IEEE754 single-precision (4 bytes) floating point number from
|
||||
/// `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x3F\x99\x99\x9A hello");
|
||||
/// assert_eq!(1.2f32, buf.get_f32_be());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_f32_be(&mut self) -> f32 {
|
||||
buf_get_impl!(self, 4, BigEndian::read_f32);
|
||||
}
|
||||
|
||||
/// Gets an IEEE754 single-precision (4 bytes) floating point number from
|
||||
/// `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x9A\x99\x99\x3F hello");
|
||||
/// assert_eq!(1.2f32, buf.get_f32_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_f32_le(&mut self) -> f32 {
|
||||
buf_get_impl!(self, 4, LittleEndian::read_f32);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use get_f64_be or get_f64_le")]
|
||||
fn get_f64<T: ByteOrder>(&mut self) -> f64 where Self: Sized {
|
||||
let mut buf = [0; 8];
|
||||
self.copy_to_slice(&mut buf);
|
||||
T::read_f64(&buf)
|
||||
}
|
||||
|
||||
/// Gets an IEEE754 double-precision (8 bytes) floating point number from
|
||||
/// `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello");
|
||||
/// assert_eq!(1.2f64, buf.get_f64_be());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_f64_be(&mut self) -> f64 {
|
||||
buf_get_impl!(self, 8, BigEndian::read_f64);
|
||||
}
|
||||
|
||||
/// Gets an IEEE754 double-precision (8 bytes) floating point number from
|
||||
/// `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Buf;
|
||||
/// use std::io::Cursor;
|
||||
///
|
||||
/// let mut buf = Cursor::new(b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello");
|
||||
/// assert_eq!(1.2f64, buf.get_f64_le());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining data in `self`.
|
||||
fn get_f64_le(&mut self) -> f64 {
|
||||
buf_get_impl!(self, 8, LittleEndian::read_f64);
|
||||
}
|
||||
|
||||
/// Transforms a `Buf` into a concrete buffer.
|
||||
///
|
||||
/// `collect()` can operate on any value that implements `Buf`, and turn it
|
||||
@@ -749,3 +1148,7 @@ impl Buf for Option<[u8; 1]> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The existance of this function makes the compiler catch if the Buf
|
||||
// trait is "object-safe" or not.
|
||||
fn _assert_trait_object(_b: &Buf) {}
|
||||
|
||||
+574
-143
@@ -1,5 +1,5 @@
|
||||
use super::{IntoBuf, Writer};
|
||||
use byteorder::ByteOrder;
|
||||
use byteorder::{LittleEndian, ByteOrder, BigEndian};
|
||||
use iovec::IoVec;
|
||||
|
||||
use std::{cmp, io, ptr, usize};
|
||||
@@ -121,7 +121,8 @@ pub trait BufMut {
|
||||
}
|
||||
|
||||
/// Returns a mutable slice starting at the current BufMut position and of
|
||||
/// length between 0 and `BufMut::remaining_mut()`.
|
||||
/// length between 0 and `BufMut::remaining_mut()`. Note that this *can* be shorter than the
|
||||
/// whole remainder of the buffer (this allows non-continuous implementation).
|
||||
///
|
||||
/// This is a lower level function. Most operations are done with other
|
||||
/// functions.
|
||||
@@ -338,41 +339,25 @@ pub trait BufMut {
|
||||
self.put_slice(&src)
|
||||
}
|
||||
|
||||
/// Writes an unsigned 16 bit integer to `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u16::<BigEndian>(0x0809);
|
||||
/// assert_eq!(buf, b"\x08\x09");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_u16<T: ByteOrder>(&mut self, n: u16) {
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use put_u16_be or put_u16_le")]
|
||||
fn put_u16<T: ByteOrder>(&mut self, n: u16) where Self: Sized {
|
||||
let mut buf = [0; 2];
|
||||
T::write_u16(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 16 bit integer to `self` in the specified byte order.
|
||||
/// Writes an unsigned 16 bit integer to `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i16::<BigEndian>(0x0809);
|
||||
/// buf.put_u16_be(0x0809);
|
||||
/// assert_eq!(buf, b"\x08\x09");
|
||||
/// ```
|
||||
///
|
||||
@@ -380,47 +365,111 @@ pub trait BufMut {
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i16<T: ByteOrder>(&mut self, n: i16) {
|
||||
fn put_u16_be(&mut self, n: u16) {
|
||||
let mut buf = [0; 2];
|
||||
BigEndian::write_u16(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an unsigned 16 bit integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u16_le(0x0809);
|
||||
/// assert_eq!(buf, b"\x09\x08");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_u16_le(&mut self, n: u16) {
|
||||
let mut buf = [0; 2];
|
||||
LittleEndian::write_u16(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use put_i16_be or put_i16_le")]
|
||||
fn put_i16<T: ByteOrder>(&mut self, n: i16) where Self: Sized {
|
||||
let mut buf = [0; 2];
|
||||
T::write_i16(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an unsigned 32 bit integer to `self` in the specified byte order.
|
||||
/// Writes a signed 16 bit integer to `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u32::<BigEndian>(0x0809A0A1);
|
||||
/// assert_eq!(buf, b"\x08\x09\xA0\xA1");
|
||||
/// buf.put_i16_be(0x0809);
|
||||
/// assert_eq!(buf, b"\x08\x09");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_u32<T: ByteOrder>(&mut self, n: u32) {
|
||||
fn put_i16_be(&mut self, n: i16) {
|
||||
let mut buf = [0; 2];
|
||||
BigEndian::write_i16(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 16 bit integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i16_le(0x0809);
|
||||
/// assert_eq!(buf, b"\x09\x08");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i16_le(&mut self, n: i16) {
|
||||
let mut buf = [0; 2];
|
||||
LittleEndian::write_i16(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use put_u32_be or put_u32_le")]
|
||||
fn put_u32<T: ByteOrder>(&mut self, n: u32) where Self: Sized {
|
||||
let mut buf = [0; 4];
|
||||
T::write_u32(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 32 bit integer to `self` in the specified byte order.
|
||||
/// Writes an unsigned 32 bit integer to `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i32::<BigEndian>(0x0809A0A1);
|
||||
/// buf.put_u32_be(0x0809A0A1);
|
||||
/// assert_eq!(buf, b"\x08\x09\xA0\xA1");
|
||||
/// ```
|
||||
///
|
||||
@@ -428,120 +477,440 @@ pub trait BufMut {
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i32<T: ByteOrder>(&mut self, n: i32) {
|
||||
fn put_u32_be(&mut self, n: u32) {
|
||||
let mut buf = [0; 4];
|
||||
T::write_i32(&mut buf, n);
|
||||
BigEndian::write_u32(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an unsigned 64 bit integer to `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u64::<BigEndian>(0x0102030405060708);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_u64<T: ByteOrder>(&mut self, n: u64) {
|
||||
let mut buf = [0; 8];
|
||||
T::write_u64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 64 bit integer to `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i64::<BigEndian>(0x0102030405060708);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i64<T: ByteOrder>(&mut self, n: i64) {
|
||||
let mut buf = [0; 8];
|
||||
T::write_i64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an unsigned n-byte integer to `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_uint::<BigEndian>(0x010203, 3);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_uint<T: ByteOrder>(&mut self, n: u64, nbytes: usize) {
|
||||
let mut buf = [0; 8];
|
||||
T::write_uint(&mut buf, n, nbytes);
|
||||
self.put_slice(&buf[0..nbytes])
|
||||
}
|
||||
|
||||
/// Writes a signed n-byte integer to `self` in the specified byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_int::<BigEndian>(0x010203, 3);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_int<T: ByteOrder>(&mut self, n: i64, nbytes: usize) {
|
||||
let mut buf = [0; 8];
|
||||
T::write_int(&mut buf, n, nbytes);
|
||||
self.put_slice(&buf[0..nbytes])
|
||||
}
|
||||
|
||||
/// Writes an IEEE754 single-precision (4 bytes) floating point number to
|
||||
/// `self` in the specified byte order.
|
||||
/// Writes an unsigned 32 bit integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_f32::<BigEndian>(1.2f32);
|
||||
/// buf.put_u32_le(0x0809A0A1);
|
||||
/// assert_eq!(buf, b"\xA1\xA0\x09\x08");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_u32_le(&mut self, n: u32) {
|
||||
let mut buf = [0; 4];
|
||||
LittleEndian::write_u32(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use put_i32_be or put_i32_le")]
|
||||
fn put_i32<T: ByteOrder>(&mut self, n: i32) where Self: Sized {
|
||||
let mut buf = [0; 4];
|
||||
T::write_i32(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 32 bit integer to `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i32_be(0x0809A0A1);
|
||||
/// assert_eq!(buf, b"\x08\x09\xA0\xA1");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i32_be(&mut self, n: i32) {
|
||||
let mut buf = [0; 4];
|
||||
BigEndian::write_i32(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 32 bit integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i32_le(0x0809A0A1);
|
||||
/// assert_eq!(buf, b"\xA1\xA0\x09\x08");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i32_le(&mut self, n: i32) {
|
||||
let mut buf = [0; 4];
|
||||
LittleEndian::write_i32(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use put_u64_be or put_u64_le")]
|
||||
fn put_u64<T: ByteOrder>(&mut self, n: u64) where Self: Sized {
|
||||
let mut buf = [0; 8];
|
||||
T::write_u64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an unsigned 64 bit integer to `self` in the big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u64_be(0x0102030405060708);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_u64_be(&mut self, n: u64) {
|
||||
let mut buf = [0; 8];
|
||||
BigEndian::write_u64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an unsigned 64 bit integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u64_le(0x0102030405060708);
|
||||
/// assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_u64_le(&mut self, n: u64) {
|
||||
let mut buf = [0; 8];
|
||||
LittleEndian::write_u64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use put_i64_be or put_i64_le")]
|
||||
fn put_i64<T: ByteOrder>(&mut self, n: i64) where Self: Sized {
|
||||
let mut buf = [0; 8];
|
||||
T::write_i64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 64 bit integer to `self` in the big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i64_be(0x0102030405060708);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i64_be(&mut self, n: i64) {
|
||||
let mut buf = [0; 8];
|
||||
BigEndian::write_i64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 64 bit integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i64_le(0x0102030405060708);
|
||||
/// assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_i64_le(&mut self, n: i64) {
|
||||
let mut buf = [0; 8];
|
||||
LittleEndian::write_i64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an unsigned 128 bit integer to `self` in the big-endian byte order.
|
||||
///
|
||||
/// **NOTE:** This method requires the `i128` feature.
|
||||
/// The current position is advanced by 16.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u128_be(0x01020304050607080910111213141516);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
#[cfg(feature = "i128")]
|
||||
fn put_u128_be(&mut self, n: u128) {
|
||||
let mut buf = [0; 16];
|
||||
BigEndian::write_u128(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an unsigned 128 bit integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// **NOTE:** This method requires the `i128` feature.
|
||||
/// The current position is advanced by 16.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_u128_le(0x01020304050607080910111213141516);
|
||||
/// assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
#[cfg(feature = "i128")]
|
||||
fn put_u128_le(&mut self, n: u128) {
|
||||
let mut buf = [0; 16];
|
||||
LittleEndian::write_u128(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 128 bit integer to `self` in the big-endian byte order.
|
||||
///
|
||||
/// **NOTE:** This method requires the `i128` feature.
|
||||
/// The current position is advanced by 16.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i128_be(0x01020304050607080910111213141516);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
#[cfg(feature = "i128")]
|
||||
fn put_i128_be(&mut self, n: i128) {
|
||||
let mut buf = [0; 16];
|
||||
BigEndian::write_i128(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes a signed 128 bit integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// **NOTE:** This method requires the `i128` feature.
|
||||
/// The current position is advanced by 16.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_i128_le(0x01020304050607080910111213141516);
|
||||
/// assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
#[cfg(feature = "i128")]
|
||||
fn put_i128_le(&mut self, n: i128) {
|
||||
let mut buf = [0; 16];
|
||||
LittleEndian::write_i128(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use put_uint_be or put_uint_le")]
|
||||
fn put_uint<T: ByteOrder>(&mut self, n: u64, nbytes: usize) where Self: Sized {
|
||||
let mut buf = [0; 8];
|
||||
T::write_uint(&mut buf, n, nbytes);
|
||||
self.put_slice(&buf[0..nbytes])
|
||||
}
|
||||
|
||||
/// Writes an unsigned n-byte integer to `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_uint_be(0x010203, 3);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_uint_be(&mut self, n: u64, nbytes: usize) {
|
||||
let mut buf = [0; 8];
|
||||
BigEndian::write_uint(&mut buf, n, nbytes);
|
||||
self.put_slice(&buf[0..nbytes])
|
||||
}
|
||||
|
||||
/// Writes an unsigned n-byte integer to `self` in the little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_uint_le(0x010203, 3);
|
||||
/// assert_eq!(buf, b"\x03\x02\x01");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_uint_le(&mut self, n: u64, nbytes: usize) {
|
||||
let mut buf = [0; 8];
|
||||
LittleEndian::write_uint(&mut buf, n, nbytes);
|
||||
self.put_slice(&buf[0..nbytes])
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use put_int_be or put_int_le")]
|
||||
fn put_int<T: ByteOrder>(&mut self, n: i64, nbytes: usize) where Self: Sized {
|
||||
let mut buf = [0; 8];
|
||||
T::write_int(&mut buf, n, nbytes);
|
||||
self.put_slice(&buf[0..nbytes])
|
||||
}
|
||||
|
||||
/// Writes a signed n-byte integer to `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_int_be(0x010203, 3);
|
||||
/// assert_eq!(buf, b"\x01\x02\x03");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_int_be(&mut self, n: i64, nbytes: usize) {
|
||||
let mut buf = [0; 8];
|
||||
BigEndian::write_int(&mut buf, n, nbytes);
|
||||
self.put_slice(&buf[0..nbytes])
|
||||
}
|
||||
|
||||
/// Writes a signed n-byte integer to `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by `nbytes`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_int_le(0x010203, 3);
|
||||
/// assert_eq!(buf, b"\x03\x02\x01");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_int_le(&mut self, n: i64, nbytes: usize) {
|
||||
let mut buf = [0; 8];
|
||||
LittleEndian::write_int(&mut buf, n, nbytes);
|
||||
self.put_slice(&buf[0..nbytes])
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use put_f32_be or put_f32_le")]
|
||||
fn put_f32<T: ByteOrder>(&mut self, n: f32) where Self: Sized {
|
||||
let mut buf = [0; 4];
|
||||
T::write_f32(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an IEEE754 single-precision (4 bytes) floating point number to
|
||||
/// `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_f32_be(1.2f32);
|
||||
/// assert_eq!(buf, b"\x3F\x99\x99\x9A");
|
||||
/// ```
|
||||
///
|
||||
@@ -549,24 +918,57 @@ pub trait BufMut {
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_f32<T: ByteOrder>(&mut self, n: f32) {
|
||||
fn put_f32_be(&mut self, n: f32) {
|
||||
let mut buf = [0; 4];
|
||||
T::write_f32(&mut buf, n);
|
||||
BigEndian::write_f32(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an IEEE754 single-precision (4 bytes) floating point number to
|
||||
/// `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 4.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_f32_le(1.2f32);
|
||||
/// assert_eq!(buf, b"\x9A\x99\x99\x3F");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_f32_le(&mut self, n: f32) {
|
||||
let mut buf = [0; 4];
|
||||
LittleEndian::write_f32(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note="use put_f64_be or put_f64_le")]
|
||||
fn put_f64<T: ByteOrder>(&mut self, n: f64) where Self: Sized {
|
||||
let mut buf = [0; 8];
|
||||
T::write_f64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an IEEE754 double-precision (8 bytes) floating point number to
|
||||
/// `self` in the specified byte order.
|
||||
/// `self` in big-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, BigEndian};
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_f64::<BigEndian>(1.2f64);
|
||||
/// buf.put_f64_be(1.2f64);
|
||||
/// assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
|
||||
/// ```
|
||||
///
|
||||
@@ -574,9 +976,34 @@ pub trait BufMut {
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_f64<T: ByteOrder>(&mut self, n: f64) {
|
||||
fn put_f64_be(&mut self, n: f64) {
|
||||
let mut buf = [0; 8];
|
||||
T::write_f64(&mut buf, n);
|
||||
BigEndian::write_f64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
/// Writes an IEEE754 double-precision (8 bytes) floating point number to
|
||||
/// `self` in little-endian byte order.
|
||||
///
|
||||
/// The current position is advanced by 8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::BufMut;
|
||||
///
|
||||
/// let mut buf = vec![];
|
||||
/// buf.put_f64_le(1.2f64);
|
||||
/// assert_eq!(buf, b"\x33\x33\x33\x33\x33\x33\xF3\x3F");
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is not enough remaining capacity in
|
||||
/// `self`.
|
||||
fn put_f64_le(&mut self, n: f64) {
|
||||
let mut buf = [0; 8];
|
||||
LittleEndian::write_f64(&mut buf, n);
|
||||
self.put_slice(&buf)
|
||||
}
|
||||
|
||||
@@ -734,3 +1161,7 @@ impl BufMut for Vec<u8> {
|
||||
&mut slice::from_raw_parts_mut(ptr, cap)[len..]
|
||||
}
|
||||
}
|
||||
|
||||
// The existance of this function makes the compiler catch if the BufMut
|
||||
// trait is "object-safe" or not.
|
||||
fn _assert_trait_object(_b: &BufMut) {}
|
||||
|
||||
@@ -63,6 +63,14 @@ impl<'a> IntoBuf for &'a [u8] {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoBuf for &'a mut [u8] {
|
||||
type Buf = io::Cursor<&'a mut [u8]>;
|
||||
|
||||
fn into_buf(self) -> Self::Buf {
|
||||
io::Cursor::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoBuf for &'a str {
|
||||
type Buf = io::Cursor<&'a [u8]>;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ mod into_buf;
|
||||
mod iter;
|
||||
mod reader;
|
||||
mod take;
|
||||
mod vec_deque;
|
||||
mod writer;
|
||||
|
||||
pub use self::buf::Buf;
|
||||
|
||||
@@ -86,3 +86,12 @@ impl<B: Buf + Sized> io::Read for Reader<B> {
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Buf + Sized> io::BufRead for Reader<B> {
|
||||
fn fill_buf(&mut self) -> io::Result<&[u8]> {
|
||||
Ok(self.buf.bytes())
|
||||
}
|
||||
fn consume(&mut self, amt: usize) {
|
||||
self.buf.advance(amt)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use super::Buf;
|
||||
|
||||
impl Buf for VecDeque<u8> {
|
||||
fn remaining(&self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
|
||||
fn bytes(&self) -> &[u8] {
|
||||
let (s1, s2) = self.as_slices();
|
||||
if s1.is_empty() {
|
||||
s2
|
||||
} else {
|
||||
s1
|
||||
}
|
||||
}
|
||||
|
||||
fn advance(&mut self, cnt: usize) {
|
||||
self.drain(..cnt);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn hello_world() {
|
||||
let mut buffer: VecDeque<u8> = VecDeque::new();
|
||||
buffer.extend(b"hello world");
|
||||
assert_eq!(11, buffer.remaining());
|
||||
assert_eq!(b"hello world", buffer.bytes());
|
||||
buffer.advance(6);
|
||||
assert_eq!(b"world", buffer.bytes());
|
||||
buffer.extend(b" piece");
|
||||
assert_eq!(b"world piece" as &[u8], &buffer.collect::<Vec<u8>>()[..]);
|
||||
}
|
||||
}
|
||||
+602
-224
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -27,8 +27,8 @@ impl<'a> fmt::Debug for BsDebug<'a> {
|
||||
try!(write!(fmt, "\\{}", c as char));
|
||||
} else if c == b'\0' {
|
||||
try!(write!(fmt, "\\0"));
|
||||
// ASCII printable except space
|
||||
} else if c > 0x20 && c < 0x7f {
|
||||
// ASCII printable
|
||||
} else if c >= 0x20 && c < 0x7f {
|
||||
try!(write!(fmt, "{}", c as char));
|
||||
} else {
|
||||
try!(write!(fmt, "\\x{:02x}", c));
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
extern crate either;
|
||||
|
||||
use {Buf, BufMut};
|
||||
|
||||
use self::either::Either;
|
||||
use self::either::Either::*;
|
||||
use iovec::IoVec;
|
||||
|
||||
impl<L, R> Buf for Either<L, R>
|
||||
where
|
||||
L: Buf,
|
||||
R: Buf,
|
||||
{
|
||||
fn remaining(&self) -> usize {
|
||||
match *self {
|
||||
Left(ref b) => b.remaining(),
|
||||
Right(ref b) => b.remaining(),
|
||||
}
|
||||
}
|
||||
|
||||
fn bytes(&self) -> &[u8] {
|
||||
match *self {
|
||||
Left(ref b) => b.bytes(),
|
||||
Right(ref b) => b.bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize {
|
||||
match *self {
|
||||
Left(ref b) => b.bytes_vec(dst),
|
||||
Right(ref b) => b.bytes_vec(dst),
|
||||
}
|
||||
}
|
||||
|
||||
fn advance(&mut self, cnt: usize) {
|
||||
match *self {
|
||||
Left(ref mut b) => b.advance(cnt),
|
||||
Right(ref mut b) => b.advance(cnt),
|
||||
}
|
||||
}
|
||||
|
||||
fn copy_to_slice(&mut self, dst: &mut [u8]) {
|
||||
match *self {
|
||||
Left(ref mut b) => b.copy_to_slice(dst),
|
||||
Right(ref mut b) => b.copy_to_slice(dst),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L, R> BufMut for Either<L, R>
|
||||
where
|
||||
L: BufMut,
|
||||
R: BufMut,
|
||||
{
|
||||
fn remaining_mut(&self) -> usize {
|
||||
match *self {
|
||||
Left(ref b) => b.remaining_mut(),
|
||||
Right(ref b) => b.remaining_mut(),
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
|
||||
match *self {
|
||||
Left(ref mut b) => b.bytes_mut(),
|
||||
Right(ref mut b) => b.bytes_mut(),
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize {
|
||||
match *self {
|
||||
Left(ref mut b) => b.bytes_vec_mut(dst),
|
||||
Right(ref mut b) => b.bytes_vec_mut(dst),
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn advance_mut(&mut self, cnt: usize) {
|
||||
match *self {
|
||||
Left(ref mut b) => b.advance_mut(cnt),
|
||||
Right(ref mut b) => b.advance_mut(cnt),
|
||||
}
|
||||
}
|
||||
|
||||
fn put_slice(&mut self, src: &[u8]) {
|
||||
match *self {
|
||||
Left(ref mut b) => b.put_slice(src),
|
||||
Right(ref mut b) => b.put_slice(src),
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-3
@@ -18,8 +18,8 @@
|
||||
//! using a reference count to track when the memory is no longer needed and can
|
||||
//! be freed.
|
||||
//!
|
||||
//! A `Bytes` handle can be created directly from an existing byte store (such as &[u8]
|
||||
//! or Vec<u8>), but usually a `BytesMut` is used first and written to. For
|
||||
//! A `Bytes` handle can be created directly from an existing byte store (such as `&[u8]`
|
||||
//! or `Vec<u8>`), but usually a `BytesMut` is used first and written to. For
|
||||
//! example:
|
||||
//!
|
||||
//! ```rust
|
||||
@@ -69,7 +69,7 @@
|
||||
//! and `BufMut` are infallible.
|
||||
|
||||
#![deny(warnings, missing_docs, missing_debug_implementations)]
|
||||
#![doc(html_root_url = "https://docs.rs/bytes/0.4")]
|
||||
#![doc(html_root_url = "https://docs.rs/bytes/0.4.12")]
|
||||
|
||||
extern crate byteorder;
|
||||
extern crate iovec;
|
||||
@@ -92,9 +92,14 @@ mod bytes;
|
||||
mod debug;
|
||||
pub use bytes::{Bytes, BytesMut};
|
||||
|
||||
#[deprecated]
|
||||
pub use byteorder::{ByteOrder, BigEndian, LittleEndian};
|
||||
|
||||
// Optional Serde support
|
||||
#[cfg(feature = "serde")]
|
||||
#[doc(hidden)]
|
||||
pub mod serde;
|
||||
|
||||
// Optional `Either` support
|
||||
#[cfg(feature = "either")]
|
||||
mod either;
|
||||
|
||||
+9
-4
@@ -33,21 +33,26 @@ fn test_get_u8() {
|
||||
#[test]
|
||||
fn test_get_u16() {
|
||||
let buf = b"\x21\x54zomg";
|
||||
assert_eq!(0x2154, Cursor::new(buf).get_u16::<byteorder::BigEndian>());
|
||||
assert_eq!(0x5421, Cursor::new(buf).get_u16::<byteorder::LittleEndian>());
|
||||
assert_eq!(0x2154, Cursor::new(buf).get_u16_be());
|
||||
assert_eq!(0x5421, Cursor::new(buf).get_u16_le());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_get_u16_buffer_underflow() {
|
||||
let mut buf = Cursor::new(b"\x21");
|
||||
buf.get_u16::<byteorder::BigEndian>();
|
||||
buf.get_u16_be();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bufs_vec() {
|
||||
let buf = Cursor::new(b"hello world");
|
||||
let mut dst: [&IoVec; 2] = Default::default();
|
||||
|
||||
let b1: &[u8] = &mut [0];
|
||||
let b2: &[u8] = &mut [0];
|
||||
|
||||
let mut dst: [&IoVec; 2] =
|
||||
[b1.into(), b2.into()];
|
||||
|
||||
assert_eq!(1, buf.bytes_vec(&mut dst[..]));
|
||||
}
|
||||
|
||||
@@ -41,11 +41,11 @@ fn test_put_u8() {
|
||||
#[test]
|
||||
fn test_put_u16() {
|
||||
let mut buf = Vec::with_capacity(8);
|
||||
buf.put_u16::<byteorder::BigEndian>(8532);
|
||||
buf.put_u16_be(8532);
|
||||
assert_eq!(b"\x21\x54", &buf[..]);
|
||||
|
||||
buf.clear();
|
||||
buf.put_u16::<byteorder::LittleEndian>(8532);
|
||||
buf.put_u16_le(8532);
|
||||
assert_eq!(b"\x54\x21", &buf[..]);
|
||||
}
|
||||
|
||||
|
||||
+263
-11
@@ -1,6 +1,6 @@
|
||||
extern crate bytes;
|
||||
|
||||
use bytes::{Bytes, BytesMut, BufMut};
|
||||
use bytes::{Bytes, BytesMut, BufMut, IntoBuf};
|
||||
|
||||
const LONG: &'static [u8] = b"mary had a little lamb, little lamb, little lamb";
|
||||
const SHORT: &'static [u8] = b"hello world";
|
||||
@@ -258,15 +258,10 @@ fn split_to_oob_mut() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn split_to_uninitialized() {
|
||||
let mut bytes = BytesMut::with_capacity(1024);
|
||||
let other = bytes.split_to(128);
|
||||
|
||||
assert_eq!(bytes.len(), 0);
|
||||
assert_eq!(bytes.capacity(), 896);
|
||||
|
||||
assert_eq!(other.len(), 0);
|
||||
assert_eq!(other.capacity(), 128);
|
||||
let _other = bytes.split_to(128);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -303,6 +298,13 @@ fn fns_defined_for_bytes_mut() {
|
||||
assert_eq!(&v[..], bytes);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mut_into_buf() {
|
||||
let mut v = vec![0, 0, 0, 0];
|
||||
let s = &mut v[..];
|
||||
s.into_buf().put_u32_le(42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reserve_convert() {
|
||||
// Inline -> Vec
|
||||
@@ -350,16 +352,16 @@ fn reserve_growth() {
|
||||
|
||||
#[test]
|
||||
fn reserve_allocates_at_least_original_capacity() {
|
||||
let mut bytes = BytesMut::with_capacity(128);
|
||||
let mut bytes = BytesMut::with_capacity(1024);
|
||||
|
||||
for i in 0..120 {
|
||||
for i in 0..1020 {
|
||||
bytes.put(i as u8);
|
||||
}
|
||||
|
||||
let _other = bytes.take();
|
||||
|
||||
bytes.reserve(16);
|
||||
assert_eq!(bytes.capacity(), 128);
|
||||
assert_eq!(bytes.capacity(), 1024);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -378,6 +380,21 @@ fn reserve_max_original_capacity_value() {
|
||||
assert_eq!(bytes.capacity(), 64 * 1024);
|
||||
}
|
||||
|
||||
// Without either looking at the internals of the BytesMut or doing weird stuff
|
||||
// with the memory allocator, there's no good way to automatically verify from
|
||||
// within the program that this actually recycles memory. Instead, just exercise
|
||||
// the code path to ensure that the results are correct.
|
||||
#[test]
|
||||
fn reserve_vec_recycling() {
|
||||
let mut bytes = BytesMut::from(Vec::with_capacity(16));
|
||||
assert_eq!(bytes.capacity(), 16);
|
||||
bytes.put("0123456789012345");
|
||||
bytes.advance(10);
|
||||
assert_eq!(bytes.capacity(), 6);
|
||||
bytes.reserve(8);
|
||||
assert_eq!(bytes.capacity(), 16);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reserve_in_arc_unique_does_not_overallocate() {
|
||||
let mut bytes = BytesMut::with_capacity(1000);
|
||||
@@ -466,6 +483,44 @@ fn from_static() {
|
||||
assert_eq!(b, b"b"[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn advance_inline() {
|
||||
let mut a = Bytes::from(&b"hello world"[..]);
|
||||
a.advance(6);
|
||||
assert_eq!(a, &b"world"[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn advance_static() {
|
||||
let mut a = Bytes::from_static(b"hello world");
|
||||
a.advance(6);
|
||||
assert_eq!(a, &b"world"[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn advance_vec() {
|
||||
let mut a = BytesMut::from(b"hello world boooo yah world zomg wat wat".to_vec());
|
||||
a.advance(16);
|
||||
assert_eq!(a, b"o yah world zomg wat wat"[..]);
|
||||
|
||||
a.advance(4);
|
||||
assert_eq!(a, b"h world zomg wat wat"[..]);
|
||||
|
||||
// Reserve some space.
|
||||
a.reserve(1024);
|
||||
assert_eq!(a, b"h world zomg wat wat"[..]);
|
||||
|
||||
a.advance(6);
|
||||
assert_eq!(a, b"d zomg wat wat"[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn advance_past_len() {
|
||||
let mut a = BytesMut::from(b"hello world".to_vec());
|
||||
a.advance(20);
|
||||
}
|
||||
|
||||
#[test]
|
||||
// Only run these tests on little endian systems. CI uses qemu for testing
|
||||
// little endian... and qemu doesn't really support threading all that well.
|
||||
@@ -514,3 +569,200 @@ fn partial_eq_bytesmut() {
|
||||
assert!(bytes2 != bytesmut);
|
||||
assert!(bytesmut != bytes2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_basic() {
|
||||
let mut buf = BytesMut::with_capacity(64);
|
||||
buf.extend_from_slice(b"aaabbbcccddd");
|
||||
|
||||
let splitted = buf.split_off(6);
|
||||
assert_eq!(b"aaabbb", &buf[..]);
|
||||
assert_eq!(b"cccddd", &splitted[..]);
|
||||
|
||||
buf.unsplit(splitted);
|
||||
assert_eq!(b"aaabbbcccddd", &buf[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_empty_other() {
|
||||
let mut buf = BytesMut::with_capacity(64);
|
||||
buf.extend_from_slice(b"aaabbbcccddd");
|
||||
|
||||
// empty other
|
||||
let other = BytesMut::new();
|
||||
|
||||
buf.unsplit(other);
|
||||
assert_eq!(b"aaabbbcccddd", &buf[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_empty_self() {
|
||||
// empty self
|
||||
let mut buf = BytesMut::new();
|
||||
|
||||
let mut other = BytesMut::with_capacity(64);
|
||||
other.extend_from_slice(b"aaabbbcccddd");
|
||||
|
||||
buf.unsplit(other);
|
||||
assert_eq!(b"aaabbbcccddd", &buf[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_inline_arc() {
|
||||
let mut buf = BytesMut::with_capacity(8); //inline
|
||||
buf.extend_from_slice(b"aaaabbbb");
|
||||
|
||||
let mut buf2 = BytesMut::with_capacity(64);
|
||||
buf2.extend_from_slice(b"ccccddddeeee");
|
||||
|
||||
buf2.split_off(8); //arc
|
||||
|
||||
buf.unsplit(buf2);
|
||||
assert_eq!(b"aaaabbbbccccdddd", &buf[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_arc_inline() {
|
||||
let mut buf = BytesMut::with_capacity(64);
|
||||
buf.extend_from_slice(b"aaaabbbbeeee");
|
||||
|
||||
buf.split_off(8); //arc
|
||||
|
||||
let mut buf2 = BytesMut::with_capacity(8); //inline
|
||||
buf2.extend_from_slice(b"ccccdddd");
|
||||
|
||||
buf.unsplit(buf2);
|
||||
assert_eq!(b"aaaabbbbccccdddd", &buf[..]);
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_both_inline() {
|
||||
let mut buf = BytesMut::with_capacity(16); //inline
|
||||
buf.extend_from_slice(b"aaaabbbbccccdddd");
|
||||
|
||||
let splitted = buf.split_off(8); // both inline
|
||||
assert_eq!(b"aaaabbbb", &buf[..]);
|
||||
assert_eq!(b"ccccdddd", &splitted[..]);
|
||||
|
||||
buf.unsplit(splitted);
|
||||
assert_eq!(b"aaaabbbbccccdddd", &buf[..]);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn unsplit_arc_different() {
|
||||
let mut buf = BytesMut::with_capacity(64);
|
||||
buf.extend_from_slice(b"aaaabbbbeeee");
|
||||
|
||||
buf.split_off(8); //arc
|
||||
|
||||
let mut buf2 = BytesMut::with_capacity(64);
|
||||
buf2.extend_from_slice(b"ccccddddeeee");
|
||||
|
||||
buf2.split_off(8); //arc
|
||||
|
||||
buf.unsplit(buf2);
|
||||
assert_eq!(b"aaaabbbbccccdddd", &buf[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_arc_non_contiguous() {
|
||||
let mut buf = BytesMut::with_capacity(64);
|
||||
buf.extend_from_slice(b"aaaabbbbeeeeccccdddd");
|
||||
|
||||
let mut buf2 = buf.split_off(8); //arc
|
||||
|
||||
let buf3 = buf2.split_off(4); //arc
|
||||
|
||||
buf.unsplit(buf3);
|
||||
assert_eq!(b"aaaabbbbccccdddd", &buf[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_two_split_offs() {
|
||||
let mut buf = BytesMut::with_capacity(64);
|
||||
buf.extend_from_slice(b"aaaabbbbccccdddd");
|
||||
|
||||
let mut buf2 = buf.split_off(8); //arc
|
||||
let buf3 = buf2.split_off(4); //arc
|
||||
|
||||
buf2.unsplit(buf3);
|
||||
buf.unsplit(buf2);
|
||||
assert_eq!(b"aaaabbbbccccdddd", &buf[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_iter_no_size_hint() {
|
||||
use std::iter;
|
||||
|
||||
let mut expect = vec![];
|
||||
|
||||
let actual: Bytes = iter::repeat(b'x')
|
||||
.scan(100, |cnt, item| {
|
||||
if *cnt >= 1 {
|
||||
*cnt -= 1;
|
||||
expect.push(item);
|
||||
Some(item)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
assert_eq!(&actual[..], &expect[..]);
|
||||
}
|
||||
|
||||
fn test_slice_ref(bytes: &Bytes, start: usize, end: usize, expected: &[u8]) {
|
||||
let slice = &(bytes.as_ref()[start..end]);
|
||||
let sub = bytes.slice_ref(&slice);
|
||||
assert_eq!(&sub[..], expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slice_ref_works() {
|
||||
let bytes = Bytes::from(&b"012345678"[..]);
|
||||
|
||||
test_slice_ref(&bytes, 0, 0, b"");
|
||||
test_slice_ref(&bytes, 0, 3, b"012");
|
||||
test_slice_ref(&bytes, 2, 6, b"2345");
|
||||
test_slice_ref(&bytes, 7, 9, b"78");
|
||||
test_slice_ref(&bytes, 9, 9, b"");
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn slice_ref_empty() {
|
||||
let bytes = Bytes::from(&b""[..]);
|
||||
let slice = &(bytes.as_ref()[0..0]);
|
||||
|
||||
let sub = bytes.slice_ref(&slice);
|
||||
assert_eq!(&sub[..], b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn slice_ref_catches_not_a_subset() {
|
||||
let bytes = Bytes::from(&b"012345678"[..]);
|
||||
let slice = &b"012345"[0..4];
|
||||
|
||||
bytes.slice_ref(slice);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn slice_ref_catches_not_an_empty_subset() {
|
||||
let bytes = Bytes::from(&b"012345678"[..]);
|
||||
let slice = &b""[0..0];
|
||||
|
||||
bytes.slice_ref(slice);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn empty_slice_ref_catches_not_an_empty_subset() {
|
||||
let bytes = Bytes::from(&b""[..]);
|
||||
let slice = &b""[0..0];
|
||||
|
||||
bytes.slice_ref(slice);
|
||||
}
|
||||
|
||||
+34
-14
@@ -55,48 +55,68 @@ fn vectored_read() {
|
||||
let mut buf = a.chain(b);
|
||||
|
||||
{
|
||||
let mut iovecs: [&IoVec; 4] = Default::default();
|
||||
let b1: &[u8] = &mut [0];
|
||||
let b2: &[u8] = &mut [0];
|
||||
let b3: &[u8] = &mut [0];
|
||||
let b4: &[u8] = &mut [0];
|
||||
let mut iovecs: [&IoVec; 4] =
|
||||
[b1.into(), b2.into(), b3.into(), b4.into()];
|
||||
|
||||
assert_eq!(2, buf.bytes_vec(&mut iovecs));
|
||||
assert_eq!(iovecs[0][..], b"hello"[..]);
|
||||
assert_eq!(iovecs[1][..], b"world"[..]);
|
||||
assert!(iovecs[2].is_empty());
|
||||
assert!(iovecs[3].is_empty());
|
||||
assert_eq!(iovecs[2][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[3][..], b"\0"[..]);
|
||||
}
|
||||
|
||||
buf.advance(2);
|
||||
|
||||
{
|
||||
let mut iovecs: [&IoVec; 4] = Default::default();
|
||||
let b1: &[u8] = &mut [0];
|
||||
let b2: &[u8] = &mut [0];
|
||||
let b3: &[u8] = &mut [0];
|
||||
let b4: &[u8] = &mut [0];
|
||||
let mut iovecs: [&IoVec; 4] =
|
||||
[b1.into(), b2.into(), b3.into(), b4.into()];
|
||||
|
||||
assert_eq!(2, buf.bytes_vec(&mut iovecs));
|
||||
assert_eq!(iovecs[0][..], b"llo"[..]);
|
||||
assert_eq!(iovecs[1][..], b"world"[..]);
|
||||
assert!(iovecs[2].is_empty());
|
||||
assert!(iovecs[3].is_empty());
|
||||
assert_eq!(iovecs[2][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[3][..], b"\0"[..]);
|
||||
}
|
||||
|
||||
buf.advance(3);
|
||||
|
||||
{
|
||||
let mut iovecs: [&IoVec; 4] = Default::default();
|
||||
let b1: &[u8] = &mut [0];
|
||||
let b2: &[u8] = &mut [0];
|
||||
let b3: &[u8] = &mut [0];
|
||||
let b4: &[u8] = &mut [0];
|
||||
let mut iovecs: [&IoVec; 4] =
|
||||
[b1.into(), b2.into(), b3.into(), b4.into()];
|
||||
|
||||
assert_eq!(1, buf.bytes_vec(&mut iovecs));
|
||||
assert_eq!(iovecs[0][..], b"world"[..]);
|
||||
assert!(iovecs[1].is_empty());
|
||||
assert!(iovecs[2].is_empty());
|
||||
assert!(iovecs[3].is_empty());
|
||||
assert_eq!(iovecs[1][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[2][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[3][..], b"\0"[..]);
|
||||
}
|
||||
|
||||
buf.advance(3);
|
||||
|
||||
{
|
||||
let mut iovecs: [&IoVec; 4] = Default::default();
|
||||
let b1: &[u8] = &mut [0];
|
||||
let b2: &[u8] = &mut [0];
|
||||
let b3: &[u8] = &mut [0];
|
||||
let b4: &[u8] = &mut [0];
|
||||
let mut iovecs: [&IoVec; 4] =
|
||||
[b1.into(), b2.into(), b3.into(), b4.into()];
|
||||
|
||||
assert_eq!(1, buf.bytes_vec(&mut iovecs));
|
||||
assert_eq!(iovecs[0][..], b"ld"[..]);
|
||||
assert!(iovecs[1].is_empty());
|
||||
assert!(iovecs[2].is_empty());
|
||||
assert!(iovecs[3].is_empty());
|
||||
assert_eq!(iovecs[1][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[2][..], b"\0"[..]);
|
||||
assert_eq!(iovecs[3][..], b"\0"[..]);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ fn fmt() {
|
||||
\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\
|
||||
\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\
|
||||
\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f\
|
||||
\\x20!\\\"#$%&'()*+,-./0123456789:;<=>?\
|
||||
\x20!\\\"#$%&'()*+,-./0123456789:;<=>?\
|
||||
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_\
|
||||
`abcdefghijklmnopqrstuvwxyz{|}~\\x7f\
|
||||
\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
extern crate bytes;
|
||||
|
||||
use std::io::{BufRead, Cursor, Read};
|
||||
|
||||
use bytes::Buf;
|
||||
|
||||
#[test]
|
||||
fn read() {
|
||||
let buf1 = Cursor::new(b"hello ");
|
||||
let buf2 = Cursor::new(b"world");
|
||||
let buf = Buf::chain(buf1, buf2); // Disambiguate with Read::chain
|
||||
let mut buffer = Vec::new();
|
||||
buf.reader().read_to_end(&mut buffer).unwrap();
|
||||
assert_eq!(b"hello world", &buffer[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn buf_read() {
|
||||
let buf1 = Cursor::new(b"hell");
|
||||
let buf2 = Cursor::new(b"o\nworld");
|
||||
let mut reader = Buf::chain(buf1, buf2).reader();
|
||||
let mut line = String::new();
|
||||
reader.read_line(&mut line).unwrap();
|
||||
assert_eq!("hello\n", &line);
|
||||
line.clear();
|
||||
reader.read_line(&mut line).unwrap();
|
||||
assert_eq!("world", &line);
|
||||
}
|
||||
Reference in New Issue
Block a user