Zig 0.17.0-dev (Split by item)

Shortcut keys
?
Show these tips
S
Focus search field
Esc
Clear focus & close tips
U
Jump to source code
↑
Move up in search results
↓
Move down in search results
↵
Go to active search result
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 standard library. Public Type Function

Hashed

Public Type Function
std.Io.Writer.Hashed
pub fn Hashed(comptime Hasher: type) type

Provides a Writer implementation based on calling Hasher.update, sending all data also to an underlying Writer.

When using this, the underlying writer is best unbuffered because all writes are passed on directly to it.

This implementation makes suboptimal buffering decisions due to being generic. A better solution will involve creating a writer for each hash function, where the splat buffer can be tailored to the hash implementation details.

Contrast with Hashing which terminates the stream pipeline.

Fields

out: *Writer
hasher: Hasher
writer: Writer

Functions

pub fn init(out: *Writer, buffer: []u8) @This()
pub fn initHasher(out: *Writer, hasher: Hasher, buffer: []u8) @This()
fn drain(w: *Writer, data: []const []const u8, splat: usize) Error!usize

File

Io/Writer.zig:2519
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
pub fn Hashed(comptime Hasher: type) type {
    return struct {
        out: *Writer,
        hasher: Hasher,
        writer: Writer,

        pub fn init(out: *Writer, buffer: []u8) @This() {
            return .initHasher(out, .{}, buffer);
        }

        pub fn initHasher(out: *Writer, hasher: Hasher, buffer: []u8) @This() {
            return .{
                .out = out,
                .hasher = hasher,
                .writer = .{
                    .buffer = buffer,
                    .vtable = &.{ .drain = @This().drain },
                },
            };
        }

        fn drain(w: *Writer, data: []const []const u8, splat: usize) Error!usize {
            const this: *@This() = @alignCast(@fieldParentPtr("writer", w));
            const aux = w.buffered();
            const aux_n = try this.out.writeSplatHeader(aux, data, splat);
            if (aux_n < w.end) {
                this.hasher.update(w.buffer[0..aux_n]);
                const remaining = w.buffer[aux_n..w.end];
                @memmove(w.buffer[0..remaining.len], remaining);
                w.end = remaining.len;
                return 0;
            }
            this.hasher.update(aux);
            const n = aux_n - w.end;
            w.end = 0;
            var remaining: usize = n;
            for (data[0 .. data.len - 1]) |slice| {
                if (remaining <= slice.len) {
                    this.hasher.update(slice[0..remaining]);
                    return n;
                }
                remaining -= slice.len;
                this.hasher.update(slice);
            }
            const pattern = data[data.len - 1];
            assert(remaining <= splat * pattern.len);
            switch (pattern.len) {
                0 => {
                    assert(remaining == 0);
                },
                1 => {
                    var buffer: [64]u8 = undefined;
                    @memset(&buffer, pattern[0]);
                    while (remaining > 0) {
                        const update_len = @min(remaining, buffer.len);
                        this.hasher.update(buffer[0..update_len]);
                        remaining -= update_len;
                    }
                },
                else => {
                    while (remaining > 0) {
                        const update_len = @min(remaining, pattern.len);
                        this.hasher.update(pattern[0..update_len]);
                        remaining -= update_len;
                    }
                },
            }
            return n;
        }
    };
}