| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #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; |
| | }; |
| |
|
| | } |
| |
|