aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/vfs.zig60
1 files changed, 51 insertions, 9 deletions
diff --git a/src/lib/vfs.zig b/src/lib/vfs.zig
index 9dfd443..abc2f8c 100644
--- a/src/lib/vfs.zig
+++ b/src/lib/vfs.zig
@@ -8,6 +8,8 @@ var root = undefined;
pub const Error = error{
NotFound,
+ RelativePathNotAllowed,
+ NotADirectory,
};
// A stream is a resource that provides a shared data stream with a driver.
@@ -19,31 +21,28 @@ pub const File = struct {};
// A hook is a resource that invokes raw driver callbacks when interacted with.
pub const Hook = struct {};
-// A directory is a resource that contains other resources.
-pub const Dir = struct {};
-
// A directory hook is a resource that provides other resources via driver callbacks.
pub const DirHook = struct {};
-pub const InodeData = union(enum) {
+pub const Resource = union(enum) {
stream: Stream,
file: File,
hook: Hook,
- dir: Dir,
+ dir: Tree,
dir_hook: DirHook,
};
pub const Inode = struct {
name: []u8,
- data: InodeData,
+ resource: Resource,
};
+pub const Node = std.DoublyLinkedList(Inode).Node;
+
pub const Tree = struct {
allocator: std.mem.Allocator,
nodes: std.DoublyLinkedList(Inode),
- pub const Node = std.DoublyLinkedList(Inode).Node;
-
pub fn init(allocator: std.mem.Allocator) Tree {
return .{
.allocator = allocator,
@@ -51,6 +50,17 @@ pub const Tree = struct {
};
}
+ pub fn find(self: *const Tree, name: []const u8) ?*Node {
+ var node = self.nodes.first orelse return null;
+ while (node) |current_node| {
+ if (current_node.next == current_node) break;
+
+ if (current_node.data.name == name) return current_node;
+ node = current_node.next;
+ }
+ return null;
+ }
+
pub fn provideResource(self: *Tree, inode: Inode) !void {
var node = try self.allocator.create(Node);
node.data = inode;
@@ -58,7 +68,7 @@ pub const Tree = struct {
}
pub fn remove(self: *Tree, name: []const u8) !void {
- if (self.findByNameExact(name)) |node| {
+ if (self.find(name)) |node| {
self.nodes.remove(node);
} else return NotFound;
}
@@ -67,3 +77,35 @@ pub const Tree = struct {
pub fn init(allocator: std.mem.Allocator) void {
root = Tree.init(allocator);
}
+
+pub fn find(path: []const u8) ?*Node {
+ if (!std.fs.path.isAbsolutePosix(path)) return null;
+
+ var it = std.fs.path.ComponentIterator(.posix, u8).init(path);
+ var tree = root;
+ while (it.next()) |component| {
+ const node = tree.find(component.name) orelse return null;
+
+ if (component == it.last()) return node;
+ if (node.data.resource == .dir) |dir| {
+ tree = dir;
+ }
+ }
+
+ // Only reached if path has no components.
+ return null;
+}
+
+pub fn provideResource(path: []const u8, resource: Resource) !void {
+ if (!std.fs.path.isAbsolutePosix(path)) return Error.RelativePathNotAllowed;
+
+ const dirname = std.fs.path.dirnamePosix(path);
+ if (find(dirname)) |node| {
+ if (node.data.resource == .dir) |dir| {
+ return dir.provideResource(.{
+ .name = std.fs.path.basenamePosix(path),
+ .resource = resource,
+ });
+ } else return Error.NotADirectory;
+ } else return Error.NotFound;
+}