From 4c1c5bf00f9784ba5e86b03af1b700fcc78e0936 Mon Sep 17 00:00:00 2001 From: Armin Friedl Date: Fri, 19 Feb 2021 06:07:32 +0100 Subject: [PATCH] Compression --- src/Archiver.cpp | 37 +++++++++++++++++++++++++----------- src/Xwim.cpp | 9 ++++----- src/archiver/LibArchiver.cpp | 35 +++++++++++++++++++++++++++++++++- 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/src/Archiver.cpp b/src/Archiver.cpp index b3e3a91..df32a25 100644 --- a/src/Archiver.cpp +++ b/src/Archiver.cpp @@ -1,7 +1,9 @@ #include "Archiver.hpp" +#include #include +#include #include #include @@ -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 #include +#include #include #include +#include #include #include @@ -16,7 +18,38 @@ namespace fs = std::filesystem; static int copy_data(shared_ptr reader, shared_ptr writer); -void LibArchiver::compress(set ins, fs::path archive_out) { return; } +void LibArchiver::compress(set 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 writer; + writer = shared_ptr(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);