ona/source/oar.cpp

112 lines
2.4 KiB
C++
Executable File

export module oar;
import coral;
import coral.files;
using coral::expected;
using coral::slice;
using coral::u8;
using coral::u64;
using coral::usize;
export namespace oar {
struct entry_path {
enum class parse_error {
};
/**
* Maximum path length.
*/
static usize const max = coral::u8_max;
/**
* Common path component separator.
*/
static char const seperator = '/';
constexpr entry_path() {
this->buffer[max] = max;
}
/**
* Returns a weak reference to the path as a [slice].
*/
constexpr slice<char const> as_slice() const {
return {this->buffer, this->filled()};
}
/**
* Compares the path to `that`, returning the difference between the two paths or `0` if they are identical.
*/
constexpr coral::size compare(entry_path const & that) const {
return coral::compare(this->as_slice().as_bytes(), that.as_slice().as_bytes());
}
/**
* Returns the number of characters composing the path.
*/
constexpr usize filled() const {
return max - this->buffer[max];
}
static constexpr expected<entry_path, parse_error> parse(slice<char const> const & text) {
// TODO: Implement.
return entry_path{};
}
private:
char buffer[max + 1] {0};
};
union entry_block {
struct {
entry_path path;
u64 data_offset;
u64 data_length;
} layout;
u8 bytes[512];
static constexpr bool is_sizeof(usize value) {
return value == sizeof(entry_block);
}
expected<bool, coral::io_error> read(coral::reader & archive_reader) {
return archive_reader.read(this->bytes).map<bool>(is_sizeof);
}
};
/**
* Length of the full magic signature at the beginning of an Oar file.
*/
constexpr usize header_signature_length {4};
/**
* Hardcoded signature magic value that this implementation of Oar expects when reading archives.
*/
constexpr u8 header_signature_magic[header_signature_length] {'o', 'a', 'r', 1};
union header_block {
struct {
u8 signature[header_signature_length];
coral::u32 entry_count;
} layout;
u8 bytes[512];
static constexpr bool is_sizeof(usize value) {
return value == sizeof(header_block);
}
expected<bool, coral::io_error> read(coral::reader & archive_reader) {
return archive_reader.read(this->bytes).map<bool>(is_sizeof).map<bool>([&](bool is_valid) -> bool {
return is_valid && coral::equals(this->layout.signature, header_signature_magic);
});
}
};
}