fxos/lib/util.cpp

77 lines
1.2 KiB
C++

#include <fxos/util.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
/* 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;
}