#pragma once #include #include namespace ts::server::file { namespace filesystem { #ifdef FS_INCLUDED namespace fs = std::experimental::filesystem; #endif class LocalFileSystem : public filesystem::AbstractProvider { using FileModifyError = filesystem::FileModifyError; using DirectoryModifyError = filesystem::DirectoryModifyError; public: virtual ~LocalFileSystem(); bool initialize(std::string & /* error */, const std::string & /* root path */); void finalize(); void lock_file(const std::string& /* path */); void unlock_file(const std::string& /* path */); [[nodiscard]] inline const auto &root_path() const { return this->root_path_; } std::shared_ptr> initialize_server(ServerId /* server */) override; std::shared_ptr> delete_server(ServerId /* server */) override; std::shared_ptr query_channel_directory(ServerId id, ChannelId channelId, const std::string &string) override; std::shared_ptr> create_channel_directory(ServerId id, ChannelId channelId, const std::string &string) override; std::shared_ptr> delete_channel_file(ServerId id, ChannelId channelId, const std::string &string) override; std::shared_ptr> rename_channel_file(ServerId id, ChannelId channelId, const std::string &, const std::string &) override; std::shared_ptr query_icon_directory(ServerId id) override; std::shared_ptr> delete_icon(ServerId id, const std::string &string) override; std::shared_ptr query_avatar_directory(ServerId id) override; std::shared_ptr> delete_avatar(ServerId id, const std::string &string) override; private: #ifdef FS_INCLUDED [[nodiscard]] fs::path server_path(ServerId); [[nodiscard]] fs::path server_channel_path(ServerId, ChannelId); [[nodiscard]] static bool exceeds_base_path(const fs::path& /* base */, const fs::path& /* target */); [[nodiscard]] bool is_any_file_locked(const fs::path& /* base */, const std::string& /* path */, std::string& /* file (relative to the base) */); [[nodiscard]] std::shared_ptr> delete_file(const fs::path& /* base */, const std::string &string); [[nodiscard]] std::shared_ptr query_directory(const fs::path& /* base */, const std::string &string, bool); #endif template std::shared_ptr> create_execute_response() { return std::make_shared>(this->result_notify_mutex, this->result_notify_cv); } std::mutex result_notify_mutex{}; std::condition_variable result_notify_cv{}; std::string root_path_{}; std::mutex locked_files_mutex{}; std::deque locked_files_{}; }; } class LocalFileServer : public AbstractFileServer { public: virtual ~LocalFileServer(); [[nodiscard]] bool initialize(std::string& /* error */); void finalize(); filesystem::AbstractProvider &file_system() override; private: filesystem::LocalFileSystem file_system_{}; }; }