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 "Archiver.hpp"
|
||||||
|
|
||||||
|
#include <spdlog/common.h>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -15,16 +17,19 @@ namespace fs = std::filesystem;
|
||||||
fs::path archive_extension(const fs::path& path) {
|
fs::path archive_extension(const fs::path& path) {
|
||||||
// TODO: creates lots of paths, refactor
|
// TODO: creates lots of paths, refactor
|
||||||
fs::path ext;
|
fs::path ext;
|
||||||
|
fs::path tmp_ext;
|
||||||
fs::path tmp_path = path;
|
fs::path tmp_path = path;
|
||||||
while (tmp_path.has_extension()) {
|
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);
|
auto search = extensions_format.find(tmp_ext);
|
||||||
|
|
||||||
// (Combined) extension not known, return last known extension
|
if (search != extensions_format.end()) {
|
||||||
if (search == extensions_format.end()) return ext;
|
// (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();
|
tmp_path = tmp_path.stem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,20 +39,28 @@ fs::path archive_extension(const fs::path& path) {
|
||||||
// Strip longest known extension from path
|
// Strip longest known extension from path
|
||||||
fs::path strip_archive_extension(const fs::path& path) {
|
fs::path strip_archive_extension(const fs::path& path) {
|
||||||
// TODO: creates lots of paths, refactor
|
// TODO: creates lots of paths, refactor
|
||||||
fs::path ext;
|
int longest_ext = 0;
|
||||||
|
fs::path tmp_ext;
|
||||||
fs::path tmp_path = path;
|
fs::path tmp_path = path;
|
||||||
|
fs::path stem_path = path;
|
||||||
|
|
||||||
while (tmp_path.has_extension()) {
|
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);
|
auto search = extensions_format.find(tmp_ext);
|
||||||
|
|
||||||
// (Combined) extension not known, return stripped path
|
if (search != extensions_format.end()) {
|
||||||
if (search == extensions_format.end()) return tmp_path;
|
// (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 = tmp_path.stem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmp_path = path;
|
||||||
|
for(int i=0; i<longest_ext; i++) tmp_path = tmp_path.stem();
|
||||||
|
|
||||||
return tmp_path;
|
return tmp_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +76,9 @@ bool can_extract(const fs::path& path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Format parse_format(const fs::path& path) {
|
Format parse_format(const fs::path& path) {
|
||||||
|
spdlog::debug("Looking for path {}", path);
|
||||||
fs::path ext = archive_extension(path);
|
fs::path ext = archive_extension(path);
|
||||||
|
spdlog::debug("Looking for ext {}", ext);
|
||||||
auto search = extensions_format.find(ext);
|
auto search = extensions_format.find(ext);
|
||||||
if (search == extensions_format.end()) {
|
if (search == extensions_format.end()) {
|
||||||
throw XwimError{"No known archiver for {}", path};
|
throw XwimError{"No known archiver for {}", path};
|
||||||
|
|
|
@ -83,11 +83,10 @@ void Xwim::infer_compression_output() {
|
||||||
if (ins.size() == 1) {
|
if (ins.size() == 1) {
|
||||||
// archive name is just the name of the input with default archive
|
// archive name is just the name of the input with default archive
|
||||||
// extension
|
// extension
|
||||||
|
fs::path archive_stem = xwim::strip_archive_extension(*ins.begin());
|
||||||
fs::path p = *ins.begin();
|
fs::path path = (*ins.begin()).stem();
|
||||||
while (p.has_extension()) p = p.stem();
|
path += default_extension;
|
||||||
p += default_extension;
|
out = path;
|
||||||
out = p;
|
|
||||||
} else {
|
} else {
|
||||||
// We cannot guess the name of the output archive
|
// We cannot guess the name of the output archive
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include <archive.h>
|
#include <archive.h>
|
||||||
#include <archive_entry.h>
|
#include <archive_entry.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -16,7 +18,38 @@ namespace fs = std::filesystem;
|
||||||
|
|
||||||
static int copy_data(shared_ptr<archive> reader, shared_ptr<archive> writer);
|
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) {
|
void LibArchiver::extract(fs::path archive_in, fs::path out) {
|
||||||
spdlog::debug("Extracting archive {} to {}", archive_in, out);
|
spdlog::debug("Extracting archive {} to {}", archive_in, out);
|
||||||
|
|
Loading…
Reference in a new issue