Add file system interfacing to core library

This commit is contained in:
kayomn 2023-02-19 02:02:51 +00:00
parent a58b0d7bdb
commit 51b73aa823
1 changed files with 137 additions and 0 deletions

137
source/core/files.cpp Normal file
View File

@ -0,0 +1,137 @@
export module core.files;
import core;
export namespace core {
/**
* Platform-generalized identifier for a resource in a [file_store].
*/
struct path {
/**
* Maximum path length.
*/
static usize const max = u8_max;
/**
* Common path component separator.
*/
static char const seperator = '/';
constexpr path() : buffer{0} {
this->buffer[max] = max;
}
/**
* Returns the base pointer of the path name.
*/
char const * begin() const {
return reinterpret_cast<char const *>(this->buffer);
}
/**
* Returns the number of bytes composing the path.
*/
constexpr usize byte_size() const {
return max - this->buffer[max];
}
/**
* Compares the path to `that`, returning the difference between the two paths or `0` if
* they are identical.
*/
constexpr size compare(path const & that) const {
return core::compare(slice{this->begin(), this->end()}.as_bytes(),
slice{that.begin(), that.end()}.as_bytes());
}
/**
* Returns the tail pointer of the path name.
*/
char const * end() const {
return reinterpret_cast<char const *>(this->buffer) + this->byte_size();
}
/**
* Tests the path against `that` for equality, returning `true` if they are identical,
* otherwise `false`.
*/
constexpr bool equals(path const & that) const {
return core::equals(slice{this->begin(), this->end()}.as_bytes(),
slice{that.begin(), that.end()}.as_bytes());
}
/**
* Returns the path hash code.
*
* *Note:* the returned hash code is not guaranteed to be unique.
*/
constexpr u64 hash() const {
return core::hash(slice{this->begin(), this->end()}.as_bytes());
}
/**
* Returns a new [path] composed of the current path joined with `text`.
*
* *Note:* should the new path exceed [max] bytes in size, an empty [path] is returned instead.
*/
constexpr path joined(slice<char const> const & text) const {
if (text.length > this->buffer[max]) return path{};
path joined_path = *this;
for (char const c : text) {
joined_path.buffer[joined_path.byte_size()] = c;
joined_path.buffer[max] -= 1;
}
return joined_path;
}
private:
u8 buffer[max + 1];
};
/**
* Platform-generalized file system interface.
*/
struct fs {
/**
* The result from a file access operation.
*
* [file_result::ok] indicates a successful file access operation.
*
* [file_result::not_found] signals that the file was not found.
*
* [file_result::access_denied] warns that the file was found but cannot be opened through
* the file system interface. The most common scenario for this error is a lack of required
* file permissions.
*/
enum class [[nodiscard]] access_result {
ok,
not_found,
access_denied,
};
/**
* Attempts to read the file in the file system located at `file_path` relative, calling
* `then` if it was successfully opened for reading.
*
* The returned [access_result] indicates whether the operation was successful or not.
*
* Once `then` returns, access to the file is closed automatically.
*/
virtual access_result read_file(path const & file_path,
callable<void(readable const &)> const & then) = 0;
/**
* Attempts to write the file in the file system located at `file_path` relative, calling
* `then` if it was successfully opened for writing.
*
* The returned [access_result] indicates whether the operation was successful or not.
*
* Once `then` returns, access to the file is closed automatically.
*/
virtual access_result write_file(path const & file_path,
callable<void(writable const &)> const & then) = 0;
};
}