Skip to content

Commit 62b0c8f

Browse files
committed
use fmtlib
1 parent d56e3f4 commit 62b0c8f

12 files changed

+81
-61
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ add_library(rlib STATIC
2424
lib/rlib/rmanifest.hpp
2525
)
2626
target_include_directories(rlib PUBLIC lib/)
27-
target_link_libraries(rlib PUBLIC argparse libcurl zstd digestpp)
27+
target_link_libraries(rlib PUBLIC argparse libcurl zstd digestpp fmt)
2828

2929
add_executable(rman-dl src/rman_dl.cpp)
3030
target_link_libraries(rman-dl PRIVATE rlib)

README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ input Bundle file(s) or folder(s) to read from. [required]
2828
Optional arguments:
2929
-h --help shows help message and exits [default: false]
3030
-v --version prints version information and exits [default: false]
31-
--force Force overwrite existing files. [default: false]
31+
--with-offset Put hex offset in name. [default: false]
32+
-f --force Force overwrite existing files. [default: false]
3233
--no-hash Do not verify hash. [default: false]
3334
--no-progress Do not print progress to cerr. [default: false]
3435
```
@@ -37,15 +38,14 @@ Optional arguments:
3738
Usage: rbun-ls.exe [options] input
3839

3940
Lists contents of one or more bundles.
40-
Output is in CSV format as follows:
41-
BundlID,ChunkID,SizeCompressed,SizeUncompressed
4241

4342
Positional arguments:
4443
input Bundle file(s) or folder(s) to read from. [required]
4544

4645
Optional arguments:
4746
-h --help shows help message and exits [default: false]
4847
-v --version prints version information and exits [default: false]
48+
--format Format output. [default: "{bundleId},{chunkId},{compressedSize},{uncompressedSize}"]
4949
```
5050

5151
```sh
@@ -90,6 +90,7 @@ manifest Manifest file to read from. [required]
9090
Optional arguments:
9191
-h --help shows help message and exits [default: false]
9292
-v --version prints version information and exits [default: false]
93+
--format Format output. [default: "/{bundleId}.bundle"]
9394
```
9495
9596
```sh
@@ -128,15 +129,14 @@ Optional arguments:
128129
Usage: rman-ls.exe [options] manifest
129130

130131
Lists files in manifest.
131-
Output is in CSV format as follows:
132-
Path,Size,ID,Lang1;Lang2;Lang3...
133132

134133
Positional arguments:
135134
manifest Manifest file to read from. [required]
136135

137136
Optional arguments:
138137
-h --help shows help message and exits [default: false]
139138
-v --version prints version information and exits [default: false]
139+
--format Format output. [default: "{path},{size},{fileId},{langs}"]
140140
-l --filter-lang Filter: language(none for international files). [default: <not representable>]
141141
-p --filter-path Filter: path with regex match. [default: <not representable>]
142142
```

dep/CMakeLists.txt

+7
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,10 @@ if(NOT digestpp_POPULATED)
8989
add_library(digestpp INTERFACE)
9090
target_include_directories(digestpp INTERFACE ${digestpp_SOURCE_DIR})
9191
endif()
92+
93+
FetchContent_Declare(
94+
fmt
95+
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
96+
GIT_TAG 8.1.1
97+
)
98+
FetchContent_MakeAvailable(fmt)

lib/rlib/common.cpp

-12
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,6 @@ auto rlib::progress_bar::update(std::uint64_t done) noexcept -> void {
6060
}
6161
}
6262

63-
auto rlib::to_hex(std::uint64_t id, std::size_t s) noexcept -> std::string {
64-
static constexpr char table[] = "0123456789ABCDEF";
65-
char result[] = "0000000000000000";
66-
auto num = static_cast<std::uint64_t>(id);
67-
auto output = result + (s - 1);
68-
while (num) {
69-
*(output--) = table[num & 0xF];
70-
num >>= 4;
71-
}
72-
return std::string(result, s);
73-
};
74-
7563
auto rlib::from_hex(std::string_view name) noexcept -> std::optional<std::uint64_t> {
7664
auto result = std::uint64_t{};
7765
auto [p, ec] = std::from_chars(name.data(), name.data() + name.size(), result, 16);

lib/rlib/common.hpp

+3-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
#pragma once
2+
#include <fmt/args.h>
3+
#include <fmt/format.h>
4+
25
#include <algorithm>
36
#include <array>
47
#include <cinttypes>
@@ -96,24 +99,8 @@ namespace rlib {
9699
std::uint64_t percent_;
97100
};
98101

99-
extern auto to_hex(std::uint64_t id, std::size_t s = 16) noexcept -> std::string;
100-
101-
template <typename T>
102-
requires(std::is_enum_v<T>)
103-
inline auto to_hex(T id, std::size_t s = 16) noexcept -> std::string { return to_hex((std::uint64_t)id, s); }
104-
105102
extern auto from_hex(std::string_view name) noexcept -> std::optional<std::uint64_t>;
106103

107-
template <typename T>
108-
requires(std::is_enum_v<T>)
109-
inline auto from_hex(std::string_view name) noexcept -> std::optional<T> {
110-
if (auto result = from_hex(name)) {
111-
return (T)*result;
112-
} else {
113-
return std::nullopt;
114-
}
115-
}
116-
117104
extern auto clean_path(std::string path) noexcept -> std::string;
118105

119106
extern auto zstd_decompress(std::span<char const> src, std::size_t count) -> std::span<char const>;

lib/rlib/rcdn.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ struct RCDN::Worker {
5454
auto start = std::to_string(chunks.front().compressed_offset);
5555
auto end = std::to_string(chunks.back().compressed_offset + chunks.back().compressed_size - 1);
5656
auto range = start + "-" + end;
57-
auto url = url_ + "/bundles/" + to_hex(chunks.front().bundleId) + ".bundle";
57+
auto url = fmt::format("{}/bundles/{}.bundle", url_, chunks.front().bundleId);
5858
rlib_assert(curl_easy_setopt(handle_, CURLOPT_URL, url.c_str()) == CURLE_OK);
5959
rlib_assert(curl_easy_setopt(handle_, CURLOPT_RANGE, range.c_str()) == CURLE_OK);
6060
buffer_.clear();

lib/rlib/rchunk.hpp

+17-1
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,20 @@ namespace rlib {
4242
std::uint64_t uncompressed_offset;
4343
using data_cb = function_ref<void(RChunk::Dst const& chunk, std::span<char const> data)>;
4444
};
45-
}
45+
}
46+
47+
template <>
48+
struct fmt::formatter<rlib::BundleID> : formatter<std::string> {
49+
template <typename FormatContext>
50+
auto format(rlib::BundleID id, FormatContext& ctx) {
51+
return formatter<std::string>::format(fmt::format("{:016X}", (std::uint64_t)id), ctx);
52+
}
53+
};
54+
55+
template <>
56+
struct fmt::formatter<rlib::ChunkID> : formatter<std::string> {
57+
template <typename FormatContext>
58+
auto format(rlib::ChunkID id, FormatContext& ctx) {
59+
return formatter<std::string>::format(fmt::format("{:016X}", (std::uint64_t)id), ctx);
60+
}
61+
};

lib/rlib/rmanifest.hpp

+8
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,11 @@ namespace rlib {
5757
struct Raw;
5858
};
5959
}
60+
61+
template <>
62+
struct fmt::formatter<rlib::FileID> : formatter<std::string> {
63+
template <typename FormatContext>
64+
auto format(rlib::FileID id, FormatContext& ctx) {
65+
return formatter<std::string>::format(fmt::format("{:016X}", (std::uint64_t)id), ctx);
66+
}
67+
};

src/rbun_ex.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ struct Main {
9595
std::uint64_t offset = 0;
9696
progress_bar p("EXTRACTED", cli.no_progress, index, offset, bundle.toc_offset);
9797
for (auto const& chunk : bundle.chunks) {
98-
auto name = to_hex(chunk.chunkId) + ".chunk";
98+
auto name = fmt::format("{}.chunk", chunk.chunkId);
9999
if (cli.with_offset) {
100-
name = to_hex(offset) + "-" + name;
100+
name = fmt::format("{:016X}-{}", offset, name);
101101
}
102102
if (!seen.contains(name)) {
103103
auto src = infile.copy(offset, chunk.compressed_size);

src/rbun_ls.cpp

+14-12
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,23 @@ using namespace rlib;
99
struct Main {
1010
struct CLI {
1111
std::vector<std::string> inputs = {};
12+
std::string format = {};
1213
} cli = {};
1314

1415
auto parse_args(int argc, char** argv) -> void {
1516
argparse::ArgumentParser program(fs::path(argv[0]).filename().generic_string());
16-
program.add_description(
17-
"Lists contents of one or more bundles."
18-
"\n"
19-
"Output is in CSV format as follows:\n"
20-
"BundlID,ChunkID,SizeCompressed,SizeUncompressed");
17+
program.add_description("Lists contents of one or more bundles.");
18+
19+
program.add_argument("--format")
20+
.help("Format output.")
21+
.default_value(std::string("{bundleId},{chunkId},{compressedSize},{uncompressedSize}"));
22+
2123
program.add_argument("input").help("Bundle file(s) or folder(s) to read from.").remaining().required();
2224

2325
program.parse_args(argc, argv);
2426

2527
cli.inputs = program.get<std::vector<std::string>>("input");
28+
cli.format = program.get<std::string>("--format");
2629
}
2730

2831
auto run() -> void {
@@ -56,13 +59,12 @@ struct Main {
5659
auto infile = IOFile(path, true);
5760
auto bundle = RBUN::read(infile);
5861
for (std::uint64_t offset = 0; auto const& chunk : bundle.chunks) {
59-
std::cout //
60-
<< to_hex(bundle.bundleId) << ',' //
61-
<< to_hex(chunk.chunkId) << ',' //
62-
<< chunk.compressed_size << ',' //
63-
<< chunk.uncompressed_size << std::endl //
64-
;
65-
offset += chunk.compressed_size;
62+
fmt::dynamic_format_arg_store<fmt::format_context> store{};
63+
store.push_back(fmt::arg("bundleId", bundle.bundleId));
64+
store.push_back(fmt::arg("chunkId", chunk.chunkId));
65+
store.push_back(fmt::arg("compressedSize", chunk.compressed_size));
66+
store.push_back(fmt::arg("uncompressedSize", chunk.uncompressed_size));
67+
std::cout << fmt::vformat(cli.format, store) << std::endl;
6668
}
6769
} catch (std::exception const& e) {
6870
std::cerr << e.what() << std::endl;

src/rman_bl.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#include <fmt/args.h>
2+
#include <fmt/format.h>
3+
14
#include <argparse.hpp>
25
#include <iostream>
36
#include <rlib/common.hpp>
@@ -9,17 +12,19 @@ using namespace rlib;
912
struct Main {
1013
struct CLI {
1114
std::string manifest = {};
12-
RMAN::Filter filter = {};
15+
std::string format = {};
1316
} cli = {};
1417

1518
auto parse_args(int argc, char** argv) -> void {
1619
argparse::ArgumentParser program(fs::path(argv[0]).filename().generic_string());
1720
program.add_description("Lists bundle names used in manifest.");
1821
program.add_argument("manifest").help("Manifest file to read from.").required();
22+
program.add_argument("--format").help("Format output.").default_value(std::string("/{bundleId}.bundle"));
1923

2024
program.parse_args(argc, argv);
2125

2226
cli.manifest = program.get<std::string>("manifest");
27+
cli.format = program.get<std::string>("format");
2328
}
2429

2530
auto run() -> void {
@@ -28,7 +33,9 @@ struct Main {
2833
auto manifest = RMAN::read(infile.copy(0, infile.size()));
2934

3035
for (auto const& bundle : manifest.bundles) {
31-
std::cout << '/' << to_hex(bundle.bundleId) << ".bundle" << std::endl;
36+
fmt::dynamic_format_arg_store<fmt::format_context> store{};
37+
store.push_back(fmt::arg("bundleId", bundle.bundleId));
38+
std::cout << fmt::vformat(cli.format, store) << std::endl;
3239
}
3340
}
3441
};

src/rman_ls.cpp

+14-9
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,19 @@ using namespace rlib;
99
struct Main {
1010
struct CLI {
1111
std::string manifest = {};
12+
std::string format = {};
1213
RMAN::Filter filter = {};
1314
} cli = {};
1415

1516
auto parse_args(int argc, char** argv) -> void {
1617
argparse::ArgumentParser program(fs::path(argv[0]).filename().generic_string());
17-
program.add_description(
18-
"Lists files in manifest."
19-
"\n"
20-
"Output is in CSV format as follows:\n"
21-
"Path,Size,ID,Lang1;Lang2;Lang3...");
18+
program.add_description("Lists files in manifest.");
2219
program.add_argument("manifest").help("Manifest file to read from.").required();
2320

21+
program.add_argument("--format")
22+
.help("Format output.")
23+
.default_value(std::string("{path},{size},{fileId},{langs}"));
24+
2425
program.add_argument("-l", "--filter-lang")
2526
.help("Filter: language(none for international files).")
2627
.default_value(std::optional<std::regex>{})
@@ -44,6 +45,8 @@ struct Main {
4445

4546
program.parse_args(argc, argv);
4647

48+
cli.format = program.get<std::string>("--format");
49+
4750
cli.filter.langs = program.get<std::optional<std::regex>>("--filter-lang");
4851
cli.filter.path = program.get<std::optional<std::regex>>("--filter-path");
4952

@@ -59,10 +62,12 @@ struct Main {
5962
if (!rfile.matches(cli.filter)) {
6063
continue;
6164
}
62-
std::cout << rfile.path << ',' //
63-
<< std::to_string(rfile.size) << ',' //
64-
<< to_hex(rfile.fileId) + ',' //
65-
<< rfile.langs << std::endl;
65+
fmt::dynamic_format_arg_store<fmt::format_context> store{};
66+
store.push_back(fmt::arg("path", rfile.path));
67+
store.push_back(fmt::arg("size", rfile.size));
68+
store.push_back(fmt::arg("fileId", rfile.fileId));
69+
store.push_back(fmt::arg("langs", rfile.langs));
70+
std::cout << fmt::vformat(cli.format, store) << std::endl;
6671
}
6772
}
6873
};

0 commit comments

Comments
 (0)