This commit is contained in:
parent
189be660f5
commit
4c1c5bf00f
3 changed files with 64 additions and 17 deletions
|
@ -1,7 +1,9 @@
|
|||
#include "Archiver.hpp"
|
||||
|
||||
#include <spdlog/common.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
|
@ -15,16 +17,19 @@ namespace fs = std::filesystem;
|
|||
fs::path archive_extension(const fs::path& path) {
|
||||
// TODO: creates lots of paths, refactor
|
||||
fs::path ext;
|
||||
fs::path tmp_ext;
|
||||
fs::path tmp_path = path;
|
||||
while (tmp_path.has_extension()) {
|
||||
fs::path tmp_ext = tmp_path.extension() += ext;
|
||||
tmp_ext = tmp_path.extension() += tmp_ext;
|
||||
auto search = extensions_format.find(tmp_ext);
|
||||
|
||||
// (Combined) extension not known, return last known extension
|
||||
if (search == extensions_format.end()) return ext;
|
||||
if (search != extensions_format.end()) {
|
||||
// (Combined) extension known. Remember as `ext` and keep
|
||||
// looking for even longer extensions.
|
||||
ext = tmp_ext;
|
||||
} // else: (Combined) extension not known, keep `ext` as-is but try longer
|
||||
// extensions
|
||||
|
||||
// Continue extending extension
|
||||
ext = tmp_ext;
|
||||
tmp_path = tmp_path.stem();
|
||||
}
|
||||
|
||||
|
@ -34,20 +39,28 @@ fs::path archive_extension(const fs::path& path) {
|
|||
// Strip longest known extension from path
|
||||
fs::path strip_archive_extension(const fs::path& path) {
|
||||
// TODO: creates lots of paths, refactor
|
||||
fs::path ext;
|
||||
int longest_ext = 0;
|
||||
fs::path tmp_ext;
|
||||
fs::path tmp_path = path;
|
||||
fs::path stem_path = path;
|
||||
|
||||
while (tmp_path.has_extension()) {
|
||||
fs::path tmp_ext = tmp_path.extension() += ext;
|
||||
tmp_ext = tmp_path.extension() += tmp_ext;
|
||||
auto search = extensions_format.find(tmp_ext);
|
||||
|
||||
// (Combined) extension not known, return stripped path
|
||||
if (search == extensions_format.end()) return tmp_path;
|
||||
if (search != extensions_format.end()) {
|
||||
// (Combined) extension known. Remember as `longest_ext` and keep
|
||||
// looking for even longer extensions.
|
||||
longest_ext++;
|
||||
} // else: (Combined) extension not known, keep `longest_ext` as-is but try longer
|
||||
// extensions
|
||||
|
||||
// Continue stripping path
|
||||
ext = tmp_ext;
|
||||
tmp_path = tmp_path.stem();
|
||||
}
|
||||
|
||||
tmp_path = path;
|
||||
for(int i=0; i<longest_ext; i++) tmp_path = tmp_path.stem();
|
||||
|
||||
return tmp_path;
|
||||
}
|
||||
|
||||
|
@ -63,7 +76,9 @@ bool can_extract(const fs::path& path) {
|
|||
}
|
||||
|
||||
Format parse_format(const fs::path& path) {
|
||||
spdlog::debug("Looking for path {}", path);
|
||||
fs::path ext = archive_extension(path);
|
||||
spdlog::debug("Looking for ext {}", ext);
|
||||
auto search = extensions_format.find(ext);
|
||||
if (search == extensions_format.end()) {
|
||||
throw XwimError{"No known archiver for {}", path};
|
||||
|
|
|
@ -83,11 +83,10 @@ void Xwim::infer_compression_output() {
|
|||
if (ins.size() == 1) {
|
||||
// archive name is just the name of the input with default archive
|
||||
// extension
|
||||
|
||||
fs::path p = *ins.begin();
|
||||
while (p.has_extension()) p = p.stem();
|
||||
p += default_extension;
|
||||
out = p;
|
||||
fs::path archive_stem = xwim::strip_archive_extension(*ins.begin());
|
||||
fs::path path = (*ins.begin()).stem();
|
||||
path += default_extension;
|
||||
out = path;
|
||||
} else {
|
||||
// We cannot guess the name of the output archive
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#include <archive.h>
|
||||
#include <archive_entry.h>
|
||||
#include <fcntl.h>
|
||||
#include <fmt/core.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
|
@ -16,7 +18,38 @@ namespace fs = std::filesystem;
|
|||
|
||||
static int copy_data(shared_ptr<archive> reader, shared_ptr<archive> writer);
|
||||
|
||||
void LibArchiver::compress(set<fs::path> ins, fs::path archive_out) { return; }
|
||||
void LibArchiver::compress(set<fs::path> ins, fs::path archive_out) {
|
||||
spdlog::debug("Compressing to {}", archive_out);
|
||||
|
||||
// cannot use unique_ptr here since unique_ptr requires a
|
||||
// complete type. `archive` is forward declared only.
|
||||
shared_ptr<archive> writer;
|
||||
writer = shared_ptr<archive>(archive_write_new(), archive_write_free);
|
||||
archive_write_add_filter_gzip(writer.get());
|
||||
archive_write_set_format_pax_restricted(writer.get());
|
||||
archive_write_open_filename(writer.get(), archive_out.c_str());
|
||||
|
||||
archive_entry *entry = archive_entry_new();
|
||||
char buff[8192];
|
||||
|
||||
for(auto path: ins) {
|
||||
archive_entry_set_pathname(entry, path.c_str());
|
||||
archive_entry_set_size(entry, fs::file_size(path));
|
||||
archive_entry_set_filetype(entry, AE_IFREG);
|
||||
archive_entry_set_perm(entry, 0644);
|
||||
archive_write_header(writer.get(), entry);
|
||||
|
||||
int fd = open(path.c_str(), O_RDONLY);
|
||||
int len = read(fd, buff, sizeof(buff));
|
||||
while (len > 0) {
|
||||
archive_write_data(writer.get(), buff, len);
|
||||
len = read(fd, buff, sizeof(buff));
|
||||
}
|
||||
|
||||
close(fd);
|
||||
archive_entry_clear(entry);
|
||||
}
|
||||
}
|
||||
|
||||
void LibArchiver::extract(fs::path archive_in, fs::path out) {
|
||||
spdlog::debug("Extracting archive {} to {}", archive_in, out);
|
||||
|
|
Loading…
Reference in a new issue