@@ -12,19 +12,21 @@ struct Main {
12
12
struct CLI {
13
13
std::string output = {};
14
14
std::vector<std::string> inputs = {};
15
+ bool with_offset = {};
15
16
bool force = {};
16
17
bool no_hash = {};
17
18
bool no_progress = {};
18
19
} cli = {};
19
- std::unordered_map<ChunkID, std::size_t > seen = {};
20
+ std::unordered_set< std::string > seen = {};
20
21
21
22
auto parse_args (int argc, char ** argv) -> void {
22
23
argparse::ArgumentParser program (fs::path (argv[0 ]).filename ().generic_string ());
23
24
program.add_description (" Extracts one or more bundles." );
24
25
program.add_argument (" output" ).help (" Directory to write chunks into." ).required ();
25
26
program.add_argument (" input" ).help (" Bundle file(s) or folder(s) to read from." ).remaining ().required ();
26
27
27
- program.add_argument (" --force" )
28
+ program.add_argument (" --with-offset" ).help (" Put hex offset in name." ).default_value (false ).implicit_value (true );
29
+ program.add_argument (" -f" , " --force" )
28
30
.help (" Force overwrite existing files." )
29
31
.default_value (false )
30
32
.implicit_value (true );
@@ -36,6 +38,7 @@ struct Main {
36
38
37
39
program.parse_args (argc, argv);
38
40
41
+ cli.with_offset = program.get <bool >(" --with-offset" );
39
42
cli.force = program.get <bool >(" --force" );
40
43
cli.no_hash = program.get <bool >(" --no-hash" );
41
44
cli.no_progress = program.get <bool >(" --no-progress" );
@@ -63,7 +66,7 @@ struct Main {
63
66
}
64
67
}
65
68
}
66
- if (!paths.empty ()) {
69
+ if (!paths.empty () && !cli. force ) {
67
70
std::cerr << " Processing existing chunks ... " << std::endl;
68
71
fs::create_directories (cli.output );
69
72
for (auto const & entry : fs::directory_iterator (cli.output )) {
@@ -73,10 +76,7 @@ struct Main {
73
76
if (entry.path ().extension () != " .chunk" ) {
74
77
continue ;
75
78
}
76
- auto name = entry.path ().filename ().replace_extension (" " ).generic_string ();
77
- if (auto id = from_hex<ChunkID>(name)) {
78
- seen[*id] = entry.file_size ();
79
- }
79
+ seen.insert (entry.path ().filename ().generic_string ());
80
80
}
81
81
}
82
82
std::cerr << " Processing input bundles ... " << std::endl;
@@ -95,17 +95,21 @@ struct Main {
95
95
std::uint64_t offset = 0 ;
96
96
progress_bar p (" EXTRACTED" , cli.no_progress , index , offset, bundle.toc_offset );
97
97
for (auto const & chunk : bundle.chunks ) {
98
- if (!seen.contains (chunk.chunkId )) {
98
+ auto name = to_hex (chunk.chunkId ) + " .chunk" ;
99
+ if (cli.with_offset ) {
100
+ name = to_hex (offset) + " -" + name;
101
+ }
102
+ if (!seen.contains (name)) {
99
103
auto src = infile.copy (offset, chunk.compressed_size );
100
104
auto dst = zstd_decompress (src, chunk.uncompressed_size );
101
105
if (!cli.no_hash ) {
102
106
auto hash_type = RChunk::hash_type (dst, chunk.chunkId );
103
107
rlib_assert (hash_type != HashType::None);
104
108
}
105
- auto outfile = IOFile (fs::path (cli.output ) / ( to_hex (chunk. chunkId ) + " .chunk " ) , true );
106
- outfile.resize (0 , 0 );
109
+ auto outfile = IOFile (fs::path (cli.output ) / name , true );
110
+ outfile.resize (0 , dst. size () );
107
111
outfile.write (0 , dst, true );
108
- seen[chunk. chunkId ] = dst. size ( );
112
+ seen. insert ( std::move (name) );
109
113
}
110
114
offset += chunk.compressed_size ;
111
115
p.update (offset);
0 commit comments