d6b136bc8f
Fixed various bugs
71 lines
2.1 KiB
Zig
71 lines
2.1 KiB
Zig
const std = @import("std");
|
|
|
|
const InodeType = @import("inode.zig").Type;
|
|
const Compression = @import("superblock.zig").Compression;
|
|
|
|
const Header = extern struct { //use extern instead of packed, due to bit alignment
|
|
count: u32,
|
|
block: u32,
|
|
num: u32,
|
|
};
|
|
|
|
const RawEntry = struct {
|
|
offset: u16,
|
|
num_offset: i16,
|
|
type: InodeType,
|
|
size: u16,
|
|
name: []const u8,
|
|
|
|
pub fn init(alloc: std.mem.Allocator, rdr: anytype) !RawEntry {
|
|
var fixed: [8]u8 = undefined;
|
|
_ = try rdr.read(&fixed);
|
|
const size = std.mem.readInt(u16, fixed[6..8], .little);
|
|
const name = try alloc.alloc(u8, size + 1);
|
|
_ = try rdr.read(name);
|
|
return .{
|
|
.offset = std.mem.readInt(u16, fixed[0..2], .little),
|
|
.num_offset = std.mem.readInt(i16, fixed[2..4], .little),
|
|
.type = @enumFromInt(std.mem.readInt(u16, fixed[4..6], .little)),
|
|
.size = size,
|
|
.name = name,
|
|
};
|
|
}
|
|
};
|
|
|
|
pub const Entry = struct {
|
|
block: u32,
|
|
offset: u16,
|
|
num: u32,
|
|
type: InodeType,
|
|
name: []const u8,
|
|
|
|
pub fn deinit(self: Entry, alloc: std.mem.Allocator) void {
|
|
alloc.free(self.name);
|
|
}
|
|
};
|
|
|
|
pub fn readDirectory(alloc: std.mem.Allocator, rdr: anytype, size: u32) ![]Entry {
|
|
var entries: std.ArrayList(Entry) = .init(alloc);
|
|
errdefer entries.deinit();
|
|
var cur_red: u32 = 3; // dir size includes "." & "..", so its actual size is off by 3.
|
|
var hdr: Header = undefined;
|
|
while (cur_red < size) {
|
|
_ = try rdr.read(std.mem.asBytes(&hdr));
|
|
cur_red += 12;
|
|
try entries.ensureUnusedCapacity(hdr.count + 1);
|
|
for (0..hdr.count + 1) |_| {
|
|
const raw_ent: RawEntry = try .init(alloc, rdr);
|
|
cur_red += 9 + raw_ent.size;
|
|
errdefer alloc.free(raw_ent.name);
|
|
entries.appendAssumeCapacity(.{
|
|
.block = hdr.block,
|
|
.offset = raw_ent.offset,
|
|
.num = @truncate(@abs(@as(i64, hdr.num) + raw_ent.num_offset)),
|
|
.type = raw_ent.type,
|
|
.name = raw_ent.name,
|
|
});
|
|
}
|
|
}
|
|
return entries.toOwnedSlice();
|
|
}
|