mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-10 13:04:15 -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 {
|
namespace dwarfs {
|
||||||
|
|
||||||
|
class file_access;
|
||||||
class glob_matcher;
|
class glob_matcher;
|
||||||
class library_dependencies;
|
class library_dependencies;
|
||||||
class logger;
|
class logger;
|
||||||
@ -67,7 +68,8 @@ struct filesystem_extractor_archive_format {
|
|||||||
|
|
||||||
class filesystem_extractor {
|
class filesystem_extractor {
|
||||||
public:
|
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);
|
static void add_library_dependencies(library_dependencies& deps);
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include <folly/system/ThreadName.h>
|
#include <folly/system/ThreadName.h>
|
||||||
|
|
||||||
#include <dwarfs/config.h>
|
#include <dwarfs/config.h>
|
||||||
|
#include <dwarfs/file_access.h>
|
||||||
#include <dwarfs/file_stat.h>
|
#include <dwarfs/file_stat.h>
|
||||||
#include <dwarfs/fstypes.h>
|
#include <dwarfs/fstypes.h>
|
||||||
#include <dwarfs/glob_matcher.h>
|
#include <dwarfs/glob_matcher.h>
|
||||||
@ -112,9 +113,11 @@ class archive_error : public std::runtime_error {
|
|||||||
template <typename LoggerPolicy>
|
template <typename LoggerPolicy>
|
||||||
class filesystem_extractor_ final : public filesystem_extractor::impl {
|
class filesystem_extractor_ final : public filesystem_extractor::impl {
|
||||||
public:
|
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)
|
: LOG_PROXY_INIT(lgr)
|
||||||
, os_{os} {}
|
, os_{os}
|
||||||
|
, fa_{std::move(fa)} {}
|
||||||
|
|
||||||
~filesystem_extractor_() override {
|
~filesystem_extractor_() override {
|
||||||
try {
|
try {
|
||||||
@ -139,13 +142,13 @@ class filesystem_extractor_ final : public filesystem_extractor::impl {
|
|||||||
|
|
||||||
configure_format(format, &output);
|
configure_format(format, &output);
|
||||||
|
|
||||||
#ifdef _WIN32
|
if (output.empty()) {
|
||||||
check_result(::archive_write_open_filename_w(
|
check_result(::archive_write_open_filename(a_, nullptr));
|
||||||
a_, output.empty() ? nullptr : output.wstring().c_str()));
|
} else {
|
||||||
#else
|
out_ = fa_->open_output_binary(output);
|
||||||
check_result(::archive_write_open_filename(
|
check_result(::archive_write_open2(a_, this, nullptr, on_stream_write,
|
||||||
a_, output.empty() ? nullptr : output.string().c_str()));
|
on_stream_close, on_stream_free));
|
||||||
#endif
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,6 +222,26 @@ class filesystem_extractor_ final : public filesystem_extractor::impl {
|
|||||||
filesystem_extractor_options const& opts) override;
|
filesystem_extractor_options const& opts) override;
|
||||||
|
|
||||||
private:
|
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
|
void configure_format(filesystem_extractor_archive_format const& format
|
||||||
[[maybe_unused]],
|
[[maybe_unused]],
|
||||||
std::filesystem::path const* output
|
std::filesystem::path const* output
|
||||||
@ -301,7 +324,9 @@ class filesystem_extractor_ final : public filesystem_extractor::impl {
|
|||||||
|
|
||||||
LOG_PROXY_DECL(debug_logger_policy);
|
LOG_PROXY_DECL(debug_logger_policy);
|
||||||
os_access const& os_;
|
os_access const& os_;
|
||||||
|
std::shared_ptr<file_access const> fa_;
|
||||||
struct ::archive* a_{nullptr};
|
struct ::archive* a_{nullptr};
|
||||||
|
std::unique_ptr<output_stream> out_;
|
||||||
std::array<int, 2> pipefd_{-1, -1};
|
std::array<int, 2> pipefd_{-1, -1};
|
||||||
std::unique_ptr<std::thread> iot_;
|
std::unique_ptr<std::thread> iot_;
|
||||||
};
|
};
|
||||||
@ -560,10 +585,12 @@ std::string filesystem_extractor_archive_format::description() const {
|
|||||||
return desc;
|
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,
|
: impl_(make_unique_logging_object<filesystem_extractor::impl,
|
||||||
internal::filesystem_extractor_,
|
internal::filesystem_extractor_,
|
||||||
logger_policies>(lgr, os)) {}
|
logger_policies>(lgr, os,
|
||||||
|
std::move(fa))) {}
|
||||||
|
|
||||||
void filesystem_extractor::add_library_dependencies(
|
void filesystem_extractor::add_library_dependencies(
|
||||||
library_dependencies& deps) {
|
library_dependencies& deps) {
|
||||||
|
@ -2289,6 +2289,30 @@ TEST(dwarfsextract_test, filters) {
|
|||||||
EXPECT_EQ(ARCHIVE_OK, ::archive_read_free(ar)) << ::archive_error_string(ar);
|
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) {
|
TEST(dwarfsextract_test, patterns) {
|
||||||
auto mkdt = mkdwarfs_tester::create_empty();
|
auto mkdt = mkdwarfs_tester::create_empty();
|
||||||
mkdt.add_test_file_tree();
|
mkdt.add_test_file_tree();
|
||||||
|
@ -211,7 +211,7 @@ int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
reader::filesystem_v2_lite fs(lgr, *iol.os, fs_image, fsopts, perfmon);
|
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
|
#ifndef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT
|
||||||
if (format.name.empty()) {
|
if (format.name.empty()) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user