From 3634d44d08c73326c7783cf2a3095acb50eb2e1c Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Tue, 29 Dec 2020 00:20:31 +0100 Subject: [PATCH] std: fix Reader.readUntilDelimiterOrEofAlloc() API The current API does not allow the user to distinguish between EOF and an empty line. Reader.readUntilDelimiterOrEof() gets this API right so update readUntilDelimiterOrEofAlloc() to match it. Returning an optional here additionally makes calling this in a loop much cleaner. Remove readUntilDelimiterOrEofArrayList() as it no longer needed to implement readUntilDelimiterOrEof() and has the same API issues described without a clear way to fix them. --- lib/std/io/reader.zig | 45 +++++++++++++------------------------------ 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/lib/std/io/reader.zig b/lib/std/io/reader.zig index b9a9eb3eeb..356ff7d8f2 100644 --- a/lib/std/io/reader.zig +++ b/lib/std/io/reader.zig @@ -101,35 +101,6 @@ pub fn Reader( return array_list.toOwnedSlice(); } - /// Replaces the `std.ArrayList` contents by reading from the stream until `delimiter` or end-of-stream is found. - /// Does not include the delimiter in the result. - /// If the `std.ArrayList` length would exceed `max_size`, `error.StreamTooLong` is returned and the - /// `std.ArrayList` is populated with `max_size` bytes from the stream. - pub fn readUntilDelimiterOrEofArrayList( - self: Self, - array_list: *std.ArrayList(u8), - delimiter: u8, - max_size: usize, - ) !void { - array_list.shrink(0); - while (true) { - var byte: u8 = self.readByte() catch |err| switch (err) { - error.EndOfStream => return, - else => |e| return e, - }; - - if (byte == delimiter) { - return; - } - - if (array_list.items.len == max_size) { - return error.StreamTooLong; - } - - try array_list.append(byte); - } - } - /// Replaces the `std.ArrayList` contents by reading from the stream until `delimiter` is found. /// Does not include the delimiter in the result. /// If the `std.ArrayList` length would exceed `max_size`, `error.StreamTooLong` is returned and the @@ -173,7 +144,10 @@ pub fn Reader( } /// Allocates enough memory to read until `delimiter` or end-of-stream. - /// If the allocated memory would be greater than `max_size`, returns `error.StreamTooLong`. + /// If the allocated memory would be greater than `max_size`, returns + /// `error.StreamTooLong`. If end-of-stream is found, returns the rest + /// of the stream. If this function is called again after that, returns + /// null. /// Caller owns returned memory. /// If this function returns an error, the contents from the stream read so far are lost. pub fn readUntilDelimiterOrEofAlloc( @@ -181,10 +155,17 @@ pub fn Reader( allocator: *mem.Allocator, delimiter: u8, max_size: usize, - ) ![]u8 { + ) !?[]u8 { var array_list = std.ArrayList(u8).init(allocator); defer array_list.deinit(); - try self.readUntilDelimiterOrEofArrayList(&array_list, delimiter, max_size); + self.readUntilDelimiterArrayList(&array_list, delimiter, max_size) catch |err| switch (err) { + error.EndOfStream => if (array_list.items.len == 0) { + return null; + } else { + return array_list.toOwnedSlice(); + }, + else => |e| return e, + }; return array_list.toOwnedSlice(); }