├── .github └── workflows │ └── ci.yml ├── .gitignore ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── src ├── error.rs ├── io │ ├── buffered.rs │ ├── cursor.rs │ ├── error.rs │ ├── impls.rs │ ├── mod.rs │ ├── traits.rs │ └── util.rs └── lib.rs └── tests └── tests.rs /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | test-nightly: 6 | runs-on: ${{ matrix.os }} 7 | strategy: 8 | fail-fast: false 9 | matrix: 10 | os: [ubuntu-latest, windows-latest, macos-latest] 11 | rust: [nightly] 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Install Rust toolchain 15 | uses: actions-rs/toolchain@v1 16 | with: 17 | toolchain: ${{ matrix.rust }} 18 | override: true 19 | - name: Run tests (no_std) 20 | uses: actions-rs/cargo@v1 21 | with: 22 | command: test 23 | args: --tests --no-default-features --features nightly 24 | - name: Run tests (std) 25 | uses: actions-rs/cargo@v1 26 | with: 27 | command: test 28 | args: --tests --no-default-features --features std,nightly 29 | - name: Run tests (alloc) 30 | uses: actions-rs/cargo@v1 31 | with: 32 | command: test 33 | args: --tests --no-default-features --features alloc,nightly 34 | test-stable: 35 | runs-on: ${{ matrix.os }} 36 | strategy: 37 | fail-fast: false 38 | matrix: 39 | os: [ubuntu-latest, windows-latest, macos-latest] 40 | rust: [stable] 41 | steps: 42 | - uses: actions/checkout@v2 43 | - name: Install Rust toolchain 44 | uses: actions-rs/toolchain@v1 45 | with: 46 | toolchain: ${{ matrix.rust }} 47 | override: true 48 | - name: Run tests (no_std) 49 | uses: actions-rs/cargo@v1 50 | with: 51 | command: test 52 | args: --no-default-features 53 | - name: Run tests (std) 54 | uses: actions-rs/cargo@v1 55 | with: 56 | command: test 57 | args: --no-default-features --features std 58 | - name: Run tests (alloc) 59 | uses: actions-rs/cargo@v1 60 | with: 61 | command: test 62 | args: --no-default-features --features alloc 63 | test-msrv: 64 | runs-on: ${{ matrix.os }} 65 | strategy: 66 | fail-fast: false 67 | matrix: 68 | os: [ubuntu-latest, windows-latest, macos-latest] 69 | rust: [1.47] 70 | steps: 71 | - uses: actions/checkout@v2 72 | - name: Install Rust toolchain 73 | uses: actions-rs/toolchain@v1 74 | with: 75 | toolchain: ${{ matrix.rust }} 76 | override: true 77 | - name: Run tests (no_std) 78 | uses: actions-rs/cargo@v1 79 | with: 80 | command: test 81 | args: --no-default-features 82 | - name: Run tests (std) 83 | uses: actions-rs/cargo@v1 84 | with: 85 | command: test 86 | args: --no-default-features --features std 87 | - name: Run tests (alloc) 88 | uses: actions-rs/cargo@v1 89 | with: 90 | command: test 91 | args: --no-default-features --features alloc 92 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | 3 | 4 | #Added by cargo 5 | # 6 | #already existing elements were commented out 7 | 8 | #/target 9 | Cargo.lock 10 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "core2" 3 | version = "0.4.0" 4 | authors = ["Brendan Molloy "] 5 | description = "The bare essentials of std::io for use in no_std. Alloc support is optional." 6 | license = "Apache-2.0 OR MIT" 7 | edition = "2018" 8 | repository = "https://github.com/bbqsrc/core2" 9 | categories = ["no-std"] 10 | 11 | [dependencies] 12 | memchr = { version = "2", default-features = false } 13 | 14 | [features] 15 | default = ["std"] 16 | std = ["alloc"] 17 | alloc = [] 18 | nightly = [] 19 | 20 | [package.metadata.docs.rs] 21 | features = ["nightly"] 22 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021 Brendan Molloy 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # core2 2 | 3 | [![Actions Status](https://github.com/bbqsrc/core2/workflows/CI/badge.svg)](https://github.com/bbqsrc/core2/actions) 4 | [![Documentation](https://docs.rs/core2/badge.svg)](https://docs.rs/core2) 5 | ![Minimum Supported Rust Version (MSRV)](https://img.shields.io/badge/rust-v1.47.0+-blue) 6 | 7 | Ever wanted a `Cursor` or the `Error` trait in `no_std`? Well now you can have it. A 'fork' of Rust's `std` modules for `no_std` environments, with the added benefit of optionally taking advantage of `alloc`. 8 | 9 | The goal of this crate is to provide a stable interface for building I/O and error trait functionality in 10 | `no_std` environments. The current code corresponds to the most recent stable API of Rust 1.47.0. 11 | It is also a goal to achieve a true alloc-less experience, with opt-in alloc support. 12 | 13 | This crate works on `stable` with some limitations in functionality, and `nightly` without limitations by adding 14 | the relevant feature flag. 15 | 16 | This crate is `std` by default -- use no default features to get `no_std` mode. 17 | 18 | ## Usage 19 | 20 | ```toml 21 | [dependencies] 22 | core2 = "0.3" 23 | ``` 24 | 25 | Add the crate, use the things you would usually want from `std::io`, but instead from `core2::io`, and 26 | use `core2::error::Error` in place of `std::error::Error`. 27 | 28 | ### Features 29 | 30 | - **std**: enables `std` pass-throughs for the polyfilled types, but allows accessing the new types 31 | - **alloc**: enable aspects of the `Read` and `Write` traits that require `alloc` support (WIP) 32 | - **nightly**: enables **nightly**-only features, such as `BufReader` and `BufWriter` with const generic buffers. 33 | 34 | ### Differences to `std::io` 35 | 36 | - No `std::io::Error`, so we have our own copy without any `Os` error functions 37 | - `IoSlice` and the `*_vectored` family of functions are not implemented. 38 | - `BufReader` and `BufWriter` have a different signature, as they now use a const generic bounded array for the internal buffer. (Requires **nightly** feature) 39 | 40 | Other than items perhaps being entirely missing or certain functions unavailable on some traits, no function signatures have been changed. 41 | 42 | ### Limitations 43 | 44 | - Using the buffer types currently requires **nightly** due to the use of const generics. 45 | - Using `copy` or the buffer types with `std` support currently requires **nightly** due to the `initializer` API. 46 | 47 | ## Where is it used? 48 | 49 | All of the below are works in progress, but should help with demonstrating how to use this crate. 50 | 51 | - [thiserror_core2](https://github.com/bbqsrc/thiserror-core2): fork of `thiserror` using the `core2::error::Error` trait. 52 | 53 | ## License 54 | 55 | Licensed under either of 56 | 57 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 58 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 59 | 60 | at your option. 61 | 62 | --- 63 | 64 | Almost all of the code in this repository is a copy of the [Rust language codebase](https://github.com/rust-lang/rust) with minor modifications. 65 | 66 | For attributions, see https://thanks.rust-lang.org/. 67 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | //! Traits for working with Errors. 2 | 3 | // A note about crates and the facade: 4 | // 5 | // Originally, the `Error` trait was defined in libcore, and the impls 6 | // were scattered about. However, coherence objected to this 7 | // arrangement, because to create the blanket impls for `Box` required 8 | // knowing that `&str: !Error`, and we have no means to deal with that 9 | // sort of conflict just now. Therefore, for the time being, we have 10 | // moved the `Error` trait into libstd. As we evolve a sol'n to the 11 | // coherence challenge (e.g., specialization, neg impls, etc) we can 12 | // reconsider what crate these items belong in. 13 | 14 | #[allow(deprecated)] 15 | use core::alloc::LayoutErr; 16 | 17 | use core::any::TypeId; 18 | use core::fmt::{Debug, Display}; 19 | 20 | #[cfg(feature = "alloc")] 21 | use alloc::{string::String, borrow::Cow, boxed::Box}; 22 | 23 | /// `Error` is a trait representing the basic expectations for error values, 24 | /// i.e., values of type `E` in [`Result`]. Errors must describe 25 | /// themselves through the [`Display`] and [`Debug`] traits, and may provide 26 | /// cause chain information: 27 | /// 28 | /// [`Error::source()`] is generally used when errors cross 29 | /// "abstraction boundaries". If one module must report an error that is caused 30 | /// by an error from a lower-level module, it can allow accessing that error 31 | /// via [`Error::source()`]. This makes it possible for the high-level 32 | /// module to provide its own errors while also revealing some of the 33 | /// implementation for debugging via `source` chains. 34 | /// 35 | /// [`Result`]: Result 36 | pub trait Error: Debug + Display { 37 | /// The lower-level source of this error, if any. 38 | /// 39 | /// # Examples 40 | /// 41 | /// ``` 42 | /// use std::error::Error; 43 | /// use std::fmt; 44 | /// 45 | /// #[derive(Debug)] 46 | /// struct SuperError { 47 | /// side: SuperErrorSideKick, 48 | /// } 49 | /// 50 | /// impl fmt::Display for SuperError { 51 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 52 | /// write!(f, "SuperError is here!") 53 | /// } 54 | /// } 55 | /// 56 | /// impl Error for SuperError { 57 | /// fn source(&self) -> Option<&(dyn Error + 'static)> { 58 | /// Some(&self.side) 59 | /// } 60 | /// } 61 | /// 62 | /// #[derive(Debug)] 63 | /// struct SuperErrorSideKick; 64 | /// 65 | /// impl fmt::Display for SuperErrorSideKick { 66 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 67 | /// write!(f, "SuperErrorSideKick is here!") 68 | /// } 69 | /// } 70 | /// 71 | /// impl Error for SuperErrorSideKick {} 72 | /// 73 | /// fn get_super_error() -> Result<(), SuperError> { 74 | /// Err(SuperError { side: SuperErrorSideKick }) 75 | /// } 76 | /// 77 | /// fn main() { 78 | /// match get_super_error() { 79 | /// Err(e) => { 80 | /// println!("Error: {}", e); 81 | /// println!("Caused by: {}", e.source().unwrap()); 82 | /// } 83 | /// _ => println!("No error"), 84 | /// } 85 | /// } 86 | /// ``` 87 | fn source(&self) -> Option<&(dyn Error + 'static)> { 88 | None 89 | } 90 | 91 | /// Gets the `TypeId` of `self`. 92 | #[doc(hidden)] 93 | fn type_id(&self, _: private::Internal) -> TypeId 94 | where 95 | Self: 'static, 96 | { 97 | TypeId::of::() 98 | } 99 | } 100 | 101 | mod private { 102 | // This is a hack to prevent `type_id` from being overridden by `Error` 103 | // implementations, since that can enable unsound downcasting. 104 | #[derive(Debug)] 105 | pub struct Internal; 106 | } 107 | 108 | #[cfg(feature = "alloc")] 109 | impl<'a, E: Error + 'a> From for Box { 110 | /// Converts a type of [`Error`] into a box of dyn [`Error`]. 111 | /// 112 | /// # Examples 113 | /// 114 | /// ``` 115 | /// use std::error::Error; 116 | /// use std::fmt; 117 | /// use std::mem; 118 | /// 119 | /// #[derive(Debug)] 120 | /// struct AnError; 121 | /// 122 | /// impl fmt::Display for AnError { 123 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 124 | /// write!(f , "An error") 125 | /// } 126 | /// } 127 | /// 128 | /// impl Error for AnError {} 129 | /// 130 | /// let an_error = AnError; 131 | /// assert!(0 == mem::size_of_val(&an_error)); 132 | /// let a_boxed_error = Box::::from(an_error); 133 | /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) 134 | /// ``` 135 | fn from(err: E) -> Box { 136 | Box::new(err) 137 | } 138 | } 139 | 140 | #[cfg(feature = "alloc")] 141 | impl<'a, E: Error + Send + Sync + 'a> From for Box { 142 | /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of 143 | /// dyn [`Error`] + [`Send`] + [`Sync`]. 144 | /// 145 | /// # Examples 146 | /// 147 | /// ``` 148 | /// use std::error::Error; 149 | /// use std::fmt; 150 | /// use std::mem; 151 | /// 152 | /// #[derive(Debug)] 153 | /// struct AnError; 154 | /// 155 | /// impl fmt::Display for AnError { 156 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 157 | /// write!(f , "An error") 158 | /// } 159 | /// } 160 | /// 161 | /// impl Error for AnError {} 162 | /// 163 | /// unsafe impl Send for AnError {} 164 | /// 165 | /// unsafe impl Sync for AnError {} 166 | /// 167 | /// let an_error = AnError; 168 | /// assert!(0 == mem::size_of_val(&an_error)); 169 | /// let a_boxed_error = Box::::from(an_error); 170 | /// assert!( 171 | /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) 172 | /// ``` 173 | fn from(err: E) -> Box { 174 | Box::new(err) 175 | } 176 | } 177 | 178 | #[cfg(feature = "alloc")] 179 | impl From for Box { 180 | /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. 181 | /// 182 | /// # Examples 183 | /// 184 | /// ``` 185 | /// use std::error::Error; 186 | /// use std::mem; 187 | /// 188 | /// let a_string_error = "a string error".to_string(); 189 | /// let a_boxed_error = Box::::from(a_string_error); 190 | /// assert!( 191 | /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) 192 | /// ``` 193 | #[inline] 194 | fn from(err: String) -> Box { 195 | struct StringError(String); 196 | 197 | impl Error for StringError {} 198 | 199 | impl Display for StringError { 200 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 201 | Display::fmt(&self.0, f) 202 | } 203 | } 204 | 205 | // Purposefully skip printing "StringError(..)" 206 | impl Debug for StringError { 207 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 208 | Debug::fmt(&self.0, f) 209 | } 210 | } 211 | 212 | Box::new(StringError(err)) 213 | } 214 | } 215 | 216 | #[cfg(feature = "alloc")] 217 | impl From for Box { 218 | /// Converts a [`String`] into a box of dyn [`Error`]. 219 | /// 220 | /// # Examples 221 | /// 222 | /// ``` 223 | /// use std::error::Error; 224 | /// use std::mem; 225 | /// 226 | /// let a_string_error = "a string error".to_string(); 227 | /// let a_boxed_error = Box::::from(a_string_error); 228 | /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) 229 | /// ``` 230 | fn from(str_err: String) -> Box { 231 | let err1: Box = From::from(str_err); 232 | let err2: Box = err1; 233 | err2 234 | } 235 | } 236 | 237 | #[cfg(feature = "alloc")] 238 | impl<'a> From<&str> for Box { 239 | /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. 240 | /// 241 | /// [`str`]: prim@str 242 | /// 243 | /// # Examples 244 | /// 245 | /// ``` 246 | /// use std::error::Error; 247 | /// use std::mem; 248 | /// 249 | /// let a_str_error = "a str error"; 250 | /// let a_boxed_error = Box::::from(a_str_error); 251 | /// assert!( 252 | /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) 253 | /// ``` 254 | #[inline] 255 | fn from(err: &str) -> Box { 256 | From::from(String::from(err)) 257 | } 258 | } 259 | 260 | #[cfg(feature = "alloc")] 261 | impl From<&str> for Box { 262 | /// Converts a [`str`] into a box of dyn [`Error`]. 263 | /// 264 | /// [`str`]: prim@str 265 | /// 266 | /// # Examples 267 | /// 268 | /// ``` 269 | /// use std::error::Error; 270 | /// use std::mem; 271 | /// 272 | /// let a_str_error = "a str error"; 273 | /// let a_boxed_error = Box::::from(a_str_error); 274 | /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) 275 | /// ``` 276 | fn from(err: &str) -> Box { 277 | From::from(String::from(err)) 278 | } 279 | } 280 | 281 | #[cfg(feature = "alloc")] 282 | impl<'a, 'b> From> for Box { 283 | /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. 284 | /// 285 | /// # Examples 286 | /// 287 | /// ``` 288 | /// use std::error::Error; 289 | /// use std::mem; 290 | /// use std::borrow::Cow; 291 | /// 292 | /// let a_cow_str_error = Cow::from("a str error"); 293 | /// let a_boxed_error = Box::::from(a_cow_str_error); 294 | /// assert!( 295 | /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) 296 | /// ``` 297 | fn from(err: Cow<'b, str>) -> Box { 298 | From::from(String::from(err)) 299 | } 300 | } 301 | 302 | #[cfg(feature = "alloc")] 303 | impl<'a> From> for Box { 304 | /// Converts a [`Cow`] into a box of dyn [`Error`]. 305 | /// 306 | /// # Examples 307 | /// 308 | /// ``` 309 | /// use std::error::Error; 310 | /// use std::mem; 311 | /// use std::borrow::Cow; 312 | /// 313 | /// let a_cow_str_error = Cow::from("a str error"); 314 | /// let a_boxed_error = Box::::from(a_cow_str_error); 315 | /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) 316 | /// ``` 317 | fn from(err: Cow<'a, str>) -> Box { 318 | From::from(String::from(err)) 319 | } 320 | } 321 | 322 | // #[unstable(feature = "never_type", issue = "35121")] 323 | #[cfg(feature = "nightly")] 324 | impl Error for ! {} 325 | 326 | #[allow(deprecated)] 327 | impl Error for LayoutErr {} 328 | 329 | impl Error for core::str::ParseBoolError {} 330 | 331 | impl Error for core::str::Utf8Error {} 332 | 333 | impl Error for core::num::ParseIntError {} 334 | 335 | impl Error for core::num::TryFromIntError {} 336 | 337 | impl Error for core::array::TryFromSliceError {} 338 | 339 | impl Error for core::num::ParseFloatError {} 340 | 341 | #[cfg(feature = "alloc")] 342 | impl Error for alloc::string::FromUtf8Error {} 343 | 344 | #[cfg(feature = "alloc")] 345 | impl Error for alloc::string::FromUtf16Error {} 346 | 347 | 348 | #[cfg(feature = "alloc")] 349 | impl Error for Box { 350 | fn source(&self) -> Option<&(dyn Error + 'static)> { 351 | Error::source(&**self) 352 | } 353 | } 354 | 355 | // Copied from `any.rs`. 356 | impl dyn Error + 'static { 357 | /// Returns `true` if the boxed type is the same as `T` 358 | #[inline] 359 | pub fn is(&self) -> bool { 360 | // Get `TypeId` of the type this function is instantiated with. 361 | let t = TypeId::of::(); 362 | 363 | // Get `TypeId` of the type in the trait object. 364 | let boxed = self.type_id(private::Internal); 365 | 366 | // Compare both `TypeId`s on equality. 367 | t == boxed 368 | } 369 | 370 | /// Returns some reference to the boxed value if it is of type `T`, or 371 | /// `None` if it isn't. 372 | #[inline] 373 | pub fn downcast_ref(&self) -> Option<&T> { 374 | if self.is::() { 375 | unsafe { Some(&*(self as *const dyn Error as *const T)) } 376 | } else { 377 | None 378 | } 379 | } 380 | 381 | /// Returns some mutable reference to the boxed value if it is of type `T`, or 382 | /// `None` if it isn't. 383 | #[inline] 384 | pub fn downcast_mut(&mut self) -> Option<&mut T> { 385 | if self.is::() { 386 | unsafe { Some(&mut *(self as *mut dyn Error as *mut T)) } 387 | } else { 388 | None 389 | } 390 | } 391 | } 392 | 393 | impl dyn Error + 'static + Send { 394 | /// Forwards to the method defined on the type `dyn Error`. 395 | #[inline] 396 | pub fn is(&self) -> bool { 397 | ::is::(self) 398 | } 399 | 400 | /// Forwards to the method defined on the type `dyn Error`. 401 | #[inline] 402 | pub fn downcast_ref(&self) -> Option<&T> { 403 | ::downcast_ref::(self) 404 | } 405 | 406 | /// Forwards to the method defined on the type `dyn Error`. 407 | #[inline] 408 | pub fn downcast_mut(&mut self) -> Option<&mut T> { 409 | ::downcast_mut::(self) 410 | } 411 | } 412 | 413 | impl dyn Error + 'static + Send + Sync { 414 | /// Forwards to the method defined on the type `dyn Error`. 415 | #[inline] 416 | pub fn is(&self) -> bool { 417 | ::is::(self) 418 | } 419 | 420 | /// Forwards to the method defined on the type `dyn Error`. 421 | #[inline] 422 | pub fn downcast_ref(&self) -> Option<&T> { 423 | ::downcast_ref::(self) 424 | } 425 | 426 | /// Forwards to the method defined on the type `dyn Error`. 427 | #[inline] 428 | pub fn downcast_mut(&mut self) -> Option<&mut T> { 429 | ::downcast_mut::(self) 430 | } 431 | } 432 | 433 | #[cfg(feature = "alloc")] 434 | impl dyn Error { 435 | #[inline] 436 | /// Attempts to downcast the box to a concrete type. 437 | pub fn downcast(self: Box) -> Result, Box> { 438 | if self.is::() { 439 | unsafe { 440 | let raw: *mut dyn Error = Box::into_raw(self); 441 | Ok(Box::from_raw(raw as *mut T)) 442 | } 443 | } else { 444 | Err(self) 445 | } 446 | } 447 | } 448 | 449 | #[cfg(feature = "alloc")] 450 | impl dyn Error + Send { 451 | #[inline] 452 | /// Attempts to downcast the box to a concrete type. 453 | pub fn downcast(self: Box) -> Result, Box> { 454 | let err: Box = self; 455 | ::downcast(err).map_err(|s| unsafe { 456 | // Reapply the `Send` marker. 457 | core::mem::transmute::, Box>(s) 458 | }) 459 | } 460 | } 461 | 462 | #[cfg(feature = "alloc")] 463 | impl dyn Error + Send + Sync { 464 | #[inline] 465 | /// Attempts to downcast the box to a concrete type. 466 | pub fn downcast(self: Box) -> Result, Box> { 467 | let err: Box = self; 468 | ::downcast(err).map_err(|s| unsafe { 469 | // Reapply the `Send + Sync` marker. 470 | core::mem::transmute::, Box>(s) 471 | }) 472 | } 473 | } 474 | -------------------------------------------------------------------------------- /src/io/buffered.rs: -------------------------------------------------------------------------------- 1 | //! Buffering wrappers for I/O traits 2 | 3 | use crate::io::{BufRead, Error, ErrorKind, Read, Result, Seek, SeekFrom, Write}; 4 | use core::{cmp, fmt}; 5 | 6 | /// The `BufReader` struct adds buffering to any reader. 7 | /// 8 | /// It can be excessively inefficient to work directly with a [`Read`] instance. 9 | /// For example, every call to [`read`][`TcpStream::read`] on [`TcpStream`] 10 | /// results in a system call. A `BufReader` performs large, infrequent reads on 11 | /// the underlying [`Read`] and maintains an in-memory buffer of the results. 12 | /// 13 | /// `BufReader` can improve the speed of programs that make *small* and 14 | /// *repeated* read calls to the same file or network socket. It does not 15 | /// help when reading very large amounts at once, or reading just one or a few 16 | /// times. It also provides no advantage when reading from a source that is 17 | /// already in memory, like a [`Vec`]``. 18 | /// 19 | /// When the `BufReader` is dropped, the contents of its buffer will be 20 | /// discarded. Creating multiple instances of a `BufReader` on the same 21 | /// stream can cause data loss. Reading from the underlying reader after 22 | /// unwrapping the `BufReader` with [`BufReader::into_inner`] can also cause 23 | /// data loss. 24 | /// 25 | /// [`TcpStream::read`]: Read::read 26 | /// [`TcpStream`]: crate::net::TcpStream 27 | /// 28 | /// # Examples 29 | /// 30 | /// ```no_run 31 | /// use std::prelude::*; 32 | /// use core2::io::BufReader; 33 | /// use std::fs::File; 34 | /// 35 | /// fn main() -> core::result::Result<()> { 36 | /// let f = File::open("log.txt")?; 37 | /// let mut reader = BufReader::new(f); 38 | /// 39 | /// let mut line = String::new(); 40 | /// let len = reader.read_line(&mut line)?; 41 | /// println!("First line is {} bytes long", len); 42 | /// Ok(()) 43 | /// } 44 | /// ``` 45 | pub struct BufReader { 46 | inner: R, 47 | buf: [u8; S], 48 | pos: usize, 49 | cap: usize, 50 | } 51 | 52 | impl BufReader { 53 | /// Creates a new `BufReader` with a default buffer capacity. The default is currently 8 KB, 54 | /// but may change in the future. 55 | /// 56 | /// # Examples 57 | /// 58 | /// ```no_run 59 | /// use core2::io::BufReader; 60 | /// use std::fs::File; 61 | /// 62 | /// fn main() -> core::result::Result<()> { 63 | /// let f = File::open("log.txt")?; 64 | /// let reader = BufReader::new(f); 65 | /// Ok(()) 66 | /// } 67 | /// ``` 68 | pub fn new(inner: R) -> BufReader { 69 | BufReader { 70 | inner, 71 | buf: [0; S], 72 | pos: 0, 73 | cap: 0, 74 | } 75 | } 76 | } 77 | 78 | impl BufReader { 79 | /// Gets a reference to the underlying reader. 80 | /// 81 | /// It is inadvisable to directly read from the underlying reader. 82 | /// 83 | /// # Examples 84 | /// 85 | /// ```no_run 86 | /// use core2::io::BufReader; 87 | /// use std::fs::File; 88 | /// 89 | /// fn main() -> core::result::Result<()> { 90 | /// let f1 = File::open("log.txt")?; 91 | /// let reader = BufReader::new(f1); 92 | /// 93 | /// let f2 = reader.get_ref(); 94 | /// Ok(()) 95 | /// } 96 | /// ``` 97 | pub fn get_ref(&self) -> &R { 98 | &self.inner 99 | } 100 | 101 | /// Gets a mutable reference to the underlying reader. 102 | /// 103 | /// It is inadvisable to directly read from the underlying reader. 104 | /// 105 | /// # Examples 106 | /// 107 | /// ```no_run 108 | /// use core2::io::BufReader; 109 | /// use std::fs::File; 110 | /// 111 | /// fn main() -> core::result::Result<()> { 112 | /// let f1 = File::open("log.txt")?; 113 | /// let mut reader = BufReader::new(f1); 114 | /// 115 | /// let f2 = reader.get_mut(); 116 | /// Ok(()) 117 | /// } 118 | /// ``` 119 | pub fn get_mut(&mut self) -> &mut R { 120 | &mut self.inner 121 | } 122 | 123 | /// Returns a reference to the internally buffered data. 124 | /// 125 | /// Unlike [`fill_buf`], this will not attempt to fill the buffer if it is empty. 126 | /// 127 | /// [`fill_buf`]: BufRead::fill_buf 128 | /// 129 | /// # Examples 130 | /// 131 | /// ```no_run 132 | /// use std::{BufReader, BufRead}; 133 | /// use std::fs::File; 134 | /// 135 | /// fn main() -> core::result::Result<()> { 136 | /// let f = File::open("log.txt")?; 137 | /// let mut reader = BufReader::new(f); 138 | /// assert!(reader.buffer().is_empty()); 139 | /// 140 | /// if reader.fill_buf()?.len() > 0 { 141 | /// assert!(!reader.buffer().is_empty()); 142 | /// } 143 | /// Ok(()) 144 | /// } 145 | /// ``` 146 | pub fn buffer(&self) -> &[u8] { 147 | &self.buf[self.pos..self.cap] 148 | } 149 | 150 | /// Returns the number of bytes the internal buffer can hold at once. 151 | /// 152 | /// # Examples 153 | /// 154 | /// ```no_run 155 | /// use std::{BufReader, BufRead}; 156 | /// use std::fs::File; 157 | /// 158 | /// fn main() -> core::result::Result<()> { 159 | /// let f = File::open("log.txt")?; 160 | /// let mut reader = BufReader::new(f); 161 | /// 162 | /// let capacity = reader.capacity(); 163 | /// let buffer = reader.fill_buf()?; 164 | /// assert!(buffer.len() <= capacity); 165 | /// Ok(()) 166 | /// } 167 | /// ``` 168 | pub fn capacity(&self) -> usize { 169 | S 170 | } 171 | 172 | /// Unwraps this `BufReader`, returning the underlying reader. 173 | /// 174 | /// Note that any leftover data in the internal buffer is lost. Therefore, 175 | /// a following read from the underlying reader may lead to data loss. 176 | /// 177 | /// # Examples 178 | /// 179 | /// ```no_run 180 | /// use core2::io::BufReader; 181 | /// use std::fs::File; 182 | /// 183 | /// fn main() -> core::result::Result<()> { 184 | /// let f1 = File::open("log.txt")?; 185 | /// let reader = BufReader::new(f1); 186 | /// 187 | /// let f2 = reader.into_inner(); 188 | /// Ok(()) 189 | /// } 190 | /// ``` 191 | pub fn into_inner(self) -> R { 192 | self.inner 193 | } 194 | 195 | /// Invalidates all data in the internal buffer. 196 | #[inline] 197 | fn discard_buffer(&mut self) { 198 | self.pos = 0; 199 | self.cap = 0; 200 | } 201 | } 202 | 203 | impl Read for BufReader { 204 | fn read(&mut self, buf: &mut [u8]) -> Result { 205 | // If we don't have any buffered data and we're doing a massive read 206 | // (larger than our internal buffer), bypass our internal buffer 207 | // entirely. 208 | if self.pos == self.cap && buf.len() >= S { 209 | self.discard_buffer(); 210 | return self.inner.read(buf); 211 | } 212 | let nread = { 213 | let mut rem = self.fill_buf()?; 214 | rem.read(buf)? 215 | }; 216 | self.consume(nread); 217 | Ok(nread) 218 | } 219 | } 220 | 221 | impl BufRead for BufReader { 222 | fn fill_buf(&mut self) -> Result<&[u8]> { 223 | // If we've reached the end of our internal buffer then we need to fetch 224 | // some more data from the underlying reader. 225 | // Branch using `>=` instead of the more correct `==` 226 | // to tell the compiler that the pos..cap slice is always valid. 227 | if self.pos >= self.cap { 228 | debug_assert!(self.pos == self.cap); 229 | self.cap = self.inner.read(&mut self.buf)?; 230 | self.pos = 0; 231 | } 232 | Ok(&self.buf[self.pos..self.cap]) 233 | } 234 | 235 | fn consume(&mut self, amt: usize) { 236 | self.pos = cmp::min(self.pos + amt, self.cap); 237 | } 238 | } 239 | 240 | impl fmt::Debug for BufReader 241 | where 242 | R: fmt::Debug, 243 | { 244 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 245 | fmt.debug_struct("BufReader") 246 | .field("reader", &self.inner) 247 | .field("buffer", &format_args!("{}/{}", self.cap - self.pos, S)) 248 | .finish() 249 | } 250 | } 251 | 252 | impl Seek for BufReader { 253 | /// Seek to an offset, in bytes, in the underlying reader. 254 | /// 255 | /// The position used for seeking with [`SeekFrom::Current`]`(_)` is the 256 | /// position the underlying reader would be at if the `BufReader` had no 257 | /// internal buffer. 258 | /// 259 | /// Seeking always discards the internal buffer, even if the seek position 260 | /// would otherwise fall within it. This guarantees that calling 261 | /// [`BufReader::into_inner()`] immediately after a seek yields the underlying reader 262 | /// at the same position. 263 | /// 264 | /// To seek without discarding the internal buffer, use [`BufReader::seek_relative`]. 265 | /// 266 | /// See [`std::Seek`] for more details. 267 | /// 268 | /// Note: In the edge case where you're seeking with [`SeekFrom::Current`]`(n)` 269 | /// where `n` minus the internal buffer length overflows an `i64`, two 270 | /// seeks will be performed instead of one. If the second seek returns 271 | /// [`Err`], the underlying reader will be left at the same position it would 272 | /// have if you called `seek` with [`SeekFrom::Current`]`(0)`. 273 | /// 274 | /// [`std::Seek`]: Seek 275 | fn seek(&mut self, pos: SeekFrom) -> Result { 276 | let result: u64; 277 | if let SeekFrom::Current(n) = pos { 278 | let remainder = (self.cap - self.pos) as i64; 279 | // it should be safe to assume that remainder fits within an i64 as the alternative 280 | // means we managed to allocate 8 exbibytes and that's absurd. 281 | // But it's not out of the realm of possibility for some weird underlying reader to 282 | // support seeking by i64::MIN so we need to handle underflow when subtracting 283 | // remainder. 284 | if let Some(offset) = n.checked_sub(remainder) { 285 | result = self.inner.seek(SeekFrom::Current(offset))?; 286 | } else { 287 | // seek backwards by our remainder, and then by the offset 288 | self.inner.seek(SeekFrom::Current(-remainder))?; 289 | self.discard_buffer(); 290 | result = self.inner.seek(SeekFrom::Current(n))?; 291 | } 292 | } else { 293 | // Seeking with Start/End doesn't care about our buffer length. 294 | result = self.inner.seek(pos)?; 295 | } 296 | self.discard_buffer(); 297 | Ok(result) 298 | } 299 | } 300 | 301 | /// Wraps a writer and buffers its output. 302 | /// 303 | /// It can be excessively inefficient to work directly with something that 304 | /// implements [`Write`]. For example, every call to 305 | /// [`write`][`TcpStream::write`] on [`TcpStream`] results in a system call. A 306 | /// `BufWriter` keeps an in-memory buffer of data and writes it to an underlying 307 | /// writer in large, infrequent batches. 308 | /// 309 | /// `BufWriter` can improve the speed of programs that make *small* and 310 | /// *repeated* write calls to the same file or network socket. It does not 311 | /// help when writing very large amounts at once, or writing just one or a few 312 | /// times. It also provides no advantage when writing to a destination that is 313 | /// in memory, like a [`Vec`]`. 314 | /// 315 | /// It is critical to call [`flush`] before `BufWriter` is dropped. Though 316 | /// dropping will attempt to flush the contents of the buffer, any errors 317 | /// that happen in the process of dropping will be ignored. Calling [`flush`] 318 | /// ensures that the buffer is empty and thus dropping will not even attempt 319 | /// file operations. 320 | /// 321 | /// # Examples 322 | /// 323 | /// Let's write the numbers one through ten to a [`TcpStream`]: 324 | /// 325 | /// ```no_run 326 | /// use std::prelude::*; 327 | /// use std::net::TcpStream; 328 | /// 329 | /// let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap(); 330 | /// 331 | /// for i in 0..10 { 332 | /// stream.write(&[i+1]).unwrap(); 333 | /// } 334 | /// ``` 335 | /// 336 | /// Because we're not buffering, we write each one in turn, incurring the 337 | /// overhead of a system call per byte written. We can fix this with a 338 | /// `BufWriter`: 339 | /// 340 | /// ```no_run 341 | /// use std::prelude::*; 342 | /// use core2::io::BufWriter; 343 | /// use std::net::TcpStream; 344 | /// 345 | /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 346 | /// 347 | /// for i in 0..10 { 348 | /// stream.write(&[i+1]).unwrap(); 349 | /// } 350 | /// stream.flush().unwrap(); 351 | /// ``` 352 | /// 353 | /// By wrapping the stream with a `BufWriter`, these ten writes are all grouped 354 | /// together by the buffer and will all be written out in one system call when 355 | /// the `stream` is flushed. 356 | /// 357 | /// [`TcpStream::write`]: Write::write 358 | /// [`TcpStream`]: crate::net::TcpStream 359 | /// [`flush`]: Write::flush 360 | pub struct BufWriter { 361 | inner: Option, 362 | buf: [u8; S], 363 | len: usize, 364 | // #30888: If the inner writer panics in a call to write, we don't want to 365 | // write the buffered data a second time in BufWriter's destructor. This 366 | // flag tells the Drop impl if it should skip the flush. 367 | panicked: bool, 368 | } 369 | 370 | /// An error returned by [`BufWriter::into_inner`] which combines an error that 371 | /// happened while writing out the buffer, and the buffered writer object 372 | /// which may be used to recover from the condition. 373 | /// 374 | /// # Examples 375 | /// 376 | /// ```no_run 377 | /// use core2::io::BufWriter; 378 | /// use std::net::TcpStream; 379 | /// 380 | /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 381 | /// 382 | /// // do stuff with the stream 383 | /// 384 | /// // we want to get our `TcpStream` back, so let's try: 385 | /// 386 | /// let stream = match stream.into_inner() { 387 | /// Ok(s) => s, 388 | /// Err(e) => { 389 | /// // Here, e is an IntoInnerError 390 | /// panic!("An error occurred"); 391 | /// } 392 | /// }; 393 | /// ``` 394 | #[derive(Debug)] 395 | pub struct IntoInnerError(W, Error); 396 | 397 | impl BufWriter 398 | where 399 | W: Write, 400 | { 401 | /// Creates a new `BufWriter` with a default buffer capacity. The default is currently 8 KB, 402 | /// but may change in the future. 403 | /// 404 | /// # Examples 405 | /// 406 | /// ```no_run 407 | /// use core2::io::BufWriter; 408 | /// use std::net::TcpStream; 409 | /// 410 | /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 411 | /// ``` 412 | pub fn new(inner: W) -> BufWriter { 413 | BufWriter { 414 | inner: Some(inner), 415 | buf: [0; S], 416 | len: 0, 417 | panicked: false, 418 | } 419 | } 420 | 421 | /// Send data in our local buffer into the inner writer, looping as 422 | /// necessary until either it's all been sent or an error occurs. 423 | /// 424 | /// Because all the data in the buffer has been reported to our owner as 425 | /// "successfully written" (by returning nonzero success values from 426 | /// `write`), any 0-length writes from `inner` must be reported as i/o 427 | /// errors from this method. 428 | fn flush_buf(&mut self) -> Result<()> { 429 | /// Helper struct to ensure the buffer is updated after all the writes 430 | /// are complete. It tracks the number of written bytes and drains them 431 | /// all from the front of the buffer when dropped. 432 | struct BufGuard<'a, const S: usize> { 433 | buffer: &'a mut [u8; S], 434 | written: usize, 435 | } 436 | 437 | impl<'a, const S: usize> BufGuard<'a, S> { 438 | fn new(buffer: &'a mut [u8; S]) -> Self { 439 | Self { buffer, written: 0 } 440 | } 441 | 442 | /// The unwritten part of the buffer 443 | fn remaining(&self) -> &[u8] { 444 | &self.buffer[self.written..] 445 | } 446 | 447 | /// Flag some bytes as removed from the front of the buffer 448 | fn consume(&mut self, amt: usize) { 449 | self.written += amt; 450 | } 451 | 452 | /// true if all of the bytes have been written 453 | fn done(&self) -> bool { 454 | self.written >= self.buffer.len() 455 | } 456 | } 457 | 458 | impl Drop for BufGuard<'_, S> { 459 | fn drop(&mut self) { 460 | if self.written > 0 { 461 | let mut new_buf = [0; S]; 462 | new_buf.copy_from_slice(&self.buffer[self.written..]); 463 | *self.buffer = new_buf; 464 | } 465 | } 466 | } 467 | 468 | let mut guard = BufGuard::new(&mut self.buf); 469 | let inner = self.inner.as_mut().unwrap(); 470 | while !guard.done() { 471 | self.panicked = true; 472 | let r = inner.write(guard.remaining()); 473 | self.panicked = false; 474 | 475 | match r { 476 | Ok(0) => { 477 | return Err(Error::new( 478 | ErrorKind::WriteZero, 479 | "failed to write the buffered data", 480 | )); 481 | } 482 | Ok(n) => guard.consume(n), 483 | Err(ref e) if e.kind() == ErrorKind::Interrupted => {} 484 | Err(e) => return Err(e), 485 | } 486 | } 487 | Ok(()) 488 | } 489 | 490 | /// Buffer some data without flushing it, regardless of the size of the 491 | /// data. Writes as much as possible without exceeding capacity. Returns 492 | /// the number of bytes written. 493 | fn write_to_buf(&mut self, buf: &[u8]) -> usize { 494 | let available = S - self.len; 495 | let amt_to_buffer = available.min(buf.len()); 496 | (&mut self.buf[available..]).copy_from_slice(&buf[..amt_to_buffer]); 497 | self.len += amt_to_buffer; 498 | amt_to_buffer 499 | } 500 | 501 | /// Gets a reference to the underlying writer. 502 | /// 503 | /// # Examples 504 | /// 505 | /// ```no_run 506 | /// use core2::io::BufWriter; 507 | /// use std::net::TcpStream; 508 | /// 509 | /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 510 | /// 511 | /// // we can use reference just like buffer 512 | /// let reference = buffer.get_ref(); 513 | /// ``` 514 | pub fn get_ref(&self) -> &W { 515 | self.inner.as_ref().unwrap() 516 | } 517 | 518 | /// Gets a mutable reference to the underlying writer. 519 | /// 520 | /// It is inadvisable to directly write to the underlying writer. 521 | /// 522 | /// # Examples 523 | /// 524 | /// ```no_run 525 | /// use core2::io::BufWriter; 526 | /// use std::net::TcpStream; 527 | /// 528 | /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 529 | /// 530 | /// // we can use reference just like buffer 531 | /// let reference = buffer.get_mut(); 532 | /// ``` 533 | pub fn get_mut(&mut self) -> &mut W { 534 | self.inner.as_mut().unwrap() 535 | } 536 | 537 | /// Returns a reference to the internally buffered data. 538 | /// 539 | /// # Examples 540 | /// 541 | /// ```no_run 542 | /// use core2::io::BufWriter; 543 | /// use std::net::TcpStream; 544 | /// 545 | /// let buf_writer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 546 | /// 547 | /// // See how many bytes are currently buffered 548 | /// let bytes_buffered = buf_writer.buffer().len(); 549 | /// ``` 550 | pub fn buffer(&self) -> &[u8] { 551 | &self.buf 552 | } 553 | 554 | /// Returns the number of bytes the internal buffer can hold without flushing. 555 | /// 556 | /// # Examples 557 | /// 558 | /// ```no_run 559 | /// use core2::io::BufWriter; 560 | /// use std::net::TcpStream; 561 | /// 562 | /// let buf_writer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 563 | /// 564 | /// // Check the capacity of the inner buffer 565 | /// let capacity = buf_writer.capacity(); 566 | /// // Calculate how many bytes can be written without flushing 567 | /// let without_flush = capacity - buf_writer.buffer().len(); 568 | /// ``` 569 | pub fn capacity(&self) -> usize { 570 | S 571 | } 572 | 573 | /// Unwraps this `BufWriter`, returning the underlying writer. 574 | /// 575 | /// The buffer is written out before returning the writer. 576 | /// 577 | /// # Errors 578 | /// 579 | /// An [`Err`] will be returned if an error occurs while flushing the buffer. 580 | /// 581 | /// # Examples 582 | /// 583 | /// ```no_run 584 | /// use core2::io::BufWriter; 585 | /// use std::net::TcpStream; 586 | /// 587 | /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 588 | /// 589 | /// // unwrap the TcpStream and flush the buffer 590 | /// let stream = buffer.into_inner().unwrap(); 591 | /// ``` 592 | pub fn into_inner(mut self) -> core::result::Result>> { 593 | match self.flush_buf() { 594 | Err(e) => Err(IntoInnerError(self, e)), 595 | Ok(()) => Ok(self.inner.take().unwrap()), 596 | } 597 | } 598 | } 599 | 600 | impl Write for BufWriter { 601 | fn write(&mut self, buf: &[u8]) -> Result { 602 | if self.len + buf.len() > S { 603 | self.flush_buf()?; 604 | } 605 | // FIXME: Why no len > capacity? Why not buffer len == capacity? #72919 606 | if buf.len() >= S { 607 | self.panicked = true; 608 | let r = self.get_mut().write(buf); 609 | self.panicked = false; 610 | r 611 | } else { 612 | self.buf.copy_from_slice(buf); 613 | Ok(buf.len()) 614 | } 615 | } 616 | 617 | fn write_all(&mut self, buf: &[u8]) -> Result<()> { 618 | // Normally, `write_all` just calls `write` in a loop. We can do better 619 | // by calling `self.get_mut().write_all()` directly, which avoids 620 | // round trips through the buffer in the event of a series of partial 621 | // writes in some circumstances. 622 | if self.len + buf.len() > S { 623 | self.flush_buf()?; 624 | } 625 | // FIXME: Why no len > capacity? Why not buffer len == capacity? #72919 626 | if buf.len() >= S { 627 | self.panicked = true; 628 | let r = self.get_mut().write_all(buf); 629 | self.panicked = false; 630 | r 631 | } else { 632 | self.buf.copy_from_slice(buf); 633 | Ok(()) 634 | } 635 | } 636 | 637 | fn flush(&mut self) -> Result<()> { 638 | self.flush_buf().and_then(|()| self.get_mut().flush()) 639 | } 640 | } 641 | 642 | impl fmt::Debug for BufWriter 643 | where 644 | W: fmt::Debug, 645 | { 646 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 647 | fmt.debug_struct("BufWriter") 648 | .field("writer", &self.inner.as_ref().unwrap()) 649 | .field("buffer", &format_args!("{}/{}", self.buf.len(), S)) 650 | .finish() 651 | } 652 | } 653 | 654 | impl Seek for BufWriter { 655 | /// Seek to the offset, in bytes, in the underlying writer. 656 | /// 657 | /// Seeking always writes out the internal buffer before seeking. 658 | fn seek(&mut self, pos: SeekFrom) -> Result { 659 | self.flush_buf()?; 660 | self.get_mut().seek(pos) 661 | } 662 | } 663 | 664 | impl Drop for BufWriter { 665 | fn drop(&mut self) { 666 | if self.inner.is_some() && !self.panicked { 667 | // dtors should not panic, so we ignore a failed flush 668 | let _r = self.flush_buf(); 669 | } 670 | } 671 | } 672 | 673 | impl IntoInnerError { 674 | /// Returns the error which caused the call to [`BufWriter::into_inner()`] 675 | /// to fail. 676 | /// 677 | /// This error was returned when attempting to write the internal buffer. 678 | /// 679 | /// # Examples 680 | /// 681 | /// ```no_run 682 | /// use core2::io::BufWriter; 683 | /// use std::net::TcpStream; 684 | /// 685 | /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 686 | /// 687 | /// // do stuff with the stream 688 | /// 689 | /// // we want to get our `TcpStream` back, so let's try: 690 | /// 691 | /// let stream = match stream.into_inner() { 692 | /// Ok(s) => s, 693 | /// Err(e) => { 694 | /// // Here, e is an IntoInnerError, let's log the inner error. 695 | /// // 696 | /// // We'll just 'log' to stdout for this example. 697 | /// println!("{}", e.error()); 698 | /// 699 | /// panic!("An unexpected error occurred."); 700 | /// } 701 | /// }; 702 | /// ``` 703 | pub fn error(&self) -> &Error { 704 | &self.1 705 | } 706 | 707 | /// Returns the buffered writer instance which generated the error. 708 | /// 709 | /// The returned object can be used for error recovery, such as 710 | /// re-inspecting the buffer. 711 | /// 712 | /// # Examples 713 | /// 714 | /// ```no_run 715 | /// use core2::io::BufWriter; 716 | /// use std::net::TcpStream; 717 | /// 718 | /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 719 | /// 720 | /// // do stuff with the stream 721 | /// 722 | /// // we want to get our `TcpStream` back, so let's try: 723 | /// 724 | /// let stream = match stream.into_inner() { 725 | /// Ok(s) => s, 726 | /// Err(e) => { 727 | /// // Here, e is an IntoInnerError, let's re-examine the buffer: 728 | /// let buffer = e.into_inner(); 729 | /// 730 | /// // do stuff to try to recover 731 | /// 732 | /// // afterwards, let's just return the stream 733 | /// buffer.into_inner().unwrap() 734 | /// } 735 | /// }; 736 | /// ``` 737 | pub fn into_inner(self) -> W { 738 | self.0 739 | } 740 | } 741 | 742 | impl From> for Error { 743 | fn from(iie: IntoInnerError) -> Error { 744 | iie.1 745 | } 746 | } 747 | 748 | impl fmt::Display for IntoInnerError { 749 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 750 | self.error().fmt(f) 751 | } 752 | } 753 | 754 | /// Private helper struct for implementing the line-buffered writing logic. 755 | /// This shim temporarily wraps a BufWriter, and uses its internals to 756 | /// implement a line-buffered writer (specifically by using the internal 757 | /// methods like write_to_buf and flush_buf). In this way, a more 758 | /// efficient abstraction can be created than one that only had access to 759 | /// `write` and `flush`, without needlessly duplicating a lot of the 760 | /// implementation details of BufWriter. This also allows existing 761 | /// `BufWriters` to be temporarily given line-buffering logic; this is what 762 | /// enables Stdout to be alternately in line-buffered or block-buffered mode. 763 | #[derive(Debug)] 764 | pub(super) struct LineWriterShim<'a, W: Write, const S: usize> { 765 | buffer: &'a mut BufWriter, 766 | } 767 | 768 | impl<'a, W: Write, const S: usize> LineWriterShim<'a, W, S> { 769 | pub fn new(buffer: &'a mut BufWriter) -> Self { 770 | Self { buffer } 771 | } 772 | 773 | /// Get a mutable reference to the inner writer (that is, the writer 774 | /// wrapped by the BufWriter). Be careful with this writer, as writes to 775 | /// it will bypass the buffer. 776 | fn inner_mut(&mut self) -> &mut W { 777 | self.buffer.get_mut() 778 | } 779 | 780 | /// Get the content currently buffered in self.buffer 781 | fn buffered(&self) -> &[u8] { 782 | self.buffer.buffer() 783 | } 784 | 785 | /// Flush the buffer iff the last byte is a newline (indicating that an 786 | /// earlier write only succeeded partially, and we want to retry flushing 787 | /// the buffered line before continuing with a subsequent write) 788 | fn flush_if_completed_line(&mut self) -> Result<()> { 789 | match self.buffered().last().copied() { 790 | Some(b'\n') => self.buffer.flush_buf(), 791 | _ => Ok(()), 792 | } 793 | } 794 | } 795 | 796 | impl<'a, W: Write, const S: usize> Write for LineWriterShim<'a, W, S> { 797 | /// Write some data into this BufReader with line buffering. This means 798 | /// that, if any newlines are present in the data, the data up to the last 799 | /// newline is sent directly to the underlying writer, and data after it 800 | /// is buffered. Returns the number of bytes written. 801 | /// 802 | /// This function operates on a "best effort basis"; in keeping with the 803 | /// convention of `Write::write`, it makes at most one attempt to write 804 | /// new data to the underlying writer. If that write only reports a partial 805 | /// success, the remaining data will be buffered. 806 | /// 807 | /// Because this function attempts to send completed lines to the underlying 808 | /// writer, it will also flush the existing buffer if it ends with a 809 | /// newline, even if the incoming data does not contain any newlines. 810 | fn write(&mut self, buf: &[u8]) -> Result { 811 | let newline_idx = match memchr::memrchr(b'\n', buf) { 812 | // If there are no new newlines (that is, if this write is less than 813 | // one line), just do a regular buffered write (which may flush if 814 | // we exceed the inner buffer's size) 815 | None => { 816 | self.flush_if_completed_line()?; 817 | return self.buffer.write(buf); 818 | } 819 | // Otherwise, arrange for the lines to be written directly to the 820 | // inner writer. 821 | Some(newline_idx) => newline_idx + 1, 822 | }; 823 | 824 | // Flush existing content to prepare for our write. We have to do this 825 | // before attempting to write `buf` in order to maintain consistency; 826 | // if we add `buf` to the buffer then try to flush it all at once, 827 | // we're obligated to return Ok(), which would mean suppressing any 828 | // errors that occur during flush. 829 | self.buffer.flush_buf()?; 830 | 831 | // This is what we're going to try to write directly to the inner 832 | // writer. The rest will be buffered, if nothing goes wrong. 833 | let lines = &buf[..newline_idx]; 834 | 835 | // Write `lines` directly to the inner writer. In keeping with the 836 | // `write` convention, make at most one attempt to add new (unbuffered) 837 | // data. Because this write doesn't touch the BufWriter state directly, 838 | // and the buffer is known to be empty, we don't need to worry about 839 | // self.buffer.panicked here. 840 | let flushed = self.inner_mut().write(lines)?; 841 | 842 | // If buffer returns Ok(0), propagate that to the caller without 843 | // doing additional buffering; otherwise we're just guaranteeing 844 | // an "ErrorKind::WriteZero" later. 845 | if flushed == 0 { 846 | return Ok(0); 847 | } 848 | 849 | // Now that the write has succeeded, buffer the rest (or as much of 850 | // the rest as possible). If there were any unwritten newlines, we 851 | // only buffer out to the last unwritten newline that fits in the 852 | // buffer; this helps prevent flushing partial lines on subsequent 853 | // calls to LineWriterShim::write. 854 | 855 | // Handle the cases in order of most-common to least-common, under 856 | // the presumption that most writes succeed in totality, and that most 857 | // writes are smaller than the buffer. 858 | // - Is this a partial line (ie, no newlines left in the unwritten tail) 859 | // - If not, does the data out to the last unwritten newline fit in 860 | // the buffer? 861 | // - If not, scan for the last newline that *does* fit in the buffer 862 | let tail = if flushed >= newline_idx { 863 | &buf[flushed..] 864 | } else if newline_idx - flushed <= self.buffer.capacity() { 865 | &buf[flushed..newline_idx] 866 | } else { 867 | let scan_area = &buf[flushed..]; 868 | let scan_area = &scan_area[..self.buffer.capacity()]; 869 | match memchr::memrchr(b'\n', scan_area) { 870 | Some(newline_idx) => &scan_area[..newline_idx + 1], 871 | None => scan_area, 872 | } 873 | }; 874 | 875 | let buffered = self.buffer.write_to_buf(tail); 876 | Ok(flushed + buffered) 877 | } 878 | 879 | fn flush(&mut self) -> Result<()> { 880 | self.buffer.flush() 881 | } 882 | 883 | /// Write some data into this BufReader with line buffering. This means 884 | /// that, if any newlines are present in the data, the data up to the last 885 | /// newline is sent directly to the underlying writer, and data after it 886 | /// is buffered. 887 | /// 888 | /// Because this function attempts to send completed lines to the underlying 889 | /// writer, it will also flush the existing buffer if it contains any 890 | /// newlines, even if the incoming data does not contain any newlines. 891 | fn write_all(&mut self, buf: &[u8]) -> Result<()> { 892 | match memchr::memrchr(b'\n', buf) { 893 | // If there are no new newlines (that is, if this write is less than 894 | // one line), just do a regular buffered write (which may flush if 895 | // we exceed the inner buffer's size) 896 | None => { 897 | self.flush_if_completed_line()?; 898 | self.buffer.write_all(buf) 899 | } 900 | Some(newline_idx) => { 901 | let (lines, tail) = buf.split_at(newline_idx + 1); 902 | 903 | if self.buffered().is_empty() { 904 | self.inner_mut().write_all(lines)?; 905 | } else { 906 | // If there is any buffered data, we add the incoming lines 907 | // to that buffer before flushing, which saves us at least 908 | // one write call. We can't really do this with `write`, 909 | // since we can't do this *and* not suppress errors *and* 910 | // report a consistent state to the caller in a return 911 | // value, but here in write_all it's fine. 912 | self.buffer.write_all(lines)?; 913 | self.buffer.flush_buf()?; 914 | } 915 | 916 | self.buffer.write_all(tail) 917 | } 918 | } 919 | } 920 | } 921 | 922 | /// Wraps a writer and buffers output to it, flushing whenever a newline 923 | /// (`0x0a`, `'\n'`) is detected. 924 | /// 925 | /// The [`BufWriter`] struct wraps a writer and buffers its output. 926 | /// But it only does this batched write when it goes out of scope, or when the 927 | /// internal buffer is full. Sometimes, you'd prefer to write each line as it's 928 | /// completed, rather than the entire buffer at once. Enter `LineWriter`. It 929 | /// does exactly that. 930 | /// 931 | /// Like [`BufWriter`], a `LineWriter`’s buffer will also be flushed when the 932 | /// `LineWriter` goes out of scope or when its internal buffer is full. 933 | /// 934 | /// If there's still a partial line in the buffer when the `LineWriter` is 935 | /// dropped, it will flush those contents. 936 | /// 937 | /// # Examples 938 | /// 939 | /// We can use `LineWriter` to write one line at a time, significantly 940 | /// reducing the number of actual writes to the file. 941 | /// 942 | /// ```no_run 943 | /// use std::fs::{self, File}; 944 | /// use std::prelude::*; 945 | /// use core2::io::LineWriter; 946 | /// 947 | /// fn main() -> core::result::Result<()> { 948 | /// let road_not_taken = b"I shall be telling this with a sigh 949 | /// Somewhere ages and ages hence: 950 | /// Two roads diverged in a wood, and I - 951 | /// I took the one less traveled by, 952 | /// And that has made all the difference."; 953 | /// 954 | /// let file = File::create("poem.txt")?; 955 | /// let mut file = LineWriter::new(file); 956 | /// 957 | /// file.write_all(b"I shall be telling this with a sigh")?; 958 | /// 959 | /// // No bytes are written until a newline is encountered (or 960 | /// // the internal buffer is filled). 961 | /// assert_eq!(fs::read_to_string("poem.txt")?, ""); 962 | /// file.write_all(b"\n")?; 963 | /// assert_eq!( 964 | /// fs::read_to_string("poem.txt")?, 965 | /// "I shall be telling this with a sigh\n", 966 | /// ); 967 | /// 968 | /// // Write the rest of the poem. 969 | /// file.write_all(b"Somewhere ages and ages hence: 970 | /// Two roads diverged in a wood, and I - 971 | /// I took the one less traveled by, 972 | /// And that has made all the difference.")?; 973 | /// 974 | /// // The last line of the poem doesn't end in a newline, so 975 | /// // we have to flush or drop the `LineWriter` to finish 976 | /// // writing. 977 | /// file.flush()?; 978 | /// 979 | /// // Confirm the whole poem was written. 980 | /// assert_eq!(fs::read("poem.txt")?, &road_not_taken[..]); 981 | /// Ok(()) 982 | /// } 983 | /// ``` 984 | pub struct LineWriter { 985 | inner: BufWriter, 986 | } 987 | 988 | impl LineWriter { 989 | /// Creates a new `LineWriter`. 990 | /// 991 | /// # Examples 992 | /// 993 | /// ```no_run 994 | /// use std::fs::File; 995 | /// use core2::io::LineWriter; 996 | /// 997 | /// fn main() -> core::result::Result<()> { 998 | /// let file = File::create("poem.txt")?; 999 | /// let file = LineWriter::new(file); 1000 | /// Ok(()) 1001 | /// } 1002 | /// ``` 1003 | pub fn new(inner: W) -> LineWriter { 1004 | LineWriter { 1005 | inner: BufWriter::new(inner), 1006 | } 1007 | } 1008 | 1009 | /// Gets a reference to the underlying writer. 1010 | /// 1011 | /// # Examples 1012 | /// 1013 | /// ```no_run 1014 | /// use std::fs::File; 1015 | /// use core2::io::LineWriter; 1016 | /// 1017 | /// fn main() -> core::result::Result<()> { 1018 | /// let file = File::create("poem.txt")?; 1019 | /// let file = LineWriter::new(file); 1020 | /// 1021 | /// let reference = file.get_ref(); 1022 | /// Ok(()) 1023 | /// } 1024 | /// ``` 1025 | pub fn get_ref(&self) -> &W { 1026 | self.inner.get_ref() 1027 | } 1028 | 1029 | /// Gets a mutable reference to the underlying writer. 1030 | /// 1031 | /// Caution must be taken when calling methods on the mutable reference 1032 | /// returned as extra writes could corrupt the output stream. 1033 | /// 1034 | /// # Examples 1035 | /// 1036 | /// ```no_run 1037 | /// use std::fs::File; 1038 | /// use core2::io::LineWriter; 1039 | /// 1040 | /// fn main() -> core::result::Result<()> { 1041 | /// let file = File::create("poem.txt")?; 1042 | /// let mut file = LineWriter::new(file); 1043 | /// 1044 | /// // we can use reference just like file 1045 | /// let reference = file.get_mut(); 1046 | /// Ok(()) 1047 | /// } 1048 | /// ``` 1049 | pub fn get_mut(&mut self) -> &mut W { 1050 | self.inner.get_mut() 1051 | } 1052 | 1053 | /// Unwraps this `LineWriter`, returning the underlying writer. 1054 | /// 1055 | /// The internal buffer is written out before returning the writer. 1056 | /// 1057 | /// # Errors 1058 | /// 1059 | /// An [`Err`] will be returned if an error occurs while flushing the buffer. 1060 | /// 1061 | /// # Examples 1062 | /// 1063 | /// ```no_run 1064 | /// use std::fs::File; 1065 | /// use core2::io::LineWriter; 1066 | /// 1067 | /// fn main() -> core::result::Result<()> { 1068 | /// let file = File::create("poem.txt")?; 1069 | /// 1070 | /// let writer: LineWriter = LineWriter::new(file); 1071 | /// 1072 | /// let file: File = writer.into_inner()?; 1073 | /// Ok(()) 1074 | /// } 1075 | /// ``` 1076 | pub fn into_inner(self) -> core::result::Result>> { 1077 | self.inner 1078 | .into_inner() 1079 | .map_err(|IntoInnerError(buf, e)| IntoInnerError(LineWriter { inner: buf }, e)) 1080 | } 1081 | } 1082 | 1083 | impl Write for LineWriter { 1084 | fn write(&mut self, buf: &[u8]) -> Result { 1085 | LineWriterShim::new(&mut self.inner).write(buf) 1086 | } 1087 | 1088 | fn flush(&mut self) -> Result<()> { 1089 | self.inner.flush() 1090 | } 1091 | 1092 | fn write_all(&mut self, buf: &[u8]) -> Result<()> { 1093 | LineWriterShim::new(&mut self.inner).write_all(buf) 1094 | } 1095 | 1096 | fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> Result<()> { 1097 | LineWriterShim::new(&mut self.inner).write_fmt(fmt) 1098 | } 1099 | } 1100 | 1101 | impl fmt::Debug for LineWriter 1102 | where 1103 | W: fmt::Debug, 1104 | { 1105 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 1106 | fmt.debug_struct("LineWriter") 1107 | .field("writer", &self.inner.inner) 1108 | .field("buffer", &format_args!("{}/{}", self.inner.len, S)) 1109 | .finish() 1110 | } 1111 | } 1112 | -------------------------------------------------------------------------------- /src/io/cursor.rs: -------------------------------------------------------------------------------- 1 | use super::{BufRead, Error, ErrorKind, Read, Result, Seek, SeekFrom, Write}; 2 | use core::cmp; 3 | 4 | /// A `Cursor` wraps an in-memory buffer and provides it with a 5 | /// [`Seek`] implementation. 6 | /// 7 | /// `Cursor`s are used with in-memory buffers, anything implementing 8 | /// [`AsRef`]`<[u8]>`, to allow them to implement [`Read`] and/or [`Write`], 9 | /// allowing these buffers to be used anywhere you might use a reader or writer 10 | /// that does actual I/O. 11 | /// 12 | /// The standard library implements some I/O traits on various types which 13 | /// are commonly used as a buffer, like `Cursor<`[`Vec`]`>` and 14 | /// `Cursor<`[`&[u8]`][bytes]`>`. 15 | /// 16 | /// # Examples 17 | /// 18 | /// We may want to write bytes to a [`File`] in our production 19 | /// code, but use an in-memory buffer in our tests. We can do this with 20 | /// `Cursor`: 21 | /// 22 | /// [bytes]: crate::slice 23 | /// [`File`]: crate::fs::File 24 | /// 25 | /// ``` 26 | /// use std::io::prelude::*; 27 | /// use core2::io::{self, Seek, SeekFrom, Write}; 28 | /// use std::fs::File; 29 | /// 30 | /// // a library function we've written 31 | /// fn write_ten_bytes_at_end(writer: &mut W) -> io::Result<()> { 32 | /// writer.seek(SeekFrom::End(-10))?; 33 | /// 34 | /// for i in 0..10 { 35 | /// writer.write(&[i])?; 36 | /// } 37 | /// 38 | /// // all went well 39 | /// Ok(()) 40 | /// } 41 | /// 42 | /// # #[cfg(feature = "std")] 43 | /// # fn foo() -> io::Result<()> { 44 | /// // Here's some code that uses this library function. 45 | /// // 46 | /// // We might want to use a BufReader here for efficiency, but let's 47 | /// // keep this example focused. 48 | /// let mut file = File::create("foo.txt").map_err(|e| io::Error::from(e))?; 49 | /// 50 | /// write_ten_bytes_at_end(&mut file)?; 51 | /// # Ok(()) 52 | /// # } 53 | /// 54 | /// // now let's write a test 55 | /// #[test] 56 | /// fn test_writes_bytes() { 57 | /// // setting up a real File is much slower than an in-memory buffer, 58 | /// // let's use a cursor instead 59 | /// use core2::io::Cursor; 60 | /// let mut buff = Cursor::new(vec![0; 15]); 61 | /// 62 | /// write_ten_bytes_at_end(&mut buff).unwrap(); 63 | /// 64 | /// assert_eq!(&buff.get_ref()[5..15], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); 65 | /// } 66 | /// ``` 67 | #[derive(Clone, Debug, Default, Eq, PartialEq)] 68 | pub struct Cursor { 69 | inner: T, 70 | pos: u64, 71 | } 72 | 73 | impl Cursor { 74 | /// Creates a new cursor wrapping the provided underlying in-memory buffer. 75 | /// 76 | /// Cursor initial position is `0` even if underlying buffer (e.g., [`Vec`]) 77 | /// is not empty. So writing to cursor starts with overwriting [`Vec`] 78 | /// content, not with appending to it. 79 | /// 80 | /// # Examples 81 | /// 82 | /// ``` 83 | /// use core2::io::Cursor; 84 | /// 85 | /// let buff = Cursor::new(Vec::new()); 86 | /// # fn force_inference(_: &Cursor>) {} 87 | /// # force_inference(&buff); 88 | /// ``` 89 | pub fn new(inner: T) -> Cursor { 90 | Cursor { pos: 0, inner } 91 | } 92 | 93 | /// Consumes this cursor, returning the underlying value. 94 | /// 95 | /// # Examples 96 | /// 97 | /// ``` 98 | /// use core2::io::Cursor; 99 | /// 100 | /// let buff = Cursor::new(Vec::new()); 101 | /// # fn force_inference(_: &Cursor>) {} 102 | /// # force_inference(&buff); 103 | /// 104 | /// let vec = buff.into_inner(); 105 | /// ``` 106 | pub fn into_inner(self) -> T { 107 | self.inner 108 | } 109 | 110 | /// Gets a reference to the underlying value in this cursor. 111 | /// 112 | /// # Examples 113 | /// 114 | /// ``` 115 | /// use core2::io::Cursor; 116 | /// 117 | /// let buff = Cursor::new(Vec::new()); 118 | /// # fn force_inference(_: &Cursor>) {} 119 | /// # force_inference(&buff); 120 | /// 121 | /// let reference = buff.get_ref(); 122 | /// ``` 123 | pub fn get_ref(&self) -> &T { 124 | &self.inner 125 | } 126 | 127 | /// Gets a mutable reference to the underlying value in this cursor. 128 | /// 129 | /// Care should be taken to avoid modifying the internal I/O state of the 130 | /// underlying value as it may corrupt this cursor's position. 131 | /// 132 | /// # Examples 133 | /// 134 | /// ``` 135 | /// use core2::io::Cursor; 136 | /// 137 | /// let mut buff = Cursor::new(Vec::new()); 138 | /// # fn force_inference(_: &Cursor>) {} 139 | /// # force_inference(&buff); 140 | /// 141 | /// let reference = buff.get_mut(); 142 | /// ``` 143 | pub fn get_mut(&mut self) -> &mut T { 144 | &mut self.inner 145 | } 146 | 147 | /// Returns the current position of this cursor. 148 | /// 149 | /// # Examples 150 | /// 151 | /// ``` 152 | /// use core2::io::{Cursor, Seek, SeekFrom}; 153 | /// use std::io::prelude::*; 154 | /// 155 | /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); 156 | /// 157 | /// assert_eq!(buff.position(), 0); 158 | /// 159 | /// buff.seek(SeekFrom::Current(2)).unwrap(); 160 | /// assert_eq!(buff.position(), 2); 161 | /// 162 | /// buff.seek(SeekFrom::Current(-1)).unwrap(); 163 | /// assert_eq!(buff.position(), 1); 164 | /// ``` 165 | pub fn position(&self) -> u64 { 166 | self.pos 167 | } 168 | 169 | /// Sets the position of this cursor. 170 | /// 171 | /// # Examples 172 | /// 173 | /// ``` 174 | /// use core2::io::Cursor; 175 | /// 176 | /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); 177 | /// 178 | /// assert_eq!(buff.position(), 0); 179 | /// 180 | /// buff.set_position(2); 181 | /// assert_eq!(buff.position(), 2); 182 | /// 183 | /// buff.set_position(4); 184 | /// assert_eq!(buff.position(), 4); 185 | /// ``` 186 | pub fn set_position(&mut self, pos: u64) { 187 | self.pos = pos; 188 | } 189 | } 190 | 191 | impl Seek for Cursor 192 | where 193 | T: AsRef<[u8]>, 194 | { 195 | fn seek(&mut self, style: SeekFrom) -> Result { 196 | let (base_pos, offset) = match style { 197 | SeekFrom::Start(n) => { 198 | self.pos = n; 199 | return Ok(n); 200 | } 201 | SeekFrom::End(n) => (self.inner.as_ref().len() as u64, n), 202 | SeekFrom::Current(n) => (self.pos, n), 203 | }; 204 | let new_pos = if offset >= 0 { 205 | base_pos.checked_add(offset as u64) 206 | } else { 207 | base_pos.checked_sub((offset.wrapping_neg()) as u64) 208 | }; 209 | match new_pos { 210 | Some(n) => { 211 | self.pos = n; 212 | Ok(self.pos) 213 | } 214 | None => Err(Error::new( 215 | ErrorKind::InvalidInput, 216 | "invalid seek to a negative or overflowing position", 217 | )), 218 | } 219 | } 220 | } 221 | 222 | impl Read for Cursor 223 | where 224 | T: AsRef<[u8]>, 225 | { 226 | fn read(&mut self, buf: &mut [u8]) -> Result { 227 | let n = Read::read(&mut self.fill_buf()?, buf)?; 228 | self.pos += n as u64; 229 | Ok(n) 230 | } 231 | 232 | fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> { 233 | let n = buf.len(); 234 | Read::read_exact(&mut self.fill_buf()?, buf)?; 235 | self.pos += n as u64; 236 | Ok(()) 237 | } 238 | } 239 | 240 | impl BufRead for Cursor 241 | where 242 | T: AsRef<[u8]>, 243 | { 244 | fn fill_buf(&mut self) -> Result<&[u8]> { 245 | let amt = cmp::min(self.pos, self.inner.as_ref().len() as u64); 246 | Ok(&self.inner.as_ref()[(amt as usize)..]) 247 | } 248 | fn consume(&mut self, amt: usize) { 249 | self.pos += amt as u64; 250 | } 251 | } 252 | 253 | // Non-resizing write implementation 254 | #[inline] 255 | fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> Result { 256 | let pos = cmp::min(*pos_mut, slice.len() as u64); 257 | let amt = (&mut slice[(pos as usize)..]).write(buf)?; 258 | *pos_mut += amt as u64; 259 | Ok(amt) 260 | } 261 | 262 | impl Write for Cursor<&mut [u8]> { 263 | #[inline] 264 | fn write(&mut self, buf: &[u8]) -> Result { 265 | slice_write(&mut self.pos, self.inner, buf) 266 | } 267 | 268 | #[inline] 269 | fn flush(&mut self) -> Result<()> { 270 | Ok(()) 271 | } 272 | } 273 | -------------------------------------------------------------------------------- /src/io/error.rs: -------------------------------------------------------------------------------- 1 | use core::{convert::From, fmt, result}; 2 | 3 | /// A specialized [`Result`] type for I/O operations. 4 | /// 5 | /// This type is broadly used across [`std::io`] for any operation which may 6 | /// produce an error. 7 | /// 8 | /// This typedef is generally used to avoid writing out [`io::Error`] directly and 9 | /// is otherwise a direct mapping to [`Result`]. 10 | /// 11 | /// While usual Rust style is to import types directly, aliases of [`Result`] 12 | /// often are not, to make it easier to distinguish between them. [`Result`] is 13 | /// generally assumed to be [`std::result::Result`][`Result`], and so users of this alias 14 | /// will generally use `io::Result` instead of shadowing the [prelude]'s import 15 | /// of [`std::result::Result`][`Result`]. 16 | /// 17 | /// [`std::io`]: crate::io 18 | /// [`io::Error`]: Error 19 | /// [`Result`]: crate::result::Result 20 | /// [prelude]: crate::prelude 21 | /// 22 | /// # Examples 23 | /// 24 | /// A convenience function that bubbles an `io::Result` to its caller: 25 | /// 26 | /// ``` 27 | /// use core2::io; 28 | /// 29 | /// #[cfg(feature = "std")] 30 | /// fn get_string() -> io::Result { 31 | /// let mut buffer = String::new(); 32 | /// 33 | /// std::io::stdin().read_line(&mut buffer).map_err(|e| io::Error::from(e))?; 34 | /// 35 | /// Ok(buffer) 36 | /// } 37 | /// ``` 38 | pub type Result = result::Result; 39 | 40 | /// The error type for I/O operations of the [`Read`], [`Write`], [`Seek`], and 41 | /// associated traits. 42 | /// 43 | /// Errors mostly originate from the underlying OS, but custom instances of 44 | /// `Error` can be created with crafted error messages and a particular value of 45 | /// [`ErrorKind`]. 46 | /// 47 | /// [`Read`]: crate::io::Read 48 | /// [`Write`]: crate::io::Write 49 | /// [`Seek`]: crate::io::Seek 50 | pub struct Error { 51 | repr: Repr, 52 | } 53 | 54 | impl crate::error::Error for Error {} 55 | 56 | impl fmt::Debug for Error { 57 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 58 | fmt::Debug::fmt(&self.repr, f) 59 | } 60 | } 61 | 62 | enum Repr { 63 | Simple(ErrorKind), 64 | Custom(Custom), 65 | } 66 | 67 | #[derive(Debug)] 68 | struct Custom { 69 | kind: ErrorKind, 70 | error: &'static str, 71 | } 72 | 73 | /// A list specifying general categories of I/O error. 74 | /// 75 | /// This list is intended to grow over time and it is not recommended to 76 | /// exhaustively match against it. 77 | /// 78 | /// It is used with the [`io::Error`] type. 79 | /// 80 | /// [`io::Error`]: Error 81 | #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 82 | // #[allow(deprecated)] 83 | #[non_exhaustive] 84 | pub enum ErrorKind { 85 | /// An entity was not found, often a file. 86 | NotFound, 87 | /// The operation lacked the necessary privileges to complete. 88 | PermissionDenied, 89 | /// The connection was refused by the remote server. 90 | ConnectionRefused, 91 | /// The connection was reset by the remote server. 92 | ConnectionReset, 93 | /// The connection was aborted (terminated) by the remote server. 94 | ConnectionAborted, 95 | /// The network operation failed because it was not connected yet. 96 | NotConnected, 97 | /// A socket address could not be bound because the address is already in 98 | /// use elsewhere. 99 | AddrInUse, 100 | /// A nonexistent interface was requested or the requested address was not 101 | /// local. 102 | AddrNotAvailable, 103 | /// The operation failed because a pipe was closed. 104 | BrokenPipe, 105 | /// An entity already exists, often a file. 106 | AlreadyExists, 107 | /// The operation needs to block to complete, but the blocking operation was 108 | /// requested to not occur. 109 | WouldBlock, 110 | /// A parameter was incorrect. 111 | InvalidInput, 112 | /// Data not valid for the operation were encountered. 113 | /// 114 | /// Unlike [`InvalidInput`], this typically means that the operation 115 | /// parameters were valid, however the error was caused by malformed 116 | /// input data. 117 | /// 118 | /// For example, a function that reads a file into a string will error with 119 | /// `InvalidData` if the file's contents are not valid UTF-8. 120 | /// 121 | /// [`InvalidInput`]: ErrorKind::InvalidInput 122 | InvalidData, 123 | /// The I/O operation's timeout expired, causing it to be canceled. 124 | TimedOut, 125 | /// An error returned when an operation could not be completed because a 126 | /// call to [`write`] returned [`Ok(0)`]. 127 | /// 128 | /// This typically means that an operation could only succeed if it wrote a 129 | /// particular number of bytes but only a smaller number of bytes could be 130 | /// written. 131 | /// 132 | /// [`write`]: crate::io::Write::write 133 | /// [`Ok(0)`]: Ok 134 | WriteZero, 135 | /// This operation was interrupted. 136 | /// 137 | /// Interrupted operations can typically be retried. 138 | Interrupted, 139 | /// Any I/O error not part of this list. 140 | /// 141 | /// Errors that are `Other` now may move to a different or a new 142 | /// [`ErrorKind`] variant in the future. It is not recommended to match 143 | /// an error against `Other` and to expect any additional characteristics, 144 | /// e.g., a specific [`Error::raw_os_error`] return value. 145 | Other, 146 | 147 | /// An error returned when an operation could not be completed because an 148 | /// "end of file" was reached prematurely. 149 | /// 150 | /// This typically means that an operation could only succeed if it read a 151 | /// particular number of bytes but only a smaller number of bytes could be 152 | /// read. 153 | UnexpectedEof, 154 | 155 | /// Any I/O error from the standard library that's not part of this list. 156 | /// 157 | /// Errors that are `Uncategorized` now may move to a different or a new 158 | /// [`ErrorKind`] variant in the future. It is not recommended to match 159 | /// an error against `Uncategorized`; use a wildcard match (`_`) instead. 160 | #[doc(hidden)] 161 | Uncategorized, 162 | } 163 | 164 | impl ErrorKind { 165 | pub(crate) fn as_str(&self) -> &'static str { 166 | match *self { 167 | ErrorKind::NotFound => "entity not found", 168 | ErrorKind::PermissionDenied => "permission denied", 169 | ErrorKind::ConnectionRefused => "connection refused", 170 | ErrorKind::ConnectionReset => "connection reset", 171 | ErrorKind::ConnectionAborted => "connection aborted", 172 | ErrorKind::NotConnected => "not connected", 173 | ErrorKind::AddrInUse => "address in use", 174 | ErrorKind::AddrNotAvailable => "address not available", 175 | ErrorKind::BrokenPipe => "broken pipe", 176 | ErrorKind::AlreadyExists => "entity already exists", 177 | ErrorKind::WouldBlock => "operation would block", 178 | ErrorKind::InvalidInput => "invalid input parameter", 179 | ErrorKind::InvalidData => "invalid data", 180 | ErrorKind::TimedOut => "timed out", 181 | ErrorKind::WriteZero => "write zero", 182 | ErrorKind::Interrupted => "operation interrupted", 183 | ErrorKind::Other => "other os error", 184 | ErrorKind::UnexpectedEof => "unexpected end of file", 185 | ErrorKind::Uncategorized => "uncategorized", 186 | } 187 | } 188 | } 189 | 190 | #[cfg(feature = "std")] 191 | impl From for ErrorKind { 192 | /// Converts an [`std::io::ErrorKind`] into an [`ErrorKind`]. 193 | /// 194 | /// This conversion allocates a new error with a simple representation of error kind. 195 | /// 196 | /// # Examples 197 | /// 198 | /// ``` 199 | /// use core2::io::{Error, ErrorKind}; 200 | /// 201 | /// let not_found = ErrorKind::from(std::io::ErrorKind::NotFound); 202 | /// let err: Error = not_found.into(); 203 | /// assert_eq!("entity not found", format!("{}", err)); 204 | /// ``` 205 | fn from(k: std::io::ErrorKind) -> Self { 206 | match k { 207 | std::io::ErrorKind::NotFound => ErrorKind::NotFound, 208 | std::io::ErrorKind::PermissionDenied => ErrorKind::PermissionDenied, 209 | std::io::ErrorKind::ConnectionRefused => ErrorKind::ConnectionRefused, 210 | std::io::ErrorKind::ConnectionReset => ErrorKind::ConnectionReset, 211 | std::io::ErrorKind::ConnectionAborted => ErrorKind::ConnectionAborted, 212 | std::io::ErrorKind::NotConnected => ErrorKind::NotConnected, 213 | std::io::ErrorKind::AddrInUse => ErrorKind::AddrInUse, 214 | std::io::ErrorKind::AddrNotAvailable => ErrorKind::AddrNotAvailable, 215 | std::io::ErrorKind::BrokenPipe => ErrorKind::BrokenPipe, 216 | std::io::ErrorKind::AlreadyExists => ErrorKind::AlreadyExists, 217 | std::io::ErrorKind::WouldBlock => ErrorKind::WouldBlock, 218 | std::io::ErrorKind::InvalidInput => ErrorKind::InvalidInput, 219 | std::io::ErrorKind::InvalidData => ErrorKind::InvalidData, 220 | std::io::ErrorKind::TimedOut => ErrorKind::TimedOut, 221 | std::io::ErrorKind::WriteZero => ErrorKind::WriteZero, 222 | std::io::ErrorKind::Interrupted => ErrorKind::Interrupted, 223 | std::io::ErrorKind::Other => ErrorKind::Other, 224 | std::io::ErrorKind::UnexpectedEof => ErrorKind::UnexpectedEof, 225 | _ => ErrorKind::Uncategorized, 226 | } 227 | } 228 | } 229 | 230 | /// Intended for use for errors not exposed to the user, where allocating onto 231 | /// the heap (for normal construction via Error::new) is too costly. 232 | impl From for Error { 233 | /// Converts an [`ErrorKind`] into an [`Error`]. 234 | /// 235 | /// This conversion allocates a new error with a simple representation of error kind. 236 | /// 237 | /// # Examples 238 | /// 239 | /// ``` 240 | /// use core2::io::{Error, ErrorKind}; 241 | /// 242 | /// let not_found = ErrorKind::NotFound; 243 | /// let error = Error::from(not_found); 244 | /// assert_eq!("entity not found", format!("{}", error)); 245 | /// ``` 246 | #[inline] 247 | fn from(kind: ErrorKind) -> Error { 248 | Error { 249 | repr: Repr::Simple(kind), 250 | } 251 | } 252 | } 253 | 254 | #[cfg(feature = "std")] 255 | impl From for Error { 256 | /// Converts an [`std::io::ErrorKind`] into an [`Error`]. 257 | /// 258 | /// This conversion allocates a new error with a simple representation of error kind. 259 | /// 260 | /// # Examples 261 | /// 262 | /// ``` 263 | /// use core2::io::{Error, ErrorKind}; 264 | /// 265 | /// let not_found = std::io::Error::from(std::io::ErrorKind::NotFound); 266 | /// let error = Error::from(not_found); 267 | /// assert_eq!("entity not found", format!("{}", error)); 268 | /// ``` 269 | #[inline] 270 | fn from(err: std::io::Error) -> Self { 271 | Self::from(ErrorKind::from(err.kind())) 272 | } 273 | } 274 | 275 | impl Error { 276 | /// Creates a new I/O error from a known kind of error as well as an 277 | /// arbitrary error payload. 278 | /// 279 | /// This function is used to generically create I/O errors which do not 280 | /// originate from the OS itself. The `error` argument is an arbitrary 281 | /// payload which will be contained in this [`Error`]. 282 | /// 283 | /// # Examples 284 | /// 285 | /// ``` 286 | /// use core2::io::{Error, ErrorKind}; 287 | /// 288 | /// // errors can be created from strings 289 | /// let custom_error = Error::new(ErrorKind::Other, "oh no!"); 290 | /// 291 | /// // errors can also be created from other errors 292 | /// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error.into_inner().unwrap()); 293 | /// ``` 294 | pub fn new(kind: ErrorKind, error: &'static str) -> Error { 295 | Self::_new(kind, error.into()) 296 | } 297 | 298 | fn _new(kind: ErrorKind, error: &'static str) -> Error { 299 | Error { 300 | repr: Repr::Custom(Custom { kind, error }), 301 | } 302 | } 303 | 304 | /// Returns a reference to the inner error wrapped by this error (if any). 305 | /// 306 | /// If this [`Error`] was constructed via [`new`] then this function will 307 | /// return [`Some`], otherwise it will return [`None`]. 308 | /// 309 | /// [`new`]: Error::new 310 | /// 311 | /// # Examples 312 | /// 313 | /// ``` 314 | /// use core2::io::{Error, ErrorKind}; 315 | /// 316 | /// fn print_error(err: &Error) { 317 | /// if let Some(inner_err) = err.get_ref() { 318 | /// println!("Inner error: {:?}", inner_err); 319 | /// } else { 320 | /// println!("No inner error"); 321 | /// } 322 | /// } 323 | /// 324 | /// #[cfg(feature = "std")] 325 | /// fn emit_error() { 326 | /// // Will print "No inner error". 327 | /// print_error(&Error::from(std::io::Error::last_os_error())); 328 | /// // Will print "Inner error: ...". 329 | /// print_error(&Error::new(ErrorKind::Other, "oh no!")); 330 | /// } 331 | /// 332 | /// #[cfg(not(feature = "std"))] 333 | /// fn emit_error() { 334 | /// // Will print "No inner error". 335 | /// print_error(&ErrorKind::Other.into()); 336 | /// // Will print "Inner error: ...". 337 | /// print_error(&Error::new(ErrorKind::Other, "oh no!")); 338 | /// } 339 | /// 340 | /// fn main() { 341 | /// emit_error(); 342 | /// } 343 | /// ``` 344 | pub fn get_ref(&self) -> Option<&&'static str> { 345 | match self.repr { 346 | Repr::Simple(..) => None, 347 | Repr::Custom(ref c) => Some(&c.error), 348 | } 349 | } 350 | 351 | /// Consumes the `Error`, returning its inner error (if any). 352 | /// 353 | /// If this [`Error`] was constructed via [`new`] then this function will 354 | /// return [`Some`], otherwise it will return [`None`]. 355 | /// 356 | /// [`new`]: Error::new 357 | /// 358 | /// # Examples 359 | /// 360 | /// ``` 361 | /// use core2::io::{Error, ErrorKind}; 362 | /// 363 | /// fn print_error(err: Error) { 364 | /// if let Some(inner_err) = err.into_inner() { 365 | /// println!("Inner error: {}", inner_err); 366 | /// } else { 367 | /// println!("No inner error"); 368 | /// } 369 | /// } 370 | /// 371 | /// #[cfg(feature = "std")] 372 | /// fn emit_error() { 373 | /// // Will print "No inner error". 374 | /// print_error(std::io::Error::last_os_error().into()); 375 | /// // Will print "Inner error: ...". 376 | /// print_error(Error::new(ErrorKind::Other, "oh no!")); 377 | /// } 378 | /// 379 | /// #[cfg(not(feature = "std"))] 380 | /// fn emit_error() { 381 | /// // Will print "No inner error". 382 | /// print_error(ErrorKind::Other.into()); 383 | /// // Will print "Inner error: ...". 384 | /// print_error(Error::new(ErrorKind::Other, "oh no!")); 385 | /// } 386 | /// 387 | /// fn main() { 388 | /// emit_error(); 389 | /// } 390 | /// ``` 391 | pub fn into_inner(self) -> Option<&'static str> { 392 | match self.repr { 393 | Repr::Simple(..) => None, 394 | Repr::Custom(c) => Some(c.error), 395 | } 396 | } 397 | 398 | /// Returns the corresponding [`ErrorKind`] for this error. 399 | /// 400 | /// # Examples 401 | /// 402 | /// ``` 403 | /// use core2::io::{Error, ErrorKind}; 404 | /// 405 | /// fn print_error(err: Error) { 406 | /// println!("{:?}", err.kind()); 407 | /// } 408 | /// 409 | /// #[cfg(feature = "std")] 410 | /// fn emit_error() { 411 | /// // Will print "Other". 412 | /// print_error(std::io::Error::last_os_error().into()); 413 | /// // Will print "AddrInUse". 414 | /// print_error(Error::new(ErrorKind::AddrInUse, "oh no!")); 415 | /// } 416 | /// 417 | /// #[cfg(not(feature = "std"))] 418 | /// fn emit_error() { 419 | /// // Will print "Other". 420 | /// print_error(ErrorKind::Other.into()); 421 | /// // Will print "AddrInUse". 422 | /// print_error(Error::new(ErrorKind::AddrInUse, "oh no!")); 423 | /// } 424 | /// 425 | /// fn main() { 426 | /// emit_error(); 427 | /// } 428 | /// ``` 429 | pub fn kind(&self) -> ErrorKind { 430 | match self.repr { 431 | Repr::Custom(ref c) => c.kind, 432 | Repr::Simple(kind) => kind, 433 | } 434 | } 435 | } 436 | 437 | impl fmt::Debug for Repr { 438 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 439 | match *self { 440 | Repr::Custom(ref c) => fmt::Debug::fmt(&c, fmt), 441 | Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(), 442 | } 443 | } 444 | } 445 | 446 | impl fmt::Display for Error { 447 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 448 | match self.repr { 449 | Repr::Custom(ref c) => c.error.fmt(fmt), 450 | Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()), 451 | } 452 | } 453 | } 454 | 455 | fn _assert_error_is_sync_send() { 456 | fn _is_sync_send() {} 457 | _is_sync_send::(); 458 | } 459 | -------------------------------------------------------------------------------- /src/io/impls.rs: -------------------------------------------------------------------------------- 1 | use super::error::{Error, ErrorKind, Result}; 2 | use super::traits::{BufRead, Read, Seek, SeekFrom, Write}; 3 | use core::{cmp, fmt, mem}; 4 | 5 | // ============================================================================= 6 | // Forwarding implementations 7 | 8 | impl Read for &mut R { 9 | #[inline] 10 | fn read(&mut self, buf: &mut [u8]) -> Result { 11 | (**self).read(buf) 12 | } 13 | 14 | #[inline] 15 | fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> { 16 | (**self).read_exact(buf) 17 | } 18 | } 19 | 20 | impl Write for &mut W { 21 | #[inline] 22 | fn write(&mut self, buf: &[u8]) -> Result { 23 | (**self).write(buf) 24 | } 25 | 26 | #[inline] 27 | fn flush(&mut self) -> Result<()> { 28 | (**self).flush() 29 | } 30 | 31 | #[inline] 32 | fn write_all(&mut self, buf: &[u8]) -> Result<()> { 33 | (**self).write_all(buf) 34 | } 35 | 36 | #[inline] 37 | fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> Result<()> { 38 | (**self).write_fmt(fmt) 39 | } 40 | } 41 | 42 | impl Seek for &mut S { 43 | #[inline] 44 | fn seek(&mut self, pos: SeekFrom) -> Result { 45 | (**self).seek(pos) 46 | } 47 | } 48 | 49 | impl BufRead for &mut B { 50 | #[inline] 51 | fn fill_buf(&mut self) -> Result<&[u8]> { 52 | (**self).fill_buf() 53 | } 54 | 55 | #[inline] 56 | fn consume(&mut self, amt: usize) { 57 | (**self).consume(amt) 58 | } 59 | } 60 | 61 | // ============================================================================= 62 | // In-memory buffer implementations 63 | 64 | /// Read is implemented for `&[u8]` by copying from the slice. 65 | /// 66 | /// Note that reading updates the slice to point to the yet unread part. 67 | /// The slice will be empty when EOF is reached. 68 | impl Read for &[u8] { 69 | #[inline] 70 | fn read(&mut self, buf: &mut [u8]) -> Result { 71 | let amt = cmp::min(buf.len(), self.len()); 72 | let (a, b) = self.split_at(amt); 73 | 74 | // First check if the amount of bytes we want to read is small: 75 | // `copy_from_slice` will generally expand to a call to `memcpy`, and 76 | // for a single byte the overhead is significant. 77 | if amt == 1 { 78 | buf[0] = a[0]; 79 | } else { 80 | buf[..amt].copy_from_slice(a); 81 | } 82 | 83 | *self = b; 84 | Ok(amt) 85 | } 86 | 87 | #[inline] 88 | fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> { 89 | if buf.len() > self.len() { 90 | return Err(Error::new( 91 | ErrorKind::UnexpectedEof, 92 | "failed to fill whole buffer", 93 | )); 94 | } 95 | let (a, b) = self.split_at(buf.len()); 96 | 97 | // First check if the amount of bytes we want to read is small: 98 | // `copy_from_slice` will generally expand to a call to `memcpy`, and 99 | // for a single byte the overhead is significant. 100 | if buf.len() == 1 { 101 | buf[0] = a[0]; 102 | } else { 103 | buf.copy_from_slice(a); 104 | } 105 | 106 | *self = b; 107 | Ok(()) 108 | } 109 | } 110 | 111 | impl BufRead for &[u8] { 112 | #[inline] 113 | fn fill_buf(&mut self) -> Result<&[u8]> { 114 | Ok(*self) 115 | } 116 | 117 | #[inline] 118 | fn consume(&mut self, amt: usize) { 119 | *self = &self[amt..]; 120 | } 121 | } 122 | 123 | /// Write is implemented for `&mut [u8]` by copying into the slice, overwriting 124 | /// its data. 125 | /// 126 | /// Note that writing updates the slice to point to the yet unwritten part. 127 | /// The slice will be empty when it has been completely overwritten. 128 | impl Write for &mut [u8] { 129 | #[inline] 130 | fn write(&mut self, data: &[u8]) -> Result { 131 | let amt = cmp::min(data.len(), self.len()); 132 | let (a, b) = mem::replace(self, &mut []).split_at_mut(amt); 133 | a.copy_from_slice(&data[..amt]); 134 | *self = b; 135 | Ok(amt) 136 | } 137 | 138 | #[inline] 139 | fn write_all(&mut self, data: &[u8]) -> Result<()> { 140 | if self.write(data)? == data.len() { 141 | Ok(()) 142 | } else { 143 | Err(Error::new( 144 | ErrorKind::WriteZero, 145 | "failed to write whole buffer", 146 | )) 147 | } 148 | } 149 | 150 | #[inline] 151 | fn flush(&mut self) -> Result<()> { 152 | Ok(()) 153 | } 154 | } 155 | 156 | /// Write is implemented for `Vec` by appending to the vector. 157 | /// The vector will grow as needed. 158 | #[cfg(feature = "alloc")] 159 | impl Write for alloc::vec::Vec { 160 | #[inline] 161 | fn write(&mut self, buf: &[u8]) -> Result { 162 | self.extend_from_slice(buf); 163 | Ok(buf.len()) 164 | } 165 | 166 | #[inline] 167 | fn write_all(&mut self, buf: &[u8]) -> Result<()> { 168 | self.extend_from_slice(buf); 169 | Ok(()) 170 | } 171 | 172 | #[inline] 173 | fn flush(&mut self) -> Result<()> { 174 | Ok(()) 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/io/mod.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "nightly")] 2 | mod buffered; 3 | mod cursor; 4 | mod error; 5 | mod impls; 6 | mod traits; 7 | mod util; 8 | 9 | #[cfg(not(feature = "std"))] 10 | pub use cursor::Cursor; 11 | #[cfg(not(feature = "std"))] 12 | pub use error::{Error, ErrorKind, Result}; 13 | #[cfg(not(feature = "std"))] 14 | pub use traits::{BufRead, Bytes, Chain, Read, Seek, SeekFrom, Take, Write}; 15 | 16 | #[cfg(feature = "std")] 17 | pub use std::io::{ 18 | BufRead, Bytes, Chain, Cursor, Error, ErrorKind, Read, Result, Seek, SeekFrom, Take, Write, 19 | }; 20 | 21 | // Use this crate's implementation on both std and no_std 22 | #[cfg(feature = "nightly")] 23 | pub use buffered::{BufReader, BufWriter, LineWriter}; 24 | 25 | #[cfg(feature = "nightly")] 26 | pub use util::copy; 27 | -------------------------------------------------------------------------------- /src/io/traits.rs: -------------------------------------------------------------------------------- 1 | use super::error::{Error, ErrorKind, Result}; 2 | use core::{cmp, fmt, slice}; 3 | 4 | #[cfg(feature = "alloc")] 5 | pub use alloc::vec::Vec; 6 | 7 | #[cfg(feature = "alloc")] 8 | struct Guard<'a> { 9 | buf: &'a mut Vec, 10 | len: usize, 11 | } 12 | 13 | #[cfg(feature = "alloc")] 14 | impl Drop for Guard<'_> { 15 | fn drop(&mut self) { 16 | unsafe { 17 | self.buf.set_len(self.len); 18 | } 19 | } 20 | } 21 | 22 | // This uses an adaptive system to extend the vector when it fills. We want to 23 | // avoid paying to allocate and zero a huge chunk of memory if the reader only 24 | // has 4 bytes while still making large reads if the reader does have a ton 25 | // of data to return. Simply tacking on an extra DEFAULT_BUF_SIZE space every 26 | // time is 4,500 times (!) slower than a default reservation size of 32 if the 27 | // reader has a very small amount of data to return. 28 | // 29 | // Because we're extending the buffer with uninitialized data for trusted 30 | // readers, we need to make sure to truncate that if any of this panics. 31 | #[cfg(feature = "alloc")] 32 | fn read_to_end(r: &mut R, buf: &mut Vec) -> Result { 33 | read_to_end_with_reservation(r, buf, |_| 32) 34 | } 35 | 36 | #[cfg(feature = "alloc")] 37 | fn read_to_end_with_reservation( 38 | r: &mut R, 39 | buf: &mut Vec, 40 | mut reservation_size: F, 41 | ) -> Result 42 | where 43 | R: Read + ?Sized, 44 | F: FnMut(&R) -> usize, 45 | { 46 | let start_len = buf.len(); 47 | let mut g = Guard { 48 | len: buf.len(), 49 | buf, 50 | }; 51 | loop { 52 | if g.len == g.buf.len() { 53 | unsafe { 54 | // FIXME(danielhenrymantilla): #42788 55 | // 56 | // - This creates a (mut) reference to a slice of 57 | // _uninitialized_ integers, which is **undefined behavior** 58 | // 59 | // - Only the standard library gets to soundly "ignore" this, 60 | // based on its privileged knowledge of unstable rustc 61 | // internals; 62 | g.buf.reserve(reservation_size(r)); 63 | let capacity = g.buf.capacity(); 64 | g.buf.set_len(capacity); 65 | r.initializer().initialize(&mut g.buf[g.len..]); 66 | } 67 | } 68 | 69 | let buf = &mut g.buf[g.len..]; 70 | match r.read(buf) { 71 | Ok(0) => return Ok(g.len - start_len), 72 | Ok(n) => { 73 | // We can't allow bogus values from read. If it is too large, the returned vec could have its length 74 | // set past its capacity, or if it overflows the vec could be shortened which could create an invalid 75 | // string if this is called via read_to_string. 76 | assert!(n <= buf.len()); 77 | g.len += n; 78 | } 79 | Err(ref e) if e.kind() == ErrorKind::Interrupted => {} 80 | Err(e) => return Err(e), 81 | } 82 | } 83 | } 84 | 85 | /// The `Read` trait allows for reading bytes from a source. 86 | /// 87 | /// Implementors of the `Read` trait are called 'readers'. 88 | /// 89 | /// Readers are defined by one required method, [`read()`]. Each call to [`read()`] 90 | /// will attempt to pull bytes from this source into a provided buffer. A 91 | /// number of other methods are implemented in terms of [`read()`], giving 92 | /// implementors a number of ways to read bytes while only needing to implement 93 | /// a single method. 94 | /// 95 | /// Readers are intended to be composable with one another. Many implementors 96 | /// throughout [`std::io`] take and provide types which implement the `Read` 97 | /// trait. 98 | /// 99 | /// Please note that each call to [`read()`] may involve a system call, and 100 | /// therefore, using something that implements [`BufRead`], such as 101 | /// [`BufReader`], will be more efficient. 102 | /// 103 | /// # Examples 104 | /// 105 | /// [`File`]s implement `Read`: 106 | /// 107 | /// ```no_run 108 | /// use std::io; 109 | /// use std::io::prelude::*; 110 | /// use std::fs::File; 111 | /// 112 | /// fn main() -> io::Result<()> { 113 | /// let mut f = File::open("foo.txt")?; 114 | /// let mut buffer = [0; 10]; 115 | /// 116 | /// // read up to 10 bytes 117 | /// f.read(&mut buffer)?; 118 | /// 119 | /// let mut buffer = Vec::new(); 120 | /// // read the whole file 121 | /// f.read_to_end(&mut buffer)?; 122 | /// 123 | /// // read into a String, so that you don't need to do the conversion. 124 | /// let mut buffer = String::new(); 125 | /// f.read_to_string(&mut buffer)?; 126 | /// 127 | /// // and more! See the other methods for more details. 128 | /// Ok(()) 129 | /// } 130 | /// ``` 131 | /// 132 | /// Read from [`&str`] because [`&[u8]`][slice] implements `Read`: 133 | /// 134 | /// ```no_run 135 | /// # use std::io; 136 | /// use std::io::prelude::*; 137 | /// 138 | /// fn main() -> io::Result<()> { 139 | /// let mut b = "This string will be read".as_bytes(); 140 | /// let mut buffer = [0; 10]; 141 | /// 142 | /// // read up to 10 bytes 143 | /// b.read(&mut buffer)?; 144 | /// 145 | /// // etc... it works exactly as a File does! 146 | /// Ok(()) 147 | /// } 148 | /// ``` 149 | /// 150 | /// [`read()`]: Read::read 151 | /// [`&str`]: prim@str 152 | /// [`std::io`]: self 153 | /// [`File`]: crate::fs::File 154 | /// [slice]: ../../std/primitive.slice.html 155 | pub trait Read { 156 | /// Pull some bytes from this source into the specified buffer, returning 157 | /// how many bytes were read. 158 | /// 159 | /// This function does not provide any guarantees about whether it blocks 160 | /// waiting for data, but if an object needs to block for a read and cannot, 161 | /// it will typically signal this via an [`Err`] return value. 162 | /// 163 | /// If the return value of this method is [`Ok(n)`], then it must be 164 | /// guaranteed that `0 <= n <= buf.len()`. A nonzero `n` value indicates 165 | /// that the buffer `buf` has been filled in with `n` bytes of data from this 166 | /// source. If `n` is `0`, then it can indicate one of two scenarios: 167 | /// 168 | /// 1. This reader has reached its "end of file" and will likely no longer 169 | /// be able to produce bytes. Note that this does not mean that the 170 | /// reader will *always* no longer be able to produce bytes. 171 | /// 2. The buffer specified was 0 bytes in length. 172 | /// 173 | /// It is not an error if the returned value `n` is smaller than the buffer size, 174 | /// even when the reader is not at the end of the stream yet. 175 | /// This may happen for example because fewer bytes are actually available right now 176 | /// (e. g. being close to end-of-file) or because read() was interrupted by a signal. 177 | /// 178 | /// No guarantees are provided about the contents of `buf` when this 179 | /// function is called, implementations cannot rely on any property of the 180 | /// contents of `buf` being true. It is recommended that *implementations* 181 | /// only write data to `buf` instead of reading its contents. 182 | /// 183 | /// Correspondingly, however, *callers* of this method may not assume any guarantees 184 | /// about how the implementation uses `buf`. The trait is safe to implement, 185 | /// so it is possible that the code that's supposed to write to the buffer might also read 186 | /// from it. It is your responsibility to make sure that `buf` is initialized 187 | /// before calling `read`. Calling `read` with an uninitialized `buf` (of the kind one 188 | /// obtains via [`MaybeUninit`]) is not safe, and can lead to undefined behavior. 189 | /// 190 | /// [`MaybeUninit`]: crate::mem::MaybeUninit 191 | /// 192 | /// # Errors 193 | /// 194 | /// If this function encounters any form of I/O or other error, an error 195 | /// variant will be returned. If an error is returned then it must be 196 | /// guaranteed that no bytes were read. 197 | /// 198 | /// An error of the [`ErrorKind::Interrupted`] kind is non-fatal and the read 199 | /// operation should be retried if there is nothing else to do. 200 | /// 201 | /// # Examples 202 | /// 203 | /// [`File`]s implement `Read`: 204 | /// 205 | /// [`Ok(n)`]: Ok 206 | /// [`File`]: crate::fs::File 207 | /// 208 | /// ```no_run 209 | /// use std::io; 210 | /// use std::io::prelude::*; 211 | /// use std::fs::File; 212 | /// 213 | /// fn main() -> io::Result<()> { 214 | /// let mut f = File::open("foo.txt")?; 215 | /// let mut buffer = [0; 10]; 216 | /// 217 | /// // read up to 10 bytes 218 | /// let n = f.read(&mut buffer[..])?; 219 | /// 220 | /// println!("The bytes: {:?}", &buffer[..n]); 221 | /// Ok(()) 222 | /// } 223 | /// ``` 224 | fn read(&mut self, buf: &mut [u8]) -> Result; 225 | 226 | /// Read all bytes until EOF in this source, placing them into `buf`. 227 | /// 228 | /// All bytes read from this source will be appended to the specified buffer 229 | /// `buf`. This function will continuously call [`read()`] to append more data to 230 | /// `buf` until [`read()`] returns either [`Ok(0)`] or an error of 231 | /// non-[`ErrorKind::Interrupted`] kind. 232 | /// 233 | /// If successful, this function will return the total number of bytes read. 234 | /// 235 | /// # Errors 236 | /// 237 | /// If this function encounters an error of the kind 238 | /// [`ErrorKind::Interrupted`] then the error is ignored and the operation 239 | /// will continue. 240 | /// 241 | /// If any other read error is encountered then this function immediately 242 | /// returns. Any bytes which have already been read will be appended to 243 | /// `buf`. 244 | /// 245 | /// # Examples 246 | /// 247 | /// [`File`]s implement `Read`: 248 | /// 249 | /// [`read()`]: Read::read 250 | /// [`Ok(0)`]: Ok 251 | /// [`File`]: crate::fs::File 252 | /// 253 | /// ```no_run 254 | /// use std::io; 255 | /// use std::io::prelude::*; 256 | /// use std::fs::File; 257 | /// 258 | /// fn main() -> io::Result<()> { 259 | /// let mut f = File::open("foo.txt")?; 260 | /// let mut buffer = Vec::new(); 261 | /// 262 | /// // read the whole file 263 | /// f.read_to_end(&mut buffer)?; 264 | /// Ok(()) 265 | /// } 266 | /// ``` 267 | /// 268 | /// (See also the [`std::fs::read`] convenience function for reading from a 269 | /// file.) 270 | /// 271 | /// [`std::fs::read`]: crate::fs::read 272 | #[cfg(feature = "alloc")] 273 | fn read_to_end(&mut self, buf: &mut Vec) -> Result { 274 | read_to_end(self, buf) 275 | } 276 | 277 | /// Determines if this `Read`er can work with buffers of uninitialized 278 | /// memory. 279 | /// 280 | /// The default implementation returns an initializer which will zero 281 | /// buffers. 282 | /// 283 | /// If a `Read`er guarantees that it can work properly with uninitialized 284 | /// memory, it should call [`Initializer::nop()`]. See the documentation for 285 | /// [`Initializer`] for details. 286 | /// 287 | /// The behavior of this method must be independent of the state of the 288 | /// `Read`er - the method only takes `&self` so that it can be used through 289 | /// trait objects. 290 | /// 291 | /// # Safety 292 | /// 293 | /// This method is unsafe because a `Read`er could otherwise return a 294 | /// non-zeroing `Initializer` from another `Read` type without an `unsafe` 295 | /// block. 296 | #[inline] 297 | unsafe fn initializer(&self) -> Initializer { 298 | Initializer::zeroing() 299 | } 300 | 301 | /// Read the exact number of bytes required to fill `buf`. 302 | /// 303 | /// This function reads as many bytes as necessary to completely fill the 304 | /// specified buffer `buf`. 305 | /// 306 | /// No guarantees are provided about the contents of `buf` when this 307 | /// function is called, implementations cannot rely on any property of the 308 | /// contents of `buf` being true. It is recommended that implementations 309 | /// only write data to `buf` instead of reading its contents. The 310 | /// documentation on [`read`] has a more detailed explanation on this 311 | /// subject. 312 | /// 313 | /// # Errors 314 | /// 315 | /// If this function encounters an error of the kind 316 | /// [`ErrorKind::Interrupted`] then the error is ignored and the operation 317 | /// will continue. 318 | /// 319 | /// If this function encounters an "end of file" before completely filling 320 | /// the buffer, it returns an error of the kind [`ErrorKind::UnexpectedEof`]. 321 | /// The contents of `buf` are unspecified in this case. 322 | /// 323 | /// If any other read error is encountered then this function immediately 324 | /// returns. The contents of `buf` are unspecified in this case. 325 | /// 326 | /// If this function returns an error, it is unspecified how many bytes it 327 | /// has read, but it will never read more than would be necessary to 328 | /// completely fill the buffer. 329 | /// 330 | /// # Examples 331 | /// 332 | /// [`File`]s implement `Read`: 333 | /// 334 | /// [`read`]: Read::read 335 | /// [`File`]: crate::fs::File 336 | /// 337 | /// ```no_run 338 | /// use std::io; 339 | /// use std::io::prelude::*; 340 | /// use std::fs::File; 341 | /// 342 | /// fn main() -> io::Result<()> { 343 | /// let mut f = File::open("foo.txt")?; 344 | /// let mut buffer = [0; 10]; 345 | /// 346 | /// // read exactly 10 bytes 347 | /// f.read_exact(&mut buffer)?; 348 | /// Ok(()) 349 | /// } 350 | /// ``` 351 | fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> { 352 | while !buf.is_empty() { 353 | match self.read(buf) { 354 | Ok(0) => break, 355 | Ok(n) => { 356 | let tmp = buf; 357 | buf = &mut tmp[n..]; 358 | } 359 | Err(ref e) if e.kind() == ErrorKind::Interrupted => {} 360 | Err(e) => return Err(e), 361 | } 362 | } 363 | if !buf.is_empty() { 364 | Err(Error::new( 365 | ErrorKind::UnexpectedEof, 366 | "failed to fill whole buffer", 367 | )) 368 | } else { 369 | Ok(()) 370 | } 371 | } 372 | 373 | /// Creates a "by reference" adaptor for this instance of `Read`. 374 | /// 375 | /// The returned adaptor also implements `Read` and will simply borrow this 376 | /// current reader. 377 | /// 378 | /// # Examples 379 | /// 380 | /// [`File`]s implement `Read`: 381 | /// 382 | /// [`File`]: crate::fs::File 383 | /// 384 | /// ```no_run 385 | /// use std::io; 386 | /// use std::io::Read; 387 | /// use std::fs::File; 388 | /// 389 | /// fn main() -> io::Result<()> { 390 | /// let mut f = File::open("foo.txt")?; 391 | /// let mut buffer = Vec::new(); 392 | /// let mut other_buffer = Vec::new(); 393 | /// 394 | /// { 395 | /// let reference = f.by_ref(); 396 | /// 397 | /// // read at most 5 bytes 398 | /// reference.take(5).read_to_end(&mut buffer)?; 399 | /// 400 | /// } // drop our &mut reference so we can use f again 401 | /// 402 | /// // original file still usable, read the rest 403 | /// f.read_to_end(&mut other_buffer)?; 404 | /// Ok(()) 405 | /// } 406 | /// ``` 407 | fn by_ref(&mut self) -> &mut Self 408 | where 409 | Self: Sized, 410 | { 411 | self 412 | } 413 | 414 | /// Transforms this `Read` instance to an [`Iterator`] over its bytes. 415 | /// 416 | /// The returned type implements [`Iterator`] where the `Item` is 417 | /// [`Result`]`<`[`u8`]`, `[`io::Error`]`>`. 418 | /// The yielded item is [`Ok`] if a byte was successfully read and [`Err`] 419 | /// otherwise. EOF is mapped to returning [`None`] from this iterator. 420 | /// 421 | /// # Examples 422 | /// 423 | /// [`File`]s implement `Read`: 424 | /// 425 | /// [`File`]: crate::fs::File 426 | /// [`Result`]: crate::result::Result 427 | /// [`io::Error`]: self::Error 428 | /// 429 | /// ```no_run 430 | /// use std::io; 431 | /// use std::io::prelude::*; 432 | /// use std::fs::File; 433 | /// 434 | /// fn main() -> io::Result<()> { 435 | /// let mut f = File::open("foo.txt")?; 436 | /// 437 | /// for byte in f.bytes() { 438 | /// println!("{}", byte.unwrap()); 439 | /// } 440 | /// Ok(()) 441 | /// } 442 | /// ``` 443 | fn bytes(self) -> Bytes 444 | where 445 | Self: Sized, 446 | { 447 | Bytes { inner: self } 448 | } 449 | 450 | /// Creates an adaptor which will chain this stream with another. 451 | /// 452 | /// The returned `Read` instance will first read all bytes from this object 453 | /// until EOF is encountered. Afterwards the output is equivalent to the 454 | /// output of `next`. 455 | /// 456 | /// # Examples 457 | /// 458 | /// [`File`]s implement `Read`: 459 | /// 460 | /// [`File`]: crate::fs::File 461 | /// 462 | /// ```no_run 463 | /// use std::io; 464 | /// use std::io::prelude::*; 465 | /// use std::fs::File; 466 | /// 467 | /// fn main() -> io::Result<()> { 468 | /// let mut f1 = File::open("foo.txt")?; 469 | /// let mut f2 = File::open("bar.txt")?; 470 | /// 471 | /// let mut handle = f1.chain(f2); 472 | /// let mut buffer = String::new(); 473 | /// 474 | /// // read the value into a String. We could use any Read method here, 475 | /// // this is just one example. 476 | /// handle.read_to_string(&mut buffer)?; 477 | /// Ok(()) 478 | /// } 479 | /// ``` 480 | fn chain(self, next: R) -> Chain 481 | where 482 | Self: Sized, 483 | { 484 | Chain { 485 | first: self, 486 | second: next, 487 | done_first: false, 488 | } 489 | } 490 | 491 | /// Creates an adaptor which will read at most `limit` bytes from it. 492 | /// 493 | /// This function returns a new instance of `Read` which will read at most 494 | /// `limit` bytes, after which it will always return EOF ([`Ok(0)`]). Any 495 | /// read errors will not count towards the number of bytes read and future 496 | /// calls to [`read()`] may succeed. 497 | /// 498 | /// # Examples 499 | /// 500 | /// [`File`]s implement `Read`: 501 | /// 502 | /// [`File`]: crate::fs::File 503 | /// [`Ok(0)`]: Ok 504 | /// [`read()`]: Read::read 505 | /// 506 | /// ```no_run 507 | /// use std::io; 508 | /// use std::io::prelude::*; 509 | /// use std::fs::File; 510 | /// 511 | /// fn main() -> io::Result<()> { 512 | /// let mut f = File::open("foo.txt")?; 513 | /// let mut buffer = [0; 5]; 514 | /// 515 | /// // read at most five bytes 516 | /// let mut handle = f.take(5); 517 | /// 518 | /// handle.read(&mut buffer)?; 519 | /// Ok(()) 520 | /// } 521 | /// ``` 522 | fn take(self, limit: u64) -> Take 523 | where 524 | Self: Sized, 525 | { 526 | Take { inner: self, limit } 527 | } 528 | } 529 | 530 | /// A type used to conditionally initialize buffers passed to `Read` methods. 531 | #[derive(Debug)] 532 | pub struct Initializer(bool); 533 | 534 | impl Initializer { 535 | /// Returns a new `Initializer` which will zero out buffers. 536 | #[inline] 537 | pub fn zeroing() -> Initializer { 538 | Initializer(true) 539 | } 540 | 541 | /// Returns a new `Initializer` which will not zero out buffers. 542 | /// 543 | /// # Safety 544 | /// 545 | /// This may only be called by `Read`ers which guarantee that they will not 546 | /// read from buffers passed to `Read` methods, and that the return value of 547 | /// the method accurately reflects the number of bytes that have been 548 | /// written to the head of the buffer. 549 | #[inline] 550 | pub unsafe fn nop() -> Initializer { 551 | Initializer(false) 552 | } 553 | 554 | /// Indicates if a buffer should be initialized. 555 | #[inline] 556 | pub fn should_initialize(&self) -> bool { 557 | self.0 558 | } 559 | 560 | /// Initializes a buffer if necessary. 561 | #[inline] 562 | pub fn initialize(&self, buf: &mut [u8]) { 563 | if self.should_initialize() { 564 | unsafe { core::ptr::write_bytes(buf.as_mut_ptr(), 0, buf.len()) } 565 | } 566 | } 567 | } 568 | 569 | /// A trait for objects which are byte-oriented sinks. 570 | /// 571 | /// Implementors of the `Write` trait are sometimes called 'writers'. 572 | /// 573 | /// Writers are defined by two required methods, [`write`] and [`flush`]: 574 | /// 575 | /// * The [`write`] method will attempt to write some data into the object, 576 | /// returning how many bytes were successfully written. 577 | /// 578 | /// * The [`flush`] method is useful for adaptors and explicit buffers 579 | /// themselves for ensuring that all buffered data has been pushed out to the 580 | /// 'true sink'. 581 | /// 582 | /// Writers are intended to be composable with one another. Many implementors 583 | /// throughout [`std::io`] take and provide types which implement the `Write` 584 | /// trait. 585 | /// 586 | /// [`write`]: Write::write 587 | /// [`flush`]: Write::flush 588 | /// [`std::io`]: self 589 | /// 590 | /// # Examples 591 | /// 592 | /// ```no_run 593 | /// use std::io::prelude::*; 594 | /// use std::fs::File; 595 | /// 596 | /// fn main() -> std::io::Result<()> { 597 | /// let data = b"some bytes"; 598 | /// 599 | /// let mut pos = 0; 600 | /// let mut buffer = File::create("foo.txt")?; 601 | /// 602 | /// while pos < data.len() { 603 | /// let bytes_written = buffer.write(&data[pos..])?; 604 | /// pos += bytes_written; 605 | /// } 606 | /// Ok(()) 607 | /// } 608 | /// ``` 609 | /// 610 | /// The trait also provides convenience methods like [`write_all`], which calls 611 | /// `write` in a loop until its entire input has been written. 612 | /// 613 | /// [`write_all`]: Write::write_all 614 | pub trait Write { 615 | /// Write a buffer into this writer, returning how many bytes were written. 616 | /// 617 | /// This function will attempt to write the entire contents of `buf`, but 618 | /// the entire write may not succeed, or the write may also generate an 619 | /// error. A call to `write` represents *at most one* attempt to write to 620 | /// any wrapped object. 621 | /// 622 | /// Calls to `write` are not guaranteed to block waiting for data to be 623 | /// written, and a write which would otherwise block can be indicated through 624 | /// an [`Err`] variant. 625 | /// 626 | /// If the return value is [`Ok(n)`] then it must be guaranteed that 627 | /// `n <= buf.len()`. A return value of `0` typically means that the 628 | /// underlying object is no longer able to accept bytes and will likely not 629 | /// be able to in the future as well, or that the buffer provided is empty. 630 | /// 631 | /// # Errors 632 | /// 633 | /// Each call to `write` may generate an I/O error indicating that the 634 | /// operation could not be completed. If an error is returned then no bytes 635 | /// in the buffer were written to this writer. 636 | /// 637 | /// It is **not** considered an error if the entire buffer could not be 638 | /// written to this writer. 639 | /// 640 | /// An error of the [`ErrorKind::Interrupted`] kind is non-fatal and the 641 | /// write operation should be retried if there is nothing else to do. 642 | /// 643 | /// # Examples 644 | /// 645 | /// ```no_run 646 | /// use std::io::prelude::*; 647 | /// use std::fs::File; 648 | /// 649 | /// fn main() -> std::io::Result<()> { 650 | /// let mut buffer = File::create("foo.txt")?; 651 | /// 652 | /// // Writes some prefix of the byte string, not necessarily all of it. 653 | /// buffer.write(b"some bytes")?; 654 | /// Ok(()) 655 | /// } 656 | /// ``` 657 | /// 658 | /// [`Ok(n)`]: Ok 659 | fn write(&mut self, buf: &[u8]) -> Result; 660 | 661 | /// Flush this output stream, ensuring that all intermediately buffered 662 | /// contents reach their destination. 663 | /// 664 | /// # Errors 665 | /// 666 | /// It is considered an error if not all bytes could be written due to 667 | /// I/O errors or EOF being reached. 668 | /// 669 | /// # Examples 670 | /// 671 | /// ```no_run 672 | /// use std::io::prelude::*; 673 | /// use std::io::BufWriter; 674 | /// use std::fs::File; 675 | /// 676 | /// fn main() -> std::io::Result<()> { 677 | /// let mut buffer = BufWriter::new(File::create("foo.txt")?); 678 | /// 679 | /// buffer.write_all(b"some bytes")?; 680 | /// buffer.flush()?; 681 | /// Ok(()) 682 | /// } 683 | /// ``` 684 | fn flush(&mut self) -> Result<()>; 685 | 686 | /// Attempts to write an entire buffer into this writer. 687 | /// 688 | /// This method will continuously call [`write`] until there is no more data 689 | /// to be written or an error of non-[`ErrorKind::Interrupted`] kind is 690 | /// returned. This method will not return until the entire buffer has been 691 | /// successfully written or such an error occurs. The first error that is 692 | /// not of [`ErrorKind::Interrupted`] kind generated from this method will be 693 | /// returned. 694 | /// 695 | /// If the buffer contains no data, this will never call [`write`]. 696 | /// 697 | /// # Errors 698 | /// 699 | /// This function will return the first error of 700 | /// non-[`ErrorKind::Interrupted`] kind that [`write`] returns. 701 | /// 702 | /// [`write`]: Write::write 703 | /// 704 | /// # Examples 705 | /// 706 | /// ```no_run 707 | /// use std::io::prelude::*; 708 | /// use std::fs::File; 709 | /// 710 | /// fn main() -> std::io::Result<()> { 711 | /// let mut buffer = File::create("foo.txt")?; 712 | /// 713 | /// buffer.write_all(b"some bytes")?; 714 | /// Ok(()) 715 | /// } 716 | /// ``` 717 | fn write_all(&mut self, mut buf: &[u8]) -> Result<()> { 718 | while !buf.is_empty() { 719 | match self.write(buf) { 720 | Ok(0) => { 721 | return Err(Error::new( 722 | ErrorKind::WriteZero, 723 | "failed to write whole buffer", 724 | )); 725 | } 726 | Ok(n) => buf = &buf[n..], 727 | Err(ref e) if e.kind() == ErrorKind::Interrupted => {} 728 | Err(e) => return Err(e), 729 | } 730 | } 731 | Ok(()) 732 | } 733 | /// Writes a formatted string into this writer, returning any error 734 | /// encountered. 735 | /// 736 | /// This method is primarily used to interface with the 737 | /// [`format_args!()`] macro, but it is rare that this should 738 | /// explicitly be called. The [`write!()`] macro should be favored to 739 | /// invoke this method instead. 740 | /// 741 | /// This function internally uses the [`write_all`] method on 742 | /// this trait and hence will continuously write data so long as no errors 743 | /// are received. This also means that partial writes are not indicated in 744 | /// this signature. 745 | /// 746 | /// [`write_all`]: Write::write_all 747 | /// 748 | /// # Errors 749 | /// 750 | /// This function will return any I/O error reported while formatting. 751 | /// 752 | /// # Examples 753 | /// 754 | /// ```no_run 755 | /// use std::io::prelude::*; 756 | /// use std::fs::File; 757 | /// 758 | /// fn main() -> std::io::Result<()> { 759 | /// let mut buffer = File::create("foo.txt")?; 760 | /// 761 | /// // this call 762 | /// write!(buffer, "{:.*}", 2, 1.234567)?; 763 | /// // turns into this: 764 | /// buffer.write_fmt(format_args!("{:.*}", 2, 1.234567))?; 765 | /// Ok(()) 766 | /// } 767 | /// ``` 768 | fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> Result<()> { 769 | // Create a shim which translates a Write to a fmt::Write and saves 770 | // off I/O errors. instead of discarding them 771 | struct Adaptor<'a, T: ?Sized + 'a> { 772 | inner: &'a mut T, 773 | error: Result<()>, 774 | } 775 | 776 | impl fmt::Write for Adaptor<'_, T> { 777 | fn write_str(&mut self, s: &str) -> fmt::Result { 778 | match self.inner.write_all(s.as_bytes()) { 779 | Ok(()) => Ok(()), 780 | Err(e) => { 781 | self.error = Err(e); 782 | Err(fmt::Error) 783 | } 784 | } 785 | } 786 | } 787 | 788 | let mut output = Adaptor { 789 | inner: self, 790 | error: Ok(()), 791 | }; 792 | match fmt::write(&mut output, fmt) { 793 | Ok(()) => Ok(()), 794 | Err(..) => { 795 | // check if the error came from the underlying `Write` or not 796 | if output.error.is_err() { 797 | output.error 798 | } else { 799 | Err(Error::new(ErrorKind::Other, "formatter error")) 800 | } 801 | } 802 | } 803 | } 804 | 805 | /// Creates a "by reference" adaptor for this instance of `Write`. 806 | /// 807 | /// The returned adaptor also implements `Write` and will simply borrow this 808 | /// current writer. 809 | /// 810 | /// # Examples 811 | /// 812 | /// ```no_run 813 | /// use std::io::Write; 814 | /// use std::fs::File; 815 | /// 816 | /// fn main() -> std::io::Result<()> { 817 | /// let mut buffer = File::create("foo.txt")?; 818 | /// 819 | /// let reference = buffer.by_ref(); 820 | /// 821 | /// // we can use reference just like our original buffer 822 | /// reference.write_all(b"some bytes")?; 823 | /// Ok(()) 824 | /// } 825 | /// ``` 826 | fn by_ref(&mut self) -> &mut Self 827 | where 828 | Self: Sized, 829 | { 830 | self 831 | } 832 | } 833 | 834 | /// The `Seek` trait provides a cursor which can be moved within a stream of 835 | /// bytes. 836 | /// 837 | /// The stream typically has a fixed size, allowing seeking relative to either 838 | /// end or the current offset. 839 | /// 840 | /// # Examples 841 | /// 842 | /// [`File`]s implement `Seek`: 843 | /// 844 | /// [`File`]: crate::fs::File 845 | /// 846 | /// ```no_run 847 | /// use std::io; 848 | /// use std::io::prelude::*; 849 | /// use std::fs::File; 850 | /// use std::io::SeekFrom; 851 | /// 852 | /// fn main() -> io::Result<()> { 853 | /// let mut f = File::open("foo.txt")?; 854 | /// 855 | /// // move the cursor 42 bytes from the start of the file 856 | /// f.seek(SeekFrom::Start(42))?; 857 | /// Ok(()) 858 | /// } 859 | /// ``` 860 | pub trait Seek { 861 | /// Seek to an offset, in bytes, in a stream. 862 | /// 863 | /// A seek beyond the end of a stream is allowed, but behavior is defined 864 | /// by the implementation. 865 | /// 866 | /// If the seek operation completed successfully, 867 | /// this method returns the new position from the start of the stream. 868 | /// That position can be used later with [`SeekFrom::Start`]. 869 | /// 870 | /// # Errors 871 | /// 872 | /// Seeking to a negative offset is considered an error. 873 | fn seek(&mut self, pos: SeekFrom) -> Result; 874 | } 875 | 876 | /// Enumeration of possible methods to seek within an I/O object. 877 | /// 878 | /// It is used by the [`Seek`] trait. 879 | #[derive(Copy, PartialEq, Eq, Clone, Debug)] 880 | pub enum SeekFrom { 881 | /// Sets the offset to the provided number of bytes. 882 | Start(u64), 883 | 884 | /// Sets the offset to the size of this object plus the specified number of 885 | /// bytes. 886 | /// 887 | /// It is possible to seek beyond the end of an object, but it's an error to 888 | /// seek before byte 0. 889 | End(i64), 890 | 891 | /// Sets the offset to the current position plus the specified number of 892 | /// bytes. 893 | /// 894 | /// It is possible to seek beyond the end of an object, but it's an error to 895 | /// seek before byte 0. 896 | Current(i64), 897 | } 898 | 899 | /// An iterator over `u8` values of a reader. 900 | /// 901 | /// This struct is generally created by calling [`bytes`] on a reader. 902 | /// Please see the documentation of [`bytes`] for more details. 903 | /// 904 | /// [`bytes`]: Read::bytes 905 | #[derive(Debug)] 906 | pub struct Bytes { 907 | inner: R, 908 | } 909 | 910 | impl Iterator for Bytes { 911 | type Item = Result; 912 | 913 | fn next(&mut self) -> Option> { 914 | let mut byte = 0; 915 | loop { 916 | return match self.inner.read(slice::from_mut(&mut byte)) { 917 | Ok(0) => None, 918 | Ok(..) => Some(Ok(byte)), 919 | Err(ref e) if e.kind() == ErrorKind::Interrupted => continue, 920 | Err(e) => Some(Err(e)), 921 | }; 922 | } 923 | } 924 | } 925 | 926 | /// A `BufRead` is a type of `Read`er which has an internal buffer, allowing it 927 | /// to perform extra ways of reading. 928 | /// 929 | /// For example, reading line-by-line is inefficient without using a buffer, so 930 | /// if you want to read by line, you'll need `BufRead`, which includes a 931 | /// [`read_line`] method as well as a [`lines`] iterator. 932 | /// 933 | /// # Examples 934 | /// 935 | /// A locked standard input implements `BufRead`: 936 | /// 937 | /// ```no_run 938 | /// use std::io; 939 | /// use std::io::prelude::*; 940 | /// 941 | /// let stdin = io::stdin(); 942 | /// for line in stdin.lock().lines() { 943 | /// println!("{}", line.unwrap()); 944 | /// } 945 | /// ``` 946 | /// 947 | /// If you have something that implements [`Read`], you can use the [`BufReader` 948 | /// type][`BufReader`] to turn it into a `BufRead`. 949 | /// 950 | /// For example, [`File`] implements [`Read`], but not `BufRead`. 951 | /// [`BufReader`] to the rescue! 952 | /// 953 | /// [`File`]: crate::fs::File 954 | /// [`read_line`]: BufRead::read_line 955 | /// [`lines`]: BufRead::lines 956 | /// 957 | /// ```no_run 958 | /// use std::io::{self, BufReader}; 959 | /// use std::io::prelude::*; 960 | /// use std::fs::File; 961 | /// 962 | /// fn main() -> io::Result<()> { 963 | /// let f = File::open("foo.txt")?; 964 | /// let f = BufReader::new(f); 965 | /// 966 | /// for line in f.lines() { 967 | /// println!("{}", line.unwrap()); 968 | /// } 969 | /// 970 | /// Ok(()) 971 | /// } 972 | /// ``` 973 | pub trait BufRead: Read { 974 | /// Returns the contents of the internal buffer, filling it with more data 975 | /// from the inner reader if it is empty. 976 | /// 977 | /// This function is a lower-level call. It needs to be paired with the 978 | /// [`consume`] method to function properly. When calling this 979 | /// method, none of the contents will be "read" in the sense that later 980 | /// calling `read` may return the same contents. As such, [`consume`] must 981 | /// be called with the number of bytes that are consumed from this buffer to 982 | /// ensure that the bytes are never returned twice. 983 | /// 984 | /// [`consume`]: BufRead::consume 985 | /// 986 | /// An empty buffer returned indicates that the stream has reached EOF. 987 | /// 988 | /// # Errors 989 | /// 990 | /// This function will return an I/O error if the underlying reader was 991 | /// read, but returned an error. 992 | /// 993 | /// # Examples 994 | /// 995 | /// A locked standard input implements `BufRead`: 996 | /// 997 | /// ```no_run 998 | /// use std::io; 999 | /// use std::io::prelude::*; 1000 | /// 1001 | /// let stdin = io::stdin(); 1002 | /// let mut stdin = stdin.lock(); 1003 | /// 1004 | /// let buffer = stdin.fill_buf().unwrap(); 1005 | /// 1006 | /// // work with buffer 1007 | /// println!("{:?}", buffer); 1008 | /// 1009 | /// // ensure the bytes we worked with aren't returned again later 1010 | /// let length = buffer.len(); 1011 | /// stdin.consume(length); 1012 | /// ``` 1013 | fn fill_buf(&mut self) -> Result<&[u8]>; 1014 | 1015 | /// Tells this buffer that `amt` bytes have been consumed from the buffer, 1016 | /// so they should no longer be returned in calls to `read`. 1017 | /// 1018 | /// This function is a lower-level call. It needs to be paired with the 1019 | /// [`fill_buf`] method to function properly. This function does 1020 | /// not perform any I/O, it simply informs this object that some amount of 1021 | /// its buffer, returned from [`fill_buf`], has been consumed and should 1022 | /// no longer be returned. As such, this function may do odd things if 1023 | /// [`fill_buf`] isn't called before calling it. 1024 | /// 1025 | /// The `amt` must be `<=` the number of bytes in the buffer returned by 1026 | /// [`fill_buf`]. 1027 | /// 1028 | /// # Examples 1029 | /// 1030 | /// Since `consume()` is meant to be used with [`fill_buf`], 1031 | /// that method's example includes an example of `consume()`. 1032 | /// 1033 | /// [`fill_buf`]: BufRead::fill_buf 1034 | fn consume(&mut self, amt: usize); 1035 | } 1036 | 1037 | /// Adaptor to chain together two readers. 1038 | /// 1039 | /// This struct is generally created by calling [`chain`] on a reader. 1040 | /// Please see the documentation of [`chain`] for more details. 1041 | /// 1042 | /// [`chain`]: Read::chain 1043 | pub struct Chain { 1044 | first: T, 1045 | second: U, 1046 | done_first: bool, 1047 | } 1048 | 1049 | impl Chain { 1050 | /// Consumes the `Chain`, returning the wrapped readers. 1051 | /// 1052 | /// # Examples 1053 | /// 1054 | /// ```no_run 1055 | /// use std::io; 1056 | /// use std::io::prelude::*; 1057 | /// use std::fs::File; 1058 | /// 1059 | /// fn main() -> io::Result<()> { 1060 | /// let mut foo_file = File::open("foo.txt")?; 1061 | /// let mut bar_file = File::open("bar.txt")?; 1062 | /// 1063 | /// let chain = foo_file.chain(bar_file); 1064 | /// let (foo_file, bar_file) = chain.into_inner(); 1065 | /// Ok(()) 1066 | /// } 1067 | /// ``` 1068 | pub fn into_inner(self) -> (T, U) { 1069 | (self.first, self.second) 1070 | } 1071 | 1072 | /// Gets references to the underlying readers in this `Chain`. 1073 | /// 1074 | /// # Examples 1075 | /// 1076 | /// ```no_run 1077 | /// use std::io; 1078 | /// use std::io::prelude::*; 1079 | /// use std::fs::File; 1080 | /// 1081 | /// fn main() -> io::Result<()> { 1082 | /// let mut foo_file = File::open("foo.txt")?; 1083 | /// let mut bar_file = File::open("bar.txt")?; 1084 | /// 1085 | /// let chain = foo_file.chain(bar_file); 1086 | /// let (foo_file, bar_file) = chain.get_ref(); 1087 | /// Ok(()) 1088 | /// } 1089 | /// ``` 1090 | pub fn get_ref(&self) -> (&T, &U) { 1091 | (&self.first, &self.second) 1092 | } 1093 | 1094 | /// Gets mutable references to the underlying readers in this `Chain`. 1095 | /// 1096 | /// Care should be taken to avoid modifying the internal I/O state of the 1097 | /// underlying readers as doing so may corrupt the internal state of this 1098 | /// `Chain`. 1099 | /// 1100 | /// # Examples 1101 | /// 1102 | /// ```no_run 1103 | /// use std::io; 1104 | /// use std::io::prelude::*; 1105 | /// use std::fs::File; 1106 | /// 1107 | /// fn main() -> io::Result<()> { 1108 | /// let mut foo_file = File::open("foo.txt")?; 1109 | /// let mut bar_file = File::open("bar.txt")?; 1110 | /// 1111 | /// let mut chain = foo_file.chain(bar_file); 1112 | /// let (foo_file, bar_file) = chain.get_mut(); 1113 | /// Ok(()) 1114 | /// } 1115 | /// ``` 1116 | pub fn get_mut(&mut self) -> (&mut T, &mut U) { 1117 | (&mut self.first, &mut self.second) 1118 | } 1119 | } 1120 | 1121 | impl fmt::Debug for Chain { 1122 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1123 | f.debug_struct("Chain") 1124 | .field("t", &self.first) 1125 | .field("u", &self.second) 1126 | .finish() 1127 | } 1128 | } 1129 | 1130 | impl Read for Chain { 1131 | fn read(&mut self, buf: &mut [u8]) -> Result { 1132 | if !self.done_first { 1133 | match self.first.read(buf)? { 1134 | 0 if !buf.is_empty() => self.done_first = true, 1135 | n => return Ok(n), 1136 | } 1137 | } 1138 | self.second.read(buf) 1139 | } 1140 | 1141 | unsafe fn initializer(&self) -> Initializer { 1142 | let initializer = self.first.initializer(); 1143 | if initializer.should_initialize() { 1144 | initializer 1145 | } else { 1146 | self.second.initializer() 1147 | } 1148 | } 1149 | } 1150 | 1151 | impl BufRead for Chain { 1152 | fn fill_buf(&mut self) -> Result<&[u8]> { 1153 | if !self.done_first { 1154 | match self.first.fill_buf()? { 1155 | buf if buf.is_empty() => { 1156 | self.done_first = true; 1157 | } 1158 | buf => return Ok(buf), 1159 | } 1160 | } 1161 | self.second.fill_buf() 1162 | } 1163 | 1164 | fn consume(&mut self, amt: usize) { 1165 | if !self.done_first { 1166 | self.first.consume(amt) 1167 | } else { 1168 | self.second.consume(amt) 1169 | } 1170 | } 1171 | } 1172 | 1173 | /// Reader adaptor which limits the bytes read from an underlying reader. 1174 | /// 1175 | /// This struct is generally created by calling [`take`] on a reader. 1176 | /// Please see the documentation of [`take`] for more details. 1177 | /// 1178 | /// [`take`]: Read::take 1179 | #[derive(Debug)] 1180 | pub struct Take { 1181 | inner: T, 1182 | limit: u64, 1183 | } 1184 | 1185 | impl Take { 1186 | /// Returns the number of bytes that can be read before this instance will 1187 | /// return EOF. 1188 | /// 1189 | /// # Note 1190 | /// 1191 | /// This instance may reach `EOF` after reading fewer bytes than indicated by 1192 | /// this method if the underlying [`Read`] instance reaches EOF. 1193 | /// 1194 | /// # Examples 1195 | /// 1196 | /// ```no_run 1197 | /// use std::io; 1198 | /// use std::io::prelude::*; 1199 | /// use std::fs::File; 1200 | /// 1201 | /// fn main() -> io::Result<()> { 1202 | /// let f = File::open("foo.txt")?; 1203 | /// 1204 | /// // read at most five bytes 1205 | /// let handle = f.take(5); 1206 | /// 1207 | /// println!("limit: {}", handle.limit()); 1208 | /// Ok(()) 1209 | /// } 1210 | /// ``` 1211 | pub fn limit(&self) -> u64 { 1212 | self.limit 1213 | } 1214 | 1215 | /// Sets the number of bytes that can be read before this instance will 1216 | /// return EOF. This is the same as constructing a new `Take` instance, so 1217 | /// the amount of bytes read and the previous limit value don't matter when 1218 | /// calling this method. 1219 | /// 1220 | /// # Examples 1221 | /// 1222 | /// ```no_run 1223 | /// use std::io; 1224 | /// use std::io::prelude::*; 1225 | /// use std::fs::File; 1226 | /// 1227 | /// fn main() -> io::Result<()> { 1228 | /// let f = File::open("foo.txt")?; 1229 | /// 1230 | /// // read at most five bytes 1231 | /// let mut handle = f.take(5); 1232 | /// handle.set_limit(10); 1233 | /// 1234 | /// assert_eq!(handle.limit(), 10); 1235 | /// Ok(()) 1236 | /// } 1237 | /// ``` 1238 | pub fn set_limit(&mut self, limit: u64) { 1239 | self.limit = limit; 1240 | } 1241 | 1242 | /// Consumes the `Take`, returning the wrapped reader. 1243 | /// 1244 | /// # Examples 1245 | /// 1246 | /// ```no_run 1247 | /// use std::io; 1248 | /// use std::io::prelude::*; 1249 | /// use std::fs::File; 1250 | /// 1251 | /// fn main() -> io::Result<()> { 1252 | /// let mut file = File::open("foo.txt")?; 1253 | /// 1254 | /// let mut buffer = [0; 5]; 1255 | /// let mut handle = file.take(5); 1256 | /// handle.read(&mut buffer)?; 1257 | /// 1258 | /// let file = handle.into_inner(); 1259 | /// Ok(()) 1260 | /// } 1261 | /// ``` 1262 | pub fn into_inner(self) -> T { 1263 | self.inner 1264 | } 1265 | 1266 | /// Gets a reference to the underlying reader. 1267 | /// 1268 | /// # Examples 1269 | /// 1270 | /// ```no_run 1271 | /// use std::io; 1272 | /// use std::io::prelude::*; 1273 | /// use std::fs::File; 1274 | /// 1275 | /// fn main() -> io::Result<()> { 1276 | /// let mut file = File::open("foo.txt")?; 1277 | /// 1278 | /// let mut buffer = [0; 5]; 1279 | /// let mut handle = file.take(5); 1280 | /// handle.read(&mut buffer)?; 1281 | /// 1282 | /// let file = handle.get_ref(); 1283 | /// Ok(()) 1284 | /// } 1285 | /// ``` 1286 | pub fn get_ref(&self) -> &T { 1287 | &self.inner 1288 | } 1289 | 1290 | /// Gets a mutable reference to the underlying reader. 1291 | /// 1292 | /// Care should be taken to avoid modifying the internal I/O state of the 1293 | /// underlying reader as doing so may corrupt the internal limit of this 1294 | /// `Take`. 1295 | /// 1296 | /// # Examples 1297 | /// 1298 | /// ```no_run 1299 | /// use std::io; 1300 | /// use std::io::prelude::*; 1301 | /// use std::fs::File; 1302 | /// 1303 | /// fn main() -> io::Result<()> { 1304 | /// let mut file = File::open("foo.txt")?; 1305 | /// 1306 | /// let mut buffer = [0; 5]; 1307 | /// let mut handle = file.take(5); 1308 | /// handle.read(&mut buffer)?; 1309 | /// 1310 | /// let file = handle.get_mut(); 1311 | /// Ok(()) 1312 | /// } 1313 | /// ``` 1314 | pub fn get_mut(&mut self) -> &mut T { 1315 | &mut self.inner 1316 | } 1317 | } 1318 | 1319 | impl Read for Take { 1320 | fn read(&mut self, buf: &mut [u8]) -> Result { 1321 | // Don't call into inner reader at all at EOF because it may still block 1322 | if self.limit == 0 { 1323 | return Ok(0); 1324 | } 1325 | 1326 | let max = cmp::min(buf.len() as u64, self.limit) as usize; 1327 | let n = self.inner.read(&mut buf[..max])?; 1328 | self.limit -= n as u64; 1329 | Ok(n) 1330 | } 1331 | 1332 | unsafe fn initializer(&self) -> Initializer { 1333 | self.inner.initializer() 1334 | } 1335 | 1336 | #[cfg(feature = "alloc")] 1337 | fn read_to_end(&mut self, buf: &mut Vec) -> Result { 1338 | // Pass in a reservation_size closure that respects the current value 1339 | // of limit for each read. If we hit the read limit, this prevents the 1340 | // final zero-byte read from allocating again. 1341 | read_to_end_with_reservation(self, buf, |self_| cmp::min(self_.limit, 32) as usize) 1342 | } 1343 | } 1344 | 1345 | impl BufRead for Take { 1346 | fn fill_buf(&mut self) -> Result<&[u8]> { 1347 | // Don't call into inner reader at all at EOF because it may still block 1348 | if self.limit == 0 { 1349 | return Ok(&[]); 1350 | } 1351 | 1352 | let buf = self.inner.fill_buf()?; 1353 | let cap = cmp::min(buf.len() as u64, self.limit) as usize; 1354 | Ok(&buf[..cap]) 1355 | } 1356 | 1357 | fn consume(&mut self, amt: usize) { 1358 | // Don't let callers reset the limit by passing an overlarge value 1359 | let amt = cmp::min(amt as u64, self.limit) as usize; 1360 | self.limit -= amt as u64; 1361 | self.inner.consume(amt); 1362 | } 1363 | } 1364 | -------------------------------------------------------------------------------- /src/io/util.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "nightly")] 2 | use core::mem::MaybeUninit; 3 | 4 | #[cfg(feature = "nightly")] 5 | use crate::io::{ErrorKind, Read, Write}; 6 | 7 | #[cfg(feature = "nightly")] 8 | pub fn copy( 9 | reader: &mut R, 10 | writer: &mut W, 11 | ) -> crate::io::Result 12 | where 13 | R: Read, 14 | W: Write, 15 | { 16 | let mut buf = MaybeUninit::<[u8; S]>::uninit(); 17 | // FIXME: #42788 18 | // 19 | // - This creates a (mut) reference to a slice of 20 | // _uninitialized_ integers, which is **undefined behavior** 21 | // 22 | // - Only the standard library gets to soundly "ignore" this, 23 | // based on its privileged knowledge of unstable rustc 24 | // internals; 25 | unsafe { 26 | reader.initializer().initialize(buf.assume_init_mut()); 27 | } 28 | 29 | let mut written = 0; 30 | loop { 31 | let len = match reader.read(unsafe { buf.assume_init_mut() }) { 32 | Ok(0) => return Ok(written), 33 | Ok(len) => len, 34 | Err(ref e) if e.kind() == ErrorKind::Interrupted => continue, 35 | Err(e) => return Err(e), 36 | }; 37 | writer.write_all(unsafe { &buf.assume_init_ref()[..len] })?; 38 | written += len as u64; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(feature = "nightly", feature(maybe_uninit_ref))] 2 | #![cfg_attr(feature = "nightly", feature(never_type))] 3 | #![cfg_attr(all(feature = "std", feature = "nightly"), feature(read_initializer))] 4 | #![cfg_attr(not(feature = "std"), no_std)] 5 | #![cfg_attr(feature = "std", allow(dead_code))] 6 | 7 | #[cfg(not(feature = "std"))] 8 | pub mod error; 9 | 10 | #[cfg(feature = "std")] 11 | pub use std::error as error; 12 | 13 | #[cfg(not(feature = "std"))] 14 | pub mod io; 15 | 16 | #[cfg(feature = "std")] 17 | pub use std::io as io; 18 | 19 | #[cfg(feature = "alloc")] 20 | extern crate alloc; 21 | -------------------------------------------------------------------------------- /tests/tests.rs: -------------------------------------------------------------------------------- 1 | use core::cmp; 2 | use core2::io::{self as io, BufRead, Cursor, Read, Write}; 3 | 4 | // #[test] 5 | // #[cfg_attr(target_os = "emscripten", ignore)] 6 | // fn read_until() { 7 | // let mut buf = Cursor::new(&b"12"[..]); 8 | // let mut v = Vec::new(); 9 | // assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 2); 10 | // assert_eq!(v, b"12"); 11 | 12 | // let mut buf = Cursor::new(&b"1233"[..]); 13 | // let mut v = Vec::new(); 14 | // assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 3); 15 | // assert_eq!(v, b"123"); 16 | // v.truncate(0); 17 | // assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 1); 18 | // assert_eq!(v, b"3"); 19 | // v.truncate(0); 20 | // assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 0); 21 | // assert_eq!(v, []); 22 | // } 23 | 24 | // #[test] 25 | // fn split() { 26 | // let buf = Cursor::new(&b"12"[..]); 27 | // let mut s = buf.split(b'3'); 28 | // assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']); 29 | // assert!(s.next().is_none()); 30 | 31 | // let buf = Cursor::new(&b"1233"[..]); 32 | // let mut s = buf.split(b'3'); 33 | // assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']); 34 | // assert_eq!(s.next().unwrap().unwrap(), vec![]); 35 | // assert!(s.next().is_none()); 36 | // } 37 | 38 | // #[test] 39 | // fn read_line() { 40 | // let mut buf = Cursor::new(&b"12"[..]); 41 | // let mut v = String::new(); 42 | // assert_eq!(buf.read_line(&mut v).unwrap(), 2); 43 | // assert_eq!(v, "12"); 44 | 45 | // let mut buf = Cursor::new(&b"12\n\n"[..]); 46 | // let mut v = String::new(); 47 | // assert_eq!(buf.read_line(&mut v).unwrap(), 3); 48 | // assert_eq!(v, "12\n"); 49 | // v.truncate(0); 50 | // assert_eq!(buf.read_line(&mut v).unwrap(), 1); 51 | // assert_eq!(v, "\n"); 52 | // v.truncate(0); 53 | // assert_eq!(buf.read_line(&mut v).unwrap(), 0); 54 | // assert_eq!(v, ""); 55 | // } 56 | 57 | // #[test] 58 | // fn lines() { 59 | // let buf = Cursor::new(&b"12\r"[..]); 60 | // let mut s = buf.lines(); 61 | // assert_eq!(s.next().unwrap().unwrap(), "12\r".to_string()); 62 | // assert!(s.next().is_none()); 63 | 64 | // let buf = Cursor::new(&b"12\r\n\n"[..]); 65 | // let mut s = buf.lines(); 66 | // assert_eq!(s.next().unwrap().unwrap(), "12".to_string()); 67 | // assert_eq!(s.next().unwrap().unwrap(), "".to_string()); 68 | // assert!(s.next().is_none()); 69 | // } 70 | 71 | // #[test] 72 | // fn read_to_end() { 73 | // let mut c = Cursor::new(&b""[..]); 74 | // let mut v = Vec::new(); 75 | // assert_eq!(c.read_to_end(&mut v).unwrap(), 0); 76 | // assert_eq!(v, []); 77 | 78 | // let mut c = Cursor::new(&b"1"[..]); 79 | // let mut v = Vec::new(); 80 | // assert_eq!(c.read_to_end(&mut v).unwrap(), 1); 81 | // assert_eq!(v, b"1"); 82 | 83 | // let cap = 1024 * 1024; 84 | // let data = (0..cap).map(|i| (i / 3) as u8).collect::>(); 85 | // let mut v = Vec::new(); 86 | // let (a, b) = data.split_at(data.len() / 2); 87 | // assert_eq!(Cursor::new(a).read_to_end(&mut v).unwrap(), a.len()); 88 | // assert_eq!(Cursor::new(b).read_to_end(&mut v).unwrap(), b.len()); 89 | // assert_eq!(v, data); 90 | // } 91 | 92 | // #[test] 93 | // fn read_to_string() { 94 | // let mut c = Cursor::new(&b""[..]); 95 | // let mut v = String::new(); 96 | // assert_eq!(c.read_to_string(&mut v).unwrap(), 0); 97 | // assert_eq!(v, ""); 98 | 99 | // let mut c = Cursor::new(&b"1"[..]); 100 | // let mut v = String::new(); 101 | // assert_eq!(c.read_to_string(&mut v).unwrap(), 1); 102 | // assert_eq!(v, "1"); 103 | 104 | // let mut c = Cursor::new(&b"\xff"[..]); 105 | // let mut v = String::new(); 106 | // assert!(c.read_to_string(&mut v).is_err()); 107 | // } 108 | 109 | #[test] 110 | fn read_exact() { 111 | let mut buf = [0; 4]; 112 | 113 | let mut c = Cursor::new(&b""[..]); 114 | assert_eq!( 115 | c.read_exact(&mut buf).unwrap_err().kind(), 116 | io::ErrorKind::UnexpectedEof 117 | ); 118 | 119 | let mut c = Cursor::new(&b"123"[..]).chain(Cursor::new(&b"456789"[..])); 120 | c.read_exact(&mut buf).unwrap(); 121 | assert_eq!(&buf, b"1234"); 122 | c.read_exact(&mut buf).unwrap(); 123 | assert_eq!(&buf, b"5678"); 124 | assert_eq!( 125 | c.read_exact(&mut buf).unwrap_err().kind(), 126 | io::ErrorKind::UnexpectedEof 127 | ); 128 | } 129 | 130 | #[test] 131 | fn read_exact_slice() { 132 | let mut buf = [0; 4]; 133 | 134 | let mut c = &b""[..]; 135 | assert_eq!( 136 | c.read_exact(&mut buf).unwrap_err().kind(), 137 | io::ErrorKind::UnexpectedEof 138 | ); 139 | 140 | let mut c = &b"123"[..]; 141 | assert_eq!( 142 | c.read_exact(&mut buf).unwrap_err().kind(), 143 | io::ErrorKind::UnexpectedEof 144 | ); 145 | // make sure the optimized (early returning) method is being used 146 | assert_eq!(&buf, &[0; 4]); 147 | 148 | let mut c = &b"1234"[..]; 149 | c.read_exact(&mut buf).unwrap(); 150 | assert_eq!(&buf, b"1234"); 151 | 152 | let mut c = &b"56789"[..]; 153 | c.read_exact(&mut buf).unwrap(); 154 | assert_eq!(&buf, b"5678"); 155 | assert_eq!(c, b"9"); 156 | } 157 | 158 | #[test] 159 | fn take_eof() { 160 | struct R; 161 | 162 | impl Read for R { 163 | fn read(&mut self, _: &mut [u8]) -> io::Result { 164 | Err(io::Error::new(io::ErrorKind::Other, "")) 165 | } 166 | } 167 | impl BufRead for R { 168 | fn fill_buf(&mut self) -> io::Result<&[u8]> { 169 | Err(io::Error::new(io::ErrorKind::Other, "")) 170 | } 171 | fn consume(&mut self, _amt: usize) {} 172 | } 173 | 174 | let mut buf = [0; 1]; 175 | assert_eq!(0, R.take(0).read(&mut buf).unwrap()); 176 | assert_eq!(b"", R.take(0).fill_buf().unwrap()); 177 | } 178 | 179 | fn cmp_bufread(mut br1: Br1, mut br2: Br2, exp: &[u8]) { 180 | let mut cat = Vec::new(); 181 | loop { 182 | let consume = { 183 | let buf1 = br1.fill_buf().unwrap(); 184 | let buf2 = br2.fill_buf().unwrap(); 185 | let minlen = if buf1.len() < buf2.len() { 186 | buf1.len() 187 | } else { 188 | buf2.len() 189 | }; 190 | assert_eq!(buf1[..minlen], buf2[..minlen]); 191 | cat.extend_from_slice(&buf1[..minlen]); 192 | minlen 193 | }; 194 | if consume == 0 { 195 | break; 196 | } 197 | br1.consume(consume); 198 | br2.consume(consume); 199 | } 200 | assert_eq!(br1.fill_buf().unwrap().len(), 0); 201 | assert_eq!(br2.fill_buf().unwrap().len(), 0); 202 | assert_eq!(&cat[..], &exp[..]) 203 | } 204 | 205 | #[test] 206 | fn chain_bufread() { 207 | let testdata = b"ABCDEFGHIJKL"; 208 | let chain1 = (&testdata[..3]) 209 | .chain(&testdata[3..6]) 210 | .chain(&testdata[6..9]) 211 | .chain(&testdata[9..]); 212 | let chain2 = (&testdata[..4]) 213 | .chain(&testdata[4..8]) 214 | .chain(&testdata[8..]); 215 | cmp_bufread(chain1, chain2, &testdata[..]); 216 | } 217 | 218 | // #[test] 219 | // fn chain_zero_length_read_is_not_eof() { 220 | // let a = b"A"; 221 | // let b = b"B"; 222 | // let mut s = String::new(); 223 | // let mut chain = (&a[..]).chain(&b[..]); 224 | // chain.read(&mut []).unwrap(); 225 | // chain.read_to_string(&mut s).unwrap(); 226 | // assert_eq!("AB", s); 227 | // } 228 | 229 | // #[bench] 230 | // #[cfg_attr(target_os = "emscripten", ignore)] 231 | // fn bench_read_to_end(b: &mut test::Bencher) { 232 | // b.iter(|| { 233 | // let mut lr = repeat(1).take(10000000); 234 | // let mut vec = Vec::with_capacity(1024); 235 | // super::read_to_end(&mut lr, &mut vec) 236 | // }); 237 | // } 238 | 239 | // #[test] 240 | // fn seek_len() -> io::Result<()> { 241 | // let mut c = Cursor::new(vec![0; 15]); 242 | // assert_eq!(c.stream_len()?, 15); 243 | 244 | // c.seek(SeekFrom::End(0))?; 245 | // let old_pos = c.stream_position()?; 246 | // assert_eq!(c.stream_len()?, 15); 247 | // assert_eq!(c.stream_position()?, old_pos); 248 | 249 | // c.seek(SeekFrom::Start(7))?; 250 | // c.seek(SeekFrom::Current(2))?; 251 | // let old_pos = c.stream_position()?; 252 | // assert_eq!(c.stream_len()?, 15); 253 | // assert_eq!(c.stream_position()?, old_pos); 254 | 255 | // Ok(()) 256 | // } 257 | 258 | // #[test] 259 | // fn seek_position() -> io::Result<()> { 260 | // // All `asserts` are duplicated here to make sure the method does not 261 | // // change anything about the seek state. 262 | // let mut c = Cursor::new(vec![0; 15]); 263 | // assert_eq!(c.stream_position()?, 0); 264 | // assert_eq!(c.stream_position()?, 0); 265 | 266 | // c.seek(SeekFrom::End(0))?; 267 | // assert_eq!(c.stream_position()?, 15); 268 | // assert_eq!(c.stream_position()?, 15); 269 | 270 | // c.seek(SeekFrom::Start(7))?; 271 | // c.seek(SeekFrom::Current(2))?; 272 | // assert_eq!(c.stream_position()?, 9); 273 | // assert_eq!(c.stream_position()?, 9); 274 | 275 | // c.seek(SeekFrom::End(-3))?; 276 | // c.seek(SeekFrom::Current(1))?; 277 | // c.seek(SeekFrom::Current(-5))?; 278 | // assert_eq!(c.stream_position()?, 8); 279 | // assert_eq!(c.stream_position()?, 8); 280 | 281 | // Ok(()) 282 | // } 283 | 284 | // A simple example reader which uses the default implementation of 285 | // read_to_end. 286 | struct ExampleSliceReader<'a> { 287 | slice: &'a [u8], 288 | } 289 | 290 | impl<'a> Read for ExampleSliceReader<'a> { 291 | fn read(&mut self, buf: &mut [u8]) -> io::Result { 292 | let len = cmp::min(self.slice.len(), buf.len()); 293 | buf[..len].copy_from_slice(&self.slice[..len]); 294 | self.slice = &self.slice[len..]; 295 | Ok(len) 296 | } 297 | } 298 | 299 | // #[test] 300 | // fn test_read_to_end_capacity() -> io::Result<()> { 301 | // let input = &b"foo"[..]; 302 | 303 | // // read_to_end() generally needs to over-allocate, both for efficiency 304 | // // and so that it can distinguish EOF. Assert that this is the case 305 | // // with this simple ExampleSliceReader struct, which uses the default 306 | // // implementation of read_to_end. Even though vec1 is allocated with 307 | // // exactly enough capacity for the read, read_to_end will allocate more 308 | // // space here. 309 | // let mut vec1 = Vec::with_capacity(input.len()); 310 | // ExampleSliceReader { slice: input }.read_to_end(&mut vec1)?; 311 | // assert_eq!(vec1.len(), input.len()); 312 | // assert!(vec1.capacity() > input.len(), "allocated more"); 313 | 314 | // // However, std::io::Take includes an implementation of read_to_end 315 | // // that will not allocate when the limit has already been reached. In 316 | // // this case, vec2 never grows. 317 | // let mut vec2 = Vec::with_capacity(input.len()); 318 | // ExampleSliceReader { slice: input }.take(input.len() as u64).read_to_end(&mut vec2)?; 319 | // assert_eq!(vec2.len(), input.len()); 320 | // assert_eq!(vec2.capacity(), input.len(), "did not allocate more"); 321 | 322 | // Ok(()) 323 | // } 324 | 325 | // #[test] 326 | // fn io_slice_mut_advance() { 327 | // let mut buf1 = [1; 8]; 328 | // let mut buf2 = [2; 16]; 329 | // let mut buf3 = [3; 8]; 330 | // let mut bufs = &mut [ 331 | // IoSliceMut::new(&mut buf1), 332 | // IoSliceMut::new(&mut buf2), 333 | // IoSliceMut::new(&mut buf3), 334 | // ][..]; 335 | 336 | // // Only in a single buffer.. 337 | // bufs = IoSliceMut::advance(bufs, 1); 338 | // assert_eq!(bufs[0].deref(), [1; 7].as_ref()); 339 | // assert_eq!(bufs[1].deref(), [2; 16].as_ref()); 340 | // assert_eq!(bufs[2].deref(), [3; 8].as_ref()); 341 | 342 | // // Removing a buffer, leaving others as is. 343 | // bufs = IoSliceMut::advance(bufs, 7); 344 | // assert_eq!(bufs[0].deref(), [2; 16].as_ref()); 345 | // assert_eq!(bufs[1].deref(), [3; 8].as_ref()); 346 | 347 | // // Removing a buffer and removing from the next buffer. 348 | // bufs = IoSliceMut::advance(bufs, 18); 349 | // assert_eq!(bufs[0].deref(), [3; 6].as_ref()); 350 | // } 351 | 352 | // #[test] 353 | // fn io_slice_mut_advance_empty_slice() { 354 | // let empty_bufs = &mut [][..]; 355 | // // Shouldn't panic. 356 | // IoSliceMut::advance(empty_bufs, 1); 357 | // } 358 | 359 | // #[test] 360 | // fn io_slice_mut_advance_beyond_total_length() { 361 | // let mut buf1 = [1; 8]; 362 | // let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..]; 363 | 364 | // // Going beyond the total length should be ok. 365 | // bufs = IoSliceMut::advance(bufs, 9); 366 | // assert!(bufs.is_empty()); 367 | // } 368 | 369 | // #[test] 370 | // fn io_slice_advance() { 371 | // let buf1 = [1; 8]; 372 | // let buf2 = [2; 16]; 373 | // let buf3 = [3; 8]; 374 | // let mut bufs = &mut [IoSlice::new(&buf1), IoSlice::new(&buf2), IoSlice::new(&buf3)][..]; 375 | 376 | // // Only in a single buffer.. 377 | // bufs = IoSlice::advance(bufs, 1); 378 | // assert_eq!(bufs[0].deref(), [1; 7].as_ref()); 379 | // assert_eq!(bufs[1].deref(), [2; 16].as_ref()); 380 | // assert_eq!(bufs[2].deref(), [3; 8].as_ref()); 381 | 382 | // // Removing a buffer, leaving others as is. 383 | // bufs = IoSlice::advance(bufs, 7); 384 | // assert_eq!(bufs[0].deref(), [2; 16].as_ref()); 385 | // assert_eq!(bufs[1].deref(), [3; 8].as_ref()); 386 | 387 | // // Removing a buffer and removing from the next buffer. 388 | // bufs = IoSlice::advance(bufs, 18); 389 | // assert_eq!(bufs[0].deref(), [3; 6].as_ref()); 390 | // } 391 | 392 | // #[test] 393 | // fn io_slice_advance_empty_slice() { 394 | // let empty_bufs = &mut [][..]; 395 | // // Shouldn't panic. 396 | // IoSlice::advance(empty_bufs, 1); 397 | // } 398 | 399 | // #[test] 400 | // fn io_slice_advance_beyond_total_length() { 401 | // let buf1 = [1; 8]; 402 | // let mut bufs = &mut [IoSlice::new(&buf1)][..]; 403 | 404 | // // Going beyond the total length should be ok. 405 | // bufs = IoSlice::advance(bufs, 9); 406 | // assert!(bufs.is_empty()); 407 | // } 408 | 409 | /// Create a new writer that reads from at most `n_bufs` and reads 410 | /// `per_call` bytes (in total) per call to write. 411 | fn test_writer() -> TestWriter { 412 | TestWriter { 413 | written: Vec::new(), 414 | per_call: 2, 415 | } 416 | } 417 | 418 | struct TestWriter { 419 | written: Vec, 420 | per_call: usize, 421 | } 422 | 423 | impl Write for TestWriter { 424 | fn write(&mut self, buf: &[u8]) -> io::Result { 425 | let n = self.per_call.min(buf.len()); 426 | self.written.extend_from_slice(&buf[..n]); 427 | Ok(n) 428 | } 429 | 430 | fn flush(&mut self) -> io::Result<()> { 431 | Ok(()) 432 | } 433 | } 434 | 435 | #[test] 436 | fn test_writer_read_from_one_buf() { 437 | let mut writer = test_writer(); 438 | 439 | assert_eq!(writer.write(&[]).unwrap(), 0); 440 | // assert_eq!(writer.write_vectored(&[]).unwrap(), 0); 441 | 442 | // Read at most 2 bytes. 443 | assert_eq!(writer.write(&[1, 1, 1]).unwrap(), 2); 444 | assert_eq!(writer.write(&[2, 2, 2]).unwrap(), 2); 445 | 446 | // Only read from first buf. 447 | assert_eq!(writer.write(&[3]).unwrap(), 1); 448 | 449 | assert_eq!(writer.written, &[1, 1, 2, 2, 3]); 450 | } 451 | 452 | // #[test] 453 | // fn test_writer_read_from_multiple_bufs() { 454 | // let mut writer = test_writer(3, 3); 455 | 456 | // // Read at most 3 bytes from two buffers. 457 | // let bufs = &[IoSlice::new(&[1]), IoSlice::new(&[2, 2, 2])]; 458 | // assert_eq!(writer.write_vectored(bufs).unwrap(), 3); 459 | 460 | // // Read at most 3 bytes from three buffers. 461 | // let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4]), IoSlice::new(&[5, 5])]; 462 | // assert_eq!(writer.write_vectored(bufs).unwrap(), 3); 463 | 464 | // assert_eq!(writer.written, &[1, 2, 2, 3, 4, 5]); 465 | // } 466 | 467 | // #[test] 468 | // fn test_write_all_vectored() { 469 | // #[rustfmt::skip] // Becomes unreadable otherwise. 470 | // let tests: Vec<(_, &'static [u8])> = vec![ 471 | // (vec![], &[]), 472 | // (vec![IoSlice::new(&[]), IoSlice::new(&[])], &[]), 473 | // (vec![IoSlice::new(&[1])], &[1]), 474 | // (vec![IoSlice::new(&[1, 2])], &[1, 2]), 475 | // (vec![IoSlice::new(&[1, 2, 3])], &[1, 2, 3]), 476 | // (vec![IoSlice::new(&[1, 2, 3, 4])], &[1, 2, 3, 4]), 477 | // (vec![IoSlice::new(&[1, 2, 3, 4, 5])], &[1, 2, 3, 4, 5]), 478 | // (vec![IoSlice::new(&[1]), IoSlice::new(&[2])], &[1, 2]), 479 | // (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2])], &[1, 2, 2]), 480 | // (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2])], &[1, 1, 2, 2]), 481 | // (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]), 482 | // (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]), 483 | // (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 1, 2, 2, 2]), 484 | // (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 2, 2, 2, 2]), 485 | // (vec![IoSlice::new(&[1, 1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 1, 2, 2, 2, 2]), 486 | // (vec![IoSlice::new(&[1]), IoSlice::new(&[2]), IoSlice::new(&[3])], &[1, 2, 3]), 487 | // (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3])], &[1, 1, 2, 2, 3, 3]), 488 | // (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 2, 2, 3, 3, 3]), 489 | // (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 1, 1, 2, 2, 2, 3, 3, 3]), 490 | // ]; 491 | 492 | // let writer_configs = &[(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)]; 493 | 494 | // for (n_bufs, per_call) in writer_configs.iter().copied() { 495 | // for (mut input, wanted) in tests.clone().into_iter() { 496 | // let mut writer = test_writer(n_bufs, per_call); 497 | // assert!(writer.write_all_vectored(&mut *input).is_ok()); 498 | // assert_eq!(&*writer.written, &*wanted); 499 | // } 500 | // } 501 | // } 502 | --------------------------------------------------------------------------------