#ifndef MAPPED_FILE_HPP #define MAPPED_FILE_HPP #include #include #include #include #include #include #include #include /* RAII class for files mapped read-only into memory using mmap */ class MappedFile { public: MappedFile(const char* filename) : error_code(0), name(filename) { fd = open(filename, O_RDONLY); if (fd < 0) { error_code = errno; return; } struct stat buf; if (fstat(fd, &buf) < 0 || !S_ISREG(buf.st_mode)) { error_code = errno; close(fd); fd = -1; return; } len = buf.st_size; addr = mmap(nullptr, len, PROT_READ, MAP_SHARED, fd, 0); if (addr == MAP_FAILED) { error_code = errno; close(fd); fd = -1; return; } } MappedFile(const MappedFile& other) = delete; ~MappedFile() { if (fd >= 0) { munmap(addr, len); close(fd); } } MappedFile& operator=(const MappedFile& other) = delete; /* return true if mapping was successful */ bool valid() const { return fd >= 0; } /* return error number for cases where mapping failed */ unsigned int get_errno() const { return error_code; } /* return the filename which was passed to the constructor */ const std::string& get_filename() const { return name; } /* return the size of the mapped object */ std::size_t get_length() const { assert(fd >= 0); return len; } /* return the start address of the mapped object */ const char* get_addr() const { assert(fd >= 0); return static_cast(addr); } private: unsigned int error_code; const std::string name; int fd; /* mapped object, -1 if invalid */ void* addr; /* start address */ std::size_t len; /* length of the file */ }; #endif