From 091b5561f3ac32224b48870b6c05c8f143349018 Mon Sep 17 00:00:00 2001 From: Bob Polis Date: Sat, 11 Jul 2020 10:05:35 +0200 Subject: [PATCH] added mapped_file class --- libscio.hpp | 25 ++++++++++++++++++++ mapped_file.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 mapped_file.cpp diff --git a/libscio.hpp b/libscio.hpp index 0d7ecb4..cd630fd 100644 --- a/libscio.hpp +++ b/libscio.hpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace sc { @@ -281,6 +282,30 @@ namespace sc { byte_order _saved_byte_order {byte_order::undefined}; }; + class mapped_file : std::istream { + public: + mapped_file() = default; + mapped_file(const std::string& path); + + mapped_file(const mapped_file&) = delete; + mapped_file& operator=(const mapped_file&) = delete; + + mapped_file(mapped_file&& other); + mapped_file& operator=(mapped_file&& other); + + ~mapped_file(); + + void open(const std::string& path); + + size_t size() const { return _length; } + + private: + int _fd {-1}; + char* _mapping {nullptr}; + size_t _length {0}; + std::stringbuf _membuf; + }; + } } diff --git a/mapped_file.cpp b/mapped_file.cpp new file mode 100644 index 0000000..c724da8 --- /dev/null +++ b/mapped_file.cpp @@ -0,0 +1,62 @@ +// +// mapped_file.cpp +// conceal +// +// Created by Bob Polis at 2020-01-06 +// Copyright (c) 2020 SwiftCoder. All rights reserved. +// + +#include "libscio.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +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; + } +} + +mapped_file::mapped_file(mapped_file&& other) { + _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) { + mapped_file mf {std::move(other)}; + std::swap(mf, *this); + return *this; +} + +void mapped_file::open(const std::string& path) { + _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(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); +}