Skip to content

Commit 6398838

Browse files
author
moonshadow565
committed
rewrite splitting
1 parent 7a4a2e5 commit 6398838

14 files changed

+431
-461
lines changed

CMakeLists.txt

+4-7
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,9 @@ add_subdirectory(dep)
1010
add_library(rlib STATIC
1111
lib/rlib/ar.hpp
1212
lib/rlib/ar.cpp
13-
lib/rlib/ar/bnk.hpp
14-
lib/rlib/ar/bnk.cpp
15-
lib/rlib/ar/wad.hpp
16-
lib/rlib/ar/wad.cpp
17-
lib/rlib/ar/wpk.hpp
18-
lib/rlib/ar/wpk.cpp
13+
lib/rlib/ar_wad.cpp
14+
lib/rlib/ar_wpk.cpp
15+
lib/rlib/ar_zip.cpp
1916
lib/rlib/common.hpp
2017
lib/rlib/common.cpp
2118
lib/rlib/iofile.cpp
@@ -32,7 +29,7 @@ add_library(rlib STATIC
3229
lib/rlib/rmanifest.hpp
3330
)
3431
target_include_directories(rlib PUBLIC lib/)
35-
target_link_libraries(rlib PUBLIC argparse libcurl zstd digestpp fmt json)
32+
target_link_libraries(rlib PUBLIC argparse libcurl zstd digestpp fmt json miniz)
3633

3734
add_executable(rman-dl src/rman_dl.cpp)
3835
target_link_libraries(rman-dl PRIVATE rlib)

dep/CMakeLists.txt

+19-1
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,22 @@ if(NOT json_POPULATED)
109109
FetchContent_Populate(json)
110110
add_library(json INTERFACE)
111111
target_include_directories(json INTERFACE ${json_SOURCE_DIR}/include)
112-
endif()
112+
endif()
113+
114+
FetchContent_Declare(
115+
miniz
116+
GIT_REPOSITORY https://github.com/richgel999/miniz.git
117+
GIT_TAG 76b3a872855388c735c564905da030f26334f3b3
118+
)
119+
FetchContent_GetProperties(miniz)
120+
if(NOT miniz_POPULATED)
121+
FetchContent_Populate(miniz)
122+
add_subdirectory(${miniz_SOURCE_DIR} ${miniz_BINARY_DIR})
123+
target_compile_definitions(miniz PUBLIC
124+
-DMINIZ_NO_DEFLATE_APIS=1
125+
-DMINIZ_NO_ZLIB_APIS=1
126+
-DMINIZ_NO_TIME=1
127+
-DMINIZ_NO_STDIO=1
128+
-DMINIZ_DISABLE_ZIP_READER_CRC32_CHECKS=1
129+
)
130+
endif()

lib/rlib/ar.cpp

+32-61
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,52 @@
11
#include "ar.hpp"
22

3-
#include "ar/bnk.hpp"
4-
#include "ar/wad.hpp"
5-
#include "ar/wpk.hpp"
6-
73
using namespace rlib;
8-
using namespace rlib::ar;
94

10-
auto ArSplit::operator()(IO const& io, offset_cb cb) const -> void {
11-
process(io, cb, 0, {.offset = 0, .size = io.size()});
5+
auto Ar::operator()(IO const& io, offset_cb cb) const -> void {
6+
process(io, cb, {.offset = 0, .size = io.size(), .nest = true});
127
}
138

14-
template <typename T>
15-
auto ArSplit::process_ar(IO const& io, offset_cb cb, Entry top_entry) const -> void {
16-
auto archive = T{};
17-
if (auto error = archive.read(io, top_entry.offset, top_entry.size)) rlib_error(error);
18-
19-
// ensure offsets are processed in order
20-
std::sort(archive.entries.begin(), archive.entries.end(), [](auto const& lhs, auto const& rhs) {
21-
if (lhs.offset < rhs.offset) return true;
22-
if (lhs.offset == rhs.offset && lhs.size > rhs.size) return true;
23-
return false;
24-
});
25-
26-
auto cur = top_entry.offset;
27-
for (auto entry : archive.entries) {
28-
// skip empty entries
29-
if (!entry.size) continue;
30-
31-
// skip duplicate or overlapping entries
32-
if (entry.offset < cur) {
33-
continue;
34-
}
35-
36-
// process any skipped data
37-
if (auto leftover = entry.offset - cur) {
38-
process(io, cb, -1, {.offset = cur, .size = leftover, .compressed = top_entry.compressed});
39-
}
40-
41-
// process current entry
42-
process(io,
43-
cb,
44-
T::can_nest && !no_nest && !entry.compressed ? 1 : -1,
45-
{
46-
.offset = entry.offset,
47-
.size = entry.size,
48-
.compressed = entry.compressed,
49-
});
50-
51-
// go to next entry
52-
cur = entry.offset + entry.size;
9+
auto Ar::process_iter_next(IO const& io,
10+
offset_cb cb,
11+
Entry const& top_entry,
12+
std::size_t& cur,
13+
Entry const& entry) const -> void {
14+
// skip empty entries
15+
if (!entry.size) return;
16+
// skip duplicate or overlapping entries
17+
if (entry.offset < cur) return;
18+
// process any skipped data
19+
if (auto leftover = entry.offset - cur) {
20+
process(io, cb, {.offset = cur, .size = leftover, .compressed = top_entry.compressed});
21+
cur += leftover;
5322
}
23+
// process current entry
24+
process(io, cb, entry);
25+
// go to next entry
26+
cur += entry.size;
27+
}
5428

55-
// process any remaining data
29+
auto Ar::process_iter_end(IO const& io, offset_cb cb, Entry const& top_entry, std::size_t cur) const -> void {
5630
if (auto remain = (top_entry.offset + top_entry.size) - cur) {
57-
process(io, cb, -1, {.offset = cur, .size = remain, .compressed = top_entry.compressed});
31+
process(io, cb, {.offset = cur, .size = remain, .compressed = top_entry.compressed});
5832
}
5933
}
6034

61-
auto ArSplit::process(IO const& io, offset_cb cb, int depth, Entry top_entry) const -> void {
62-
if (depth >= 0 && top_entry.size >= 64) {
63-
char buffer[8] = {};
64-
rlib_assert(io.read(top_entry.offset, buffer));
65-
if (!no_bnk && BNK::check_magic(buffer)) {
66-
return process_ar<BNK>(io, cb, top_entry);
67-
}
68-
if (!no_wad && depth < 1 && WAD::check_magic(buffer)) {
69-
return process_ar<WAD>(io, cb, top_entry);
70-
}
71-
if (!no_wpk && WPK::check_magic(buffer)) {
72-
return process_ar<WPK>(io, cb, top_entry);
73-
}
35+
auto Ar::process(IO const& io, offset_cb cb, Entry const& top_entry) const -> void {
36+
if (top_entry.nest && !no_wad && process_try_wad(io, cb, top_entry)) {
37+
return;
38+
}
39+
if (top_entry.nest && !no_wpk && process_try_wpk(io, cb, top_entry)) {
40+
return;
41+
}
42+
if (top_entry.nest && !no_zip && process_try_zip(io, cb, top_entry)) {
43+
return;
7444
}
7545
for (auto i = top_entry.offset, remain = top_entry.size; remain;) {
7646
auto size = std::min(chunk_size, remain);
7747
cb({.offset = i, .size = size, .compressed = top_entry.compressed});
7848
i += size;
7949
remain -= size;
8050
}
51+
return;
8152
}

lib/rlib/ar.hpp

+21-6
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,41 @@
33
#include <rlib/iofile.hpp>
44

55
namespace rlib {
6-
struct ArSplit {
6+
struct Ar {
77
struct Entry {
88
std::size_t offset;
99
std::size_t size;
1010
bool compressed;
11+
bool nest;
1112
};
1213
using offset_cb = function_ref<void(Entry)>;
1314

1415
std::size_t chunk_size;
15-
bool no_bnk;
1616
bool no_wad;
1717
bool no_wpk;
18-
bool no_nest;
18+
bool no_zip;
1919

2020
auto operator()(IO const& io, offset_cb cb) const -> void;
2121

2222
private:
23-
auto process(IO const& io, offset_cb cb, int depth, Entry top_entry) const -> void;
23+
struct WAD;
24+
struct WPK;
25+
struct ZIP;
2426

25-
template <typename T>
26-
auto process_ar(IO const& io, offset_cb cb, Entry top_entry) const -> void;
27+
auto process(IO const& io, offset_cb cb, Entry const& top_entry) const -> void;
28+
29+
auto process_try_wad(IO const& io, offset_cb cb, Entry const& top_entry) const -> bool;
30+
31+
auto process_try_wpk(IO const& io, offset_cb cb, Entry const& top_entry) const -> bool;
32+
33+
auto process_try_zip(IO const& io, offset_cb cb, Entry const& top_entry) const -> bool;
34+
35+
auto process_iter_next(IO const& io,
36+
offset_cb cb,
37+
Entry const& top_entry,
38+
std::size_t& cur,
39+
Entry const& entry) const -> void;
40+
41+
auto process_iter_end(IO const& io, offset_cb cb, Entry const& top_entry, std::size_t cur) const -> void;
2742
};
2843
}

lib/rlib/ar/bnk.cpp

-89
This file was deleted.

lib/rlib/ar/bnk.hpp

-21
This file was deleted.

0 commit comments

Comments
 (0)