Custom zip parsing (#140)
## Summary * Use custom zip central directory parsing to lower memory usage when loading zipped epub content
This commit is contained in:
@@ -1,20 +1,46 @@
|
||||
#pragma once
|
||||
#include <Print.h>
|
||||
#include <FS.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "miniz.h"
|
||||
#include <unordered_map>
|
||||
|
||||
class ZipFile {
|
||||
std::string filePath;
|
||||
mutable mz_zip_archive zipArchive = {};
|
||||
bool loadFileStat(const char* filename, mz_zip_archive_file_stat* fileStat) const;
|
||||
long getDataOffset(const mz_zip_archive_file_stat& fileStat) const;
|
||||
public:
|
||||
struct FileStatSlim {
|
||||
uint16_t method; // Compression method
|
||||
uint32_t compressedSize; // Compressed size
|
||||
uint32_t uncompressedSize; // Uncompressed size
|
||||
uint32_t localHeaderOffset; // Offset of local file header
|
||||
};
|
||||
|
||||
struct ZipDetails {
|
||||
uint32_t centralDirOffset;
|
||||
uint16_t totalEntries;
|
||||
bool isSet;
|
||||
};
|
||||
|
||||
private:
|
||||
const std::string& filePath;
|
||||
File file;
|
||||
ZipDetails zipDetails = {0, 0, false};
|
||||
std::unordered_map<std::string, FileStatSlim> fileStatSlimCache;
|
||||
|
||||
bool loadFileStatSlim(const char* filename, FileStatSlim* fileStat);
|
||||
long getDataOffset(const FileStatSlim& fileStat);
|
||||
bool loadZipDetails();
|
||||
|
||||
public:
|
||||
explicit ZipFile(std::string filePath);
|
||||
~ZipFile() { mz_zip_reader_end(&zipArchive); }
|
||||
bool getInflatedFileSize(const char* filename, size_t* size) const;
|
||||
uint8_t* readFileToMemory(const char* filename, size_t* size = nullptr, bool trailingNullByte = false) const;
|
||||
bool readFileToStream(const char* filename, Print& out, size_t chunkSize) const;
|
||||
explicit ZipFile(const std::string& filePath) : filePath(filePath) {}
|
||||
~ZipFile() = default;
|
||||
// Zip file can be opened and closed by hand in order to allow for quick calculation of inflated file size
|
||||
// It is NOT recommended to pre-open it for any kind of inflation due to memory constraints
|
||||
bool isOpen() const { return !!file; }
|
||||
bool open();
|
||||
bool close();
|
||||
bool loadAllFileStatSlims();
|
||||
bool getInflatedFileSize(const char* filename, size_t* size);
|
||||
// Due to the memory required to run each of these, it is recommended to not preopen the zip file for multiple
|
||||
// These functions will open and close the zip as needed
|
||||
uint8_t* readFileToMemory(const char* filename, size_t* size = nullptr, bool trailingNullByte = false);
|
||||
bool readFileToStream(const char* filename, Print& out, size_t chunkSize);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user