diff --git a/lib/std/io.zig b/lib/std/io.zig index 2ebf8c3b87..4618db95e4 100644 --- a/lib/std/io.zig +++ b/lib/std/io.zig @@ -568,52 +568,33 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize, comptime OutStreamEr unbuffered_out_stream: *Stream, - buffer: [buffer_size]u8, - index: usize, + const FifoType = std.fifo.LinearFifo(u8, std.fifo.LinearFifoBufferType{ .Static = buffer_size }); + fifo: FifoType, pub fn init(unbuffered_out_stream: *Stream) Self { return Self{ .unbuffered_out_stream = unbuffered_out_stream, - .buffer = undefined, - .index = 0, + .fifo = FifoType.init(), .stream = Stream{ .writeFn = writeFn }, }; } pub fn flush(self: *Self) !void { - try self.unbuffered_out_stream.write(self.buffer[0..self.index]); - self.index = 0; + while (true) { + const slice = self.fifo.readableSlice(0); + if (slice.len == 0) break; + try self.unbuffered_out_stream.write(slice); + self.fifo.discard(slice.len); + } } fn writeFn(out_stream: *Stream, bytes: []const u8) Error!void { const self = @fieldParentPtr(Self, "stream", out_stream); - - if (bytes.len == 1) { - // This is not required logic but a shorter path - // for single byte writes - self.buffer[self.index] = bytes[0]; - self.index += 1; - if (self.index == buffer_size) { - try self.flush(); - } - return; - } else if (bytes.len >= self.buffer.len) { + if (bytes.len >= self.fifo.writableLength()) { try self.flush(); return self.unbuffered_out_stream.write(bytes); } - var src_index: usize = 0; - - while (src_index < bytes.len) { - const dest_space_left = self.buffer.len - self.index; - const copy_amt = math.min(dest_space_left, bytes.len - src_index); - mem.copy(u8, self.buffer[self.index..], bytes[src_index .. src_index + copy_amt]); - self.index += copy_amt; - assert(self.index <= self.buffer.len); - if (self.index == self.buffer.len) { - try self.flush(); - } - src_index += copy_amt; - } + self.fifo.writeAssumeCapacity(bytes); } }; } diff --git a/lib/std/io/test.zig b/lib/std/io/test.zig index 6c194b0f3d..7716e603a0 100644 --- a/lib/std/io/test.zig +++ b/lib/std/io/test.zig @@ -5,6 +5,7 @@ const meta = std.meta; const trait = std.trait; const DefaultPrng = std.rand.DefaultPrng; const expect = std.testing.expect; +const expectEqual = std.testing.expectEqual; const expectError = std.testing.expectError; const mem = std.mem; const fs = std.fs; @@ -44,8 +45,8 @@ test "write a file, read it, then delete it" { defer file.close(); const file_size = try file.getEndPos(); - const expected_file_size = "begin".len + data.len + "end".len; - expect(file_size == expected_file_size); + const expected_file_size: u64 = "begin".len + data.len + "end".len; + expectEqual(expected_file_size, file_size); var file_in_stream = file.inStream(); var buf_stream = io.BufferedInStream(File.ReadError).init(&file_in_stream.stream);