Skip to content

Commit

Permalink
std: fix Reader.readUntilDelimiterOrEofAlloc() API
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ifreund authored and aarvay committed Jan 4, 2021
1 parent 98fed23 commit 714ae8c
Showing 1 changed file with 13 additions and 32 deletions.
45 changes: 13 additions & 32 deletions lib/std/io/reader.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -173,18 +144,28 @@ 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(
self: Self,
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();
}

Expand Down

0 comments on commit 714ae8c

Please sign in to comment.