blkar_lib/
cli_decode.rs

1use crate::cli_utils::*;
2use crate::decode_core;
3use crate::decode_core::Param;
4use crate::file_utils;
5use crate::json_printer::BracketType;
6use crate::output_channel::OutputChannel;
7use clap::*;
8use std::sync::Arc;
9
10pub fn sub_command<'a, 'b>() -> App<'a, 'b> {
11    SubCommand::with_name("decode")
12        .about("Decode SBX container")
13        .arg(in_file_arg().help("SBX container to decode"))
14        .arg(out_arg().help(
15            "Decoded file name. Supply - to use stdout as output. Use ./- for files named -.
16If output is stdout, progress text and final stats are outputted to stderr instead.
17If OUT is not provided, then the original file name stored in the SBX container
18(STOREDNAME) is used if present (only the file part of STOREDNAME is used). If
19OUT is provided and is a directory, then the output file is stored as OUT/STOREDNAME
20if STOREDNAME is present (only the file part of STOREDNAME is used). If OUT is
21provided and is not a directory, then it is used directly.",
22        ))
23        .arg(force_arg().help("Force overwrite even if OUT exists"))
24        .arg(multi_pass_arg().help(
25            "Disable truncation of OUT, and skip writing if a non-blank data
26chunk already exists at the location. This allows writing to OUT
27multiple times to update it gradually. Ignored if output is stdout.",
28        ))
29        .arg(multi_pass_no_skip_arg().help(
30            "Disable truncation of OUT, write even if a non-blank data chunk
31exists at the location. This allows writing to OUT multiple times
32to update it gradually. Ignored if output is stdout.",
33        ))
34        .arg(no_meta_arg())
35        .arg(pr_verbosity_level_arg())
36        .arg(ref_from_byte_arg())
37        .arg(ref_to_byte_inc_arg())
38        .arg(ref_to_byte_exc_arg())
39        .arg(guess_burst_from_byte_arg())
40        .arg(from_byte_arg().help(FROM_BYTE_ARG_HELP_MSG_REF_BLOCK))
41        .arg(to_byte_inc_arg())
42        .arg(to_byte_exc_arg())
43        .arg(force_misalign_arg())
44        .arg(burst_arg().help(
45            "Burst error resistance level used by the container.
46Use this if the level used by the container is above 1000,
47as blkar will only guess up to 1000. Or use this when blkar
48fails to guess correctly. blkar uses this value only if
49output is stdout and container version is RS enabled.",
50        ))
51        .arg(verbose_arg().help("Show reference block info"))
52        .arg(json_arg())
53}
54
55pub fn decode<'a>(matches: &ArgMatches<'a>) -> i32 {
56    let mut json_printer = get_json_printer!(matches);
57
58    let out = matches.value_of("out");
59
60    // update json_printer output channel if stdout is going to be used by file output
61    if let Some(ref f) = out {
62        if file_utils::check_if_file_is_stdout(f) {
63            let output_channel = OutputChannel::Stderr;
64
65            if !json_printer.json_enabled() {
66                print_block!(output_channel =>
67                             "Warning :";
68                             "";
69                             "    Since output is stdout, blkar can only output data chunks in the";
70                             "    anticipated encoding order.";
71                             "";
72                             "        For version with no FEC enabled (version 1, 2, 3), this means blkar";
73                             "        reads in the sequential pattern with optional metadata block and";
74                             "        outputs the data chunks.";
75                             "";
76                             "        For version with FEC enabled (version 17, 18, 19), this means blkar";
77                             "        first guesses the burst resistance level, then reads using the block";
78                             "        set interleaving pattern and outputs the data chunks.";
79                             "";
80                             "    blkar also tries to strip the data padding at the end of the container";
81                             "    at a best effort basis, but does not provide any guarantees.";
82                             "";
83                             "    If the ordering matches the anticipated ordering, output of blkar to";
84                             "    stdout should match the one produced in output to file mode. If the";
85                             "    ordering is not as anticipated, you may fix it by sorting the SBX";
86                             "    container using the blkar sort command first.";
87                             "";
88                );
89            }
90
91            Arc::get_mut(&mut json_printer)
92                .unwrap()
93                .set_output_channel(output_channel);
94        }
95    }
96
97    json_printer.print_open_bracket(None, BracketType::Curly);
98
99    let pr_verbosity_level = get_pr_verbosity_level!(matches, json_printer);
100
101    let burst = get_burst_opt!(matches, json_printer);
102
103    let in_file = get_in_file!(matches, json_printer);
104
105    let from_pos = get_from_pos!(matches, json_printer);
106    let to_pos = get_to_pos!(matches, json_printer);
107
108    let ref_from_pos = get_ref_from_pos!(matches, json_printer);
109    let ref_to_pos = get_ref_to_pos!(matches, json_printer);
110
111    let guess_burst_from_pos = get_guess_burst_from_pos!(matches, json_printer);
112
113    let param = Param::new(
114        get_ref_block_choice!(matches),
115        ref_from_pos,
116        ref_to_pos,
117        guess_burst_from_pos,
118        matches.is_present("force"),
119        get_multi_pass!(matches, json_printer),
120        &json_printer,
121        from_pos,
122        to_pos,
123        matches.is_present("force_misalign"),
124        in_file,
125        out,
126        matches.is_present("verbose"),
127        pr_verbosity_level,
128        burst,
129    );
130    match decode_core::decode_file(&param) {
131        Ok(Some(s)) => exit_with_msg!(ok json_printer => "{}", s),
132        Ok(None) => exit_with_msg!(ok json_printer => ""),
133        Err(e) => exit_with_msg!(op json_printer => "{}", e),
134    }
135}