Application Context Implementation #4
36
src/oar.zig
36
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.
|
/// Typically, following this block in memory is the file data it holds the meta-information for.
|
||||||
///
|
///
|
||||||
pub const Entry = extern struct {
|
pub const Entry = extern struct {
|
||||||
|
signature: [3]u8,
|
||||||
|
revision: u8,
|
||||||
name_length: u8,
|
name_length: u8,
|
||||||
name_buffer: [255]u8 = std.mem.zeroes([255]u8),
|
name_buffer: [255]u8 = std.mem.zeroes([255]u8),
|
||||||
file_size: u64,
|
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";
|
||||||
};
|
};
|
||||||
|
|
18
src/sys.zig
18
src/sys.zig
|
@ -459,22 +459,16 @@ pub const FileSystem = union(enum) {
|
||||||
const file_access = @ptrCast(*FileAccess, ext.SDL_RWFromFile(
|
const file_access = @ptrCast(*FileAccess, ext.SDL_RWFromFile(
|
||||||
&path_buffer, "rb") orelse return error.FileNotFound);
|
&path_buffer, "rb") orelse return error.FileNotFound);
|
||||||
|
|
||||||
while (true) {
|
while (oar.Entry.read(file_access) catch return error.FileNotFound) |entry| {
|
||||||
var entry = std.mem.zeroes(oar.Entry);
|
if (!entry.isValid()) break;
|
||||||
const entry_buffer = std.mem.asBytes(&entry);
|
|
||||||
|
|
||||||
if ((file_access.read(entry_buffer) catch return
|
if (std.mem.eql(u8, entry.name_buffer[0 .. entry.name_length],
|
||||||
error.FileNotFound) != entry_buffer.len) return error.FileNotFound;
|
path.buffer[0 .. path.length])) return file_access;
|
||||||
|
|
||||||
if (std.mem.eql(u8, entry.name_buffer[0 .. entry.
|
file_access.seek(entry.file_size) catch break;
|
||||||
name_length], path.buffer[0 .. path.length])) {
|
|
||||||
|
|
||||||
return file_access;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file_access.seek(math.roundUp(u64, entry.file_size,
|
return error.FileNotFound;
|
||||||
entry_buffer.len)) catch return error.FileNotFound;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
.native => |native| {
|
.native => |native| {
|
||||||
|
|
Loading…
Reference in New Issue