Skip to content

Commit f08f4d0

Browse files
authored
Merge pull request uutils#8804 from sylvestre/fold-perf
fold: improve the performances - now same as GNU
2 parents 03f160c + b3d16cc commit f08f4d0

File tree

1 file changed

+28
-12
lines changed

1 file changed

+28
-12
lines changed

src/uu/fold/src/fold.rs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
use clap::{Arg, ArgAction, Command};
99
use std::fs::File;
10-
use std::io::{BufRead, BufReader, Read, Write, stdin, stdout};
10+
use std::io::{BufRead, BufReader, BufWriter, Read, Write, stdin, stdout};
1111
use std::path::Path;
1212
use uucore::display::Quotable;
1313
use uucore::error::{FromIo, UResult, USimpleError};
@@ -108,6 +108,8 @@ fn handle_obsolete(args: &[String]) -> (Vec<String>, Option<String>) {
108108
}
109109

110110
fn fold(filenames: &[String], bytes: bool, spaces: bool, width: usize) -> UResult<()> {
111+
let mut output = BufWriter::new(stdout());
112+
111113
for filename in filenames {
112114
let filename: &str = filename;
113115
let mut stdin_buf;
@@ -121,11 +123,15 @@ fn fold(filenames: &[String], bytes: bool, spaces: bool, width: usize) -> UResul
121123
});
122124

123125
if bytes {
124-
fold_file_bytewise(buffer, spaces, width)?;
126+
fold_file_bytewise(buffer, spaces, width, &mut output)?;
125127
} else {
126-
fold_file(buffer, spaces, width)?;
128+
fold_file(buffer, spaces, width, &mut output)?;
127129
}
128130
}
131+
132+
output
133+
.flush()
134+
.map_err_context(|| translate!("fold-error-failed-to-write"))?;
129135
Ok(())
130136
}
131137

@@ -137,7 +143,12 @@ fn fold(filenames: &[String], bytes: bool, spaces: bool, width: usize) -> UResul
137143
/// to all other characters in the stream.
138144
///
139145
/// If `spaces` is `true`, attempt to break lines at whitespace boundaries.
140-
fn fold_file_bytewise<T: Read>(mut file: BufReader<T>, spaces: bool, width: usize) -> UResult<()> {
146+
fn fold_file_bytewise<T: Read, W: Write>(
147+
mut file: BufReader<T>,
148+
spaces: bool,
149+
width: usize,
150+
output: &mut W,
151+
) -> UResult<()> {
141152
let mut line = Vec::new();
142153

143154
loop {
@@ -150,7 +161,7 @@ fn fold_file_bytewise<T: Read>(mut file: BufReader<T>, spaces: bool, width: usiz
150161
}
151162

152163
if line == [NL] {
153-
println!();
164+
output.write_all(&[NL])?;
154165
line.truncate(0);
155166
continue;
156167
}
@@ -189,10 +200,10 @@ fn fold_file_bytewise<T: Read>(mut file: BufReader<T>, spaces: bool, width: usiz
189200
let at_eol = i >= len;
190201

191202
if at_eol {
192-
stdout().write_all(slice)?;
203+
output.write_all(slice)?;
193204
} else {
194-
stdout().write_all(slice)?;
195-
stdout().write_all(&[NL])?;
205+
output.write_all(slice)?;
206+
output.write_all(&[NL])?;
196207
}
197208
}
198209

@@ -211,7 +222,12 @@ fn fold_file_bytewise<T: Read>(mut file: BufReader<T>, spaces: bool, width: usiz
211222
/// If `spaces` is `true`, attempt to break lines at whitespace boundaries.
212223
#[allow(unused_assignments)]
213224
#[allow(clippy::cognitive_complexity)]
214-
fn fold_file<T: Read>(mut file: BufReader<T>, spaces: bool, width: usize) -> UResult<()> {
225+
fn fold_file<T: Read, W: Write>(
226+
mut file: BufReader<T>,
227+
spaces: bool,
228+
width: usize,
229+
writer: &mut W,
230+
) -> UResult<()> {
215231
let mut line = Vec::new();
216232
let mut output = Vec::new();
217233
let mut col_count = 0;
@@ -229,8 +245,8 @@ fn fold_file<T: Read>(mut file: BufReader<T>, spaces: bool, width: usize) -> URe
229245
None => output.len(),
230246
};
231247

232-
stdout().write_all(&output[..consume])?;
233-
stdout().write_all(&[NL])?;
248+
writer.write_all(&output[..consume])?;
249+
writer.write_all(&[NL])?;
234250
output.drain(..consume);
235251

236252
// we know there are no tabs left in output, so each char counts
@@ -289,7 +305,7 @@ fn fold_file<T: Read>(mut file: BufReader<T>, spaces: bool, width: usize) -> URe
289305
}
290306

291307
if !output.is_empty() {
292-
stdout().write_all(&output)?;
308+
writer.write_all(&output)?;
293309
output.truncate(0);
294310
}
295311

0 commit comments

Comments
 (0)