1 extern crate clap;
2 extern crate libflate;
3
4 use clap::App;
5 use clap::Arg;
6 use clap::SubCommand;
7 use libflate::gzip;
8 use libflate::zlib;
9 use std::fs;
10 use std::io;
11 use std::io::Read;
12 use std::io::Write;
13 use std::process;
14
main()15 fn main() {
16 let matches = App::new("deflate")
17 .arg(
18 Arg::with_name("INPUT")
19 .short("i")
20 .long("input")
21 .value_name("FILE")
22 .takes_value(true)
23 .default_value("-"),
24 )
25 .arg(
26 Arg::with_name("OUTPUT")
27 .short("o")
28 .long("output")
29 .value_name("FILE")
30 .takes_value(true)
31 .default_value("-"),
32 )
33 .arg(Arg::with_name("VERBOSE").short("v").long("verbose"))
34 .subcommand(SubCommand::with_name("copy"))
35 .subcommand(
36 SubCommand::with_name("byte-read").arg(
37 Arg::with_name("UNIT")
38 .short("u")
39 .long("unit")
40 .takes_value(true)
41 .default_value("1"),
42 ),
43 )
44 .subcommand(SubCommand::with_name("gzip-decode"))
45 .subcommand(SubCommand::with_name("gzip-decode-multi"))
46 .subcommand(SubCommand::with_name("gzip-encode"))
47 .subcommand(SubCommand::with_name("zlib-decode"))
48 .subcommand(SubCommand::with_name("zlib-encode"))
49 .get_matches();
50
51 let input_filename = matches.value_of("INPUT").unwrap();
52 let input: Box<dyn io::Read> = if input_filename == "-" {
53 Box::new(io::stdin())
54 } else {
55 Box::new(
56 fs::File::open(input_filename).expect(&format!("Can't open file: {}", input_filename)),
57 )
58 };
59 let mut input = io::BufReader::new(input);
60
61 let output_filename = matches.value_of("OUTPUT").unwrap();
62 let output: Box<dyn io::Write> = if output_filename == "-" {
63 Box::new(io::stdout())
64 } else if output_filename == "/dev/null" {
65 Box::new(io::sink())
66 } else {
67 Box::new(
68 fs::File::create(output_filename)
69 .expect(&format!("Can't create file: {}", output_filename)),
70 )
71 };
72 let mut output = io::BufWriter::new(output);
73
74 let verbose = matches.is_present("VERBOSE");
75 if let Some(_matches) = matches.subcommand_matches("copy") {
76 io::copy(&mut input, &mut output).expect("Coyping failed");
77 } else if let Some(matches) = matches.subcommand_matches("byte-read") {
78 let unit = matches
79 .value_of("UNIT")
80 .and_then(|x| x.parse::<usize>().ok())
81 .unwrap();
82 let mut buf = vec![0; unit];
83 let mut reader = input;
84 let mut count = 0;
85 while let Ok(size) = reader.read(&mut buf) {
86 if size == 0 {
87 break;
88 }
89 count += size;
90 }
91 println!("COUNT: {}", count);
92 } else if let Some(_matches) = matches.subcommand_matches("gzip-decode") {
93 let mut decoder = gzip::Decoder::new(input).expect("Read GZIP header failed");
94 if verbose {
95 let _ = writeln!(&mut io::stderr(), "HEADER: {:?}", decoder.header());
96 }
97 io::copy(&mut decoder, &mut output).expect("Decoding GZIP stream failed");
98 } else if let Some(_matches) = matches.subcommand_matches("gzip-decode-multi") {
99 let mut decoder = gzip::MultiDecoder::new(input).expect("Read GZIP header failed");
100 io::copy(&mut decoder, &mut output).expect("Decoding GZIP stream failed");
101 } else if let Some(_matches) = matches.subcommand_matches("gzip-encode") {
102 let mut encoder = gzip::Encoder::new(output).unwrap();
103 io::copy(&mut input, &mut encoder).expect("Encoding GZIP stream failed");
104 encoder.finish().into_result().unwrap();
105 } else if let Some(_matches) = matches.subcommand_matches("zlib-decode") {
106 let mut decoder = zlib::Decoder::new(input).expect("Read ZLIB header failed");
107 if verbose {
108 let _ = writeln!(&mut io::stderr(), "HEADER: {:?}", decoder.header());
109 }
110 io::copy(&mut decoder, &mut output).expect("Decoding ZLIB stream failed");
111 } else if let Some(_matches) = matches.subcommand_matches("zlib-encode") {
112 let mut encoder = zlib::Encoder::new(output).unwrap();
113 io::copy(&mut input, &mut encoder).expect("Encoding ZLIB stream failed");
114 encoder.finish().into_result().unwrap();
115 } else {
116 println!("{}", matches.usage());
117 process::exit(1);
118 }
119 }
120