#include "ro_file.h" #include <algorithm> #include <stdexcept> #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> namespace { std::pair<char*, std::size_t> initialize(const std::string& name) { int fd = open(name.c_str(), O_RDONLY); if (fd == -1) throw std::runtime_error("Can't open " + name + ": " + strerror(errno)); off_t n = lseek(fd, 0, SEEK_END); void* p = MAP_FAILED; if (n != off_t(-1)) p = mmap(0, (std::size_t) n, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); if (p == MAP_FAILED) throw std::runtime_error("Can't map " + name + ": " + strerror(errno)); return std::make_pair(static_cast<char*>(p), static_cast<std::size_t>(n)); } } ro_file::ro_file(const std::string& name) : file(name), base(0), length(0) { std::pair<char*, std::size_t> p = initialize(file); base = p.first; length = p.second; } ro_file::ro_file(const ro_file& C) : file(C.file), base(0), length(0) { std::pair<char*, std::size_t> p = initialize(file); base = p.first; length = p.second; } ro_file& ro_file::operator=(const ro_file& C) { if (C != *this) { std::string tmp = C.file; std::pair<char*, std::size_t> p = initialize(C.file); munmap(base, length); file.swap(tmp); base = p.first; length = p.second; } return *this; } ro_file::~ro_file() { munmap(base, length); } void ro_file::swap(ro_file& C) { std::swap(file, C.file); std::swap(base, C.base); std::swap(length, C.length); } bool operator==(const ro_file& x, const ro_file& y) { return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); } bool operator<(const ro_file& x, const ro_file& y) { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } 1