1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-05 15:37:47 +00:00

uucore: update data_encoding and add wrap_write()

This commit is contained in:
Alex Lyon 2018-05-22 09:55:05 -07:00 committed by Roy Ivy III
parent 2ad767586b
commit 40738bfb0a
3 changed files with 61 additions and 28 deletions

View file

@ -5,8 +5,10 @@ authors = []
[dependencies] [dependencies]
getopts = "0.2.14" getopts = "0.2.14"
failure = { version = "0.1.1", optional = true }
failure_derive = { version = "0.1.1", optional = true }
time = { version = "0.1.38", optional = true } time = { version = "0.1.38", optional = true }
data-encoding = { version = "^1.1", optional = true } data-encoding = { version = "^2.1", optional = true }
libc = { version = "0.2.34", optional = true } libc = { version = "0.2.34", optional = true }
[target.'cfg(target_os = "redox")'.dependencies] [target.'cfg(target_os = "redox")'.dependencies]
@ -15,7 +17,7 @@ termion = "1.5"
[features] [features]
fs = ["libc"] fs = ["libc"]
utf8 = [] utf8 = []
encoding = ["data-encoding"] encoding = ["data-encoding", "failure", "failure_derive"]
parse_time = [] parse_time = []
mode = ["libc"] mode = ["libc"]
utmpx = ["time", "libc"] utmpx = ["time", "libc"]

View file

@ -7,10 +7,30 @@
// //
extern crate data_encoding; extern crate data_encoding;
use self::data_encoding::{decode, base32, base64}; use self::data_encoding::{DecodeError, BASE32, BASE64};
use std::io::Read; use std::io::{self, Read, Write};
pub type DecodeResult = Result<Vec<u8>, decode::Error>; #[derive(Fail, Debug)]
pub enum EncodingError {
#[fail(display = "{}", _0)]
Decode(#[cause] DecodeError),
#[fail(display = "{}", _0)]
Io(#[cause] io::Error),
}
impl From<io::Error> for EncodingError {
fn from(err: io::Error) -> EncodingError {
EncodingError::Io(err)
}
}
impl From<DecodeError> for EncodingError {
fn from(err: DecodeError) -> EncodingError {
EncodingError::Decode(err)
}
}
pub type DecodeResult = Result<Vec<u8>, EncodingError>;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum Format { pub enum Format {
@ -21,16 +41,16 @@ use self::Format::*;
pub fn encode(f: Format, input: &[u8]) -> String { pub fn encode(f: Format, input: &[u8]) -> String {
match f { match f {
Base32 => base32::encode(input), Base32 => BASE32.encode(input),
Base64 => base64::encode(input), Base64 => BASE64.encode(input),
} }
} }
pub fn decode(f: Format, input: &[u8]) -> DecodeResult { pub fn decode(f: Format, input: &[u8]) -> DecodeResult {
match f { Ok(match f {
Base32 => base32::decode(input), Base32 => BASE32.decode(input)?,
Base64 => base64::decode(input), Base64 => BASE64.decode(input)?,
} })
} }
pub struct Data<R: Read> { pub struct Data<R: Read> {
@ -38,7 +58,7 @@ pub struct Data<R: Read> {
ignore_garbage: bool, ignore_garbage: bool,
input: R, input: R,
format: Format, format: Format,
alphabet: &'static str, alphabet: &'static [u8],
} }
impl<R: Read> Data<R> { impl<R: Read> Data<R> {
@ -49,8 +69,8 @@ impl<R: Read> Data<R> {
input: input, input: input,
format: format, format: format,
alphabet: match format { alphabet: match format {
Base32 => "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=", Base32 => b"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",
Base64 => "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=+/", Base64 => b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=+/",
}, },
} }
} }
@ -66,18 +86,14 @@ impl<R: Read> Data<R> {
} }
pub fn decode(&mut self) -> DecodeResult { pub fn decode(&mut self) -> DecodeResult {
let mut buf = String::new(); let mut buf = vec![];
self.input.read_to_string(&mut buf).unwrap(); self.input.read_to_end(&mut buf)?;
let clean = if self.ignore_garbage { if self.ignore_garbage {
buf.chars() buf.retain(|c| self.alphabet.contains(c));
.filter(|&c| self.alphabet.contains(c))
.collect::<String>()
} else { } else {
buf.chars() buf.retain(|&c| c != b'\r' && c != b'\n');
.filter(|&c| c != '\r' && c != '\n')
.collect::<String>()
}; };
decode(self.format, clean.as_bytes()) decode(self.format, &buf)
} }
pub fn encode(&mut self) -> String { pub fn encode(&mut self) -> String {
@ -87,15 +103,25 @@ impl<R: Read> Data<R> {
} }
} }
// NOTE: this will likely be phased out at some point
pub fn wrap_print(line_wrap: usize, res: String) { pub fn wrap_print(line_wrap: usize, res: String) {
if line_wrap == 0 { let stdout = io::stdout();
return print!("{}", res); wrap_write(stdout.lock(), line_wrap, res).unwrap();
} }
pub fn wrap_write<W: Write>(mut writer: W, line_wrap: usize, res: String) -> io::Result<()> {
use std::cmp::min; use std::cmp::min;
if line_wrap == 0 {
return write!(writer, "{}", res);
}
let mut start = 0; let mut start = 0;
while start < res.len() { while start < res.len() {
let end = min(start + line_wrap, res.len()); let end = min(start + line_wrap, res.len());
println!("{}", &res[start..end]); writeln!(writer, "{}", &res[start..end])?;
start = end; start = end;
} }
Ok(())
} }

View file

@ -2,6 +2,11 @@
pub extern crate libc; pub extern crate libc;
#[cfg(feature = "winapi")] #[cfg(feature = "winapi")]
pub extern crate winapi; pub extern crate winapi;
#[cfg(feature = "failure")]
extern crate failure;
#[cfg(feature = "failure_derive")]
#[macro_use]
extern crate failure_derive;
#[macro_use] #[macro_use]
mod macros; mod macros;