blkar_lib/
cli_decode.rs

1use decode_core::Param;
2use decode_core;
3
4use json_printer::BracketType;
5
6use clap::*;
7use cli_utils::*;
8
9use output_channel::OutputChannel;
10use file_utils;
11
12use std::sync::Arc;
13
14pub fn sub_command<'a, 'b>() -> App<'a, 'b> {
15    SubCommand::with_name("decode")
16        .about("Decode SBX container
17
18===== IMPORTANT =====
19Please note that this is the last version of this software to be released under the name rsbx,
20future releases will be published under the name blkar. See project repo for details.
21=====================")
22        .arg(in_file_arg()
23             .help("SBX container to decode"))
24        .arg(out_arg()
25             .help("Decoded file name. Supply - to use STDOUT as output. If OUT is not provided,
26then the original file name stored in the SBX container (STOREDNAME) is used
27if present. If OUT is provided and is a directory, then the output file is
28stored as OUT/STOREDNAME if STOREDNAME is present. If OUT is provided and is
29not a directory, then it is used directly."))
30        .arg(Arg::with_name("force")
31             .short("f")
32             .long("force")
33             .help("Force overwrite even if OUT exists"))
34        .arg(no_meta_arg())
35        .arg(pr_verbosity_level_arg())
36        .arg(verbose_arg()
37             .help("Show reference block info"))
38        .arg(json_arg())
39}
40
41pub fn decode<'a>(matches : &ArgMatches<'a>) -> i32 {
42    let mut json_printer = get_json_printer!(matches);
43
44    let out              = matches.value_of("out");
45
46    // update json_printer output channel if stdout is going to be used by file output
47    if let Some(ref f) = out {
48        if file_utils::check_if_file_is_stdout(f) {
49            let output_channel = OutputChannel::Stderr;
50
51            if !json_printer.json_enabled() {
52                print_block!(output_channel =>
53                             "Warning :";
54                             "";
55                             "    Since output is stdout, rsbx can only output data chunks in the";
56                             "    anticipated encoding order.";
57                             "";
58                             "        For versions with no RS enabled (version 1, 2, 3), this means rsbx";
59                             "        outputs data chunks in the same order as the blocks are stored.";
60                             "";
61                             "        For versions with RS enabled (version 17, 18, 19), this means rsbx";
62                             "        first guesses the burst resistance level, then reads using the block";
63                             "        set interleaving pattern and outputs the data chunks.";
64                             "";
65                             "    rsbx also tries to strip the data padding at the end of the container";
66                             "    at a best effort basis, but does not provide any guarantees.";
67                             "";
68                             "    If the ordering matches the anticipated ordering, output of rsbx to";
69                             "    stdout should match the one produced in output to file mode. If the";
70                             "    ordering is not as anticipated, you may fix it by sorting the SBX";
71                             "    container using the rsbx sort command first.";
72                             "";
73                );
74            }
75
76            Arc::get_mut(&mut json_printer).unwrap().set_output_channel(output_channel);
77        }
78    }
79
80    json_printer.print_open_bracket(None, BracketType::Curly);
81
82    let pr_verbosity_level = get_pr_verbosity_level!(matches, json_printer);
83
84    let in_file = get_in_file!(matches, json_printer);
85
86    let param = Param::new(get_ref_block_choice!(matches),
87                           matches.is_present("force"),
88                           &json_printer,
89                           in_file,
90                           out,
91                           matches.is_present("verbose"),
92                           pr_verbosity_level);
93    match decode_core::decode_file(&param) {
94        Ok(Some(s)) => exit_with_msg!(ok json_printer => "{}", s),
95        Ok(None)    => exit_with_msg!(ok json_printer => ""),
96        Err(e)      => exit_with_msg!(op json_printer => "{}", e),
97    }
98}