#include "ro_file.h"
#include
#include
#include
#include
#include
#include
#include
#include
namespace {
std::pair 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(p),
static_cast(n));
}
}
ro_file::ro_file(const std::string& name)
: file(name), base(0), length(0)
{
std::pair 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 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 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());
}