Files
piar/src/main.rs
2016-06-15 16:14:42 +02:00

133 lines
3.1 KiB
Rust

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<String> = 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<u8> = vec![];
index.write_i32::<LittleEndian>(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::<LittleEndian>().unwrap();
output_file.write_all(&[bbp::get_byte(index)]).unwrap();
pb.add(size as u64);
}
}