| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #pragma once |
|
|
| #if defined(ENV_HAS_POSIX_FILE_STAT) |
| #include "utilities/scalar_guard.hpp" |
| #include <sys/mman.h> |
| #include <fcntl.h> |
| #include <unistd.h> |
| #endif |
|
|
| #if defined(ENV_HAS_WIN_API) |
| #include <Windows.h> |
| #endif |
|
|
| #include <utilities/file.hpp> |
|
|
| namespace utilities { |
|
|
| struct file_mapper { |
| file_mapper() = delete; |
|
|
| explicit file_mapper(const std::string& path) { |
| #if defined(ENV_HAS_POSIX_FILE_STAT) |
|
|
| auto fd_guard = scalar_guard<int>( |
| ::open(path.c_str(), O_RDONLY), |
| [](const int& fd) { if (fd != -1) ::close(fd); } |
| ); |
|
|
| if (-1 == fd_guard.get()) { |
| return; |
| } |
|
|
| auto size = file_size(path); |
| auto map_guard = scalar_guard<void*>( |
| ::mmap(nullptr, size, PROT_READ, MAP_SHARED, fd_guard.get(), 0), |
| [&size](void*& addr) { if (MAP_FAILED != addr && nullptr != addr) ::munmap(addr, size); } |
| ); |
|
|
| if (MAP_FAILED == map_guard.get()) { |
| return; |
| } |
|
|
| this->size_ = size; |
| std::swap(this->fd_, fd_guard.get()); |
| std::swap(this->buffer_, map_guard.get()); |
| #endif |
| } |
|
|
| ~file_mapper() { |
| #if defined(ENV_HAS_POSIX_FILE_STAT) |
| if (nullptr != this->buffer_) { |
| ::munmap(this->buffer_, this->size_); |
| this->buffer_ = nullptr; |
| } |
| if (-1 != this->fd_) { |
| ::close(this->fd_); |
| this->fd_ = -1; |
| } |
| #endif |
| } |
|
|
| [[nodiscard]] void* get() const { |
| return this->buffer_; |
| } |
|
|
| [[nodiscard]] uint64_t size() const { |
| return this->size_; |
| } |
|
|
| private: |
| int fd_ = -1; |
| void* buffer_ = nullptr; |
| uint64_t size_ = 0; |
| }; |
|
|
| } |
|
|