Further tweaks & fixes
This commit is contained in:
+51
-3
@@ -14,6 +14,7 @@ const MetadataReader = @import("reader/metadata.zig").MetadataReader;
|
||||
pub const FileError = error{
|
||||
NotRegular,
|
||||
NotDirectory,
|
||||
NotFound,
|
||||
};
|
||||
|
||||
pub fn File(comptime T: type) type {
|
||||
@@ -95,8 +96,19 @@ pub fn File(comptime T: type) type {
|
||||
}
|
||||
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 {
|
||||
self.rdr.alloc.free(self.name);
|
||||
self.inode.deinit(self.rdr.alloc);
|
||||
if (self.entries != null) {
|
||||
for (self.entries.?) |e| {
|
||||
@@ -109,8 +121,44 @@ pub fn File(comptime T: type) type {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter(self: Self) !void {
|
||||
_ = self;
|
||||
pub fn open(self: Self, path: []const u8) !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
@@ -47,22 +47,14 @@ pub fn SfsReader(comptime T: type) type {
|
||||
self.export_table.deinit();
|
||||
}
|
||||
|
||||
pub fn archiveRoot(self: *Self) !File(T) {
|
||||
var meta = MetadataReader(T).init(
|
||||
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 root(self: *Self) !File(T) {
|
||||
return .initFromRef(self, self.super.root_ref, "");
|
||||
}
|
||||
pub fn open(self: *Self, path: []const u8) !File(T) {
|
||||
_ = self;
|
||||
_ = path;
|
||||
// return self.root.?.open(path);
|
||||
return error{TODO}.TODO;
|
||||
var rt = try self.root();
|
||||
if (path.len == 0 or (path.len == 1 and path[0] == '/')) return rt;
|
||||
defer rt.deinit();
|
||||
return rt.open(path);
|
||||
}
|
||||
|
||||
/// Returns the inode with the given Inode Number.
|
||||
|
||||
+19
-2
@@ -7,12 +7,29 @@ pub const SfsFile = SfsReader(std.fs.File);
|
||||
|
||||
const test_file = "testing/LinuxPATest.sfs";
|
||||
|
||||
test "OpenTest" {
|
||||
test "OpenFile" {
|
||||
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.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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user