// TJP COPYRIGHT HEADER #include "VirtualFileSystem.hpp" #include #include "minizip/ioapi.h" #ifdef WIN32 #include "minizip/iowin32.h" #endif #include "minizip/unzip.h" #include "../zip/MemoryBuffer.hpp" #include #include namespace tjp::core::zip { using Contents = file::Contents; using ContentsView = file::ContentsView; struct VirtualFileSystem::I { zip::MemoryBuffer memoryBuffer; unzFile uf = nullptr; I(Contents &&contents); ~I(); Contents get(const StringView &fileName); void put(const StringView &fileName, ContentsView); bool has(const StringView &fileName); } ; VirtualFileSystem::I::I(Contents &&contents) : memoryBuffer(std::move(contents)) { uf = unzOpen2("dummy.zip", &memoryBuffer.funcs); } VirtualFileSystem::I::~I() { if (uf) unzClose(uf); uf = nullptr; } Contents VirtualFileSystem::I::get(const StringView &fileName) { // debug_break(); if (unzLocateFile(uf,fileName.data(),false)!=UNZ_OK) throw Exception { "File does not exist" }; unz_file_info file_info; char filename_inzip[256]; int err; err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0); if (err!=UNZ_OK) { throw Exception ("unzGetCurrentFileInfo"); } Contents contents; contents.resize(file_info.uncompressed_size); try { if (unzOpenCurrentFile(uf) != UNZ_OK) throw Exception { "Open failure" }; auto len = unzReadCurrentFile(uf, contents.data(), contents.size()); if (len != contents.size()) throw Exception { "Read error" }; unzCloseCurrentFile (uf); return contents; } catch (Exception &e) { unzCloseCurrentFile (uf); throw e; } } bool VirtualFileSystem::I::has(const StringView &fileName) { return unzLocateFile(uf,fileName.data(),false) == UNZ_OK; } void VirtualFileSystem::I::put(const StringView &fileName, ContentsView) { throw Exception { "Not implemented" }; } VirtualFileSystem::VirtualFileSystem(Contents &&contents) : i(new I(std::move(contents))) { } Contents VirtualFileSystem::get(const StringView &path) const { return i->get(path); } Optional VirtualFileSystem::get_if(const StringView &path) const { try { return i->get(path); } catch(...) { } return {}; } void VirtualFileSystem::put(const StringView &path, ContentsView contents) { return i->put(path, contents); } bool VirtualFileSystem::has(const StringView &path) const { return i->has(path); } } // namespace