| ... | @@ -1,24 +1,22 @@ | ... | @@ -1,24 +1,22 @@ |
| 1 | const std = @import("../std.zig"); | 1 | const std = @import("../std.zig"); |
| | 2 | |
| 2 | const io = std.io; | 3 | const io = std.io; |
| | 4 | const mem = std.mem; |
| 3 | | 5 | |
| 4 | pub fn BufferedWriter(comptime buffer_size: usize, comptime WriterType: type) type { | 6 | pub fn BufferedWriter(comptime buffer_size: usize, comptime WriterType: type) type { |
| 5 | return struct { | 7 | return struct { |
| 6 | unbuffered_writer: WriterType, | 8 | unbuffered_writer: WriterType, |
| 7 | fifo: FifoType = FifoType.init(), | 9 | buf: [buffer_size]u8 = undefined, |
| | 10 | end: usize = 0, |
| 8 | | 11 | |
| 9 | pub const Error = WriterType.Error; | 12 | pub const Error = WriterType.Error; |
| 10 | pub const Writer = io.Writer(*Self, Error, write); | 13 | pub const Writer = io.Writer(*Self, Error, write); |
| 11 | | 14 | |
| 12 | const Self = @This(); | 15 | const Self = @This(); |
| 13 | const FifoType = std.fifo.LinearFifo(u8, std.fifo.LinearFifoBufferType{ .Static = buffer_size }); | | |
| 14 | | 16 | |
| 15 | pub fn flush(self: *Self) !void { | 17 | pub fn flush(self: *Self) !void { |
| 16 | while (true) { | 18 | try self.unbuffered_writer.writeAll(self.buf[0..self.end]); |
| 17 | const slice = self.fifo.readableSlice(0); | 19 | self.end = 0; |
| 18 | if (slice.len == 0) break; | | |
| 19 | try self.unbuffered_writer.writeAll(slice); | | |
| 20 | self.fifo.discard(slice.len); | | |
| 21 | } | | |
| 22 | } | 20 | } |
| 23 | | 21 | |
| 24 | pub fn writer(self: *Self) Writer { | 22 | pub fn writer(self: *Self) Writer { |
| ... | @@ -26,11 +24,14 @@ pub fn BufferedWriter(comptime buffer_size: usize, comptime WriterType: type) ty | ... | @@ -26,11 +24,14 @@ pub fn BufferedWriter(comptime buffer_size: usize, comptime WriterType: type) ty |
| 26 | } | 24 | } |
| 27 | | 25 | |
| 28 | pub fn write(self: *Self, bytes: []const u8) Error!usize { | 26 | pub fn write(self: *Self, bytes: []const u8) Error!usize { |
| 29 | if (bytes.len >= self.fifo.writableLength()) { | 27 | if (self.end + bytes.len > self.buf.len) { |
| 30 | try self.flush(); | 28 | try self.flush(); |
| 31 | return self.unbuffered_writer.write(bytes); | 29 | if (bytes.len > self.buf.len) |
| | 30 | return self.unbuffered_writer.write(bytes); |
| 32 | } | 31 | } |
| 33 | self.fifo.writeAssumeCapacity(bytes); | 32 | |
| | 33 | mem.copy(u8, self.buf[self.end..], bytes); |
| | 34 | self.end += bytes.len; |
| 34 | return bytes.len; | 35 | return bytes.len; |
| 35 | } | 36 | } |
| 36 | }; | 37 | }; |