extern crate getopts; extern crate byteorder; extern crate pbr; #[macro_use] extern crate lazy_static; use std::env; use std::fs; use std::io::BufReader; use std::io::prelude::*; use std::i32; use std::io::Cursor; use getopts::Options; use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian}; use pbr::{ProgressBar, Units}; mod bbp; fn print_usage(program: &str, opts: Options) { let brief = format!("Usage: {} [option] INPUT OUTPUT", program); print!("{}", opts.usage(&brief)); } fn main() { let args: Vec = env::args().collect(); let program = args[0].clone(); let mut opts = Options::new(); opts.optflag("c", "", "compress file"); opts.optflag("d", "", "decompress file"); opts.optflag("h", "help", "display this help and exit"); let matches = match opts.parse(&args[1..]) { Ok(m) => m, Err(_) => { print_usage(&program, opts); std::process::exit(1); } }; if matches.opt_present("help") { print_usage(&program, opts); std::process::exit(0); } if matches.free.len() == 1 { println!("Missing operand: OUTPUT"); println!("Try `{} --help` for more information.", program); std::process::exit(1); } if matches.free.is_empty() { println!("Missing operand: INPUT OUTPUT"); println!("Try `{} --help` for more information.", program); std::process::exit(1); } if matches.opt_present("c") { let input = &matches.free[0]; let output = &matches.free[1]; compress(input, output); } else if matches.opt_present("d") { let input = &matches.free[0]; let output = &matches.free[1]; extract(input, output) } } fn compress(input: &str, output: &str) { let mut output_file = fs::File::create(output).unwrap(); let input_file = fs::File::open(input).unwrap(); let n_bytes = input_file.metadata().unwrap().len() as u64; let input_buf = BufReader::new(input_file); let mut i : i32 = 0; let mut pb = ProgressBar::new(n_bytes); pb.set_units(Units::Bytes); for b in input_buf.bytes() { let b = b.unwrap(); for n in 0..i32::MAX { if b == bbp::get_byte(n) { i = n; break; } } let mut index : Vec = vec![]; index.write_i32::(i).unwrap(); output_file.write_all(&index).unwrap(); pb.inc(); } } fn extract(input: &str, output: &str) { let mut input_file = fs::File::open(input).unwrap(); let n_bytes = input_file.metadata().unwrap().len() as u64; let mut output_file = fs::File::create(output).unwrap(); let mut buf = vec![0; 4]; let mut pb = ProgressBar::new(n_bytes); pb.set_units(Units::Bytes); loop { let size = input_file.read(&mut buf).unwrap(); if size == 0 { break; } let mut c = Cursor::new(&buf); let index = c.read_i32::().unwrap(); output_file.write_all(&[bbp::get_byte(index)]).unwrap(); pb.add(size as u64); } }