Archived
1
Fork 0
This repository has been archived on 2025-04-12. You can view files and clone it, but cannot push or open issues or pull requests.
graphite/editor/include/compress.h
2024-01-03 16:05:02 -05:00

104 lines
No EOL
3 KiB
C++

#pragma once
#include <archive.h>
#include <archive_entry.h>
inline void CreateArchive(std::vector<std::string> paths, const std::string& destinationPath, const std::string& rootDir)
{
archive* archive;
archive_entry *entry;
entry = archive_entry_new();
archive = archive_write_new();
archive_write_add_filter_none(archive);
archive_write_set_format_zip(archive);
archive_write_open_filename(archive, destinationPath.c_str());
for(unsigned int i = 0; i < paths.size(); i++)
{
std::fstream file(paths[i].c_str(), std::ios::binary | std::ios::in);
if(file.is_open())
{
file.seekg(0, std::ios::end);
long size = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<char> buffer(size);
if(size == 0 || file.read(&buffer[0], size))
{
std::string fileName = paths[i].substr(paths[i].rfind('\\') + 1);
if(rootDir != "")
fileName = Utility::RemoveSubstrings(fileName, {rootDir + "/"});
archive_entry_set_pathname(entry, fileName.c_str());
archive_entry_set_size(entry, size);
archive_entry_set_filetype(entry, AE_IFREG);
archive_entry_set_perm(entry, 0644);
archive_write_header(archive, entry);
archive_write_data(archive, size == 0 ? "" : &buffer[0], size);
file.close();
continue;
}
file.close();
archive_entry_clear(entry);
}
}
archive_entry_free(entry);
archive_write_close(archive);
#ifndef MACOS
archive_write_free(archive); //for some reason this is undefined under macos
#endif
}
//modified from https://github.com/libarchive/libarchive/wiki/Examples#A_Complete_Extractor
inline void copy_data(archive* ar, archive* aw)
{
const void* buff;
size_t size;
off_t offset;
while(archive_read_data_block(ar, &buff, &size, &offset) != ARCHIVE_EOF)
archive_write_data_block(aw, buff, size, offset);
}
inline void ExtractArchive(const std::string& archivePath, const std::string& destPath)
{
archive* a, *ext;
archive_entry* entry;
a = archive_read_new();
archive_read_support_format_all(a);
archive_read_support_filter_all(a);
ext = archive_write_disk_new();
archive_write_disk_set_standard_lookup(ext);
archive_read_open_filename(a, archivePath.c_str(), 16384);
while(archive_read_next_header(a, &entry) != ARCHIVE_EOF)
{
const char* currentFile = archive_entry_pathname(entry);
std::string fullOutputPath = destPath + currentFile;
archive_entry_set_pathname(entry, fullOutputPath.c_str());
archive_write_header(ext, entry);
if (archive_entry_size(entry) > 0)
copy_data(a, ext);
archive_write_finish_entry(ext);
}
archive_read_close(a);
archive_read_free(a);
archive_write_close(ext);
archive_write_free(ext);
}