Commit 3632f31ec2

daurnimator <quae@daurnimator.com>
2019-11-10 17:22:42
std: use LinearFifo to implement io.BufferedOutStreamCustom
1 parent dd75cc2
Changed files (2)
lib
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);
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);
         }
     };
 }