139 lines
2.5 KiB
C++
139 lines
2.5 KiB
C++
// TJP COPYRIGHT HEADER
|
|
|
|
#include "VirtualFileSystem.hpp"
|
|
|
|
#include <zlib/zlib.h>
|
|
|
|
#include "minizip/ioapi.h"
|
|
#ifdef WIN32
|
|
#include "minizip/iowin32.h"
|
|
#endif
|
|
|
|
#include "minizip/unzip.h"
|
|
|
|
#include "../zip/MemoryBuffer.hpp"
|
|
|
|
#include <tjp/core/exception/Exception.hpp>
|
|
|
|
#include <tjp/core/debug/debug_break.h>
|
|
|
|
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<Contents> 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
|