From f945c2a1c8384319f9588a8f95ff8c97821213fe Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 9 Jan 2023 22:33:26 -0700 Subject: [PATCH] expose std.io.bufferedReaderSize This allows setting a custom buffer size. In this case I wanted it because using a buffer size large enough to fit a TLS ciphertext record elides a memcpy(). This commit also adds `readAtLeast` to the Reader interface. --- lib/std/io.zig | 1 + lib/std/io/buffered_reader.zig | 8 ++++++-- lib/std/io/reader.zig | 14 ++++++++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/std/io.zig b/lib/std/io.zig index d2a59a61a8..a61f2a4e0e 100644 --- a/lib/std/io.zig +++ b/lib/std/io.zig @@ -114,6 +114,7 @@ pub const bufferedWriter = @import("io/buffered_writer.zig").bufferedWriter; pub const BufferedReader = @import("io/buffered_reader.zig").BufferedReader; pub const bufferedReader = @import("io/buffered_reader.zig").bufferedReader; +pub const bufferedReaderSize = @import("io/buffered_reader.zig").bufferedReaderSize; pub const PeekStream = @import("io/peek_stream.zig").PeekStream; pub const peekStream = @import("io/peek_stream.zig").peekStream; diff --git a/lib/std/io/buffered_reader.zig b/lib/std/io/buffered_reader.zig index aca665fb30..2f6677c6a5 100644 --- a/lib/std/io/buffered_reader.zig +++ b/lib/std/io/buffered_reader.zig @@ -45,8 +45,12 @@ pub fn BufferedReader(comptime buffer_size: usize, comptime ReaderType: type) ty }; } -pub fn bufferedReader(underlying_stream: anytype) BufferedReader(4096, @TypeOf(underlying_stream)) { - return .{ .unbuffered_reader = underlying_stream }; +pub fn bufferedReader(reader: anytype) BufferedReader(4096, @TypeOf(reader)) { + return .{ .unbuffered_reader = reader }; +} + +pub fn bufferedReaderSize(comptime size: usize, reader: anytype) BufferedReader(size, @TypeOf(reader)) { + return .{ .unbuffered_reader = reader }; } test "io.BufferedReader OneByte" { diff --git a/lib/std/io/reader.zig b/lib/std/io/reader.zig index b86aca6cbd..ba5dc98072 100644 --- a/lib/std/io/reader.zig +++ b/lib/std/io/reader.zig @@ -30,10 +30,20 @@ pub fn Reader( /// means the stream reached the end. Reaching the end of a stream is not an error /// condition. pub fn readAll(self: Self, buffer: []u8) Error!usize { + return readAtLeast(self, buffer, 1); + } + + /// Returns the number of bytes read, calling the underlying read + /// function the minimal number of times until the buffer has at least + /// `len` bytes filled. If the number read is less than `len` it means + /// the stream reached the end. Reaching the end of the stream is not + /// an error condition. + pub fn readAtLeast(self: Self, buffer: []u8, len: usize) Error!usize { + assert(len <= buffer.len); var index: usize = 0; - while (index != buffer.len) { + while (index < len) { const amt = try self.read(buffer[index..]); - if (amt == 0) return index; + if (amt == 0) break; index += amt; } return index;