diff options
| author | Stefan Boberg <[email protected]> | 2023-09-20 15:22:03 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-09-20 15:22:03 +0200 |
| commit | 14d7568f9c7d970b7bbf7b6463a0a8530f98bb6f (patch) | |
| tree | bf24ac15759385cea339f7e1cf5380f984f5699a /src/zenvfs/vfsprovider.h | |
| parent | changelog version bump (diff) | |
| download | zen-14d7568f9c7d970b7bbf7b6463a0a8530f98bb6f.tar.xz zen-14d7568f9c7d970b7bbf7b6463a0a8530f98bb6f.zip | |
VFS implementation for local storage service (#396)
currently, only Windows (using Projected File System) is supported
Diffstat (limited to 'src/zenvfs/vfsprovider.h')
| -rw-r--r-- | src/zenvfs/vfsprovider.h | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/zenvfs/vfsprovider.h b/src/zenvfs/vfsprovider.h new file mode 100644 index 000000000..8e6896956 --- /dev/null +++ b/src/zenvfs/vfsprovider.h @@ -0,0 +1,112 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "projfsproviderinterface.h" + +#if ZEN_WITH_VFS + +# include <zencore/compactbinarybuilder.h> +# include <zencore/except.h> +# include <zencore/string.h> +# include <zencore/thread.h> + +ZEN_THIRD_PARTY_INCLUDES_START +# if ZEN_PLATFORM_WINDOWS +# include <zencore/windows.h> +# include <projectedfslib.h> +# endif +ZEN_THIRD_PARTY_INCLUDES_END + +# include <unordered_map> +# include <vector> + +namespace zen { + +class VfsTree +{ +public: + VfsTree(); + ~VfsTree(); + + void Initialize(VfsTreeDataSource& DataProvider); + void SetTree(VfsTreeNode&& TreeRoot, VfsTreeDataSource& DataProvider); + VfsTreeNode& GetTree(); + VfsTreeNode* FindNode(std::wstring NodeName); + void ReadChunkData(Oid ChunkId, void* DataBuffer, uint64_t ByteOffset, uint64_t Length); + +private: + struct Impl; + + Impl* m_Impl; +}; + +////////////////////////////////////////////////////////////////////////// + +struct VfsProvider : public ProjFsProviderInterface +{ + struct EnumerationState + { + std::string Path; + const VfsTreeNode* Node = nullptr; + std::vector<std::unique_ptr<VfsTreeNode>>::const_iterator Iterator; + std::vector<std::unique_ptr<VfsTreeNode>>::const_iterator EndIterator; + + void RestartScan(); + inline bool IsCurrentValid() { return Iterator != EndIterator; } + bool MatchesPattern(PCWSTR SearchExpression); + void MoveToNext(); + const WCHAR* GetCurrentFileName(); + PRJ_FILE_BASIC_INFO& GetCurrentBasicInfo(); + + PRJ_FILE_BASIC_INFO BasicInfo; + std::wstring CurrentName; + }; + + ////////////////////////////////////////////////////////////////////////// + + VfsProvider(std::string_view RootPath); + ~VfsProvider(); + + void Initialize(); + void Cleanup(); + + void AddMount(std::string_view Mountpoint, Ref<VfsTreeDataSource>&& DataSource); + void RequestStop(); + + // ProjFsProviderInterface implementation + + virtual void Run() override; + + virtual HRESULT StartDirEnum(_In_ const PRJ_CALLBACK_DATA* CallbackData, _In_ const GUID* EnumerationId) override; + virtual HRESULT EndDirEnum(_In_ const PRJ_CALLBACK_DATA* CallbackData, _In_ const GUID* EnumerationId) override; + virtual HRESULT GetDirEnum(_In_ const PRJ_CALLBACK_DATA* CallbackData, + _In_ const GUID* EnumerationId, + _In_opt_ PCWSTR SearchExpression, + _In_ PRJ_DIR_ENTRY_BUFFER_HANDLE DirEntryBufferHandle) override; + virtual HRESULT GetPlaceholderInfo(_In_ const PRJ_CALLBACK_DATA* CallbackData) override; + virtual HRESULT GetFileData(_In_ const PRJ_CALLBACK_DATA* CallbackData, _In_ UINT64 ByteOffset, _In_ UINT32 Length) override; + virtual HRESULT Notify(_In_ const PRJ_CALLBACK_DATA* CallbackData, + _In_ BOOLEAN IsDirectory, + _In_ PRJ_NOTIFICATION NotificationType, + _In_opt_ PCWSTR DestinationFileName, + _Inout_ PRJ_NOTIFICATION_PARAMETERS* NotificationParameters) override; + virtual HRESULT QueryFileName(_In_ const PRJ_CALLBACK_DATA* CallbackData) override; + virtual void CancelCommand(_In_ const PRJ_CALLBACK_DATA* CallbackData) override; + +private: + std::string m_RootPath; + Guid m_RootGuid; + VfsTree* m_Tree = nullptr; + + RwLock m_EnumerationsLock; + std::unordered_map<zen::Guid, EnumerationState> m_ActiveEnumerations; + + Event m_StopRunningEvent; + std::atomic_flag m_IsRunning; + std::atomic_flag m_IsInitialized; +}; + +} // namespace zen + +#endif |