#pragma once #include #include inline void CreateArchive(std::vector 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 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); }