convert big endian
This commit is contained in:
parent
ab981ee778
commit
bb38807ed1
121
src/fs.cpp
121
src/fs.cpp
@ -8,8 +8,6 @@
|
||||
|
||||
namespace vc5::filesys {
|
||||
|
||||
using BlockData = std::array<u8, block_size>;
|
||||
|
||||
namespace {
|
||||
|
||||
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) {
|
||||
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)
|
||||
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];
|
||||
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)
|
||||
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) {
|
||||
|
||||
@ -169,18 +167,18 @@ auto Fs::inode_last_block_id(const INode& inode) -> Result<u16>
|
||||
auto first_block_id = inode.blocks[inode_dind_block];
|
||||
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)
|
||||
return std::unexpected(first_ind_block.error());
|
||||
|
||||
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)
|
||||
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 {
|
||||
return std::unexpected("inode at capacity");
|
||||
@ -299,6 +297,95 @@ auto Fs::sync_to_disk() -> Result<void>
|
||||
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>
|
||||
requires(sizeof(Data) <= block_size)
|
||||
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 = {};
|
||||
m_disk->read(block.data(), block_id);
|
||||
|
||||
std::memcpy(block.data(),
|
||||
reinterpret_cast<const uint8_t*>(&data) + offset,
|
||||
sizeof(Data));
|
||||
auto writer = BeWriter(block.data() + offset);
|
||||
data.write(writer);
|
||||
|
||||
m_disk->write(block.data(), block_id);
|
||||
|
||||
return {};
|
||||
@ -340,8 +427,10 @@ auto Fs::read_block(u16 block_id) -> Result<Data>
|
||||
BlockData block = {};
|
||||
m_disk->read(block.data(), block_id);
|
||||
|
||||
auto reader = BeReader(block.data());
|
||||
|
||||
Data data;
|
||||
std::memcpy(reinterpret_cast<uint8_t*>(&data), block.data(), sizeof(Data));
|
||||
data.read(reader);
|
||||
|
||||
return data;
|
||||
}
|
||||
@ -351,8 +440,10 @@ template <typename Data>
|
||||
auto Fs::write_block(const Data& data, u16 block_id) -> Result<void>
|
||||
{
|
||||
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);
|
||||
return {};
|
||||
}
|
||||
|
||||
61
src/fs.hpp
61
src/fs.hpp
@ -3,6 +3,7 @@
|
||||
#include "block_device.hpp"
|
||||
#include "types.hpp"
|
||||
#include <bitset>
|
||||
#include <concepts>
|
||||
#include <cstddef>
|
||||
#include <expected>
|
||||
#include <string_view>
|
||||
@ -20,6 +21,16 @@ struct DirEntry {
|
||||
u16 next;
|
||||
u16 name_len;
|
||||
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;
|
||||
@ -46,6 +57,18 @@ struct INode {
|
||||
u16 last_block_size;
|
||||
u32 size;
|
||||
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);
|
||||
@ -65,12 +88,50 @@ struct Superblock {
|
||||
u16 inode_blocks_count;
|
||||
std::array<u16, iblocks_max_count> iblocks;
|
||||
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);
|
||||
|
||||
struct BlocksBitmap {
|
||||
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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user