#include #include #include #include #include #include "common.hh" #include "util.hh" MmapFile::MmapFile(std::string fileName) : name_(std::move(fileName)), fd_(fopen(name_.c_str(), "rb")), size_(0), base_(nullptr) { if (!fd_) throw POSIXException{errno, "Could not open "s + name_}; struct stat statBuf; if (fstat(fileno(fd_.get()), &statBuf) != 0) throw POSIXException(errno, "Could not stat"); if (statBuf.st_size <= 0) throw Exception{"File size is zero or less"}; size_ = static_cast(statBuf.st_size); base_ = mmap(nullptr, size_, PROT_READ, MAP_SHARED, fileno(fd_.get()), 0); if (!base_) throw POSIXException(errno, "mmap failed"); } MmapFile::MmapFile(MmapFile && move): name_(std::move(move.name_)), fd_(std::move(move.fd_)), size_(move.size_), base_(move.base_) { move.base_ = nullptr; } MmapFile::~MmapFile() { if (base_) { if (munmap(base_, size_) != 0) fprintf(stderr, "Warning: munmap failed: %s\n", strerror(errno)); base_ = nullptr; } } MmapFile& MmapFile::operator=(MmapFile && move) { fd_ = std::move(move.fd_); if (base_) if (munmap(base_, size_) != 0) fprintf(stderr, "Warning: munmap failed: %s\n", strerror(errno)); base_ = move.base_; move.base_ = nullptr; size_ = move.size_; name_ = std::move(move.name_); return *this; } std::string const& MmapFile::name() const { if (!*this) throw std::logic_error("name() called on invalid MmapFile"); return name_; } size_t MmapFile::size() const { if (!*this) throw std::logic_error("size() called on invalid MmapFile"); return size_; } char const* MmapFile::data() const { if (!*this) throw std::logic_error("data() called on invalid MmapFile"); return static_cast(base_); } MmapFile::operator bool() const { return base_; }