1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-30 12:37:49 +00:00

Merge pull request #355 from Arcterus/perf

Performance improvements
This commit is contained in:
Heather 2014-07-12 09:30:01 +04:00
commit c1be1de35f
2 changed files with 50 additions and 39 deletions

View file

@ -17,8 +17,8 @@ extern crate getopts;
extern crate libc; extern crate libc;
#[phase(plugin, link)] extern crate log; #[phase(plugin, link)] extern crate log;
use std::io::{println, File, stdin, stdout}; use std::io::{println, File, stdout};
use std::str; use std::io::stdio::stdin_raw;
use getopts::{ use getopts::{
getopts, getopts,
@ -74,11 +74,15 @@ pub fn uumain(args: Vec<String>) -> int {
}, },
None => 76 None => 76
}; };
let mut input = if matches.free.is_empty() || matches.free.get(0).as_slice() == "-" { let mut stdin_buf;
box stdin() as Box<Reader> let mut file_buf;
let input = if matches.free.is_empty() || matches.free.get(0).as_slice() == "-" {
stdin_buf = stdin_raw();
&mut stdin_buf as &mut Reader
} else { } else {
let path = Path::new(matches.free.get(0).clone()); let path = Path::new(matches.free.get(0).as_slice());
box File::open(&path) as Box<Reader> file_buf = File::open(&path);
&mut file_buf as &mut Reader
}; };
match mode { match mode {
@ -94,33 +98,42 @@ pub fn uumain(args: Vec<String>) -> int {
fn decode(input: &mut Reader, ignore_garbage: bool) { fn decode(input: &mut Reader, ignore_garbage: bool) {
let mut to_decode = match input.read_to_string() { let mut to_decode = match input.read_to_string() {
Ok(m) => m, Ok(m) => m,
Err(f) => fail!(f.to_string()) Err(f) => fail!(f)
}; };
to_decode = str::replace(to_decode.as_slice(), "\n", ""); let slice =
if ignore_garbage {
to_decode.as_slice()
.trim_chars(|c: char| {
let num = match c.to_ascii_opt() {
Some(ascii) => ascii.to_byte(),
None => return false
};
!(num >= 'a' as u8 && num <= 'z' as u8 ||
num >= 'A' as u8 && num <= 'Z' as u8 ||
num >= '0' as u8 && num <= '9' as u8 ||
num == '+' as u8 || num == '/' as u8)
})
} else {
to_decode = to_decode.as_slice().replace("\n", "");
to_decode.as_slice()
};
if ignore_garbage { match slice.from_base64() {
let standard_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
to_decode = to_decode.as_slice()
.trim_chars(|c| !standard_chars.contains_char(c))
.into_string()
}
match to_decode.as_slice().from_base64() {
Ok(bytes) => { Ok(bytes) => {
let mut out = stdout(); let mut out = stdout();
match out.write(bytes.as_slice()) { match out.write(bytes.as_slice()) {
Ok(_) => {} Ok(_) => {}
Err(f) => { crash!(1, "{}", f.to_string()); } Err(f) => { crash!(1, "{}", f); }
} }
match out.flush() { match out.flush() {
Ok(_) => {} Ok(_) => {}
Err(f) => { crash!(1, "{}", f.to_string()); } Err(f) => { crash!(1, "{}", f); }
} }
} }
Err(s) => { Err(s) => {
error!("error: {}", s.to_string()); error!("error: {}", s);
fail!() fail!()
} }
} }
@ -137,7 +150,7 @@ fn encode(input: &mut Reader, line_wrap: uint) {
}; };
let to_encode = match input.read_to_end() { let to_encode = match input.read_to_end() {
Ok(m) => m, Ok(m) => m,
Err(f) => fail!(f.to_string()) Err(err) => crash!(1, "{}", err)
}; };
let encoded = to_encode.as_slice().to_base64(b64_conf); let encoded = to_encode.as_slice().to_base64(b64_conf);
@ -176,4 +189,3 @@ enum Mode {
Help, Help,
Version Version
} }

View file

@ -41,36 +41,35 @@ fn crc_final(mut crc: u32, mut length: uint) -> u32 {
!crc !crc
} }
#[inline]
fn cksum(fname: &str) -> IoResult<(u32, uint)> { fn cksum(fname: &str) -> IoResult<(u32, uint)> {
let mut crc = 0u32; let mut crc = 0u32;
let mut size = 0u; let mut size = 0u;
let mut rd = try!(open_file(fname)); let mut stdin_buf;
let mut file_buf;
let rd = match fname {
"-" => {
stdin_buf = stdin_raw();
&mut stdin_buf as &mut Reader
}
_ => {
file_buf = try!(File::open(&Path::new(fname)));
&mut file_buf as &mut Reader
}
};
let mut bytes: [u8, ..1024 * 1024] = unsafe { mem::uninitialized() }; let mut bytes: [u8, ..1024 * 1024] = unsafe { mem::uninitialized() };
loop { loop {
match rd.read(bytes) { match rd.read(bytes) {
Ok(num_bytes) => { Ok(num_bytes) => {
for &b in bytes.iter().take(num_bytes) { for &b in bytes.slice_to(num_bytes).iter() {
crc = crc_update(crc, b); crc = crc_update(crc, b);
} }
size += num_bytes; size += num_bytes;
} }
Err(err) => { Err(IoError { kind: EndOfFile, .. }) => return Ok((crc_final(crc, size), size)),
return match err { Err(err) => return Err(err)
IoError{kind: k, ..} if k == EndOfFile => Ok((crc_final(crc, size), size)),
_ => Err(err),
}
}
}
}
}
fn open_file(name: &str) -> IoResult<Box<Reader>> {
match name {
"-" => Ok(box stdin_raw() as Box<Reader>),
_ => {
let f = try!(File::open(&Path::new(name)));
Ok(box f as Box<Reader>)
} }
} }
} }