mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-09 12:28:13 -04:00
refactor: use file_access
abstraction in filesystem_extractor
This commit is contained in:
parent
19fcdbdd03
commit
938677302e
@ -38,6 +38,7 @@
|
||||
|
||||
namespace dwarfs {
|
||||
|
||||
class file_access;
|
||||
class glob_matcher;
|
||||
class library_dependencies;
|
||||
class logger;
|
||||
@ -67,7 +68,8 @@ struct filesystem_extractor_archive_format {
|
||||
|
||||
class filesystem_extractor {
|
||||
public:
|
||||
filesystem_extractor(logger& lgr, os_access const& os);
|
||||
filesystem_extractor(logger& lgr, os_access const& os,
|
||||
std::shared_ptr<file_access const> fa = nullptr);
|
||||
|
||||
static void add_library_dependencies(library_dependencies& deps);
|
||||
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include <folly/system/ThreadName.h>
|
||||
|
||||
#include <dwarfs/config.h>
|
||||
#include <dwarfs/file_access.h>
|
||||
#include <dwarfs/file_stat.h>
|
||||
#include <dwarfs/fstypes.h>
|
||||
#include <dwarfs/glob_matcher.h>
|
||||
@ -112,9 +113,11 @@ class archive_error : public std::runtime_error {
|
||||
template <typename LoggerPolicy>
|
||||
class filesystem_extractor_ final : public filesystem_extractor::impl {
|
||||
public:
|
||||
explicit filesystem_extractor_(logger& lgr, os_access const& os)
|
||||
explicit filesystem_extractor_(logger& lgr, os_access const& os,
|
||||
std::shared_ptr<file_access const> fa)
|
||||
: LOG_PROXY_INIT(lgr)
|
||||
, os_{os} {}
|
||||
, os_{os}
|
||||
, fa_{std::move(fa)} {}
|
||||
|
||||
~filesystem_extractor_() override {
|
||||
try {
|
||||
@ -139,13 +142,13 @@ class filesystem_extractor_ final : public filesystem_extractor::impl {
|
||||
|
||||
configure_format(format, &output);
|
||||
|
||||
#ifdef _WIN32
|
||||
check_result(::archive_write_open_filename_w(
|
||||
a_, output.empty() ? nullptr : output.wstring().c_str()));
|
||||
#else
|
||||
check_result(::archive_write_open_filename(
|
||||
a_, output.empty() ? nullptr : output.string().c_str()));
|
||||
#endif
|
||||
if (output.empty()) {
|
||||
check_result(::archive_write_open_filename(a_, nullptr));
|
||||
} else {
|
||||
out_ = fa_->open_output_binary(output);
|
||||
check_result(::archive_write_open2(a_, this, nullptr, on_stream_write,
|
||||
on_stream_close, on_stream_free));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -219,6 +222,26 @@ class filesystem_extractor_ final : public filesystem_extractor::impl {
|
||||
filesystem_extractor_options const& opts) override;
|
||||
|
||||
private:
|
||||
static la_ssize_t on_stream_write(struct archive* /*a*/, void* client_data,
|
||||
void const* buffer, size_t length) {
|
||||
auto self = static_cast<filesystem_extractor_*>(client_data);
|
||||
auto& os = self->out_->os();
|
||||
os.write(static_cast<char const*>(buffer), length);
|
||||
return os.good() ? static_cast<la_ssize_t>(length) : -1;
|
||||
}
|
||||
|
||||
static int on_stream_close(struct archive* /*a*/, void* client_data) {
|
||||
auto self = static_cast<filesystem_extractor_*>(client_data);
|
||||
self->out_->close();
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
|
||||
static int on_stream_free(struct archive* /*a*/, void* client_data) {
|
||||
auto self = static_cast<filesystem_extractor_*>(client_data);
|
||||
self->out_.reset();
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
|
||||
void configure_format(filesystem_extractor_archive_format const& format
|
||||
[[maybe_unused]],
|
||||
std::filesystem::path const* output
|
||||
@ -301,7 +324,9 @@ class filesystem_extractor_ final : public filesystem_extractor::impl {
|
||||
|
||||
LOG_PROXY_DECL(debug_logger_policy);
|
||||
os_access const& os_;
|
||||
std::shared_ptr<file_access const> fa_;
|
||||
struct ::archive* a_{nullptr};
|
||||
std::unique_ptr<output_stream> out_;
|
||||
std::array<int, 2> pipefd_{-1, -1};
|
||||
std::unique_ptr<std::thread> iot_;
|
||||
};
|
||||
@ -560,10 +585,12 @@ std::string filesystem_extractor_archive_format::description() const {
|
||||
return desc;
|
||||
}
|
||||
|
||||
filesystem_extractor::filesystem_extractor(logger& lgr, os_access const& os)
|
||||
filesystem_extractor::filesystem_extractor(
|
||||
logger& lgr, os_access const& os, std::shared_ptr<file_access const> fa)
|
||||
: impl_(make_unique_logging_object<filesystem_extractor::impl,
|
||||
internal::filesystem_extractor_,
|
||||
logger_policies>(lgr, os)) {}
|
||||
logger_policies>(lgr, os,
|
||||
std::move(fa))) {}
|
||||
|
||||
void filesystem_extractor::add_library_dependencies(
|
||||
library_dependencies& deps) {
|
||||
|
@ -2289,6 +2289,30 @@ TEST(dwarfsextract_test, filters) {
|
||||
EXPECT_EQ(ARCHIVE_OK, ::archive_read_free(ar)) << ::archive_error_string(ar);
|
||||
}
|
||||
|
||||
TEST(dwarfsextract_test, auto_format) {
|
||||
auto t = dwarfsextract_tester::create_with_image();
|
||||
ASSERT_EQ(0, t.run({"-i", "image.dwarfs", "-f", "auto", "-o", "image.tar"}))
|
||||
<< t.err();
|
||||
|
||||
auto out = t.fa->get_file("image.tar").value();
|
||||
|
||||
auto ar = ::archive_read_new();
|
||||
ASSERT_EQ(ARCHIVE_OK, ::archive_read_support_format_all(ar))
|
||||
<< ::archive_error_string(ar);
|
||||
ASSERT_EQ(ARCHIVE_OK, ::archive_read_open_memory(ar, out.data(), out.size()))
|
||||
<< ::archive_error_string(ar);
|
||||
|
||||
struct archive_entry* entry;
|
||||
int ret = ::archive_read_next_header(ar, &entry);
|
||||
|
||||
EXPECT_EQ(ARCHIVE_OK, ret) << ::archive_error_string(ar);
|
||||
auto fmt = ::archive_format(ar);
|
||||
EXPECT_EQ(ARCHIVE_FORMAT_TAR, fmt & ARCHIVE_FORMAT_BASE_MASK) << fmt::format(
|
||||
"expected TAR ({:08x}), got {:08x}", ARCHIVE_FORMAT_TAR, fmt);
|
||||
|
||||
EXPECT_EQ(ARCHIVE_OK, ::archive_read_free(ar)) << ::archive_error_string(ar);
|
||||
}
|
||||
|
||||
TEST(dwarfsextract_test, patterns) {
|
||||
auto mkdt = mkdwarfs_tester::create_empty();
|
||||
mkdt.add_test_file_tree();
|
||||
|
@ -211,7 +211,7 @@ int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) {
|
||||
#endif
|
||||
|
||||
reader::filesystem_v2_lite fs(lgr, *iol.os, fs_image, fsopts, perfmon);
|
||||
utility::filesystem_extractor fsx(lgr, *iol.os);
|
||||
utility::filesystem_extractor fsx(lgr, *iol.os, iol.file);
|
||||
|
||||
#ifndef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT
|
||||
if (format.name.empty()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user