2023-08-21 21:23:13 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <solanaceae/message3/file.hpp>
|
|
|
|
|
|
|
|
#include "./mio.hpp"
|
|
|
|
|
|
|
|
#include <filesystem>
|
|
|
|
#include <fstream>
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
struct FileRWMapped : public FileI {
|
|
|
|
mio::ummap_sink _file_map;
|
|
|
|
|
|
|
|
// TODO: add truncate support?
|
|
|
|
FileRWMapped(std::string_view file_path, uint64_t file_size) {
|
|
|
|
_file_size = file_size;
|
|
|
|
|
|
|
|
if (!std::filesystem::exists(file_path)) {
|
|
|
|
std::ofstream(std::string{file_path}) << '\0'; // force create the file
|
|
|
|
}
|
|
|
|
std::filesystem::resize_file(file_path, file_size); // ensure size, usually sparse
|
|
|
|
|
|
|
|
std::error_code err;
|
|
|
|
// sink, is also read
|
2023-08-21 21:40:08 +02:00
|
|
|
_file_map.map(std::string{file_path}, 0, file_size, err);
|
2023-08-21 21:23:13 +02:00
|
|
|
|
|
|
|
if (err) {
|
|
|
|
// TODO: errro
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-22 17:20:56 +02:00
|
|
|
virtual ~FileRWMapped(void) override {}
|
2023-08-21 21:23:13 +02:00
|
|
|
|
|
|
|
bool isGood(void) override {
|
|
|
|
return _file_map.is_mapped();
|
|
|
|
}
|
|
|
|
|
2023-08-22 17:20:56 +02:00
|
|
|
std::vector<uint8_t> read(uint64_t pos, uint64_t size) override {
|
2023-08-21 21:23:13 +02:00
|
|
|
if (pos+size > _file_size) {
|
2023-08-22 17:20:56 +02:00
|
|
|
//assert(false && "read past end");
|
2023-08-21 21:23:13 +02:00
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2023-08-22 17:20:56 +02:00
|
|
|
return {_file_map.data()+pos, _file_map.data()+(pos+size)};
|
2023-08-21 21:23:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool write(uint64_t pos, const std::vector<uint8_t>& data) override {
|
|
|
|
if (pos+data.size() > _file_size) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::memcpy(_file_map.data()+pos, data.data(), data.size());
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|