Function findFile [src]
Prototype
pub fn findFile(fr: *File.Reader) FindFileError!EndRecord Parameters
fr: *File.Reader Possible Errors
In WASI, this error may occur when the file descriptor does not hold the required rights to get its filestat information.
reading a timerfd with CANCEL_ON_SET will lead to this error when the clock goes through a discontinuous change
Unable to read file due to lock.
This error occurs in Linux if the process to be read from no longer exists.
Occurs if, for example, the file handle is a network socket and therefore does not have a size.
The Operating System returned an undocumented error code.
This error is in theory not possible, but it would be better to handle this error than to invoke undefined behavior.
When this error code is observed, it usually means the Zig Standard Library needs a small patch to add the error code to the error set for the respective function.
This error occurs when no global event loop is configured, and reading from the file descriptor would block.
Source
pub fn findFile(fr: *File.Reader) FindFileError!EndRecord {
const end_pos = try fr.getSize();
var buf: [@sizeOf(EndRecord) + std.math.maxInt(u16)]u8 = undefined;
const record_len_max = @min(end_pos, buf.len);
var loaded_len: u32 = 0;
var comment_len: u16 = 0;
while (true) {
const record_len: u32 = @as(u32, comment_len) + @sizeOf(EndRecord);
if (record_len > record_len_max)
return error.ZipNoEndRecord;
if (record_len > loaded_len) {
const new_loaded_len = @min(loaded_len + 300, record_len_max);
const read_len = new_loaded_len - loaded_len;
try fr.seekTo(end_pos - @as(u64, new_loaded_len));
const read_buf: []u8 = buf[buf.len - new_loaded_len ..][0..read_len];
fr.interface.readSliceAll(read_buf) catch |err| switch (err) {
error.ReadFailed => return fr.err.?,
error.EndOfStream => return error.EndOfStream,
};
loaded_len = new_loaded_len;
}
const record_bytes = buf[buf.len - record_len ..][0..@sizeOf(EndRecord)];
if (std.mem.eql(u8, record_bytes[0..4], &end_record_sig) and
std.mem.readInt(u16, record_bytes[20..22], .little) == comment_len)
{
const record: *align(1) EndRecord = @ptrCast(record_bytes.ptr);
if (!is_le) std.mem.byteSwapAllFields(EndRecord, record);
return record.*;
}
if (comment_len == std.math.maxInt(u16))
return error.ZipNoEndRecord;
comment_len += 1;
}
}