Use a lock on stdout

This commit is contained in:
sharkdp committed 2018-11-05 21:38:29 +01:00
1 parent abd52ce7de
commit 6d6ee6fb24
1 file changed
+40 -10
+40 -10
View File
@@ -2,27 +2,49 @@
extern crate clap; extern crate clap;
use std::fs::File; use std::fs::File;
use std::io::{self, prelude::*}; use std::io::{self, prelude::*, StdoutLock};
use clap::{App, AppSettings, Arg}; use clap::{App, AppSettings, Arg};
const BUFFER_SIZE: usize = 64; const BUFFER_SIZE: usize = 64;
struct Printer { struct Printer<'a> {
idx: usize, idx: usize,
line: Vec<u8>,
stdout: StdoutLock<'a>,
} }
impl Printer { impl<'a> Printer<'a> {
fn print_byte(&mut self, b: u8) { fn new(stdout: StdoutLock) -> Printer {
print!("{:02x} ", b); Printer {
idx: 1,
line: vec![],
stdout,
}
}
fn print_byte(&mut self, b: u8) -> io::Result<()> {
write!(self.stdout, "{:02x} ", b)?;
self.line.push(b);
match self.idx % 16 { match self.idx % 16 {
8 => print!(" "), 8 => write!(self.stdout, " ")?,
0 => println!(), 0 => {
self.print_textline()?;
}
_ => {} _ => {}
} }
self.idx += 1; self.idx += 1;
Ok(())
}
fn print_textline(&mut self) -> io::Result<()> {
write!(self.stdout, "")?;
writeln!(self.stdout);
Ok(())
} }
} }
@@ -42,7 +64,8 @@ fn run() -> io::Result<()> {
let mut buffer = [0; BUFFER_SIZE]; let mut buffer = [0; BUFFER_SIZE];
let mut file = File::open(filename)?; let mut file = File::open(filename)?;
let mut printer = Printer { idx: 1 }; let stdout = io::stdout();
let mut printer = Printer::new(stdout.lock());
loop { loop {
let size = file.read(&mut buffer)?; let size = file.read(&mut buffer)?;
if size == 0 { if size == 0 {
@@ -50,10 +73,17 @@ fn run() -> io::Result<()> {
} }
for b in &buffer[..size] { for b in &buffer[..size] {
printer.print_byte(*b); let res = printer.print_byte(*b);
if res.is_err() {
// Broken pipe
break;
}
} }
} }
println!();
// Finish last line
printer.print_textline().ok();
Ok(()) Ok(())
} }