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{
|
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
@@ -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
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user