-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
378 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// | ||
// Created by Kirill Zhukov on 11.05.2023. | ||
// | ||
|
||
#include "ZIPArchive.h" | ||
|
||
|
||
void ZIPArchive::lookup_directory() { | ||
std::vector<std::string> directories = {this->path}; | ||
|
||
while (!directories.empty()) { | ||
std::string dir_path = directories.back(); | ||
directories.pop_back(); | ||
|
||
DIR* dir = opendir(dir_path.c_str()); | ||
if (dir == nullptr) { | ||
std::cerr << "Error opening directory " << dir_path << std::endl; | ||
continue; | ||
} | ||
|
||
dirent* entry; | ||
while ((entry = readdir(dir)) != nullptr) { | ||
if (entry->d_type == DT_DIR) { | ||
if (std::string(entry->d_name) == "." || std::string(entry->d_name) == "..") { | ||
continue; // Skip current and parent directories | ||
} | ||
std::string subdir_path = dir_path + "/" + entry->d_name; | ||
directories.push_back(subdir_path); | ||
} else { | ||
size_t pos = dir_path.find(this->path); | ||
if (pos == std::string::npos) { | ||
std::cerr << "Error: root path not found in directory path " << dir_path << std::endl; | ||
continue; | ||
} | ||
std::string parent_path = dir_path.substr(pos + this->path.length()); | ||
if (parent_path.front() == '/') { | ||
parent_path = parent_path.substr(1); | ||
} | ||
|
||
if (parent_path.empty()) { | ||
this->files.emplace_back(entry->d_name); | ||
} else { | ||
this->files.push_back(std::string(parent_path).append("/").append(entry->d_name)); | ||
} | ||
} | ||
} | ||
closedir(dir); | ||
} | ||
} | ||
|
||
const std::string &ZIPArchive::getPath() const { | ||
return path; | ||
} | ||
|
||
void ZIPArchive::setPath(const std::string &path) { | ||
ZIPArchive::path = path; | ||
} | ||
|
||
const std::string &ZIPArchive::getArchivePath() const { | ||
return archive_path; | ||
} | ||
|
||
void ZIPArchive::setArchivePath(const std::string &archivePath) { | ||
archive_path = archivePath; | ||
} | ||
|
||
void ZIPArchive::archive() { | ||
if (this->files.empty()) { | ||
this->lookup_directory(); | ||
} | ||
FILE *zip = fopen(this->archive_path.c_str(), "wb"); | ||
|
||
time_t mod_time = time(NULL); | ||
tm_t *mod_tm = localtime(&mod_time); | ||
uint16_t dos_mod_time = zip_time(mod_tm); | ||
uint16_t dos_mod_date = zip_date(mod_tm); | ||
std::vector<Compressed_file> compressed_files; | ||
|
||
for (auto &it : this->files) { | ||
std::string filepath = this->path + "/" + it; | ||
if (isDirectory(filepath.c_str())) { | ||
FILE *fp = fopen(filepath.c_str(), "r"); | ||
size_t uncompressed_filesize = getFileSize(fp); | ||
char data[uncompressed_filesize]; | ||
fread(data, sizeof(data), 1, fp); | ||
uint32_t crc32 = th_crc32((uint8_t *) data, uncompressed_filesize); | ||
Compressed_file cf = compress_file(data); | ||
cf.crc32 = crc32; | ||
cf.lfh_offset = ftell(zip); | ||
cf.uncompressed_size = uncompressed_filesize; | ||
compressed_files.push_back(cf); | ||
write_local_file_header(zip, it.c_str(), crc32, cf.compressed_size, uncompressed_filesize, dos_mod_time, | ||
dos_mod_date); | ||
fwrite(cf.compressed_data.c_str(), cf.compressed_size, 1, fp); | ||
fclose(fp); | ||
continue; | ||
} | ||
Compressed_file cf{}; | ||
cf.crc32 = 0; | ||
cf.lfh_offset = ftell(zip); | ||
cf.compressed_size = 0; | ||
cf.uncompressed_size = 0; | ||
compressed_files.push_back(cf); | ||
write_local_file_header(zip, it.c_str(), 0, cf.compressed_size, 0, dos_mod_time, dos_mod_date); | ||
} | ||
ulong_t cd_offset = ftell(zip); | ||
for (long_t i = 0; i < this->files.size(); i++) { | ||
Compressed_file cf = compressed_files.at(i); | ||
write_central_directory_file_header(zip, this->files.at(i).c_str(), cf.crc32, cf.compressed_size, cf.uncompressed_size, cf.lfh_offset, dos_mod_time, dos_mod_date); | ||
} | ||
ulong_t cd_sz = cd_offset - ftell(zip); | ||
write_end_of_central_directory_record(zip, this->files.size(), cd_sz, cd_offset); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// | ||
// Created by Kirill Zhukov on 11.05.2023. | ||
// | ||
|
||
#ifndef THEIA_ZIP_ZIPARCHIVE_H | ||
#define THEIA_ZIP_ZIPARCHIVE_H | ||
#include "iostream" | ||
#include "vector" | ||
#include "dirent.h" | ||
#include "zip.h" | ||
#include "crc32.h" | ||
|
||
class ZIPArchive { | ||
public: | ||
ZIPArchive(char *path, char *archive_path) : path(path), archive_path(archive_path) { | ||
generate_crc32_table(); | ||
} | ||
public: | ||
std::vector<std::string> files; | ||
public: | ||
void archive(); | ||
const std::string &getPath() const; | ||
void setPath(const std::string &path); | ||
const std::string &getArchivePath() const; | ||
void setArchivePath(const std::string &archivePath); | ||
private: | ||
void lookup_directory(); | ||
private: | ||
std::string path; | ||
std::string archive_path; | ||
}; | ||
|
||
#endif //THEIA_ZIP_ZIPARCHIVE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// | ||
// Created by Kirill Zhukov on 11.05.2023. | ||
// | ||
|
||
#ifndef THEIA_ZIP_CRC32_H | ||
#define THEIA_ZIP_CRC32_H | ||
|
||
#include <cstdint> | ||
#include "unistd.h" | ||
|
||
static uint32_t crc_table[256]; | ||
static inline void generate_crc32_table() { | ||
uint32_t c; | ||
int i, j; | ||
|
||
for (i = 0; i < 256; i++) { | ||
c = i; | ||
for (j = 0; j < 8; j++) { | ||
if (c & 1) { | ||
c = 0xEDB88320 ^ (c >> 1); | ||
} else { | ||
c = c >> 1; | ||
} | ||
} | ||
crc_table[i] = c; | ||
} | ||
} | ||
|
||
static inline uint32_t th_crc32(uint8_t *data, size_t length) { | ||
uint32_t c = 0 ^ ~0U; | ||
while (length--) { | ||
c = crc_table[(c ^ *data++) & 0xFF] ^ (c >> 8); | ||
} | ||
return c ^ ~0U; | ||
} | ||
|
||
#if 0 | ||
|
||
#define POLYNOMIAL 0xEDB88320 | ||
uint32_t crc32(uint8_t *data, size_t len) { | ||
uint32_t crc = ~0; | ||
uint32_t i, j; | ||
uint32_t byte; | ||
|
||
static uint32_t table[0x100]; | ||
|
||
// Generate lookup table | ||
if (table[1] == 0) { | ||
for (i = 0; i < 0x100; ++i) { | ||
uint32_t crc = i; | ||
for (j = 0; j < 8; ++j) { | ||
crc = (crc >> 1) ^ (- (int32_t)(crc & 1) & POLYNOMIAL); | ||
} | ||
table[i] = crc; | ||
} | ||
} | ||
|
||
// Calculate CRC | ||
for (i = 0; i < len; ++i) { | ||
byte = data[i]; | ||
crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF]; | ||
} | ||
|
||
return ~crc; | ||
} | ||
|
||
#endif | ||
|
||
#endif //THEIA_ZIP_CRC32_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,67 +1,8 @@ | ||
#include <cstdio> | ||
#include <cstdlib> | ||
#include <dirent.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <unistd.h> | ||
#include <cstring> | ||
#include <string> | ||
#include <iostream> | ||
#include "vector" | ||
#include "stack" | ||
#include <filesystem> | ||
|
||
class DirectoryScanner { | ||
public: | ||
std::vector<std::string> files; | ||
void print_directory_contents(const std::string& root_path) { | ||
std::vector<std::string> directories = {root_path}; | ||
|
||
while (!directories.empty()) { | ||
std::string dir_path = directories.back(); | ||
directories.pop_back(); | ||
|
||
DIR* dir = opendir(dir_path.c_str()); | ||
if (dir == nullptr) { | ||
std::cerr << "Error opening directory " << dir_path << std::endl; | ||
continue; | ||
} | ||
|
||
dirent* entry; | ||
while ((entry = readdir(dir)) != nullptr) { | ||
if (entry->d_type == DT_DIR) { | ||
if (std::string(entry->d_name) == "." || std::string(entry->d_name) == "..") { | ||
continue; // Skip current and parent directories | ||
} | ||
std::string subdir_path = dir_path + "/" + entry->d_name; | ||
directories.push_back(subdir_path); | ||
} else { | ||
size_t pos = dir_path.find(root_path); | ||
if (pos == std::string::npos) { | ||
std::cerr << "Error: root path not found in directory path " << dir_path << std::endl; | ||
continue; | ||
} | ||
std::string parent_path = dir_path.substr(pos + root_path.length()); | ||
if (parent_path.front() == '/') { | ||
parent_path = parent_path.substr(1); | ||
} | ||
// std::cout << parent_path << "/" << entry->d_name << std::endl; | ||
this->files.push_back(std::string(parent_path).append(entry->d_name)); | ||
} | ||
} | ||
|
||
closedir(dir); | ||
} | ||
} | ||
}; | ||
#include "ZIPArchive.h" | ||
|
||
int main(int argc, char *argv[]) { | ||
DirectoryScanner directoryScanner; | ||
directoryScanner.print_directory_contents("/Users/kirillzhukov/Desktop/test"); | ||
// print_directory_contents("/Users/kirillzhukov/Desktop/test", ""); | ||
for(auto it : directoryScanner.files) { | ||
printf("dir: %s\n", it.c_str()); | ||
} | ||
ZIPArchive archiver("/Users/kirillzhukov/Desktop/mvfst", "/Users/kirillzhukov/Desktop/ar/mvfst.zip"); | ||
archiver.archive(); | ||
return 0; | ||
} | ||
|
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.