Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <filesystem>
- class ScopedFileLock
- {
- public:
- ScopedFileLock(ScopedFileLock const&) = delete;
- ScopedFileLock(ScopedFileLock&&) = delete;
- ScopedFileLock& operator=(ScopedFileLock const&) = delete;
- ScopedFileLock& operator=(ScopedFileLock&&) = delete;
- protected:
- ScopedFileLock(std::filesystem::path path) : path_(path)
- {
- if (!std::filesystem::exists(path)) {
- throw GenericError { fmt::format("Could not resolve path '{}'",
- path.generic_string()) };
- }
- handle_ = ::CreateFile(path.generic_string().c_str(),
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (handle_ == INVALID_HANDLE_VALUE) {
- throw GenericError { fmt::format("Failed to open the file at path '{}'",
- path.generic_string()) };
- }
- if (!::LockFile(handle_, 0, 0, MAXDWORD, MAXDWORD)) {
- ::CloseHandle(handle_);
- throw GenericError { fmt::format("Failed to lock the file at path '{}'",
- path.generic_string()) };
- }
- }
- ~ScopedFileLock()
- {
- ::UnlockFile(handle_, 0, 0, MAXDWORD, MAXDWORD);
- ::CloseHandle(handle_);
- }
- std::filesystem::path path_;
- HANDLE handle_;
- };
- template<typename ios, typename = std::enable_if_t<std::is_base_of_v<std::ios_base, ios>>>
- class ScopedFileIOBase : private ScopedFileLock
- {
- public:
- std::uintmax_t get_file_size() { return file_size_; }
- protected:
- ScopedFileIOBase(std::filesystem::path path)
- : ScopedFileLock { path }, stream_ { path, std::ios::binary | std::ios::ate }
- {
- if (!stream_) {
- throw GenericError { fmt::format("Failed to open the file at path '{}'",
- path.generic_string()) };
- }
- file_size_ = std::filesystem::file_size(path);
- }
- ios stream_;
- std::uintmax_t file_size_;
- };
- class ScopedFileReader : public ScopedFileIOBase<std::ifstream>
- {
- public:
- ScopedFileReader(auto path) : ScopedFileIOBase { path } {}
- template<typename T>
- void ReadTo(T* dest)
- {
- stream_.read(reinterpret_cast<char*>(dest), file_size_);
- }
- ComPtr<ID3DBlob> ReadToBlob()
- {
- ComPtr<ID3DBlob> blob;
- D3DCreateBlob(file_size_, blob.GetAddressOf());
- stream_.read(reinterpret_cast<char*>(blob->GetBufferPointer()), blob->GetBufferSize());
- return blob;
- }
- };
- class ScopedFileWriter : public ScopedFileIOBase<std::ofstream>
- {
- public:
- ScopedFileWriter(auto path) : ScopedFileIOBase { path, std::ios::binary } {}
- void Write(std::string const& src) { stream_.write(src.c_str(), src.size()); }
- };
Advertisement
Add Comment
Please, Sign In to add comment