diff --git a/src/oar.zig b/src/oar.zig index 7660c8c..b85304a 100644 --- a/src/oar.zig +++ b/src/oar.zig @@ -7,8 +7,42 @@ const sys = @import("./sys.zig"); /// Typically, following this block in memory is the file data it holds the meta-information for. /// pub const Entry = extern struct { + signature: [3]u8, + revision: u8, name_length: u8, name_buffer: [255]u8 = std.mem.zeroes([255]u8), file_size: u64, - padding: [248]u8, + padding: [244]u8, + + /// + /// Returns `true` if `entry` correctly identifies itself as a valid Oar entry, otherwise + /// `false`. + /// + pub fn isValid(entry: Entry) bool { + return std.mem.eql(u8, &entry.signature, "oar"); + } + + /// + /// Attempts to read an [Entry] from `file_access` at its current cursor position. + /// + /// Returns the read [Entry] value or `null` if the end of file is reached before completing the + /// read. + /// + pub fn read(file_access: *sys.FileAccess) sys.FileAccess.Error!?Entry { + var entry = std.mem.zeroes(Entry); + const origin = try file_access.queryCursor(); + + if ((try file_access.read(std.mem.asBytes(&entry))) != @sizeOf(Entry)) { + try file_access.seek(origin); + + return null; + } + + return entry; + } + + /// + /// Magic identifier used to validate [Entry] data. + /// + const signature_magic = "oar"; }; diff --git a/src/sys.zig b/src/sys.zig index edaf8db..fa7b1a3 100644 --- a/src/sys.zig +++ b/src/sys.zig @@ -459,22 +459,16 @@ pub const FileSystem = union(enum) { const file_access = @ptrCast(*FileAccess, ext.SDL_RWFromFile( &path_buffer, "rb") orelse return error.FileNotFound); - while (true) { - var entry = std.mem.zeroes(oar.Entry); - const entry_buffer = std.mem.asBytes(&entry); + while (oar.Entry.read(file_access) catch return error.FileNotFound) |entry| { + if (!entry.isValid()) break; - if ((file_access.read(entry_buffer) catch return - error.FileNotFound) != entry_buffer.len) return error.FileNotFound; + if (std.mem.eql(u8, entry.name_buffer[0 .. entry.name_length], + path.buffer[0 .. path.length])) return file_access; - if (std.mem.eql(u8, entry.name_buffer[0 .. entry. - name_length], path.buffer[0 .. path.length])) { - - return file_access; - } - - file_access.seek(math.roundUp(u64, entry.file_size, - entry_buffer.len)) catch return error.FileNotFound; + file_access.seek(entry.file_size) catch break; } + + return error.FileNotFound; }, .native => |native| {