A fork of https://github.com/crosspoint-reader/crosspoint-reader
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at records-reader 72 lines 2.7 kB view raw
1#pragma once 2#include <HalStorage.h> 3 4#include <deque> 5#include <string> 6#include <unordered_map> 7 8class ZipFile { 9 public: 10 struct FileStatSlim { 11 uint16_t method; // Compression method 12 uint32_t compressedSize; // Compressed size 13 uint32_t uncompressedSize; // Uncompressed size 14 uint32_t localHeaderOffset; // Offset of local file header 15 }; 16 17 struct ZipDetails { 18 uint32_t centralDirOffset; 19 uint16_t totalEntries; 20 bool isSet; 21 }; 22 23 // Target for batch uncompressed size lookup (sorted by hash, then len) 24 struct SizeTarget { 25 uint64_t hash; // FNV-1a 64-bit hash of normalized path 26 uint16_t len; // Length of path for collision reduction 27 uint16_t index; // Caller's index (e.g. spine index) 28 }; 29 30 // FNV-1a 64-bit hash computed from char buffer (no std::string allocation) 31 static uint64_t fnvHash64(const char* s, size_t len) { 32 uint64_t hash = 14695981039346656037ull; 33 for (size_t i = 0; i < len; i++) { 34 hash ^= static_cast<uint8_t>(s[i]); 35 hash *= 1099511628211ull; 36 } 37 return hash; 38 } 39 40 private: 41 const std::string& filePath; 42 FsFile file; 43 ZipDetails zipDetails = {0, 0, false}; 44 std::unordered_map<std::string, FileStatSlim> fileStatSlimCache; 45 46 // Cursor for sequential central-dir scanning optimization 47 uint32_t lastCentralDirPos = 0; 48 bool lastCentralDirPosValid = false; 49 50 bool loadFileStatSlim(const char* filename, FileStatSlim* fileStat); 51 long getDataOffset(const FileStatSlim& fileStat); 52 bool loadZipDetails(); 53 54 public: 55 explicit ZipFile(const std::string& filePath) : filePath(filePath) {} 56 ~ZipFile() = default; 57 // Zip file can be opened and closed by hand in order to allow for quick calculation of inflated file size 58 // It is NOT recommended to pre-open it for any kind of inflation due to memory constraints 59 bool isOpen() const { return !!file; } 60 bool open(); 61 bool close(); 62 bool loadAllFileStatSlims(); 63 bool getInflatedFileSize(const char* filename, size_t* size); 64 // Batch lookup: scan ZIP central dir once and fill sizes for matching targets. 65 // targets must be sorted by (hash, len). sizes[target.index] receives uncompressedSize. 66 // Returns number of targets matched. 67 int fillUncompressedSizes(std::deque<SizeTarget>& targets, std::deque<uint32_t>& sizes); 68 // Due to the memory required to run each of these, it is recommended to not preopen the zip file for multiple 69 // These functions will open and close the zip as needed 70 uint8_t* readFileToMemory(const char* filename, size_t* size = nullptr, bool trailingNullByte = false); 71 bool readFileToStream(const char* filename, Print& out, size_t chunkSize); 72};