vc5/src/block_device.hpp
2026-01-15 22:06:47 +01:00

73 lines
1.5 KiB
C++

#pragma once
#include <cstdint>
#include <filesystem>
#include <format>
#include <fstream>
#include <ios>
#include <stdexcept>
#include <vector>
namespace vc5 {
namespace fs = std::filesystem;
class BlockDevice {
public:
virtual ~BlockDevice() = default;
static constexpr uint16_t block_size = 512;
virtual auto block_count() -> uint16_t = 0;
virtual void read(uint8_t* data, uint16_t block) = 0;
virtual void write(const uint8_t* data, uint16_t block) = 0;
};
class MemoryDisk final : public BlockDevice {
public:
explicit MemoryDisk(uint16_t block_count)
: m_data(block_size * block_count, 0)
, m_block_count(block_count)
{
}
auto block_count() -> uint16_t override
{
return m_block_count;
}
void read(uint8_t* data, uint16_t block) override;
void write(const uint8_t* data, uint16_t block) override;
auto data() -> uint8_t*
{
return m_data.data();
}
private:
std::vector<uint8_t> m_data;
uint16_t m_block_count;
};
class FileDisk final : public BlockDevice {
public:
explicit FileDisk(fs::path file_path)
: m_file(file_path, std::ios_base::binary)
{
if (not m_file) {
throw std::invalid_argument(std::format(
"unable to open file '{}'", std::string(file_path)));
}
}
auto block_count() -> uint16_t override;
void read(uint8_t* data, uint16_t block) override;
void write(const uint8_t* data, uint16_t block) override;
private:
std::fstream m_file;
};
}