Guest User

Untitled

a guest
Jul 1st, 2023
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.06 KB | Source Code | 0 0
  1. #pragma once
  2.  
  3. #include <filesystem>
  4.  
  5. class ScopedFileLock
  6. {
  7. public:
  8.     ScopedFileLock(ScopedFileLock const&)            = delete;
  9.     ScopedFileLock(ScopedFileLock&&)                 = delete;
  10.     ScopedFileLock& operator=(ScopedFileLock const&) = delete;
  11.     ScopedFileLock& operator=(ScopedFileLock&&)      = delete;
  12.  
  13. protected:
  14.     ScopedFileLock(std::filesystem::path path) : path_(path)
  15.     {
  16.         if (!std::filesystem::exists(path)) {
  17.             throw GenericError { fmt::format("Could not resolve path '{}'",
  18.                                              path.generic_string()) };
  19.         }
  20.  
  21.         handle_ = ::CreateFile(path.generic_string().c_str(),
  22.                                GENERIC_READ,
  23.                                FILE_SHARE_READ,
  24.                                NULL,
  25.                                OPEN_EXISTING,
  26.                                FILE_ATTRIBUTE_NORMAL,
  27.                                NULL);
  28.  
  29.         if (handle_ == INVALID_HANDLE_VALUE) {
  30.             throw GenericError { fmt::format("Failed to open the file at path '{}'",
  31.                                              path.generic_string()) };
  32.         }
  33.  
  34.         if (!::LockFile(handle_, 0, 0, MAXDWORD, MAXDWORD)) {
  35.             ::CloseHandle(handle_);
  36.  
  37.             throw GenericError { fmt::format("Failed to lock the file at path '{}'",
  38.                                              path.generic_string()) };
  39.         }
  40.     }
  41.  
  42.     ~ScopedFileLock()
  43.     {
  44.         ::UnlockFile(handle_, 0, 0, MAXDWORD, MAXDWORD);
  45.         ::CloseHandle(handle_);
  46.     }
  47.  
  48.     std::filesystem::path path_;
  49.  
  50.     HANDLE handle_;
  51. };
  52.  
  53. template<typename ios, typename = std::enable_if_t<std::is_base_of_v<std::ios_base, ios>>>
  54. class ScopedFileIOBase : private ScopedFileLock
  55. {
  56. public:
  57.     std::uintmax_t get_file_size() { return file_size_; }
  58.  
  59. protected:
  60.     ScopedFileIOBase(std::filesystem::path path)
  61.         : ScopedFileLock { path }, stream_ { path, std::ios::binary | std::ios::ate }
  62.     {
  63.         if (!stream_) {
  64.             throw GenericError { fmt::format("Failed to open the file at path '{}'",
  65.                                              path.generic_string()) };
  66.         }
  67.  
  68.         file_size_ = std::filesystem::file_size(path);
  69.     }
  70.  
  71.     ios stream_;
  72.  
  73.     std::uintmax_t file_size_;
  74. };
  75.  
  76. class ScopedFileReader : public ScopedFileIOBase<std::ifstream>
  77. {
  78. public:
  79.     ScopedFileReader(auto path) : ScopedFileIOBase { path } {}
  80.  
  81.     template<typename T>
  82.     void ReadTo(T* dest)
  83.     {
  84.         stream_.read(reinterpret_cast<char*>(dest), file_size_);
  85.     }
  86.  
  87.     ComPtr<ID3DBlob> ReadToBlob()
  88.     {
  89.         ComPtr<ID3DBlob> blob;
  90.  
  91.         D3DCreateBlob(file_size_, blob.GetAddressOf());
  92.  
  93.         stream_.read(reinterpret_cast<char*>(blob->GetBufferPointer()), blob->GetBufferSize());
  94.  
  95.         return blob;
  96.     }
  97. };
  98.  
  99. class ScopedFileWriter : public ScopedFileIOBase<std::ofstream>
  100. {
  101. public:
  102.     ScopedFileWriter(auto path) : ScopedFileIOBase { path, std::ios::binary } {}
  103.  
  104.     void Write(std::string const& src) { stream_.write(src.c_str(), src.size()); }
  105. };
  106.  
Advertisement
Add Comment
Please, Sign In to add comment