libscio/mapped_file.cpp

70 lines
1.7 KiB
C++
Raw Normal View History

2020-07-11 10:05:35 +02:00
//
// mapped_file.cpp
// conceal
//
// Created by Bob Polis at 2020-01-06
// Copyright (c) 2020 SwiftCoder. All rights reserved.
//
#include "libscio.hpp"
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <utility>
#include <stdexcept>
#include <algorithm>
#include <libscerror.hpp>
2020-07-11 10:06:28 +02:00
using namespace sc::io;
2020-07-11 12:41:20 +02:00
mapped_file::mapped_file() : std::istream {&_membuf} {}
2020-07-11 10:05:35 +02:00
mapped_file::mapped_file(const std::string& path) : std::istream {&_membuf} {
open(path);
}
mapped_file::~mapped_file() {
if (_mapping) {
munmap(_mapping, _length);
_mapping = nullptr;
_length = 0;
}
if (_fd != -1) {
close(_fd);
_fd = -1;
}
}
2020-07-11 15:47:46 +02:00
mapped_file::mapped_file(mapped_file&& other) : std::istream {std::move(other)} {
2020-07-11 10:05:35 +02:00
_fd = other._fd;
_mapping = other._mapping;
_length = other._length;
_membuf = std::move(other._membuf);
other._fd = -1;
other._mapping = nullptr;
other._length = 0;
other._membuf.pubsetbuf(nullptr, 0);
}
mapped_file& mapped_file::operator=(mapped_file &&other) {
2020-07-11 12:41:20 +02:00
if (&other != this) {
mapped_file mf {std::move(other)};
std::swap(mf, *this);
}
2020-07-11 10:05:35 +02:00
return *this;
}
void mapped_file::open(const std::string& path) {
2020-07-11 12:41:20 +02:00
if (_fd != -1) throw std::runtime_error("already open");
2020-07-11 10:05:35 +02:00
_fd = ::open(path.c_str(), O_RDONLY);
throw_if_min1_msg(_fd, "could not open file");
struct stat st;
throw_if_min1_msg(fstat(_fd, &st), "could not stat file");
_length = st.st_size;
_mapping = reinterpret_cast<char*>(mmap(nullptr, _length, PROT_READ, MAP_PRIVATE, _fd, 0));
if (_mapping == MAP_FAILED) throw std::runtime_error("could not map file");
_membuf.pubsetbuf(_mapping, _length);
}