Compare commits

...

2 Commits

Author SHA1 Message Date
bb38807ed1 convert big endian 2026-02-02 19:32:17 +01:00
ab981ee778 remove bytereader/writer 2026-02-02 19:31:54 +01:00
2 changed files with 167 additions and 59 deletions

View File

@ -8,8 +8,6 @@
namespace vc5::filesys { namespace vc5::filesys {
using BlockData = std::array<u8, block_size>;
namespace { namespace {
auto inode_mode(INodeType type) -> u16 auto inode_mode(INodeType type) -> u16
@ -115,7 +113,7 @@ auto Fs::append_to_directory(INode& dir_inode, const DirEntry& entry)
for (u16 i = 0; i < inode_ndir_blocks; ++i) { for (u16 i = 0; i < inode_ndir_blocks; ++i) {
auto dir_entry_block = dir_inode.blocks[i]; auto dir_entry_block = dir_inode.blocks[i];
auto block = read_block<BlockData>(dir_entry_block); auto block = read_block<IntBlock<u16>>(dir_entry_block);
if (not block) if (not block)
return std::unexpected(block.error()); return std::unexpected(block.error());
} }
@ -155,11 +153,11 @@ auto Fs::inode_last_block_id(const INode& inode) -> Result<u16>
auto block_id = inode.blocks[inode_ind_block]; auto block_id = inode.blocks[inode_ind_block];
assert(block_id != 0); assert(block_id != 0);
auto ind_block = read_block<BlockData>(block_id); auto ind_block = read_block<IntBlock<u16>>(block_id);
if (not ind_block) if (not ind_block)
return std::unexpected(ind_block.error()); return std::unexpected(ind_block.error());
return ind_block.value()[inode.blocks_count - inode_ind_block]; return ind_block->data[inode.blocks_count - inode_ind_block];
} else if (inode.blocks_count == inode_dind_block) { } else if (inode.blocks_count == inode_dind_block) {
@ -169,18 +167,18 @@ auto Fs::inode_last_block_id(const INode& inode) -> Result<u16>
auto first_block_id = inode.blocks[inode_dind_block]; auto first_block_id = inode.blocks[inode_dind_block];
assert(first_block_id != 0); assert(first_block_id != 0);
auto first_ind_block = read_block<BlockData>(first_block_id); auto first_ind_block = read_block<IntBlock<u16>>(first_block_id);
if (not first_ind_block) if (not first_ind_block)
return std::unexpected(first_ind_block.error()); return std::unexpected(first_ind_block.error());
auto second_block_id auto second_block_id
= first_ind_block.value()[inode.blocks_count - inode_dind_block]; = first_ind_block->data[inode.blocks_count - inode_dind_block];
auto second_ind_block = read_block<BlockData>(second_block_id); auto second_ind_block = read_block<IntBlock<u16>>(second_block_id);
if (not second_ind_block) if (not second_ind_block)
return std::unexpected(second_ind_block.error()); return std::unexpected(second_ind_block.error());
return second_ind_block.value()[inode.blocks_count - inode_dind_block]; return second_ind_block->data[inode.blocks_count - inode_dind_block];
} else { } else {
return std::unexpected("inode at capacity"); return std::unexpected("inode at capacity");
@ -299,6 +297,95 @@ auto Fs::sync_to_disk() -> Result<void>
return {}; return {};
} }
class BeWriter {
public:
template <typename Data>
BeWriter(Data* data)
: m_data(reinterpret_cast<u8*>(data)) {};
template <typename Int>
requires std::is_integral_v<Int>
auto operator<<(Int v) -> BeWriter&
{
for (std::size_t i = 0; i < sizeof(Int); ++i) {
*m_data = v >> (sizeof(Int) - i - 1) * 8 & 0xff;
m_data++;
}
return *this;
}
template <std::size_t size>
requires(size % 8 == 0)
auto operator<<(const std::bitset<size>& bitmap) -> BeWriter&
{
for (std::size_t bit = 0; bit < bitmap.size(); bit += 8) {
u8 v = 0;
for (std::size_t i = 0; i < 8; ++i)
v |= bitmap[bit + i] << i;
*this << v;
}
return *this;
}
template <typename Elem, std::size_t size>
requires std::is_integral_v<Elem>
auto operator<<(const std::array<Elem, size>& array) -> BeWriter&
{
for (auto elem : array)
*this << elem;
return *this;
}
private:
u8* m_data;
};
class BeReader {
public:
template <typename Data>
BeReader(const Data* data)
: m_data(reinterpret_cast<const u8*>(data)) {};
template <typename Int>
requires std::is_integral_v<Int>
auto operator>>(Int& v) -> BeReader&
{
v = 0;
for (std::size_t i = 0; i < sizeof(Int); ++i) {
v |= *m_data << (sizeof(Int) - i - 1) * 8;
m_data++;
}
return *this;
}
template <std::size_t size>
requires(size % 8 == 0)
auto operator>>(std::bitset<size>& bitmap) -> BeReader&
{
for (std::size_t bit = 0; bit < bitmap.size(); bit += 8) {
u8 v;
*this >> v;
for (std::size_t i = 0; i < 8; ++i)
bitmap[bit + i] = v >> i & 1;
}
return *this;
}
template <typename Elem, std::size_t size>
requires std::is_integral_v<Elem>
auto operator>>(std::array<Elem, size>& array) -> BeReader&
{
for (auto& elem : array)
*this >> elem;
return *this;
}
private:
const u8* m_data;
};
using BlockData = std::array<u8, block_size>;
template <typename Data> template <typename Data>
requires(sizeof(Data) <= block_size) requires(sizeof(Data) <= block_size)
auto Fs::read_block_part(u16 block_id, u16 offset) -> Result<Data> auto Fs::read_block_part(u16 block_id, u16 offset) -> Result<Data>
@ -325,9 +412,9 @@ auto Fs::write_block_part(u16 block_id, const Data& data, u16 offset)
BlockData block = {}; BlockData block = {};
m_disk->read(block.data(), block_id); m_disk->read(block.data(), block_id);
std::memcpy(block.data(), auto writer = BeWriter(block.data() + offset);
reinterpret_cast<const uint8_t*>(&data) + offset, data.write(writer);
sizeof(Data));
m_disk->write(block.data(), block_id); m_disk->write(block.data(), block_id);
return {}; return {};
@ -340,8 +427,10 @@ auto Fs::read_block(u16 block_id) -> Result<Data>
BlockData block = {}; BlockData block = {};
m_disk->read(block.data(), block_id); m_disk->read(block.data(), block_id);
auto reader = BeReader(block.data());
Data data; Data data;
std::memcpy(reinterpret_cast<uint8_t*>(&data), block.data(), sizeof(Data)); data.read(reader);
return data; return data;
} }
@ -351,8 +440,10 @@ template <typename Data>
auto Fs::write_block(const Data& data, u16 block_id) -> Result<void> auto Fs::write_block(const Data& data, u16 block_id) -> Result<void>
{ {
BlockData block = {}; BlockData block = {};
std::memcpy(
block.data(), reinterpret_cast<const uint8_t*>(&data), sizeof(Data)); auto writer = BeWriter(block.data());
data.write(writer);
m_disk->write(block.data(), block_id); m_disk->write(block.data(), block_id);
return {}; return {};
} }

View File

@ -3,6 +3,7 @@
#include "block_device.hpp" #include "block_device.hpp"
#include "types.hpp" #include "types.hpp"
#include <bitset> #include <bitset>
#include <concepts>
#include <cstddef> #include <cstddef>
#include <expected> #include <expected>
#include <string_view> #include <string_view>
@ -20,6 +21,16 @@ struct DirEntry {
u16 next; u16 next;
u16 name_len; u16 name_len;
std::array<char, name_max_len> name; std::array<char, name_max_len> name;
template <typename Writer> void write(Writer& w) const
{
w << inode << next << name_len << name;
}
template <typename Reader> auto read(Reader& r)
{
r >> inode >> next >> name_len >> name;
}
}; };
constexpr u16 inode_size = 32; constexpr u16 inode_size = 32;
@ -46,6 +57,18 @@ struct INode {
u16 last_block_size; u16 last_block_size;
u32 size; u32 size;
std::array<u16, inode_blocks_count> blocks; std::array<u16, inode_blocks_count> blocks;
template <typename Writer> void write(Writer& w) const
{
w << mode << blocks_count << links_count << last_block_size << size
<< blocks;
}
template <typename Reader> auto read(Reader& r)
{
r >> mode >> blocks_count >> links_count >> last_block_size >> size
>> blocks;
}
}; };
static_assert(sizeof(INode) <= inode_size); static_assert(sizeof(INode) <= inode_size);
@ -65,12 +88,50 @@ struct Superblock {
u16 inode_blocks_count; u16 inode_blocks_count;
std::array<u16, iblocks_max_count> iblocks; std::array<u16, iblocks_max_count> iblocks;
std::bitset<inodes_max_count> inode_bitmap; std::bitset<inodes_max_count> inode_bitmap;
template <typename Writer> void write(Writer& w) const
{
w << volume_id << fs_version << blocks_count << blocks_free
<< root_inode << inode_blocks_count << iblocks << inode_bitmap;
}
template <typename Reader> auto read(Reader& r)
{
r >> volume_id >> fs_version >> blocks_count >> blocks_free
>> root_inode >> inode_blocks_count >> iblocks >> inode_bitmap;
}
}; };
static_assert(sizeof(Superblock) <= block_size); static_assert(sizeof(Superblock) <= block_size);
struct BlocksBitmap { struct BlocksBitmap {
std::bitset<blocks_max_count> bitmap; std::bitset<blocks_max_count> bitmap;
template <typename Writer> void write(Writer& w) const
{
w << bitmap;
}
template <typename Reader> auto read(Reader& r)
{
r >> bitmap;
}
};
template <typename Int>
requires std::is_integral_v<Int>
struct IntBlock {
std::array<u16, block_size / sizeof(Int)> data;
template <typename Writer> void write(Writer& w) const
{
w << data;
}
template <typename Reader> auto read(Reader& r)
{
r >> data;
}
}; };
static_assert(sizeof(BlocksBitmap) <= block_size); static_assert(sizeof(BlocksBitmap) <= block_size);
@ -149,48 +210,4 @@ private:
BlocksBitmap m_blocks_bitmap = {}; BlocksBitmap m_blocks_bitmap = {};
}; };
class ByteReader {
public:
template <typename Data>
ByteReader(const Data* data)
: m_data(reinterpret_cast<const u8*>(data)) {};
template <typename Data>
requires std::is_integral_v<Data>
auto operator>>(Data& v) -> ByteReader&
{
v = 0;
for (std::size_t i = 0; i < sizeof(Data); ++i) {
v |= *m_data << (sizeof(Data) - i - 1) * 8;
m_data++;
}
return *this;
}
private:
const u8* m_data;
};
class ByteWriter {
public:
template <typename Data>
ByteWriter(Data* data)
: m_data(reinterpret_cast<u8*>(data)) {};
template <typename Data>
requires std::is_integral_v<Data>
auto operator>>(Data& v) -> ByteWriter&
{
v = 0;
for (std::size_t i = 0; i < sizeof(Data); ++i) {
*m_data = v >> (sizeof(Data) - i - 1) * 8 & 0xff;
m_data++;
}
return *this;
}
private:
u8* m_data;
};
} }