1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT 2 // file at the top-level directory of this distribution and at 3 // http://rust-lang.org/COPYRIGHT. 4 // 5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or 6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license 7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your 8 // option. This file may not be copied, modified, or distributed 9 // except according to those terms. 10 11 //! Buffering wrappers for I/O traits 12 13 use core::prelude::v1::*; 14 use io::prelude::*; 15 16 use core::cmp; 17 use core::fmt; 18 use io::{self, Initializer, DEFAULT_BUF_SIZE, Error, ErrorKind, SeekFrom}; 19 use io::memchr; 20 21 /// The `BufReader` struct adds buffering to any reader. 22 /// 23 /// It can be excessively inefficient to work directly with a [`Read`] instance. 24 /// For example, every call to [`read`][`TcpStream::read`] on [`TcpStream`] 25 /// results in a system call. A `BufReader` performs large, infrequent reads on 26 /// the underlying [`Read`] and maintains an in-memory buffer of the results. 27 /// 28 /// `BufReader` can improve the speed of programs that make *small* and 29 /// *repeated* read calls to the same file or network socket. It does not 30 /// help when reading very large amounts at once, or reading just one or a few 31 /// times. It also provides no advantage when reading from a source that is 32 /// already in memory, like a `Vec<u8>`. 33 /// 34 /// [`Read`]: ../../std/io/trait.Read.html 35 /// [`TcpStream::read`]: ../../std/net/struct.TcpStream.html#method.read 36 /// [`TcpStream`]: ../../std/net/struct.TcpStream.html 37 /// 38 /// # Examples 39 /// 40 /// ```no_run 41 /// use std::io::prelude::*; 42 /// use std::io::BufReader; 43 /// use std::fs::File; 44 /// 45 /// fn main() -> std::io::Result<()> { 46 /// let f = File::open("log.txt")?; 47 /// let mut reader = BufReader::new(f); 48 /// 49 /// let mut line = String::new(); 50 /// let len = reader.read_line(&mut line)?; 51 /// println!("First line is {} bytes long", len); 52 /// Ok(()) 53 /// } 54 /// ``` 55 pub struct BufReader<R> { 56 inner: R, 57 buf: Box<[u8]>, 58 pos: usize, 59 cap: usize, 60 } 61 62 impl<R: Read> BufReader<R> { 63 /// Creates a new `BufReader` with a default buffer capacity. The default is currently 8 KB, 64 /// but may change in the future. 65 /// 66 /// # Examples 67 /// 68 /// ```no_run 69 /// use std::io::BufReader; 70 /// use std::fs::File; 71 /// 72 /// fn main() -> std::io::Result<()> { 73 /// let f = File::open("log.txt")?; 74 /// let reader = BufReader::new(f); 75 /// Ok(()) 76 /// } 77 /// ``` new(inner: R) -> BufReader<R>78 pub fn new(inner: R) -> BufReader<R> { 79 BufReader::with_capacity(DEFAULT_BUF_SIZE, inner) 80 } 81 82 /// Creates a new `BufReader` with the specified buffer capacity. 83 /// 84 /// # Examples 85 /// 86 /// Creating a buffer with ten bytes of capacity: 87 /// 88 /// ```no_run 89 /// use std::io::BufReader; 90 /// use std::fs::File; 91 /// 92 /// fn main() -> std::io::Result<()> { 93 /// let f = File::open("log.txt")?; 94 /// let reader = BufReader::with_capacity(10, f); 95 /// Ok(()) 96 /// } 97 /// ``` with_capacity(cap: usize, inner: R) -> BufReader<R>98 pub fn with_capacity(cap: usize, inner: R) -> BufReader<R> { 99 unsafe { 100 let mut buffer = Vec::with_capacity(cap); 101 buffer.set_len(cap); 102 inner.initializer().initialize(&mut buffer); 103 BufReader { 104 inner, 105 buf: buffer.into_boxed_slice(), 106 pos: 0, 107 cap: 0, 108 } 109 } 110 } 111 112 /// Gets a reference to the underlying reader. 113 /// 114 /// It is inadvisable to directly read from the underlying reader. 115 /// 116 /// # Examples 117 /// 118 /// ```no_run 119 /// use std::io::BufReader; 120 /// use std::fs::File; 121 /// 122 /// fn main() -> std::io::Result<()> { 123 /// let f1 = File::open("log.txt")?; 124 /// let reader = BufReader::new(f1); 125 /// 126 /// let f2 = reader.get_ref(); 127 /// Ok(()) 128 /// } 129 /// ``` get_ref(&self) -> &R130 pub fn get_ref(&self) -> &R { &self.inner } 131 132 /// Gets a mutable reference to the underlying reader. 133 /// 134 /// It is inadvisable to directly read from the underlying reader. 135 /// 136 /// # Examples 137 /// 138 /// ```no_run 139 /// use std::io::BufReader; 140 /// use std::fs::File; 141 /// 142 /// fn main() -> std::io::Result<()> { 143 /// let f1 = File::open("log.txt")?; 144 /// let mut reader = BufReader::new(f1); 145 /// 146 /// let f2 = reader.get_mut(); 147 /// Ok(()) 148 /// } 149 /// ``` get_mut(&mut self) -> &mut R150 pub fn get_mut(&mut self) -> &mut R { &mut self.inner } 151 152 /// Returns a reference to the internally buffered data. 153 /// 154 /// Unlike `fill_buf`, this will not attempt to fill the buffer if it is empty. 155 /// 156 /// # Examples 157 /// 158 /// ```no_run 159 /// # #![feature(bufreader_buffer)] 160 /// use std::io::{BufReader, BufRead}; 161 /// use std::fs::File; 162 /// 163 /// fn main() -> std::io::Result<()> { 164 /// let f = File::open("log.txt")?; 165 /// let mut reader = BufReader::new(f); 166 /// assert!(reader.buffer().is_empty()); 167 /// 168 /// if reader.fill_buf()?.len() > 0 { 169 /// assert!(!reader.buffer().is_empty()); 170 /// } 171 /// Ok(()) 172 /// } 173 /// ``` buffer(&self) -> &[u8]174 pub fn buffer(&self) -> &[u8] { 175 &self.buf[self.pos..self.cap] 176 } 177 178 /// Unwraps this `BufReader`, returning the underlying reader. 179 /// 180 /// Note that any leftover data in the internal buffer is lost. 181 /// 182 /// # Examples 183 /// 184 /// ```no_run 185 /// use std::io::BufReader; 186 /// use std::fs::File; 187 /// 188 /// fn main() -> std::io::Result<()> { 189 /// let f1 = File::open("log.txt")?; 190 /// let reader = BufReader::new(f1); 191 /// 192 /// let f2 = reader.into_inner(); 193 /// Ok(()) 194 /// } 195 /// ``` into_inner(self) -> R196 pub fn into_inner(self) -> R { self.inner } 197 } 198 199 impl<R: Seek> BufReader<R> { 200 /// Seeks relative to the current position. If the new position lies within the buffer, 201 /// the buffer will not be flushed, allowing for more efficient seeks. 202 /// This method does not return the location of the underlying reader, so the caller 203 /// must track this information themselves if it is required. seek_relative(&mut self, offset: i64) -> io::Result<()>204 pub fn seek_relative(&mut self, offset: i64) -> io::Result<()> { 205 let pos = self.pos as u64; 206 if offset < 0 { 207 if let Some(new_pos) = pos.checked_sub((-offset) as u64) { 208 self.pos = new_pos as usize; 209 return Ok(()) 210 } 211 } else { 212 if let Some(new_pos) = pos.checked_add(offset as u64) { 213 if new_pos <= self.cap as u64 { 214 self.pos = new_pos as usize; 215 return Ok(()) 216 } 217 } 218 } 219 self.seek(SeekFrom::Current(offset)).map(|_|()) 220 } 221 } 222 223 impl<R: Read> Read for BufReader<R> { read(&mut self, buf: &mut [u8]) -> io::Result<usize>224 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { 225 // If we don't have any buffered data and we're doing a massive read 226 // (larger than our internal buffer), bypass our internal buffer 227 // entirely. 228 if self.pos == self.cap && buf.len() >= self.buf.len() { 229 return self.inner.read(buf); 230 } 231 let nread = { 232 let mut rem = self.fill_buf()?; 233 rem.read(buf)? 234 }; 235 self.consume(nread); 236 Ok(nread) 237 } 238 239 // we can't skip unconditionally because of the large buffer case in read. initializer(&self) -> Initializer240 unsafe fn initializer(&self) -> Initializer { 241 self.inner.initializer() 242 } 243 } 244 245 impl<R: Read> BufRead for BufReader<R> { fill_buf(&mut self) -> io::Result<&[u8]>246 fn fill_buf(&mut self) -> io::Result<&[u8]> { 247 // If we've reached the end of our internal buffer then we need to fetch 248 // some more data from the underlying reader. 249 // Branch using `>=` instead of the more correct `==` 250 // to tell the compiler that the pos..cap slice is always valid. 251 if self.pos >= self.cap { 252 debug_assert!(self.pos == self.cap); 253 self.cap = self.inner.read(&mut self.buf)?; 254 self.pos = 0; 255 } 256 Ok(&self.buf[self.pos..self.cap]) 257 } 258 consume(&mut self, amt: usize)259 fn consume(&mut self, amt: usize) { 260 self.pos = cmp::min(self.pos + amt, self.cap); 261 } 262 } 263 264 impl<R> fmt::Debug for BufReader<R> where R: fmt::Debug { fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result265 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 266 fmt.debug_struct("BufReader") 267 .field("reader", &self.inner) 268 .field("buffer", &format_args!("{}/{}", self.cap - self.pos, self.buf.len())) 269 .finish() 270 } 271 } 272 273 impl<R: Seek> Seek for BufReader<R> { 274 /// Seek to an offset, in bytes, in the underlying reader. 275 /// 276 /// The position used for seeking with `SeekFrom::Current(_)` is the 277 /// position the underlying reader would be at if the `BufReader` had no 278 /// internal buffer. 279 /// 280 /// Seeking always discards the internal buffer, even if the seek position 281 /// would otherwise fall within it. This guarantees that calling 282 /// `.into_inner()` immediately after a seek yields the underlying reader 283 /// at the same position. 284 /// 285 /// To seek without discarding the internal buffer, use [`Seek::seek_relative`]. 286 /// 287 /// See [`std::io::Seek`] for more details. 288 /// 289 /// Note: In the edge case where you're seeking with `SeekFrom::Current(n)` 290 /// where `n` minus the internal buffer length overflows an `i64`, two 291 /// seeks will be performed instead of one. If the second seek returns 292 /// `Err`, the underlying reader will be left at the same position it would 293 /// have if you called `seek` with `SeekFrom::Current(0)`. seek(&mut self, pos: SeekFrom) -> io::Result<u64>294 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { 295 let result: u64; 296 if let SeekFrom::Current(n) = pos { 297 let remainder = (self.cap - self.pos) as i64; 298 // it should be safe to assume that remainder fits within an i64 as the alternative 299 // means we managed to allocate 8 exbibytes and that's absurd. 300 // But it's not out of the realm of possibility for some weird underlying reader to 301 // support seeking by i64::min_value() so we need to handle underflow when subtracting 302 // remainder. 303 if let Some(offset) = n.checked_sub(remainder) { 304 result = self.inner.seek(SeekFrom::Current(offset))?; 305 } else { 306 // seek backwards by our remainder, and then by the offset 307 self.inner.seek(SeekFrom::Current(-remainder))?; 308 self.pos = self.cap; // empty the buffer 309 result = self.inner.seek(SeekFrom::Current(n))?; 310 } 311 } else { 312 // Seeking with Start/End doesn't care about our buffer length. 313 result = self.inner.seek(pos)?; 314 } 315 self.pos = self.cap; // empty the buffer 316 Ok(result) 317 } 318 } 319 320 /// Wraps a writer and buffers its output. 321 /// 322 /// It can be excessively inefficient to work directly with something that 323 /// implements [`Write`]. For example, every call to 324 /// [`write`][`Tcpstream::write`] on [`TcpStream`] results in a system call. A 325 /// `BufWriter` keeps an in-memory buffer of data and writes it to an underlying 326 /// writer in large, infrequent batches. 327 /// 328 /// `BufWriter` can improve the speed of programs that make *small* and 329 /// *repeated* write calls to the same file or network socket. It does not 330 /// help when writing very large amounts at once, or writing just one or a few 331 /// times. It also provides no advantage when writing to a destination that is 332 /// in memory, like a `Vec<u8>`. 333 /// 334 /// When the `BufWriter` is dropped, the contents of its buffer will be written 335 /// out. However, any errors that happen in the process of flushing the buffer 336 /// when the writer is dropped will be ignored. Code that wishes to handle such 337 /// errors must manually call [`flush`] before the writer is dropped. 338 /// 339 /// # Examples 340 /// 341 /// Let's write the numbers one through ten to a [`TcpStream`]: 342 /// 343 /// ```no_run 344 /// use std::io::prelude::*; 345 /// use std::net::TcpStream; 346 /// 347 /// let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap(); 348 /// 349 /// for i in 0..10 { 350 /// stream.write(&[i+1]).unwrap(); 351 /// } 352 /// ``` 353 /// 354 /// Because we're not buffering, we write each one in turn, incurring the 355 /// overhead of a system call per byte written. We can fix this with a 356 /// `BufWriter`: 357 /// 358 /// ```no_run 359 /// use std::io::prelude::*; 360 /// use std::io::BufWriter; 361 /// use std::net::TcpStream; 362 /// 363 /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 364 /// 365 /// for i in 0..10 { 366 /// stream.write(&[i+1]).unwrap(); 367 /// } 368 /// ``` 369 /// 370 /// By wrapping the stream with a `BufWriter`, these ten writes are all grouped 371 /// together by the buffer, and will all be written out in one system call when 372 /// the `stream` is dropped. 373 /// 374 /// [`Write`]: ../../std/io/trait.Write.html 375 /// [`Tcpstream::write`]: ../../std/net/struct.TcpStream.html#method.write 376 /// [`TcpStream`]: ../../std/net/struct.TcpStream.html 377 /// [`flush`]: #method.flush 378 pub struct BufWriter<W: Write> { 379 inner: Option<W>, 380 pub /* relibc */ buf: Vec<u8>, 381 // #30888: If the inner writer panics in a call to write, we don't want to 382 // write the buffered data a second time in BufWriter's destructor. This 383 // flag tells the Drop impl if it should skip the flush. 384 panicked: bool, 385 } 386 387 /// An error returned by `into_inner` which combines an error that 388 /// happened while writing out the buffer, and the buffered writer object 389 /// which may be used to recover from the condition. 390 /// 391 /// # Examples 392 /// 393 /// ```no_run 394 /// use std::io::BufWriter; 395 /// use std::net::TcpStream; 396 /// 397 /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 398 /// 399 /// // do stuff with the stream 400 /// 401 /// // we want to get our `TcpStream` back, so let's try: 402 /// 403 /// let stream = match stream.into_inner() { 404 /// Ok(s) => s, 405 /// Err(e) => { 406 /// // Here, e is an IntoInnerError 407 /// panic!("An error occurred"); 408 /// } 409 /// }; 410 /// ``` 411 #[derive(Debug)] 412 pub struct IntoInnerError<W>(W, Error); 413 414 impl<W: Write> BufWriter<W> { 415 /// Creates a new `BufWriter` with a default buffer capacity. The default is currently 8 KB, 416 /// but may change in the future. 417 /// 418 /// # Examples 419 /// 420 /// ```no_run 421 /// use std::io::BufWriter; 422 /// use std::net::TcpStream; 423 /// 424 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 425 /// ``` new(inner: W) -> BufWriter<W>426 pub fn new(inner: W) -> BufWriter<W> { 427 BufWriter::with_capacity(DEFAULT_BUF_SIZE, inner) 428 } 429 430 /// Creates a new `BufWriter` with the specified buffer capacity. 431 /// 432 /// # Examples 433 /// 434 /// Creating a buffer with a buffer of a hundred bytes. 435 /// 436 /// ```no_run 437 /// use std::io::BufWriter; 438 /// use std::net::TcpStream; 439 /// 440 /// let stream = TcpStream::connect("127.0.0.1:34254").unwrap(); 441 /// let mut buffer = BufWriter::with_capacity(100, stream); 442 /// ``` with_capacity(cap: usize, inner: W) -> BufWriter<W>443 pub fn with_capacity(cap: usize, inner: W) -> BufWriter<W> { 444 BufWriter { 445 inner: Some(inner), 446 buf: Vec::with_capacity(cap), 447 panicked: false, 448 } 449 } 450 flush_buf(&mut self) -> io::Result<()>451 fn flush_buf(&mut self) -> io::Result<()> { 452 let mut written = 0; 453 let len = self.buf.len(); 454 let mut ret = Ok(()); 455 while written < len { 456 self.panicked = true; 457 let r = self.inner.as_mut().unwrap().write(&self.buf[written..]); 458 self.panicked = false; 459 460 match r { 461 Ok(0) => { 462 ret = Err(Error::new(ErrorKind::WriteZero, 463 "failed to write the buffered data")); 464 break; 465 } 466 Ok(n) => written += n, 467 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} 468 Err(e) => { ret = Err(e); break } 469 470 } 471 } 472 if written > 0 { 473 self.buf.drain(..written); 474 } 475 ret 476 } 477 purge_buf(&mut self)478 pub fn purge_buf(&mut self) { 479 self.buf = vec![]; 480 } 481 482 /// Gets a reference to the underlying writer. 483 /// 484 /// # Examples 485 /// 486 /// ```no_run 487 /// use std::io::BufWriter; 488 /// use std::net::TcpStream; 489 /// 490 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 491 /// 492 /// // we can use reference just like buffer 493 /// let reference = buffer.get_ref(); 494 /// ``` get_ref(&self) -> &W495 pub fn get_ref(&self) -> &W { self.inner.as_ref().unwrap() } 496 497 /// Gets a mutable reference to the underlying writer. 498 /// 499 /// It is inadvisable to directly write to the underlying writer. 500 /// 501 /// # Examples 502 /// 503 /// ```no_run 504 /// use std::io::BufWriter; 505 /// use std::net::TcpStream; 506 /// 507 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 508 /// 509 /// // we can use reference just like buffer 510 /// let reference = buffer.get_mut(); 511 /// ``` get_mut(&mut self) -> &mut W512 pub fn get_mut(&mut self) -> &mut W { self.inner.as_mut().unwrap() } 513 514 /// Unwraps this `BufWriter`, returning the underlying writer. 515 /// 516 /// The buffer is written out before returning the writer. 517 /// 518 /// # Errors 519 /// 520 /// An `Err` will be returned if an error occurs while flushing the buffer. 521 /// 522 /// # Examples 523 /// 524 /// ```no_run 525 /// use std::io::BufWriter; 526 /// use std::net::TcpStream; 527 /// 528 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 529 /// 530 /// // unwrap the TcpStream and flush the buffer 531 /// let stream = buffer.into_inner().unwrap(); 532 /// ``` into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>>533 pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> { 534 match self.flush_buf() { 535 Err(e) => Err(IntoInnerError(self, e)), 536 Ok(()) => Ok(self.inner.take().unwrap()) 537 } 538 } 539 } 540 541 impl<W: Write> Write for BufWriter<W> { write(&mut self, buf: &[u8]) -> io::Result<usize>542 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 543 if self.buf.len() + buf.len() > self.buf.capacity() { 544 self.flush_buf()?; 545 } 546 if buf.len() >= self.buf.capacity() { 547 self.panicked = true; 548 let r = self.inner.as_mut().unwrap().write(buf); 549 self.panicked = false; 550 r 551 } else { 552 Write::write(&mut self.buf, buf) 553 } 554 } flush(&mut self) -> io::Result<()>555 fn flush(&mut self) -> io::Result<()> { 556 self.flush_buf().and_then(|()| self.get_mut().flush()) 557 } 558 } 559 560 impl<W: Write> fmt::Debug for BufWriter<W> where W: fmt::Debug { fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result561 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 562 fmt.debug_struct("BufWriter") 563 .field("writer", &self.inner.as_ref().unwrap()) 564 .field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity())) 565 .finish() 566 } 567 } 568 569 impl<W: Write + Seek> Seek for BufWriter<W> { 570 /// Seek to the offset, in bytes, in the underlying writer. 571 /// 572 /// Seeking always writes out the internal buffer before seeking. seek(&mut self, pos: SeekFrom) -> io::Result<u64>573 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { 574 self.flush_buf().and_then(|_| self.get_mut().seek(pos)) 575 } 576 } 577 578 impl<W: Write> Drop for BufWriter<W> { drop(&mut self)579 fn drop(&mut self) { 580 if self.inner.is_some() && !self.panicked { 581 // dtors should not panic, so we ignore a failed flush 582 let _r = self.flush_buf(); 583 } 584 } 585 } 586 587 impl<W> IntoInnerError<W> { 588 /// Returns the error which caused the call to `into_inner()` to fail. 589 /// 590 /// This error was returned when attempting to write the internal buffer. 591 /// 592 /// # Examples 593 /// 594 /// ```no_run 595 /// use std::io::BufWriter; 596 /// use std::net::TcpStream; 597 /// 598 /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 599 /// 600 /// // do stuff with the stream 601 /// 602 /// // we want to get our `TcpStream` back, so let's try: 603 /// 604 /// let stream = match stream.into_inner() { 605 /// Ok(s) => s, 606 /// Err(e) => { 607 /// // Here, e is an IntoInnerError, let's log the inner error. 608 /// // 609 /// // We'll just 'log' to stdout for this example. 610 /// println!("{}", e.error()); 611 /// 612 /// panic!("An unexpected error occurred."); 613 /// } 614 /// }; 615 /// ``` error(&self) -> &Error616 pub fn error(&self) -> &Error { &self.1 } 617 618 /// Returns the buffered writer instance which generated the error. 619 /// 620 /// The returned object can be used for error recovery, such as 621 /// re-inspecting the buffer. 622 /// 623 /// # Examples 624 /// 625 /// ```no_run 626 /// use std::io::BufWriter; 627 /// use std::net::TcpStream; 628 /// 629 /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); 630 /// 631 /// // do stuff with the stream 632 /// 633 /// // we want to get our `TcpStream` back, so let's try: 634 /// 635 /// let stream = match stream.into_inner() { 636 /// Ok(s) => s, 637 /// Err(e) => { 638 /// // Here, e is an IntoInnerError, let's re-examine the buffer: 639 /// let buffer = e.into_inner(); 640 /// 641 /// // do stuff to try to recover 642 /// 643 /// // afterwards, let's just return the stream 644 /// buffer.into_inner().unwrap() 645 /// } 646 /// }; 647 /// ``` into_inner(self) -> W648 pub fn into_inner(self) -> W { self.0 } 649 } 650 651 impl<W> From<IntoInnerError<W>> for Error { from(iie: IntoInnerError<W>) -> Error652 fn from(iie: IntoInnerError<W>) -> Error { iie.1 } 653 } 654 655 impl<W> fmt::Display for IntoInnerError<W> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result656 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 657 self.error().fmt(f) 658 } 659 } 660 661 /// Wraps a writer and buffers output to it, flushing whenever a newline 662 /// (`0x0a`, `'\n'`) is detected. 663 /// 664 /// The [`BufWriter`][bufwriter] struct wraps a writer and buffers its output. 665 /// But it only does this batched write when it goes out of scope, or when the 666 /// internal buffer is full. Sometimes, you'd prefer to write each line as it's 667 /// completed, rather than the entire buffer at once. Enter `LineWriter`. It 668 /// does exactly that. 669 /// 670 /// Like [`BufWriter`], a `LineWriter`’s buffer will also be flushed when the 671 /// `LineWriter` goes out of scope or when its internal buffer is full. 672 /// 673 /// [bufwriter]: struct.BufWriter.html 674 /// 675 /// If there's still a partial line in the buffer when the `LineWriter` is 676 /// dropped, it will flush those contents. 677 /// 678 /// # Examples 679 /// 680 /// We can use `LineWriter` to write one line at a time, significantly 681 /// reducing the number of actual writes to the file. 682 /// 683 /// ```no_run 684 /// use std::fs::{self, File}; 685 /// use std::io::prelude::*; 686 /// use std::io::LineWriter; 687 /// 688 /// fn main() -> std::io::Result<()> { 689 /// let road_not_taken = b"I shall be telling this with a sigh 690 /// Somewhere ages and ages hence: 691 /// Two roads diverged in a wood, and I - 692 /// I took the one less traveled by, 693 /// And that has made all the difference."; 694 /// 695 /// let file = File::create("poem.txt")?; 696 /// let mut file = LineWriter::new(file); 697 /// 698 /// file.write_all(b"I shall be telling this with a sigh")?; 699 /// 700 /// // No bytes are written until a newline is encountered (or 701 /// // the internal buffer is filled). 702 /// assert_eq!(fs::read_to_string("poem.txt")?, ""); 703 /// file.write_all(b"\n")?; 704 /// assert_eq!( 705 /// fs::read_to_string("poem.txt")?, 706 /// "I shall be telling this with a sigh\n", 707 /// ); 708 /// 709 /// // Write the rest of the poem. 710 /// file.write_all(b"Somewhere ages and ages hence: 711 /// Two roads diverged in a wood, and I - 712 /// I took the one less traveled by, 713 /// And that has made all the difference.")?; 714 /// 715 /// // The last line of the poem doesn't end in a newline, so 716 /// // we have to flush or drop the `LineWriter` to finish 717 /// // writing. 718 /// file.flush()?; 719 /// 720 /// // Confirm the whole poem was written. 721 /// assert_eq!(fs::read("poem.txt")?, &road_not_taken[..]); 722 /// Ok(()) 723 /// } 724 /// ``` 725 pub struct LineWriter<W: Write> { 726 pub /* relibc */ inner: BufWriter<W>, 727 need_flush: bool, 728 } 729 730 impl<W: Write> LineWriter<W> { 731 /// Creates a new `LineWriter`. 732 /// 733 /// # Examples 734 /// 735 /// ```no_run 736 /// use std::fs::File; 737 /// use std::io::LineWriter; 738 /// 739 /// fn main() -> std::io::Result<()> { 740 /// let file = File::create("poem.txt")?; 741 /// let file = LineWriter::new(file); 742 /// Ok(()) 743 /// } 744 /// ``` new(inner: W) -> LineWriter<W>745 pub fn new(inner: W) -> LineWriter<W> { 746 // Lines typically aren't that long, don't use a giant buffer 747 LineWriter::with_capacity(1024, inner) 748 } 749 750 /// Creates a new `LineWriter` with a specified capacity for the internal 751 /// buffer. 752 /// 753 /// # Examples 754 /// 755 /// ```no_run 756 /// use std::fs::File; 757 /// use std::io::LineWriter; 758 /// 759 /// fn main() -> std::io::Result<()> { 760 /// let file = File::create("poem.txt")?; 761 /// let file = LineWriter::with_capacity(100, file); 762 /// Ok(()) 763 /// } 764 /// ``` with_capacity(cap: usize, inner: W) -> LineWriter<W>765 pub fn with_capacity(cap: usize, inner: W) -> LineWriter<W> { 766 LineWriter { 767 inner: BufWriter::with_capacity(cap, inner), 768 need_flush: false, 769 } 770 } 771 772 /// Gets a reference to the underlying writer. 773 /// 774 /// # Examples 775 /// 776 /// ```no_run 777 /// use std::fs::File; 778 /// use std::io::LineWriter; 779 /// 780 /// fn main() -> std::io::Result<()> { 781 /// let file = File::create("poem.txt")?; 782 /// let file = LineWriter::new(file); 783 /// 784 /// let reference = file.get_ref(); 785 /// Ok(()) 786 /// } 787 /// ``` get_ref(&self) -> &W788 pub fn get_ref(&self) -> &W { self.inner.get_ref() } 789 790 /// Gets a mutable reference to the underlying writer. 791 /// 792 /// Caution must be taken when calling methods on the mutable reference 793 /// returned as extra writes could corrupt the output stream. 794 /// 795 /// # Examples 796 /// 797 /// ```no_run 798 /// use std::fs::File; 799 /// use std::io::LineWriter; 800 /// 801 /// fn main() -> std::io::Result<()> { 802 /// let file = File::create("poem.txt")?; 803 /// let mut file = LineWriter::new(file); 804 /// 805 /// // we can use reference just like file 806 /// let reference = file.get_mut(); 807 /// Ok(()) 808 /// } 809 /// ``` get_mut(&mut self) -> &mut W810 pub fn get_mut(&mut self) -> &mut W { self.inner.get_mut() } 811 812 /// Unwraps this `LineWriter`, returning the underlying writer. 813 /// 814 /// The internal buffer is written out before returning the writer. 815 /// 816 /// # Errors 817 /// 818 /// An `Err` will be returned if an error occurs while flushing the buffer. 819 /// 820 /// # Examples 821 /// 822 /// ```no_run 823 /// use std::fs::File; 824 /// use std::io::LineWriter; 825 /// 826 /// fn main() -> std::io::Result<()> { 827 /// let file = File::create("poem.txt")?; 828 /// 829 /// let writer: LineWriter<File> = LineWriter::new(file); 830 /// 831 /// let file: File = writer.into_inner()?; 832 /// Ok(()) 833 /// } 834 /// ``` into_inner(self) -> Result<W, IntoInnerError<LineWriter<W>>>835 pub fn into_inner(self) -> Result<W, IntoInnerError<LineWriter<W>>> { 836 self.inner.into_inner().map_err(|IntoInnerError(buf, e)| { 837 IntoInnerError(LineWriter { 838 inner: buf, 839 need_flush: false, 840 }, e) 841 }) 842 } 843 purge(&mut self)844 pub fn purge(&mut self) { 845 self.inner.purge_buf(); 846 self.need_flush = false; 847 } 848 } 849 850 impl<W: Write> Write for LineWriter<W> { write(&mut self, buf: &[u8]) -> io::Result<usize>851 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 852 if self.need_flush { 853 self.flush()?; 854 } 855 856 // Find the last newline character in the buffer provided. If found then 857 // we're going to write all the data up to that point and then flush, 858 // otherwise we just write the whole block to the underlying writer. 859 let i = match memchr::memrchr(b'\n', buf) { 860 Some(i) => i, 861 None => return self.inner.write(buf), 862 }; 863 864 865 // Ok, we're going to write a partial amount of the data given first 866 // followed by flushing the newline. After we've successfully written 867 // some data then we *must* report that we wrote that data, so future 868 // errors are ignored. We set our internal `need_flush` flag, though, in 869 // case flushing fails and we need to try it first next time. 870 let n = self.inner.write(&buf[..i + 1])?; 871 self.need_flush = true; 872 if self.flush().is_err() || n != i + 1 { 873 return Ok(n) 874 } 875 876 // At this point we successfully wrote `i + 1` bytes and flushed it out, 877 // meaning that the entire line is now flushed out on the screen. While 878 // we can attempt to finish writing the rest of the data provided. 879 // Remember though that we ignore errors here as we've successfully 880 // written data, so we need to report that. 881 match self.inner.write(&buf[i + 1..]) { 882 Ok(i) => Ok(n + i), 883 Err(_) => Ok(n), 884 } 885 } 886 flush(&mut self) -> io::Result<()>887 fn flush(&mut self) -> io::Result<()> { 888 self.inner.flush()?; 889 self.need_flush = false; 890 Ok(()) 891 } 892 } 893 894 impl<W: Write> fmt::Debug for LineWriter<W> where W: fmt::Debug { fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result895 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 896 fmt.debug_struct("LineWriter") 897 .field("writer", &self.inner.inner) 898 .field("buffer", 899 &format_args!("{}/{}", self.inner.buf.len(), self.inner.buf.capacity())) 900 .finish() 901 } 902 } 903 904 #[cfg(test)] 905 mod tests { 906 use io::prelude::*; 907 use io::{self, BufReader, BufWriter, LineWriter, SeekFrom}; 908 use sync::atomic::{AtomicUsize, Ordering}; 909 use thread; 910 use test; 911 912 /// A dummy reader intended at testing short-reads propagation. 913 pub struct ShortReader { 914 lengths: Vec<usize>, 915 } 916 917 impl Read for ShortReader { read(&mut self, _: &mut [u8]) -> io::Result<usize>918 fn read(&mut self, _: &mut [u8]) -> io::Result<usize> { 919 if self.lengths.is_empty() { 920 Ok(0) 921 } else { 922 Ok(self.lengths.remove(0)) 923 } 924 } 925 } 926 927 #[test] test_buffered_reader()928 fn test_buffered_reader() { 929 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; 930 let mut reader = BufReader::with_capacity(2, inner); 931 932 let mut buf = [0, 0, 0]; 933 let nread = reader.read(&mut buf); 934 assert_eq!(nread.unwrap(), 3); 935 let b: &[_] = &[5, 6, 7]; 936 assert_eq!(buf, b); 937 938 let mut buf = [0, 0]; 939 let nread = reader.read(&mut buf); 940 assert_eq!(nread.unwrap(), 2); 941 let b: &[_] = &[0, 1]; 942 assert_eq!(buf, b); 943 944 let mut buf = [0]; 945 let nread = reader.read(&mut buf); 946 assert_eq!(nread.unwrap(), 1); 947 let b: &[_] = &[2]; 948 assert_eq!(buf, b); 949 950 let mut buf = [0, 0, 0]; 951 let nread = reader.read(&mut buf); 952 assert_eq!(nread.unwrap(), 1); 953 let b: &[_] = &[3, 0, 0]; 954 assert_eq!(buf, b); 955 956 let nread = reader.read(&mut buf); 957 assert_eq!(nread.unwrap(), 1); 958 let b: &[_] = &[4, 0, 0]; 959 assert_eq!(buf, b); 960 961 assert_eq!(reader.read(&mut buf).unwrap(), 0); 962 } 963 964 #[test] test_buffered_reader_seek()965 fn test_buffered_reader_seek() { 966 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; 967 let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner)); 968 969 assert_eq!(reader.seek(SeekFrom::Start(3)).ok(), Some(3)); 970 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..])); 971 assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(3)); 972 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..])); 973 assert_eq!(reader.seek(SeekFrom::Current(1)).ok(), Some(4)); 974 assert_eq!(reader.fill_buf().ok(), Some(&[1, 2][..])); 975 reader.consume(1); 976 assert_eq!(reader.seek(SeekFrom::Current(-2)).ok(), Some(3)); 977 } 978 979 #[test] test_buffered_reader_seek_relative()980 fn test_buffered_reader_seek_relative() { 981 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; 982 let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner)); 983 984 assert!(reader.seek_relative(3).is_ok()); 985 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..])); 986 assert!(reader.seek_relative(0).is_ok()); 987 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..])); 988 assert!(reader.seek_relative(1).is_ok()); 989 assert_eq!(reader.fill_buf().ok(), Some(&[1][..])); 990 assert!(reader.seek_relative(-1).is_ok()); 991 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..])); 992 assert!(reader.seek_relative(2).is_ok()); 993 assert_eq!(reader.fill_buf().ok(), Some(&[2, 3][..])); 994 } 995 996 #[test] test_buffered_reader_seek_underflow()997 fn test_buffered_reader_seek_underflow() { 998 // gimmick reader that yields its position modulo 256 for each byte 999 struct PositionReader { 1000 pos: u64 1001 } 1002 impl Read for PositionReader { 1003 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { 1004 let len = buf.len(); 1005 for x in buf { 1006 *x = self.pos as u8; 1007 self.pos = self.pos.wrapping_add(1); 1008 } 1009 Ok(len) 1010 } 1011 } 1012 impl Seek for PositionReader { 1013 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { 1014 match pos { 1015 SeekFrom::Start(n) => { 1016 self.pos = n; 1017 } 1018 SeekFrom::Current(n) => { 1019 self.pos = self.pos.wrapping_add(n as u64); 1020 } 1021 SeekFrom::End(n) => { 1022 self.pos = u64::max_value().wrapping_add(n as u64); 1023 } 1024 } 1025 Ok(self.pos) 1026 } 1027 } 1028 1029 let mut reader = BufReader::with_capacity(5, PositionReader { pos: 0 }); 1030 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1, 2, 3, 4][..])); 1031 assert_eq!(reader.seek(SeekFrom::End(-5)).ok(), Some(u64::max_value()-5)); 1032 assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5)); 1033 // the following seek will require two underlying seeks 1034 let expected = 9223372036854775802; 1035 assert_eq!(reader.seek(SeekFrom::Current(i64::min_value())).ok(), Some(expected)); 1036 assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5)); 1037 // seeking to 0 should empty the buffer. 1038 assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(expected)); 1039 assert_eq!(reader.get_ref().pos, expected); 1040 } 1041 1042 #[test] test_buffered_writer()1043 fn test_buffered_writer() { 1044 let inner = Vec::new(); 1045 let mut writer = BufWriter::with_capacity(2, inner); 1046 1047 writer.write(&[0, 1]).unwrap(); 1048 assert_eq!(*writer.get_ref(), [0, 1]); 1049 1050 writer.write(&[2]).unwrap(); 1051 assert_eq!(*writer.get_ref(), [0, 1]); 1052 1053 writer.write(&[3]).unwrap(); 1054 assert_eq!(*writer.get_ref(), [0, 1]); 1055 1056 writer.flush().unwrap(); 1057 assert_eq!(*writer.get_ref(), [0, 1, 2, 3]); 1058 1059 writer.write(&[4]).unwrap(); 1060 writer.write(&[5]).unwrap(); 1061 assert_eq!(*writer.get_ref(), [0, 1, 2, 3]); 1062 1063 writer.write(&[6]).unwrap(); 1064 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5]); 1065 1066 writer.write(&[7, 8]).unwrap(); 1067 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8]); 1068 1069 writer.write(&[9, 10, 11]).unwrap(); 1070 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); 1071 1072 writer.flush().unwrap(); 1073 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); 1074 } 1075 1076 #[test] test_buffered_writer_inner_flushes()1077 fn test_buffered_writer_inner_flushes() { 1078 let mut w = BufWriter::with_capacity(3, Vec::new()); 1079 w.write(&[0, 1]).unwrap(); 1080 assert_eq!(*w.get_ref(), []); 1081 let w = w.into_inner().unwrap(); 1082 assert_eq!(w, [0, 1]); 1083 } 1084 1085 #[test] test_buffered_writer_seek()1086 fn test_buffered_writer_seek() { 1087 let mut w = BufWriter::with_capacity(3, io::Cursor::new(Vec::new())); 1088 w.write_all(&[0, 1, 2, 3, 4, 5]).unwrap(); 1089 w.write_all(&[6, 7]).unwrap(); 1090 assert_eq!(w.seek(SeekFrom::Current(0)).ok(), Some(8)); 1091 assert_eq!(&w.get_ref().get_ref()[..], &[0, 1, 2, 3, 4, 5, 6, 7][..]); 1092 assert_eq!(w.seek(SeekFrom::Start(2)).ok(), Some(2)); 1093 w.write_all(&[8, 9]).unwrap(); 1094 assert_eq!(&w.into_inner().unwrap().into_inner()[..], &[0, 1, 8, 9, 4, 5, 6, 7]); 1095 } 1096 1097 #[test] test_read_until()1098 fn test_read_until() { 1099 let inner: &[u8] = &[0, 1, 2, 1, 0]; 1100 let mut reader = BufReader::with_capacity(2, inner); 1101 let mut v = Vec::new(); 1102 reader.read_until(0, &mut v).unwrap(); 1103 assert_eq!(v, [0]); 1104 v.truncate(0); 1105 reader.read_until(2, &mut v).unwrap(); 1106 assert_eq!(v, [1, 2]); 1107 v.truncate(0); 1108 reader.read_until(1, &mut v).unwrap(); 1109 assert_eq!(v, [1]); 1110 v.truncate(0); 1111 reader.read_until(8, &mut v).unwrap(); 1112 assert_eq!(v, [0]); 1113 v.truncate(0); 1114 reader.read_until(9, &mut v).unwrap(); 1115 assert_eq!(v, []); 1116 } 1117 1118 #[test] test_line_buffer_fail_flush()1119 fn test_line_buffer_fail_flush() { 1120 // Issue #32085 1121 struct FailFlushWriter<'a>(&'a mut Vec<u8>); 1122 1123 impl<'a> Write for FailFlushWriter<'a> { 1124 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 1125 self.0.extend_from_slice(buf); 1126 Ok(buf.len()) 1127 } 1128 fn flush(&mut self) -> io::Result<()> { 1129 Err(io::Error::new(io::ErrorKind::Other, "flush failed")) 1130 } 1131 } 1132 1133 let mut buf = Vec::new(); 1134 { 1135 let mut writer = LineWriter::new(FailFlushWriter(&mut buf)); 1136 let to_write = b"abc\ndef"; 1137 if let Ok(written) = writer.write(to_write) { 1138 assert!(written < to_write.len(), "didn't flush on new line"); 1139 // PASS 1140 return; 1141 } 1142 } 1143 assert!(buf.is_empty(), "write returned an error but wrote data"); 1144 } 1145 1146 #[test] test_line_buffer()1147 fn test_line_buffer() { 1148 let mut writer = LineWriter::new(Vec::new()); 1149 writer.write(&[0]).unwrap(); 1150 assert_eq!(*writer.get_ref(), []); 1151 writer.write(&[1]).unwrap(); 1152 assert_eq!(*writer.get_ref(), []); 1153 writer.flush().unwrap(); 1154 assert_eq!(*writer.get_ref(), [0, 1]); 1155 writer.write(&[0, b'\n', 1, b'\n', 2]).unwrap(); 1156 assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n']); 1157 writer.flush().unwrap(); 1158 assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2]); 1159 writer.write(&[3, b'\n']).unwrap(); 1160 assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n']); 1161 } 1162 1163 #[test] test_read_line()1164 fn test_read_line() { 1165 let in_buf: &[u8] = b"a\nb\nc"; 1166 let mut reader = BufReader::with_capacity(2, in_buf); 1167 let mut s = String::new(); 1168 reader.read_line(&mut s).unwrap(); 1169 assert_eq!(s, "a\n"); 1170 s.truncate(0); 1171 reader.read_line(&mut s).unwrap(); 1172 assert_eq!(s, "b\n"); 1173 s.truncate(0); 1174 reader.read_line(&mut s).unwrap(); 1175 assert_eq!(s, "c"); 1176 s.truncate(0); 1177 reader.read_line(&mut s).unwrap(); 1178 assert_eq!(s, ""); 1179 } 1180 1181 #[test] test_lines()1182 fn test_lines() { 1183 let in_buf: &[u8] = b"a\nb\nc"; 1184 let reader = BufReader::with_capacity(2, in_buf); 1185 let mut it = reader.lines(); 1186 assert_eq!(it.next().unwrap().unwrap(), "a".to_string()); 1187 assert_eq!(it.next().unwrap().unwrap(), "b".to_string()); 1188 assert_eq!(it.next().unwrap().unwrap(), "c".to_string()); 1189 assert!(it.next().is_none()); 1190 } 1191 1192 #[test] test_short_reads()1193 fn test_short_reads() { 1194 let inner = ShortReader{lengths: vec![0, 1, 2, 0, 1, 0]}; 1195 let mut reader = BufReader::new(inner); 1196 let mut buf = [0, 0]; 1197 assert_eq!(reader.read(&mut buf).unwrap(), 0); 1198 assert_eq!(reader.read(&mut buf).unwrap(), 1); 1199 assert_eq!(reader.read(&mut buf).unwrap(), 2); 1200 assert_eq!(reader.read(&mut buf).unwrap(), 0); 1201 assert_eq!(reader.read(&mut buf).unwrap(), 1); 1202 assert_eq!(reader.read(&mut buf).unwrap(), 0); 1203 assert_eq!(reader.read(&mut buf).unwrap(), 0); 1204 } 1205 1206 #[test] 1207 #[should_panic] dont_panic_in_drop_on_panicked_flush()1208 fn dont_panic_in_drop_on_panicked_flush() { 1209 struct FailFlushWriter; 1210 1211 impl Write for FailFlushWriter { 1212 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) } 1213 fn flush(&mut self) -> io::Result<()> { 1214 Err(io::Error::last_os_error()) 1215 } 1216 } 1217 1218 let writer = FailFlushWriter; 1219 let _writer = BufWriter::new(writer); 1220 1221 // If writer panics *again* due to the flush error then the process will 1222 // abort. 1223 panic!(); 1224 } 1225 1226 #[test] 1227 #[cfg_attr(target_os = "emscripten", ignore)] panic_in_write_doesnt_flush_in_drop()1228 fn panic_in_write_doesnt_flush_in_drop() { 1229 static WRITES: AtomicUsize = AtomicUsize::new(0); 1230 1231 struct PanicWriter; 1232 1233 impl Write for PanicWriter { 1234 fn write(&mut self, _: &[u8]) -> io::Result<usize> { 1235 WRITES.fetch_add(1, Ordering::SeqCst); 1236 panic!(); 1237 } 1238 fn flush(&mut self) -> io::Result<()> { Ok(()) } 1239 } 1240 1241 thread::spawn(|| { 1242 let mut writer = BufWriter::new(PanicWriter); 1243 let _ = writer.write(b"hello world"); 1244 let _ = writer.flush(); 1245 }).join().unwrap_err(); 1246 1247 assert_eq!(WRITES.load(Ordering::SeqCst), 1); 1248 } 1249 1250 struct AcceptOneThenFail { 1251 written: bool, 1252 flushed: bool, 1253 } 1254 1255 impl Write for AcceptOneThenFail { write(&mut self, data: &[u8]) -> io::Result<usize>1256 fn write(&mut self, data: &[u8]) -> io::Result<usize> { 1257 if !self.written { 1258 assert_eq!(data, b"a\nb\n"); 1259 self.written = true; 1260 Ok(data.len()) 1261 } else { 1262 Err(io::Error::new(io::ErrorKind::NotFound, "test")) 1263 } 1264 } 1265 flush(&mut self) -> io::Result<()>1266 fn flush(&mut self) -> io::Result<()> { 1267 assert!(self.written); 1268 assert!(!self.flushed); 1269 self.flushed = true; 1270 Err(io::Error::new(io::ErrorKind::Other, "test")) 1271 } 1272 } 1273 1274 #[test] erroneous_flush_retried()1275 fn erroneous_flush_retried() { 1276 let a = AcceptOneThenFail { 1277 written: false, 1278 flushed: false, 1279 }; 1280 1281 let mut l = LineWriter::new(a); 1282 assert_eq!(l.write(b"a\nb\na").unwrap(), 4); 1283 assert!(l.get_ref().written); 1284 assert!(l.get_ref().flushed); 1285 l.get_mut().flushed = false; 1286 1287 assert_eq!(l.write(b"a").unwrap_err().kind(), io::ErrorKind::Other) 1288 } 1289 } 1290