From 9c7ff133dcfac23b78c2229cad700e4280a3091f Mon Sep 17 00:00:00 2001 From: Knight Date: Sat, 6 Aug 2016 11:46:18 +0800 Subject: [PATCH] base32: implemented --- src/base32/base32.rs | 110 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 src/base32/base32.rs diff --git a/src/base32/base32.rs b/src/base32/base32.rs new file mode 100644 index 000000000..0f65c19c8 --- /dev/null +++ b/src/base32/base32.rs @@ -0,0 +1,110 @@ +// This file is part of the uutils coreutils package. +// +// (c) Jian Zeng +// +// For the full copyright and license information, please view the LICENSE file +// that was distributed with this source code. +// + +#![crate_name = "uu_base32"] + +extern crate getopts; + +#[macro_use] +extern crate uucore; +use uucore::encoding::{Data, Format, wrap_print}; + +use getopts::Options; +use std::fs::File; +use std::io::{BufReader, Read, stdin, Write}; +use std::path::Path; + +static NAME: &'static str = "base32"; +static VERSION: &'static str = env!("CARGO_PKG_VERSION"); + +pub fn uumain(args: Vec) -> i32 { + let mut opts = Options::new(); + opts.optflag("d", "decode", "decode data"); + opts.optflag("i", + "ignore-garbage", + "when decoding, ignore non-alphabetic characters"); + opts.optopt("w", + "wrap", + "wrap encoded lines after COLS character (default 76, 0 to disable wrapping)", + "COLS"); + opts.optflag("", "help", "display this help text and exit"); + opts.optflag("", "version", "output version information and exit"); + let matches = match opts.parse(&args[1..]) { + Ok(m) => m, + Err(e) => { + disp_err!("{}", e); + return 1; + } + }; + + if matches.opt_present("help") { + return help(&opts); + } else if matches.opt_present("version") { + return version(); + } + + let line_wrap = match matches.opt_str("wrap") { + Some(s) => { + match s.parse() { + Ok(n) => n, + Err(e) => { + crash!(1, "invalid wrap size: ‘{}’: {}", s, e); + } + } + } + None => 76, + }; + + if matches.free.len() > 1 { + disp_err!("extra operand ‘{}’", matches.free[0]); + return 1; + } + + let input = if matches.free.is_empty() || &matches.free[0][..] == "-" { + BufReader::new(Box::new(stdin()) as Box) + } else { + let path = Path::new(matches.free[0].as_str()); + let file_buf = safe_unwrap!(File::open(&path)); + BufReader::new(Box::new(file_buf) as Box) + }; + + let mut data = Data::new(input, Format::Base32) + .line_wrap(line_wrap) + .ignore_garbage(matches.opt_present("ignore-garbage")); + + if !matches.opt_present("decode") { + wrap_print(line_wrap, data.encode()); + } else { + match data.decode() { + Ok(s) => print!("{}", String::from_utf8(s).unwrap()), + Err(_) => crash!(1, "invalid input"), + } + } + + 0 +} + +fn help(opts: &Options) -> i32 { + let msg = format!("Usage: {} [OPTION]... [FILE]\n\n\ + Base32 encode or decode FILE, or standard input, to standard output.\n\ + With no FILE, or when FILE is -, read standard input.\n\n\ + The data are encoded as described for the base32 alphabet in RFC \ + 4648.\nWhen decoding, the input may contain newlines in addition \ + to the bytes of the formal\nbase32 alphabet. Use --ignore-garbage \ + to attempt to recover from any other\nnon-alphabet bytes in the \ + encoded stream.", + NAME); + + print!("{}", opts.usage(&msg)); + 0 +} + +fn version() -> i32 { + println!("{} {}", NAME, VERSION); + 0 +}