Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

fileWriteFileStreaming

Dispatch.fileWriteFileStreaming
fn fileWriteFileStreaming(
    userdata: ?*anyopaque,
    file: File,
    header: []const u8,
    file_reader: *File.Reader,
    limit: Io.Limit,
) File.Writer.WriteFileError!usize

File

lib/std/Io/Dispatch.zig:3341

Code

fn fileWriteFileStreaming(
    userdata: ?*anyopaque,
    file: File,
    header: []const u8,
    file_reader: *File.Reader,
    limit: Io.Limit,
) File.Writer.WriteFileError!usize {
    const ev: *Evented = @ptrCast(@alignCast(userdata));
    const reader_buffered = file_reader.interface.buffered();
    if (reader_buffered.len >= @backingInt(limit)) {
        const n = try fileWriteStreaming(ev, file, header, &.{limit.slice(reader_buffered)}, 1);
        file_reader.interface.toss(n -| header.len);
        return n;
    }
    const file_limit = @backingInt(limit) - reader_buffered.len;
    const out_fd = file.handle;
    const in_fd = file_reader.file.handle;

    if (file_reader.size) |size| {
        if (size - file_reader.pos == 0) {
            if (reader_buffered.len != 0) {
                const n = try fileWriteStreaming(ev, file, header, &.{limit.slice(reader_buffered)}, 1);
                file_reader.interface.toss(n -| header.len);
                return n;
            } else {
                return error.EndOfStream;
            }
        }
    }

    if (@atomicLoad(UseSendfile, &ev.use_sendfile, .monotonic) == .disabled) return error.Unimplemented;
    const offset = std.math.cast(c.off_t, file_reader.pos) orelse return error.Unimplemented;
    var hdtr_data: c.sf_hdtr = undefined;
    var headers: [2]iovec_const = undefined;
    var headers_i: u8 = 0;
    if (header.len != 0) {
        headers[headers_i] = .{ .base = header.ptr, .len = header.len };
        headers_i += 1;
    }
    if (reader_buffered.len != 0) {
        headers[headers_i] = .{ .base = reader_buffered.ptr, .len = reader_buffered.len };
        headers_i += 1;
    }
    const hdtr: ?*c.sf_hdtr = if (headers_i == 0) null else b: {
        hdtr_data = .{
            .headers = &headers,
            .hdr_cnt = headers_i,
            .trailers = null,
            .trl_cnt = 0,
        };
        break :b &hdtr_data;
    };
    const max_count = std.math.maxInt(i32); // Avoid EINVAL.
    var len: c.off_t = @min(file_limit, max_count);
    const flags = 0;
    while (true) switch (c.errno(c.sendfile(in_fd, out_fd, offset, &len, hdtr, flags))) {
        .SUCCESS => break,
        .OPNOTSUPP, .NOTSOCK, .NOSYS => {
            // Give calling code chance to observe before trying
            // something else.
            @atomicStore(UseSendfile, &ev.use_sendfile, .disabled, .monotonic);
            return 0;
        },
        .INTR => if (len > 0) break,
        .AGAIN => {
            if (len == 0) return error.WouldBlock;
            break;
        },
        else => |e| {
            assert(error.Unexpected == switch (e) {
                .NOTCONN => return error.BrokenPipe,
                .IO => return error.InputOutput,
                .PIPE => return error.BrokenPipe,
                .BADF => |err| errnoBug(err),
                .FAULT => |err| errnoBug(err),
                .INVAL => |err| errnoBug(err),
                else => |err| unexpectedErrno(err),
            });
            // Give calling code chance to observe the error before trying
            // something else.
            @atomicStore(UseSendfile, &ev.use_sendfile, .disabled, .monotonic);
            return 0;
        },
    };
    if (len == 0) {
        file_reader.size = file_reader.pos;
        return error.EndOfStream;
    }
    const u_len: usize = @bitCast(len);
    file_reader.interface.toss(u_len -| header.len);
    return u_len;
}