| Age | Commit message (Collapse) | Author | Lines |
|
|
|
Stabilize `seek_seek_relative`
This PR stabilizes `seek_seek_relative`:
```rust
// std::io::Seek
trait Seek {
fn seek_relative(&mut self, offset: i64) -> Result<()>;
}
```
<br>
Tracking issue: https://github.com/rust-lang/rust/issues/117374.
Implementation PR: https://github.com/rust-lang/rust/pull/116750.
FCPs already completed in the tracking issue.
Closes https://github.com/rust-lang/rust/issues/117374.
r? libs-api
|
|
|
|
Improve several `Read` implementations
- `read_to_end` and `read_to_string` for `Cursor`
- Error on OOM in `read_to_string` of `&[u8]` and `VecDeque<u8>`
- Avoid making the slices contiguous in `VecDeque::read_to_string`
- ~`read_exact` and (unstable) `read_buf_exact` for `Take`~
- ~`read_buf` for `UnixStream` and `&UnixStream`~ (moved to #123084)
- `read_to_end` for `ChildStdErr`
|
|
|
|
|
|
Avoid a panic in `set_output_capture` in the default panic handler
This avoid a panic in the default panic handler by not using `set_output_capture` as `OUTPUT_CAPTURE.with` may panic once `OUTPUT_CAPTURE` is dropped.
A new non-panicking `try_set_output_capture` variant of `set_output_capture` is added for use in the default panic handler.
|
|
|
|
|
|
|
|
|
|
callers
|
|
impl From<TryReserveError> for io::Error
There's an obvious mapping between these two errors, and it makes I/O code less noisy.
I've chosen to use simple `ErrorKind::OutOfMemory` `io::Error`, without keeping `TryReserveError` for the `source()`, because:
* It matches current uses in libstd,
* `ErrorData::Custom` allocates, which is a risky proposition for handling OOM errors specifically.
* Currently `TryReserveError` has no public fields/methods, so it's usefulness is limited. How allocators should report errors, especially custom and verbose ones is still an open question.
Just in case I've added note in the doccomment that this may change.
The compiler forced me to declare stability of this impl. I think this implementation is simple enough that it doesn't need full-blown stabilization period, and I've marked it for the next release, but of course I can adjust the attribute if needed.
|
|
|
|
Currently all architecture-specific memchr code is only used in
`std::io`. Most of the actual `memchr` capacity exposed to the user
through the slice API is instead implemented in core::slice::memchr.
Hence this commit deletes memchr from std::sys[_common] and replace
calls to it by calls to core::slice::memchr functions. This deletes
(r)memchr from the list of symbols linked to libc.
|
|
Specialize some methods of `io::Chain`
This PR specializes the implementation of some methods of `io::Chain`, which could bring performance improvements when using it.
|
|
This also keeps the old `advance` method under `advance_unchecked` name.
This makes pattern like `std::io::default_read_buf` safe to write.
|
|
fix #120603 by adding a check in default_read_buf
Fixes #120603 by checking the returned read n is in-bounds of the cursor.
Interestingly, I noticed that `BorrowedBuf` side-steps this issue by using checked accesses. Maybe this can be switched to unchecked to mirror what BufReader does https://github.com/rust-lang/rust/blob/bf3c6c5bed498f41ad815641319a1ad9bcecb8e8/library/core/src/io/borrowed_buf.rs#L95
|
|
|
|
- Use `const_io_error` instead of `Error::new`
- Use the same message as `read_exact`
|
|
|
|
unify read_to_end and io::copy impls for reading into a Vec
This ports over the initial probe (to avoid allocation) and the dynamic read sizing from the io::copy specialization to the `default_read_to_end` implementation which already had its own optimizations for different cases.
I think it should be a best-of-both now.
suggested by `@a1phyr` in https://github.com/rust-lang/rust/pull/117576#issuecomment-1803408492
|
|
|
|
Improve rewind documentation
The persistent use of an internal cursor for readers is expected for buffer data types that aren't read all at once, but for files it leads to the confusing situation where calling `read_to_end` on the same file handle multiple times only returns the contents of the file for the first call. This PR adds a note to the documentation clarifying that in that case, `rewind()` must first be called.
I'm unsure if this is the right location for the docs update. Maybe it should also be duplicated on `File`?
|
|
Add `BufRead::skip_until`
Alternative version of `BufRead::read_until` that simply discards data, rather than copying it into a buffer.
Useful for situations like skipping irrelevant data in a binary file format that is NUL-terminated.
<details>
<summary>Benchmark</summary>
```
running 2 tests
test bench_read_until ... bench: 123 ns/iter (+/- 6)
test bench_skip_until ... bench: 66 ns/iter (+/- 3)
```
```rs
#![feature(test)]
extern crate test;
use test::Bencher;
use std::io::{ErrorKind, BufRead};
fn skip_until<R: BufRead + ?Sized>(r: &mut R, delim: u8) -> Result<usize, std::io::Error> {
let mut read = 0;
loop {
let (done, used) = {
let available = match r.fill_buf() {
Ok(n) => n,
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
};
match memchr::memchr(delim, available) {
Some(i) => (true, i + 1),
None => (false, available.len()),
}
};
r.consume(used);
read += used;
if done || used == 0 {
return Ok(read);
}
}
}
const STR: &[u8] = b"Ferris\0Hello, world!\0";
#[bench]
fn bench_skip_until(b: &mut Bencher) {
b.iter(|| {
let mut io = std::io::Cursor::new(test::black_box(STR));
skip_until(&mut io, b'\0').unwrap();
let mut hello = Vec::with_capacity(b"Hello, world!\0".len());
let num_bytes = io.read_until(b'\0', &mut hello).unwrap();
assert_eq!(num_bytes, b"Hello, world!\0".len());
assert_eq!(hello, b"Hello, world!\0");
});
}
#[bench]
fn bench_read_until(b: &mut Bencher) {
b.iter(|| {
let mut io = std::io::Cursor::new(test::black_box(STR));
io.read_until(b'\0', &mut Vec::new()).unwrap();
let mut hello = Vec::with_capacity(b"Hello, world!\0".len());
let num_bytes = io.read_until(b'\0', &mut hello).unwrap();
assert_eq!(num_bytes, b"Hello, world!\0".len());
assert_eq!(hello, b"Hello, world!\0");
});
}
```
</details>
|
|
Add Seek::seek_relative
The `BufReader` struct has a `seek_relative` method because its `Seek::seek` implementation involved dumping the internal buffer (https://github.com/rust-lang/rust/issues/31100).
Unfortunately, there isn't really a good way to take advantage of that method in generic code. This PR adds the same method to the main `Seek` trait with the straightforward default method, and an override for `BufReader` that calls its implementation.
_Also discussed in [this](https://internals.rust-lang.org/t/add-seek-seek-relative/19546) internals.rust-lang.org thread._
|
|
Assigned new feature name `core_io_borrowed_buf` to distinguish from the
`Read::read_buf` functionality in `std::io`.
|
|
|
|
|
|
|
|
|
|
This reduces the runtime for a simple program using `Bytes::next` to
iterate through a file from 220ms to 70ms on my Linux box.
|
|
|
|
This greatly increases its speed.
|
|
|
|
This variable seems to serve no purpose, and it's a little confusing
when reading std source code, so remove it.
|
|
|
|
|
|
add more explicit I/O safety documentation
Fixes https://github.com/rust-lang/unsafe-code-guidelines/issues/434
Cc https://github.com/rust-lang/rust/issues/114167
Cc `@Manishearth` `@sunfishcode` `@joshtriplett`
|
|
|
|
|
|
|
|
|
|
Co-authored-by: Dan Gohman <dev@sunfishcode.online>
|
|
`Ok(0)` is indeed something the caller may interpret as an error, but
that's the *correct* thing to return if the writer can't accept any more
bytes.
|
|
|
|
|
|
|
|
|
|
|