aboutsummaryrefslogtreecommitdiff
path: root/src/zenvfs/vfsprovider.h
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2023-09-20 15:22:03 +0200
committerGitHub <[email protected]>2023-09-20 15:22:03 +0200
commit14d7568f9c7d970b7bbf7b6463a0a8530f98bb6f (patch)
treebf24ac15759385cea339f7e1cf5380f984f5699a /src/zenvfs/vfsprovider.h
parentchangelog version bump (diff)
downloadzen-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.h112
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