diff options
Diffstat (limited to 'src/utils')
-rw-r--r-- | src/utils/cpp/tmp_dir.cpp | 23 | ||||
-rw-r--r-- | src/utils/cpp/tmp_dir.hpp | 37 |
2 files changed, 59 insertions, 1 deletions
diff --git a/src/utils/cpp/tmp_dir.cpp b/src/utils/cpp/tmp_dir.cpp index 88cc0f98..8d6e0724 100644 --- a/src/utils/cpp/tmp_dir.cpp +++ b/src/utils/cpp/tmp_dir.cpp @@ -21,7 +21,6 @@ #endif #include <cstdlib> -#include <string> #include <string_view> #include <tuple> @@ -41,6 +40,28 @@ auto TmpDir::CreateNestedDirectory(TmpDir::Ptr const& parent) noexcept return CreateImpl(parent, parent->GetPath()); } +auto TmpDir::CreateFile(TmpDir::Ptr const& parent, + std::string const& file_name) noexcept -> TmpFile::Ptr { + // Create a new tmp directory to guarantee uniqueness: + auto temp_dir = CreateNestedDirectory(parent); + if (temp_dir == nullptr) { + return nullptr; + } + + try { + auto file_path = std::filesystem::weakly_canonical( + std::filesystem::absolute(temp_dir->GetPath() / file_name)); + if (not FileSystemManager::CreateFile(file_path)) { + return nullptr; + } + + return std::shared_ptr<TmpFile const>{ + new TmpFile(std::move(temp_dir), std::move(file_path))}; + } catch (...) { + return nullptr; + } +} + auto TmpDir::CreateImpl(TmpDir::Ptr parent, std::filesystem::path const& path) noexcept -> Ptr { static constexpr std::string_view kDirTemplate = "tmp.XXXXXX"; diff --git a/src/utils/cpp/tmp_dir.hpp b/src/utils/cpp/tmp_dir.hpp index 28805e3d..4312d97e 100644 --- a/src/utils/cpp/tmp_dir.hpp +++ b/src/utils/cpp/tmp_dir.hpp @@ -17,8 +17,11 @@ #include <filesystem> #include <memory> +#include <string> #include <utility> +class TmpFile; + class TmpDir final { public: using Ptr = std::shared_ptr<TmpDir const>; @@ -43,6 +46,14 @@ class TmpDir final { [[nodiscard]] static auto CreateNestedDirectory( TmpDir::Ptr const& parent) noexcept -> Ptr; + /// \brief Create a new unique temporary file. To guarantee uniqueness, + /// every file gets created in a new temporary directory. This file remains + /// valid even if the parent directory goes out of scope. + [[nodiscard]] static auto CreateFile( + TmpDir::Ptr const& parent, + std::string const& file_name = "file") noexcept + -> std::shared_ptr<TmpFile const>; + private: explicit TmpDir(TmpDir::Ptr parent, std::filesystem::path path) noexcept : parent_{std::move(parent)}, tmp_dir_{std::move(path)} {} @@ -55,4 +66,30 @@ class TmpDir final { std::filesystem::path tmp_dir_; }; +class TmpFile final { + friend class TmpDir; + + public: + using Ptr = std::shared_ptr<TmpFile const>; + + TmpFile(TmpFile const&) = delete; + auto operator=(TmpFile const&) -> TmpFile& = delete; + TmpFile(TmpFile&& other) = delete; + auto operator=(TmpFile&&) -> TmpFile& = delete; + ~TmpFile() noexcept = default; + + [[nodiscard]] auto GetPath() const& noexcept + -> std::filesystem::path const& { + return file_path_; + } + + private: + explicit TmpFile(TmpDir::Ptr parent, + std::filesystem::path file_path) noexcept + : parent_{std::move(parent)}, file_path_{std::move(file_path)} {} + + TmpDir::Ptr parent_; + std::filesystem::path file_path_; +}; + #endif // INCLUDED_SRC_OTHER_TOOLS_TMP_DIR_HPP |