#include #include #include #include #include /* A file abstraction that supports both direct load and memory mapping */ File::File(std::string file_path, bool use_mmap): m_path(file_path), m_mmap(use_mmap) { char const *path = file_path.c_str(); int fd = open(path, O_RDONLY); if(!fd) throw std::runtime_error(format("cannot open '%s'", path)); struct stat statbuf; ssize_t x = fstat(fd, &statbuf); if(x < 0) { close(fd); throw std::runtime_error(format("cannot stat '%s'", path)); } m_size = statbuf.st_size; if(use_mmap) { m_addr = (char *)mmap(nullptr, m_size, PROT_READ, MAP_SHARED, fd, 0); close(fd); if(m_addr == (char *)MAP_FAILED) { throw std::runtime_error(format( "cannot map '%s'", path)); } } else { m_addr = new char [m_size]; x = read(fd, m_addr, m_size); close(fd); if(x != statbuf.st_size) { throw std::runtime_error(format( "error while reading '%s'", path)); } } } std::string File::path() const noexcept { return m_path; } size_t File::size() const noexcept { return m_size; } char *File::data() const noexcept { return m_addr; } File::~File() { if(m_mmap) munmap(m_addr, m_size); else delete[] m_addr; }