Further tweaks & fixes

This commit is contained in:
Caleb Gardner
2025-07-17 09:16:32 -05:00
parent d6b136bc8f
commit 4d52627d5d
3 changed files with 76 additions and 19 deletions
+51 -3
View File
@@ -14,6 +14,7 @@ const MetadataReader = @import("reader/metadata.zig").MetadataReader;
pub const FileError = error{ pub const FileError = error{
NotRegular, NotRegular,
NotDirectory, NotDirectory,
NotFound,
}; };
pub fn File(comptime T: type) type { pub fn File(comptime T: type) type {
@@ -95,8 +96,19 @@ pub fn File(comptime T: type) type {
} }
return out; return out;
} }
pub fn initFromRef(rdr: *SfsReader(T), ref: Inode.Ref, name: []const u8) !Self {
var meta: MetadataReader(T) = .init(rdr.alloc, rdr.super.comp, rdr.rdr, ref.block + rdr.super.inode_start);
try meta.skip(ref.offset);
const inode: Inode = try .init(&meta, rdr.alloc, rdr.super.block_size);
return .init(rdr, inode, name);
}
pub fn initFromEntry(rdr: *SfsReader(T), ent: DirEntry) !Self {
var meta: MetadataReader(T) = .init(rdr.alloc, rdr.super.comp, rdr.rdr, ent.block + rdr.super.inode_start);
try meta.skip(ent.offset);
const inode: Inode = try .init(&meta, rdr.alloc, rdr.super.block_size);
return .init(rdr, inode, ent.name);
}
pub fn deinit(self: Self) void { pub fn deinit(self: Self) void {
self.rdr.alloc.free(self.name);
self.inode.deinit(self.rdr.alloc); self.inode.deinit(self.rdr.alloc);
if (self.entries != null) { if (self.entries != null) {
for (self.entries.?) |e| { for (self.entries.?) |e| {
@@ -109,8 +121,44 @@ pub fn File(comptime T: type) type {
} }
} }
pub fn iter(self: Self) !void { pub fn open(self: Self, path: []const u8) !Self {
_ = self; if (self.entries == null) return FileError.NotDirectory;
if (path.len == 0) return self;
const idx = std.mem.indexOf(u8, path, "/") orelse path.len;
if (idx == 0) return self.open(path[1..]);
const name = path[0..idx];
for (self.entries.?) |e| {
if (std.mem.eql(u8, e.name, name)) {
var fil: Self = try .initFromEntry(self.rdr, e);
if (idx >= path.len - 1) return fil;
defer fil.deinit();
return fil.open(path[idx + 1 ..]);
}
}
return FileError.NotFound;
}
pub fn iterate(self: Self) Iterator {
return .{
.rdr = self.rdr,
.entries = self.entries.?,
};
}
const Iterator = struct {
rdr: *SfsReader(T),
entries: []DirEntry,
idx: u32 = 0,
pub fn next(self: *Iterator) !?File(T) {
if (self.idx >= self.entries.len) return null;
const out = try Self.initFromEntry(self.rdr, self.entries[self.idx]);
self.idx += 1;
return out;
}
pub fn reset(self: *Iterator) void {
self.idx = 0;
} }
}; };
};
} }
+6 -14
View File
@@ -47,22 +47,14 @@ pub fn SfsReader(comptime T: type) type {
self.export_table.deinit(); self.export_table.deinit();
} }
pub fn archiveRoot(self: *Self) !File(T) { pub fn root(self: *Self) !File(T) {
var meta = MetadataReader(T).init( return .initFromRef(self, self.super.root_ref, "");
self.alloc,
self.super.comp,
self.rdr,
self.super.inode_start + self.super.root_ref.block,
);
try meta.skip(self.super.root_ref.offset);
const root_inode: Inode = try .init(&meta, self.alloc, self.super.block_size);
return try .init(self, root_inode, "");
} }
pub fn open(self: *Self, path: []const u8) !File(T) { pub fn open(self: *Self, path: []const u8) !File(T) {
_ = self; var rt = try self.root();
_ = path; if (path.len == 0 or (path.len == 1 and path[0] == '/')) return rt;
// return self.root.?.open(path); defer rt.deinit();
return error{TODO}.TODO; return rt.open(path);
} }
/// Returns the inode with the given Inode Number. /// Returns the inode with the given Inode Number.
+19 -2
View File
@@ -7,12 +7,29 @@ pub const SfsFile = SfsReader(std.fs.File);
const test_file = "testing/LinuxPATest.sfs"; const test_file = "testing/LinuxPATest.sfs";
test "OpenTest" { test "OpenFile" {
const fil = try std.fs.cwd().openFile(test_file, .{}); const fil = try std.fs.cwd().openFile(test_file, .{});
defer fil.close(); defer fil.close();
var rdr: SfsFile = try .init(std.testing.allocator, fil, 0); var rdr: SfsFile = try .init(std.testing.allocator, fil, 0);
defer rdr.deinit(); defer rdr.deinit();
std.debug.print("{}\n", .{rdr.super}); std.debug.print("{}\n", .{rdr.super});
const root = try rdr.archiveRoot(); const root = try rdr.root();
defer root.deinit();
var iter = root.iterate();
while (try iter.next()) |f| {
defer f.deinit();
std.debug.print("{s}\n", .{f.name});
}
const start = try root.open("Start.exe");
defer start.deinit();
}
test "ReadFile" {
const fil = try std.fs.cwd().openFile(test_file, .{});
defer fil.close();
var rdr: SfsFile = try .init(std.testing.allocator, fil, 0);
defer rdr.deinit();
std.debug.print("{}\n", .{rdr.super});
const root = try rdr.root();
defer root.deinit(); defer root.deinit();
} }