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.

WriterIndirect

A Io.Writer that writes its data to another Io.Writer, and only writes new data to its own buffer during drain.

testing.WriterIndirect
pub const WriterIndirect = struct

File

lib/std/testing.zig:1339

Code

pub const WriterIndirect = struct {
    out: *Io.Writer,
    interface: Io.Writer,

    pub fn init(out: *Io.Writer, buffer: []u8) WriterIndirect {
        return .{
            .out = out,
            .interface = .{
                .vtable = &.{
                    .drain = drain,
                },
                .buffer = buffer,
                .end = 0,
            },
        };
    }

    fn drain(w: *Io.Writer, data: []const []const u8, splat: usize) std.Io.Writer.Error!usize {
        const w_indirect: *WriterIndirect = @alignCast(@fieldParentPtr("interface", w));

        // Write all data in the buffer to `out`
        try w_indirect.out.writeAll(w.buffer[0..w.end]);
        w.end = 0;

        // Refill buffer using data
        {
            const end_before_fill = w.end;
            for (data[0 .. data.len - 1]) |bytes| {
                const dest = w.buffer[w.end..];
                const len = @min(bytes.len, dest.len);
                @memcpy(dest[0..len], bytes[0..len]);
                w.end += len;
            }
            const pattern = data[data.len - 1];
            switch (pattern.len) {
                0 => {},
                1 => {
                    const len = @min(w.buffer[w.end..].len, splat);
                    @memset(w.buffer[w.end..][0..len], pattern[0]);
                    w.end += len;
                },
                else => {
                    const dest = w.buffer[w.end..];
                    for (0..splat) |i| {
                        const start_i = i * pattern.len;
                        if (start_i >= dest.len) break;
                        const remaining = dest[start_i..];
                        const len = @min(pattern.len, remaining.len);
                        @memcpy(remaining[0..len], pattern[0..len]);
                        w.end += len;
                    }
                },
            }

            return w.end - end_before_fill;
        }
    }
}