mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
std: use LinearFifo to implement io.BufferedOutStreamCustom
This commit is contained in:
parent
dd75cc214d
commit
3632f31ec2
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user