2025-04-04 16:19:32 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
2025-04-08 18:46:57 +02:00
|
|
|
#include "util/File.h"
|
2025-04-04 16:19:32 +02:00
|
|
|
#include <cstddef>
|
|
|
|
|
#include <utility>
|
|
|
|
|
|
2025-04-05 21:50:45 +02:00
|
|
|
class block_dev
|
|
|
|
|
{
|
|
|
|
|
std::size_t m_block_size = 0;
|
|
|
|
|
std::size_t m_block_count = 0;
|
2025-04-04 16:19:32 +02:00
|
|
|
|
|
|
|
|
public:
|
2025-04-05 21:50:45 +02:00
|
|
|
virtual ~block_dev() = default;
|
|
|
|
|
|
|
|
|
|
std::size_t block_size() const
|
|
|
|
|
{
|
|
|
|
|
return m_block_size;
|
|
|
|
|
}
|
|
|
|
|
std::size_t block_count() const
|
|
|
|
|
{
|
|
|
|
|
return m_block_count;
|
|
|
|
|
}
|
|
|
|
|
std::size_t size() const
|
|
|
|
|
{
|
|
|
|
|
return block_size() * block_count();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual std::size_t read(std::size_t blockIndex, void* data,
|
|
|
|
|
std::size_t blockCount) = 0;
|
|
|
|
|
|
|
|
|
|
virtual std::size_t write(std::size_t blockIndex, const void* data,
|
|
|
|
|
std::size_t blockCount) = 0;
|
2025-04-04 16:19:32 +02:00
|
|
|
|
|
|
|
|
protected:
|
2025-04-05 21:50:45 +02:00
|
|
|
void set_block_info(std::size_t size, std::size_t count)
|
|
|
|
|
{
|
|
|
|
|
m_block_size = size;
|
|
|
|
|
m_block_count = count;
|
|
|
|
|
}
|
2025-04-04 16:19:32 +02:00
|
|
|
};
|
|
|
|
|
|
2025-04-05 21:50:45 +02:00
|
|
|
class file_block_dev final : public block_dev
|
|
|
|
|
{
|
|
|
|
|
fs::file m_file;
|
2025-04-04 16:19:32 +02:00
|
|
|
|
|
|
|
|
public:
|
2025-04-05 21:50:45 +02:00
|
|
|
explicit file_block_dev(fs::file file, std::size_t blockSize = 2048)
|
|
|
|
|
: m_file(std::move(file))
|
|
|
|
|
{
|
|
|
|
|
set_block_info(blockSize, m_file.size() / blockSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::size_t read(std::size_t blockIndex, void* data,
|
|
|
|
|
std::size_t blockCount) override
|
|
|
|
|
{
|
|
|
|
|
auto result = m_file.read_at(block_size() * blockIndex, data,
|
|
|
|
|
blockCount * block_size());
|
|
|
|
|
return result / block_size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::size_t write(std::size_t blockIndex, const void* data,
|
|
|
|
|
std::size_t blockCount) override
|
|
|
|
|
{
|
|
|
|
|
auto result = m_file.write_at(block_size() * blockIndex, data,
|
|
|
|
|
blockCount * block_size());
|
|
|
|
|
return result / block_size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fs::file& file()
|
|
|
|
|
{
|
|
|
|
|
return m_file;
|
|
|
|
|
}
|
|
|
|
|
fs::file release()
|
|
|
|
|
{
|
|
|
|
|
return std::exchange(m_file, {});
|
|
|
|
|
}
|
2025-04-04 16:19:32 +02:00
|
|
|
};
|
|
|
|
|
|
2025-04-05 21:50:45 +02:00
|
|
|
class file_view_block_dev final : public block_dev
|
|
|
|
|
{
|
|
|
|
|
const fs::file* m_file;
|
2025-04-04 16:19:32 +02:00
|
|
|
|
|
|
|
|
public:
|
2025-04-05 21:50:45 +02:00
|
|
|
explicit file_view_block_dev(const fs::file& file,
|
|
|
|
|
std::size_t blockSize = 2048)
|
|
|
|
|
: m_file(&file)
|
|
|
|
|
{
|
|
|
|
|
set_block_info(blockSize, m_file->size() / blockSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::size_t read(std::size_t blockIndex, void* data,
|
|
|
|
|
std::size_t blockCount) override
|
|
|
|
|
{
|
|
|
|
|
auto result = m_file->read_at(block_size() * blockIndex, data,
|
|
|
|
|
blockCount * block_size());
|
|
|
|
|
return result / block_size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::size_t write(std::size_t blockIndex, const void* data,
|
|
|
|
|
std::size_t blockCount) override
|
|
|
|
|
{
|
|
|
|
|
auto result = m_file->write_at(block_size() * blockIndex, data,
|
|
|
|
|
blockCount * block_size());
|
|
|
|
|
return result / block_size();
|
|
|
|
|
}
|
2025-04-04 16:19:32 +02:00
|
|
|
};
|