Guest User

Untitled

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