2#ifndef LIBSBX_FILESYSTEM_MEMORY_FILE_HPP_
3#define LIBSBX_FILESYSTEM_MEMORY_FILE_HPP_
9#include <libsbx/utility/lockable.hpp>
11#include <libsbx/filesystem/file_base.hpp>
12#include <libsbx/filesystem/file_info.hpp>
14namespace sbx::filesystem {
18template<utility::lockable Lockable>
23 using lockable_type = Lockable;
26 : _data{std::make_shared<std::vector<std::uint8_t>>()} {}
40 [[nodiscard]]
auto data()
const -> std::shared_ptr<std::vector<std::uint8_t>> {
41 auto lock = std::scoped_lock{_mutex};
46 [[nodiscard]]
auto writable_data() -> std::shared_ptr<std::vector<std::uint8_t>> {
47 auto lock = std::scoped_lock{_mutex};
49 if (!_data || _data.use_count() == 1) {
53 _data = std::make_shared<std::vector<std::uint8_t>>(*_data);
58 auto reset() ->
void {
59 auto lock = std::scoped_lock{_mutex};
61 _data = std::make_shared<std::vector<std::uint8_t>>();
67 auto other_data = other.data();
69 auto lock = std::scoped_lock{_mutex};
72 _data = std::make_shared<std::vector<std::uint8_t>>();
74 _data = std::make_shared<std::vector<std::uint8_t>>(*other_data);
80 mutable lockable_type _mutex;
81 std::shared_ptr<std::vector<std::uint8_t>> _data;
85template<utility::lockable Lockable>
86using memory_file_object_ptr = std::shared_ptr<memory_file_object<Lockable>>;
90template<utility::lockable Lockable>
95 using lockable_type = Lockable;
98 : _info(std::move(info)),
99 _object(std::move(
object)) {
101 _object = std::make_shared<detail::memory_file_object<lockable_type>>();
111 [[nodiscard]]
auto info()
const ->
const file_info&
override {
112 auto lock = std::scoped_lock{_mutex};
117 [[nodiscard]]
auto size()
const -> std::uint64_t
override {
118 auto lock = std::scoped_lock{_mutex};
124 auto data = _object->data();
126 return data ? data->size() : 0;
129 [[nodiscard]]
auto is_read_only()
const ->
bool override {
130 auto lock = std::scoped_lock{_mutex};
132 return !mode_has_flag(_mode, mode::write);
135 [[nodiscard]]
auto open(
const mode mode) ->
bool override {
136 auto lock = std::scoped_lock{_mutex};
138 if (!is_mode_valid(mode)) {
142 if (_is_open && _mode == mode) {
151 if (mode_has_flag(mode, mode::append)) {
152 auto data = _object->data();
154 _position = data ? data->size() : 0;
157 if (mode_has_flag(mode, mode::truncate)) {
166 auto close() ->
void override {
167 auto lock = std::scoped_lock{_mutex};
174 [[nodiscard]]
auto is_open()
const ->
bool override {
175 auto lock = std::scoped_lock{_mutex};
180 auto seek(std::uint64_t offset, origin origin) -> std::uint64_t
override {
181 auto lock = std::scoped_lock{_mutex};
187 auto data = _object->data();
189 const auto size = data ? data->size() : 0;
192 case origin::begin: {
197 _position = (offset < size) ? size - offset : 0;
206 _position = std::min(_position, size);
211 [[nodiscard]]
auto tell()
const -> std::uint64_t
override {
212 auto lock = std::scoped_lock{_mutex};
217 auto read(std::span<std::uint8_t> buffer) -> std::uint64_t
override {
218 auto lock = std::scoped_lock{_mutex};
220 if (!_is_open || !mode_has_flag(_mode, mode::read)) {
224 auto data = _object->data();
230 if (_position >= data->size()) {
234 const auto to_read = std::min<std::uint64_t>(buffer.size(), data->size() - _position);
240 std::memcpy(buffer.data(), data->data() + _position, to_read);
241 _position += to_read;
246 auto read(std::vector<std::uint8_t>& buffer, std::uint64_t size) -> std::uint64_t
override {
249 return read(std::span<std::uint8_t>(buffer));
252 auto write(std::span<const std::uint8_t> buffer) -> std::uint64_t
override {
253 auto lock = std::scoped_lock{_mutex};
255 if (!_is_open || !mode_has_flag(_mode, mode::write)) {
259 auto data = _object->writable_data();
265 const auto write_size = buffer.size();
267 if (write_size == 0) {
271 if (_position + write_size > data->size()) {
272 data->resize(_position + write_size);
275 std::memcpy(data->data() + _position, buffer.data(), write_size);
277 _position += write_size;
282 auto write(
const std::vector<std::uint8_t>& buffer) -> std::uint64_t
override {
283 return write(std::span<const std::uint8_t>(buffer));
288 mutable lockable_type _mutex;
291 detail::memory_file_object_ptr<lockable_type> _object;
293 bool _is_open{
false};
294 std::uint64_t _position{0};
295 mode _mode{mode::read};
Definition: memory_file.hpp:91
Definition: memory_file.hpp:19
Definition: file_base.hpp:15
Definition: file_info.hpp:10