First
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
#pragma once
|
||||
|
||||
#include "tl/result.h"
|
||||
#include "tl/string.h"
|
||||
#include "tl/vector_map.h"
|
||||
|
||||
#include "fs/IPack.h"
|
||||
#include "fs/AbsPath.h"
|
||||
#include "fs/zip/ZipReader.h"
|
||||
|
||||
#include "fs/Api.h"
|
||||
|
||||
namespace fs
|
||||
{
|
||||
class MapSourceView;
|
||||
|
||||
class FS_API ZipPack final : virtual public IPack
|
||||
{
|
||||
public:
|
||||
ZipPack() = default;
|
||||
~ZipPack() override = default;
|
||||
|
||||
typedef tl::result<tl::unique_ref<ZipPack>, Error> CreateResult;
|
||||
|
||||
static CreateResult create(tl::unique_ref<IMapSource> zipFileSource);
|
||||
static CreateResult create(tl::lent_ref<const IFilesystem> filesystem, AbsPath zipFileLocation);
|
||||
|
||||
virtual void setEncryptionData(const tl::string& key, uint32_t rounds);
|
||||
|
||||
OpenSourceResult openSource(const AbsPath& path, SourceFlags flags = SourceFlags()) const override;
|
||||
OpenStreamSourceResult openStreamSource(const AbsPath& path, SourceFlags flags = SourceFlags()) const override;
|
||||
OpenMapSourceResult openMapSource(const AbsPath& path, MapView mapView = MapView(), SourceFlags flags = SourceFlags()) const override;
|
||||
|
||||
IsFileResult isFile(const AbsPath& path) const override;
|
||||
IsFolderResult isFolder(const AbsPath& path) const override;
|
||||
ExistsResult exists(const AbsPath& path) const override;
|
||||
|
||||
GetStatResult getStat(const AbsPath& path) const override;
|
||||
|
||||
cppcoro::generator<EnumerateEntry> enumerate(const AbsPath& path) const override;
|
||||
cppcoro::generator<EnumerateEntry> enumerateRecursively(const AbsPath& path) const override;
|
||||
|
||||
tl::result<AbsPath, Error> convertToNativePath(const AbsPath& path) const override;
|
||||
|
||||
protected:
|
||||
struct File;
|
||||
struct Folder;
|
||||
struct EntryIndex;
|
||||
|
||||
ZipPack(tl::unique_ref<IMapSource> zipFileSource, ZipReader zipReader);
|
||||
ZipPack(tl::lent_ref<const IFilesystem> filesystem, AbsPath zipFileLocation, ZipReader zipReader);
|
||||
|
||||
OpenMapSourceResult openRawMapSource(const File& file, MapView mapView) const;
|
||||
OpenSourceResult openRawSource(const File& file) const;
|
||||
|
||||
OpenSourceResult openZipSource(const File& file) const;
|
||||
OpenMapSourceResult openZipMapSource(const File& file) const;
|
||||
OpenStreamSourceResult openZipStreamSource(const File& file) const;
|
||||
|
||||
uint16_t getOrAddFolder(AbsPath folderPath, tl::vector<tl::vector<EntryIndex>>& io_childrenIndices);
|
||||
void createEntries(ZipReader zipReader);
|
||||
|
||||
struct File
|
||||
{
|
||||
tl::string name;
|
||||
uint8_t isCompressed : 1;
|
||||
uint8_t uncompressedSizeH = 0;
|
||||
uint8_t compressedSizeH = 0;
|
||||
uint8_t dataOffsetH = 0;
|
||||
uint16_t parentIndex = 0;
|
||||
uint32_t lastModTimePoint = 0;
|
||||
uint32_t uncompressedSizeL = 0;
|
||||
uint32_t compressedSizeL = 0;
|
||||
uint32_t dataOffsetL = 0;
|
||||
};
|
||||
static_assert(sizeof(File) <= sizeof(tl::string) + 40, "Check your sizes!!!");
|
||||
|
||||
struct Folder
|
||||
{
|
||||
tl::string name;
|
||||
uint16_t parentIndex = 0;
|
||||
uint16_t childrenStartIndex = 0; // this is an index inside m_childrenIndices
|
||||
uint16_t childrenCount = 0;
|
||||
uint32_t lastModTimePoint = 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:
|
||||
tl::lent_ptr<const IFilesystem> m_filesystem;
|
||||
|
||||
mutable std::mutex m_zipMapSourceLock;
|
||||
tl::unique_ptr<IMapSource> m_zipMapSource;
|
||||
|
||||
AbsPath m_zipFileLocation;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user