aboutsummaryrefslogtreecommitdiffstats
path: root/src/bin/geniza-sleep.rs
blob: 582b766b1e54e0f83de0cff41406c789bd85fb13 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// Free Software under GPL-3.0, see LICENSE
// Copyright 2017 Bryan Newbold

#[macro_use]
extern crate clap;
extern crate env_logger;
#[macro_use]
extern crate error_chain;
extern crate geniza;

// TODO: more careful import
use geniza::*;
use std::path::Path;
use clap::{App, SubCommand};

fn run() -> Result<()> {
    env_logger::init().unwrap();

    let matches = App::new("geniza-sleep")
        .version(env!("CARGO_PKG_VERSION"))
        .subcommand(
            SubCommand::with_name("info")
                .about("Reads a SLEEP dir register and shows some basic metadata")
                .arg_from_usage("<DIR> 'directory containing files'")
                .arg_from_usage("<prefix> 'prefix for each data file'"),
        )
        .subcommand(
            SubCommand::with_name("create")
                .about("Creates an SLEEP directory register (with header)")
                .arg_from_usage("<DIR> 'directory containing files'")
                .arg_from_usage("<prefix> 'prefix for each data file'"),
        )
        .subcommand(
            SubCommand::with_name("chunk")
                .about("Dumps raw data for a single given chunk from a register (by index)")
                .arg_from_usage("<DIR> 'directory containing files'")
                .arg_from_usage("<prefix> 'prefix for each data file'")
                .arg_from_usage("<index> 'index of the data chunk to dump'"),
        )
        .subcommand(
            SubCommand::with_name("verify")
                .about("Verifies the given register")
                .arg_from_usage("<DIR> 'directory containing files'")
                .arg_from_usage("<prefix> 'prefix for each data file'")
        )
        .subcommand(
            SubCommand::with_name("file-info")
                .about("Reads a single SLEEP file and shows some basic metadata")
                .arg_from_usage("<FILE> 'SLEEP file to read'"),
        )
        .subcommand(
            SubCommand::with_name("file-create")
                .about("Creates an empty single SLEEP file (with header)")
                .arg_from_usage("<FILE> 'SLEEP file to write (can't exist)'")
                .arg_from_usage("<magic> 'Magic word to use (eg, 0x5025700)'")
                .arg_from_usage("<entry_size> 'Size of each entry (bytes)'")
                .arg_from_usage("<algo_name> 'Name of algorithm (empty string for none)'"),
        )
        .subcommand(
            SubCommand::with_name("file-read-all")
                .about("Reads a single SLEEP file, iterates through all entries, prints raw bytes")
                .arg_from_usage("<FILE> 'SLEEP file to read'"),
        )
        .subcommand(
            SubCommand::with_name("file-chunk")
                .about("Dumps raw data for a single given chunk from a SLEEP file (by index)")
                .arg_from_usage("<FILE> 'SLEEP file to read'")
                .arg_from_usage("<index> 'index of the data chunk to dump'"),
        )
        .subcommand(
            SubCommand::with_name("write-example-alphabet")
                .about("Creates a content register in the given folder, with example data added")
                .arg_from_usage("<DIR> 'directory containing files'")
                .arg_from_usage("<prefix> 'prefix for each data file'")
        )
        .get_matches();


    match matches.subcommand() {
        ("info", Some(subm)) => {
            let dir = Path::new(subm.value_of("DIR").unwrap());
            let prefix = subm.value_of("prefix").unwrap();
            let mut sdr = SleepDirRegister::open(dir, prefix, false)?;
            println!("Entry count: {}", sdr.len()?);
            println!("Total size (bytes): {}", sdr.len_bytes()?);
        }
        ("create", Some(subm)) => {
            let dir = Path::new(subm.value_of("DIR").unwrap());
            let prefix = subm.value_of("prefix").unwrap();
            SleepDirRegister::create(dir, prefix)?;
            println!("Done!");
        }
        ("chunk", Some(subm)) => {
            let dir = Path::new(subm.value_of("DIR").unwrap());
            let prefix = subm.value_of("prefix").unwrap();
            let index = value_t_or_exit!(subm, "index", u64);
            let mut sdr = SleepDirRegister::open(dir, prefix, false)?;
            println!("{:?}", sdr.get_data_entry(index)?);
        }
        ("verify", Some(subm)) => {
            let dir = Path::new(subm.value_of("DIR").unwrap());
            let prefix = subm.value_of("prefix").unwrap();
            let mut sdr = SleepDirRegister::open(dir, prefix, false)?;
            println!("{:?}", sdr.verify());
        }
        ("file-info", Some(subm)) => {
            let path = Path::new(subm.value_of("FILE").unwrap());
            let sf = SleepFile::open(path, false)?;
            println!("Magic: 0x{:X}", sf.get_magic());
            println!(
                "Algorithm: '{}'",
                sf.get_algorithm().or(Some("".to_string())).unwrap()
            );
            println!("Entry Size (bytes): {}", sf.get_entry_size());
            println!("Entry count: {}", sf.len()?);
        }
        ("file-create", Some(subm)) => {
            let path = Path::new(subm.value_of("FILE").unwrap());
            let algo_name = subm.value_of("algo_name").unwrap();
            let algo_name = if algo_name.len() == 0 {
                None
            } else {
                Some(algo_name.to_string())
            };
            SleepFile::create(
                path,
                value_t_or_exit!(subm, "magic", u32),
                value_t_or_exit!(subm, "entry_size", u16),
                algo_name,
            )?;
            println!("Done!");
        }
        ("file-read-all", Some(subm)) => {
            let path = Path::new(subm.value_of("FILE").unwrap());
            let mut sf = SleepFile::open(path, false)?;
            for i in 0..sf.len()? {
                println!("{}: {:?}", i, sf.read(i));
            }
        }
        ("file-chunk", Some(subm)) => {
            let path = Path::new(subm.value_of("FILE").unwrap());
            let index = value_t_or_exit!(subm, "index", u64);
            let mut sf = SleepFile::open(path, false)?;
            //debug!(println!("{:?}", sdr));
            println!("{:?}", sf.read(index)?);
        }
        ("write-example-alphabet", Some(subm)) => {
            let dir = Path::new(subm.value_of("DIR").unwrap());
            let prefix = subm.value_of("prefix").unwrap();
            let mut sdr = SleepDirRegister::create(dir, prefix)?;
            sdr.append(&[0x61; 1])?; // a
            sdr.append(&[0x62; 1])?; // b
            sdr.append(&[0x63; 1])?; // c
            sdr.append(&[0x64; 1])?; // d
            sdr.append(&[0x65; 1])?; // e
            sdr.append(&[0x66; 1])?; // f
            println!("Done!");
        }
        _ => {
            println!("Missing or unimplemented command!");
            println!("{}", matches.usage());
            ::std::process::exit(-1);
        }
    }
    Ok(())
}

quick_main!(run);