Determine extract spec
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
d33d0ba544
commit
008973a7e8
4 changed files with 73 additions and 31 deletions
|
@ -15,26 +15,6 @@ namespace logger = spdlog;
|
||||||
|
|
||||||
namespace xwim {
|
namespace xwim {
|
||||||
|
|
||||||
Archive::Archive(std::string path) : path{std::filesystem::path(path)} {
|
|
||||||
int r; // libarchive error handling
|
|
||||||
|
|
||||||
logger::trace("Setting up archive reader");
|
|
||||||
this->xwim_archive = archive_read_new();
|
|
||||||
archive_read_support_filter_all(this->xwim_archive);
|
|
||||||
archive_read_support_format_all(this->xwim_archive);
|
|
||||||
|
|
||||||
logger::trace("Reading archive at {}", path.c_str());
|
|
||||||
r = archive_read_open_filename(this->xwim_archive, path.c_str(), 10240);
|
|
||||||
if (r != ARCHIVE_OK)
|
|
||||||
throw ArchiveException{"Could not open archive file", this->xwim_archive};
|
|
||||||
|
|
||||||
logger::trace("Archive read succesfully");
|
|
||||||
}
|
|
||||||
|
|
||||||
Archive::~Archive() {
|
|
||||||
archive_read_free(this->xwim_archive);
|
|
||||||
}
|
|
||||||
|
|
||||||
static archive_entry* _archive_next_entry(archive* archive) {
|
static archive_entry* _archive_next_entry(archive* archive) {
|
||||||
int r; // libarchive error handling
|
int r; // libarchive error handling
|
||||||
archive_entry* entry;
|
archive_entry* entry;
|
||||||
|
@ -46,6 +26,7 @@ static archive_entry* _archive_next_entry(archive* archive) {
|
||||||
logger::trace("Got archive header");
|
logger::trace("Got archive header");
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _spec_is_root_filename(ArchiveSpec* spec,
|
static void _spec_is_root_filename(ArchiveSpec* spec,
|
||||||
archive_entry* entry,
|
archive_entry* entry,
|
||||||
std::filesystem::path* filepath) {
|
std::filesystem::path* filepath) {
|
||||||
|
@ -80,19 +61,21 @@ static void _spec_is_root_dir(ArchiveSpec* spec, archive_entry* entry) {
|
||||||
static void _spec_has_single_root(ArchiveSpec* spec,
|
static void _spec_has_single_root(ArchiveSpec* spec,
|
||||||
archive_entry* first_entry,
|
archive_entry* first_entry,
|
||||||
archive* archive) {
|
archive* archive) {
|
||||||
|
std::filesystem::path first_entry_root =
|
||||||
std::filesystem::path first_entry_root = *(std::filesystem::path{archive_entry_pathname(first_entry)}.begin());
|
*(std::filesystem::path{archive_entry_pathname(first_entry)}.begin());
|
||||||
logger::trace("Testing roots");
|
logger::trace("Testing roots");
|
||||||
|
|
||||||
spec->has_single_root = true;
|
spec->has_single_root = true;
|
||||||
archive_entry* entry;
|
archive_entry* entry;
|
||||||
while (archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
|
while (archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
|
||||||
std::filesystem::path next_entry{archive_entry_pathname(entry)};
|
std::filesystem::path next_entry{archive_entry_pathname(entry)};
|
||||||
logger::trace("Path: {}, Root: {}", next_entry.string(), next_entry.begin()->string());
|
logger::trace("Path: {}, Root: {}", next_entry.string(),
|
||||||
|
next_entry.begin()->string());
|
||||||
|
|
||||||
if (first_entry_root != *next_entry.begin()) {
|
if (first_entry_root != *next_entry.begin()) {
|
||||||
logger::debug("Archive has multiple roots");
|
logger::debug("Archive has multiple roots");
|
||||||
logger::debug("\t-> Archive root I: {}", first_entry_root.begin()->string());
|
logger::debug("\t-> Archive root I: {}",
|
||||||
|
first_entry_root.begin()->string());
|
||||||
logger::debug("\t-> Archive root II: {}", next_entry.begin()->string());
|
logger::debug("\t-> Archive root II: {}", next_entry.begin()->string());
|
||||||
|
|
||||||
spec->has_single_root = false;
|
spec->has_single_root = false;
|
||||||
|
@ -103,6 +86,26 @@ static void _spec_has_single_root(ArchiveSpec* spec,
|
||||||
logger::debug("Archive has single root: {}", first_entry_root.string());
|
logger::debug("Archive has single root: {}", first_entry_root.string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Archive::Archive(std::filesystem::path path) : path{path} {
|
||||||
|
int r; // libarchive error handling
|
||||||
|
|
||||||
|
logger::trace("Setting up archive reader");
|
||||||
|
this->xwim_archive = archive_read_new();
|
||||||
|
archive_read_support_filter_all(this->xwim_archive);
|
||||||
|
archive_read_support_format_all(this->xwim_archive);
|
||||||
|
|
||||||
|
logger::trace("Reading archive at {}", path.c_str());
|
||||||
|
r = archive_read_open_filename(this->xwim_archive, path.c_str(), 10240);
|
||||||
|
if (r != ARCHIVE_OK)
|
||||||
|
throw ArchiveException{"Could not open archive file", this->xwim_archive};
|
||||||
|
|
||||||
|
logger::trace("Archive read succesfully");
|
||||||
|
}
|
||||||
|
|
||||||
|
Archive::~Archive() {
|
||||||
|
archive_read_free(this->xwim_archive);
|
||||||
|
}
|
||||||
|
|
||||||
ArchiveSpec Archive::check() {
|
ArchiveSpec Archive::check() {
|
||||||
logger::trace("Creating archive spec for {}", this->path.string());
|
logger::trace("Creating archive spec for {}", this->path.string());
|
||||||
|
|
||||||
|
@ -113,6 +116,7 @@ ArchiveSpec Archive::check() {
|
||||||
logger::debug("Archive is empty");
|
logger::debug("Archive is empty");
|
||||||
return {false, false, false};
|
return {false, false, false};
|
||||||
}
|
}
|
||||||
|
|
||||||
logger::trace("Found archive entry {}", archive_entry_pathname(first_entry));
|
logger::trace("Found archive entry {}", archive_entry_pathname(first_entry));
|
||||||
|
|
||||||
_spec_is_root_filename(&archive_spec, first_entry, &this->path);
|
_spec_is_root_filename(&archive_spec, first_entry, &this->path);
|
||||||
|
@ -122,4 +126,6 @@ ArchiveSpec Archive::check() {
|
||||||
return archive_spec;
|
return archive_spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Archive::extract(ExtractSpec extract_spec) {}
|
||||||
|
|
||||||
} // namespace xwim
|
} // namespace xwim
|
||||||
|
|
|
@ -19,7 +19,7 @@ class Archive {
|
||||||
archive* xwim_archive;
|
archive* xwim_archive;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Archive(std::string path);
|
explicit Archive(std::filesystem::path path);
|
||||||
~Archive();
|
~Archive();
|
||||||
|
|
||||||
ArchiveSpec check();
|
ArchiveSpec check();
|
||||||
|
|
27
src/main.cpp
27
src/main.cpp
|
@ -14,11 +14,30 @@ int main(int argc, char** argv) {
|
||||||
logger::flush_on(logger::level::trace);
|
logger::flush_on(logger::level::trace);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
std::string filename{argv[1]};
|
std::filesystem::path filepath{argv[1]};
|
||||||
xwim::Archive archive{filename};
|
xwim::Archive archive{filepath};
|
||||||
xwim::ArchiveSpec spec = archive.check();
|
xwim::ArchiveSpec archive_spec = archive.check();
|
||||||
|
|
||||||
logger::info("{}", spec);
|
logger::info("{}", archive_spec);
|
||||||
|
|
||||||
|
xwim::ExtractSpec extract_spec{};
|
||||||
|
|
||||||
|
if (!archive_spec.has_single_root || !archive_spec.is_root_filename) {
|
||||||
|
extract_spec.make_dir = true;
|
||||||
|
|
||||||
|
std::filesystem::path stem = filepath.stem();
|
||||||
|
|
||||||
|
while (stem.has_extension())
|
||||||
|
stem = stem.stem();
|
||||||
|
|
||||||
|
extract_spec.dirname = stem;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (archive_spec.has_subarchive) {
|
||||||
|
extract_spec.extract_subarchive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
archive.extract(extract_spec);
|
||||||
|
|
||||||
} catch (xwim::ArchiveException& ae) {
|
} catch (xwim::ArchiveException& ae) {
|
||||||
logger::error("{}", ae.what());
|
logger::error("{}", ae.what());
|
||||||
|
|
21
src/spec.hpp
21
src/spec.hpp
|
@ -17,8 +17,9 @@ struct ArchiveSpec {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExtractSpec {
|
struct ExtractSpec {
|
||||||
bool make_dir;
|
bool make_dir = false;
|
||||||
std::filesystem::path dirname;
|
std::filesystem::path dirname{};
|
||||||
|
bool extract_subarchive = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace xwim
|
} // namespace xwim
|
||||||
|
@ -40,4 +41,20 @@ struct fmt::formatter<xwim::ArchiveSpec> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct fmt::formatter<xwim::ExtractSpec> {
|
||||||
|
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
|
||||||
|
|
||||||
|
template <typename FormatContext>
|
||||||
|
auto format(const xwim::ExtractSpec& spec, FormatContext& ctx) {
|
||||||
|
return format_to(ctx.out(),
|
||||||
|
"ExtractSpec["
|
||||||
|
" .make_dir={},"
|
||||||
|
" .dirname={}"
|
||||||
|
" .extract_subarchive={}"
|
||||||
|
" ]",
|
||||||
|
spec.make_dir, spec.dirname, spec.extract_subarchive);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue