diff --git a/lib/std/Progress.zig b/lib/std/Progress.zig index 963e1b2869..cc94b1920e 100644 --- a/lib/std/Progress.zig +++ b/lib/std/Progress.zig @@ -608,12 +608,10 @@ pub fn unlockStdErr() void { } /// Protected by `stderr_mutex`. -var stderr_buffered_writer: Writer = .{ - .unbuffered_writer = stderr_file_writer.interface(), - .buffer = &.{}, -}; +const stderr_writer: *Writer = &stderr_file_writer.interface; /// Protected by `stderr_mutex`. var stderr_file_writer: std.fs.File.Writer = .{ + .interface = std.fs.File.Writer.init_interface(&.{}), .file = if (is_windows) undefined else .stderr(), .mode = .streaming, }; @@ -628,14 +626,14 @@ pub fn lockStderrWriter(buffer: []u8) *Writer { stderr_mutex.lock(); clearWrittenWithEscapeCodes() catch {}; if (is_windows) stderr_file_writer.file = .stderr(); - stderr_buffered_writer.flush() catch {}; - stderr_buffered_writer.buffer = buffer; - return &stderr_buffered_writer; + stderr_writer.flush() catch {}; + stderr_writer.buffer = buffer; + return &stderr_writer; } pub fn unlockStderrWriter() void { - stderr_buffered_writer.flush() catch {}; - stderr_buffered_writer.buffer = &.{}; + stderr_writer.flush() catch {}; + stderr_writer.buffer = &.{}; stderr_mutex.unlock(); } diff --git a/lib/std/crypto/phc_encoding.zig b/lib/std/crypto/phc_encoding.zig index ccf7831550..8551e065cd 100644 --- a/lib/std/crypto/phc_encoding.zig +++ b/lib/std/crypto/phc_encoding.zig @@ -197,12 +197,9 @@ pub fn serialize(params: anytype, str: []u8) Error![]const u8 { /// Compute the number of bytes required to serialize `params` pub fn calcSize(params: anytype) usize { var trash: [128]u8 = undefined; - var bw: Writer = .{ - .unbuffered_writer = .discarding, - .buffer = &trash, - }; - serializeTo(params, &bw) catch unreachable; - return bw.count; + var w: Writer = .discarding(&trash); + serializeTo(params, &w) catch unreachable; + return w.count; } fn serializeTo(params: anytype, out: *Writer) !void { diff --git a/lib/std/crypto/sha2.zig b/lib/std/crypto/sha2.zig index 4ea2714973..8e74fe7899 100644 --- a/lib/std/crypto/sha2.zig +++ b/lib/std/crypto/sha2.zig @@ -383,22 +383,19 @@ fn Sha2x32(comptime iv: Iv32, digest_bits: comptime_int) type { for (&d.s, v) |*dv, vv| dv.* +%= vv; } - pub fn writable(this: *@This(), buffer: []u8) Writer { + pub fn writer(this: *@This(), buffer: []u8) Writer { return .{ - .unbuffered_writer = .{ - .context = this, - .vtable = &.{ - .writeSplat = writeSplat, - .writeFile = Writer.unimplementedWriteFile, - }, - }, + .context = this, + .vtable = &.{ .drain = drain }, .buffer = buffer, }; } - fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) Writer.Error!usize { - const this: *@This() = @ptrCast(@alignCast(context)); + fn drain(w: *Writer, data: []const []const u8, splat: usize) Writer.Error!usize { + const this: *@This() = @ptrCast(@alignCast(w.context)); const start_total = this.total_len; + this.update(w.buffered()); + w.end = 0; for (data[0 .. data.len - 1]) |slice| this.update(slice); for (0..splat) |_| this.update(data[data.len - 1]); return @intCast(this.total_len - start_total); diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index 6e6e710f1f..b731ea87ad 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -845,14 +845,11 @@ pub fn bufPrintZ(buf: []u8, comptime fmt: []const u8, args: anytype) BufPrintErr /// Count the characters needed for format. pub fn count(comptime fmt: []const u8, args: anytype) usize { var trash_buffer: [64]u8 = undefined; - var bw: Writer = .{ - .unbuffered_writer = .discarding, - .buffer = &trash_buffer, - }; - bw.print(fmt, args) catch |err| switch (err) { + var w: Writer = .discarding(&trash_buffer); + w.print(fmt, args) catch |err| switch (err) { error.WriteFailed => unreachable, }; - return bw.count; + return w.count; } pub fn allocPrint(gpa: Allocator, comptime fmt: []const u8, args: anytype) Allocator.Error![]u8 { diff --git a/lib/std/io/Writer.zig b/lib/std/io/Writer.zig index d2d890802a..7e06119aba 100644 --- a/lib/std/io/Writer.zig +++ b/lib/std/io/Writer.zig @@ -155,11 +155,7 @@ pub fn writeSplat(w: *Writer, data: []const []const u8, splat: usize) Error!usiz assert(data.len > 0); const buffer = w.buffer; const count = countSplat(0, data, splat); - if (w.end + count > buffer.len) { - const end = w.end; - const n = try w.vtable.drain(w, data, splat); - return n -| end; - } + if (w.end + count > buffer.len) return w.vtable.drain(w, data, splat); w.count += count; for (data) |bytes| { @memcpy(buffer[w.end..][0..bytes.len], bytes); @@ -168,7 +164,6 @@ pub fn writeSplat(w: *Writer, data: []const []const u8, splat: usize) Error!usiz const pattern = data[data.len - 1]; if (splat == 0) { @branchHint(.unlikely); - // It was added in the loop above; undo it here. w.end -= pattern.len; return count; } @@ -245,24 +240,14 @@ pub fn writableSlice(w: *Writer, len: usize) Error![]u8 { /// If `minimum_length` is zero, this is equivalent to `unusedCapacitySlice`. pub fn writableSliceGreedy(w: *Writer, minimum_length: usize) Error![]u8 { assert(w.buffer.len >= minimum_length); - const cap_slice = w.buffer[w.end..]; - if (cap_slice.len >= minimum_length) { - @branchHint(.likely); - return cap_slice; + while (true) { + const cap_slice = w.buffer[w.end..]; + if (cap_slice.len >= minimum_length) { + @branchHint(.likely); + return cap_slice; + } + assert(0 == try w.vtable.drain(w, &.{""}, 1)); } - const buffer = w.buffer[0..w.end]; - const n = try w.unbuffered_writer.writeVec(&.{buffer}); - if (n == buffer.len) { - @branchHint(.likely); - w.end = 0; - return w.buffer; - } - if (n > 0) { - const remainder = buffer[n..]; - std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); - w.end = remainder.len; - } - return w.buffer[w.end..]; } pub fn ensureUnusedCapacity(w: *Writer, n: usize) Error!void { @@ -358,39 +343,17 @@ pub fn print(w: *Writer, comptime format: []const u8, args: anytype) Error!void } pub fn writeByte(w: *Writer, byte: u8) Error!void { - const buffer = w.buffer[0..w.end]; - if (buffer.len < w.buffer.len) { + while (w.buffer.len - w.end == 0) { + const n = try w.vtable.drain(w, &.{&.{byte}}, 1); + if (n > 0) { + w.count += 1; + return; + } + } else { @branchHint(.likely); - buffer.ptr[buffer.len] = byte; - w.end = buffer.len + 1; + w.buffer[w.end] = byte; + w.end += 1; w.count += 1; - return; - } - var buffers: [2][]const u8 = .{ buffer, &.{byte} }; - while (true) { - const n = try w.unbuffered_writer.writeVec(&buffers); - if (n == 0) { - @branchHint(.unlikely); - continue; - } - w.count += 1; - if (n >= buffer.len) { - @branchHint(.likely); - if (n > buffer.len) { - @branchHint(.likely); - w.end = 0; - return; - } else { - buffer[0] = byte; - w.end = 1; - return; - } - } - const remainder = buffer[n..]; - std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); - buffer[remainder.len] = byte; - w.end = remainder.len + 1; - return; } } diff --git a/lib/std/zon/stringify.zig b/lib/std/zon/stringify.zig index e5d964826b..d1cfea266d 100644 --- a/lib/std/zon/stringify.zig +++ b/lib/std/zon/stringify.zig @@ -1040,11 +1040,8 @@ pub const Serializer = struct { }; test Serializer { - var bw: Writer = .{ - .unbuffered_writer = .discarding, - .buffer = &.{}, - }; - var s: Serializer = .{ .writer = &bw }; + var w: Writer = .discarding(&.{}); + var s: Serializer = .{ .writer = &w }; var vec2 = try s.beginStruct(.{}); try vec2.field("x", 1.5, .{}); try vec2.fieldPrefix("prefix");