56c367a3c4
Prefixed all libzip zip_ funcs to fs_zip_ to avoid clashes and link errors due to assimp Zip pack and zip writer work with libzip now
145 lines
4.1 KiB
C++
145 lines
4.1 KiB
C++
#pragma once
|
|
|
|
#include "tl/result.h"
|
|
#include "tl/string.h"
|
|
#include "tl/vector_map.h"
|
|
#include "fs/IStreamSource.h"
|
|
|
|
#include "fs/IPack.h"
|
|
#include "fs/AbsPath.h"
|
|
|
|
#include "fs/Api.h"
|
|
|
|
struct zip;
|
|
struct zip_source;
|
|
struct zip_file;
|
|
namespace tl
|
|
{
|
|
template<> struct ptr_traits<zip>
|
|
{
|
|
static constexpr inline bool custom_deleter = true;
|
|
static constexpr inline bool requires_virtual_destructor_check = false;
|
|
};
|
|
//template<> struct ptr_traits<zip_source>
|
|
//{
|
|
// static constexpr inline bool custom_deleter = true;
|
|
// static constexpr inline bool requires_virtual_destructor_check = false;
|
|
//};
|
|
template<> struct ptr_traits<zip_file>
|
|
{
|
|
static constexpr inline bool custom_deleter = true;
|
|
static constexpr inline bool requires_virtual_destructor_check = false;
|
|
};
|
|
}
|
|
|
|
namespace fs
|
|
{
|
|
class MapSourceView;
|
|
|
|
class FS_API ZipPack final : public IPack
|
|
{
|
|
public:
|
|
ZipPack() = default;
|
|
~ZipPack() override = default;
|
|
|
|
typedef tl::result<tl::unique_ref<ZipPack>, Error> CreateResult;
|
|
|
|
static CreateResult create(tl::unique_ref<IMapSource> source);
|
|
static CreateResult create(tl::lent_ref<const IFilesystem> filesystem, AbsPathView path);
|
|
|
|
void setEncryptionData(const tl::string& key, uint32_t rounds);
|
|
|
|
OpenSourceResult openSource(AbsPathView path, SourceFlags flags = SourceFlags()) const override;
|
|
OpenStreamSourceResult openStreamSource(AbsPathView path, SourceFlags flags = SourceFlags()) const override;
|
|
OpenMapSourceResult openMapSource(AbsPathView path, MapView mapView = MapView(), SourceFlags flags = SourceFlags()) const override;
|
|
|
|
IsFileResult isFile(AbsPathView path) const override;
|
|
IsFolderResult isFolder(AbsPathView path) const override;
|
|
ExistsResult exists(AbsPathView path) const override;
|
|
|
|
GetStatResult getStat(AbsPathView path) const override;
|
|
|
|
cppcoro::generator<EnumerateEntry> enumerate(AbsPath path) const override;
|
|
cppcoro::generator<EnumerateEntry> enumerateRecursively(AbsPath path) const override;
|
|
|
|
tl::result<AbsPath, Error> convertToNativePath(AbsPathView path) const override;
|
|
|
|
struct ZipData
|
|
{
|
|
tl::unique_ptr<IMapSource> fsMapSource;
|
|
|
|
tl::lent_ptr<const IFilesystem> filesystem;
|
|
AbsPath path;
|
|
tl::unique_ptr<ISource> fsSource;
|
|
uint64_t cachedSize = uint64_t(-1);
|
|
|
|
//tl::unique_ptr<zip_source> zipSource;
|
|
tl::unique_ptr<zip> zipArchive;
|
|
};
|
|
|
|
protected:
|
|
struct File;
|
|
struct Folder;
|
|
struct EntryIndex;
|
|
|
|
ZipPack(tl::shared_ptr<ZipData> data);
|
|
|
|
//OpenMapSourceResult openRawMapSource(const File& file, MapView mapView) const;
|
|
//OpenSourceResult openRawSource(const File& file) const;
|
|
|
|
OpenSourceResult _openSource(const File& file) const;
|
|
OpenMapSourceResult _openMapSource(const File& file) const;
|
|
OpenStreamSourceResult _openStreamSource(const File& file) const;
|
|
|
|
uint16_t getOrAddFolder(AbsPathView folderPath, tl::vector<tl::vector<EntryIndex>>& io_childrenIndices);
|
|
void createEntries(zip& archive);
|
|
|
|
struct File
|
|
{
|
|
uint16_t zipIndex = 0; //index inside the zip archive
|
|
tl::string name;
|
|
uint16_t parentIndex = 0;
|
|
};
|
|
static_assert(sizeof(File) <= sizeof(tl::string) + 40, "Check your sizes!!!");
|
|
|
|
struct Folder
|
|
{
|
|
uint16_t zipIndex = 0; //index inside the zip archive
|
|
tl::string name;
|
|
uint16_t parentIndex = 0;
|
|
uint16_t childrenStartIndex = 0; // this is an index inside m_childrenIndices
|
|
uint16_t childrenCount = 0;
|
|
};
|
|
static_assert(sizeof(Folder) <= sizeof(tl::string) + 20, "Check your sizes!!!");
|
|
|
|
struct EntryIndex
|
|
{
|
|
EntryIndex() = default;
|
|
EntryIndex(bool isFolder, uint16_t index)
|
|
: isFolder(isFolder)
|
|
, index(index)
|
|
{
|
|
}
|
|
uint32_t isFolder : 1;
|
|
uint32_t index : 16;
|
|
};
|
|
static_assert(sizeof(EntryIndex) == 4, "Check your sizes!!!");
|
|
|
|
private:
|
|
mutable std::mutex m_zipMapSourceLock;
|
|
tl::shared_ptr<ZipData> m_zipData;
|
|
|
|
tl::string m_encryptionKey;
|
|
uint32_t m_encryptionRounds = 32;
|
|
|
|
tl::vector_map<uint64_t, EntryIndex> m_pathToIndex;
|
|
tl::vector<File> m_files;
|
|
tl::vector<Folder> m_folders;
|
|
tl::vector<EntryIndex> m_childrenIndices; // these are indices inside the m_files or m_folders
|
|
|
|
void buildUpPath(RelPath& path, const Folder& folder, uint32_t toIndex) const;
|
|
void buildUpPath(RelPath& path, const File& file, uint32_t toIndex) const;
|
|
};
|
|
|
|
}
|