authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-12-03 21:03:48+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-12-03 21:03:48+01:00
loga8e543bd6b4748b3a980ad45dc231748ef6b598b
tree91827d56049653d5c53f7674075f3555697c5637
parentac85e1f2c8959b8aba0862d31d531f5fa8d5d14c
parentf598245836814f30ae063b191da4374fbf110a99
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #7280 from leecannon/master

Add `readUntilDelimiterOrEofArrayList` & `readUntilDelimiterOrEofAlloc`

1 files changed, 46 insertions(+), 1 deletions(-)

lib/std/io/reader.zig+46-1
......@@ -64,7 +64,7 @@ pub fn Reader(
6464 self: Self,
6565 comptime alignment: ?u29,
6666 array_list: *std.ArrayListAligned(u8, alignment),
67 max_append_size: usize
67 max_append_size: usize,
6868 ) !void {
6969 try array_list.ensureCapacity(math.min(max_append_size, 4096));
7070 const original_len = array_list.items.len;
......@@ -101,6 +101,35 @@ pub fn Reader(
101101 return array_list.toOwnedSlice();
102102 }
103103
104 /// Replaces the `std.ArrayList` contents by reading from the stream until `delimiter` or end-of-stream is found.
105 /// Does not include the delimiter in the result.
106 /// If the `std.ArrayList` length would exceed `max_size`, `error.StreamTooLong` is returned and the
107 /// `std.ArrayList` is populated with `max_size` bytes from the stream.
108 pub fn readUntilDelimiterOrEofArrayList(
109 self: Self,
110 array_list: *std.ArrayList(u8),
111 delimiter: u8,
112 max_size: usize,
113 ) !void {
114 array_list.shrink(0);
115 while (true) {
116 var byte: u8 = self.readByte() catch |err| switch (err) {
117 error.EndOfStream => return,
118 else => |e| return e,
119 };
120
121 if (byte == delimiter) {
122 return;
123 }
124
125 if (array_list.items.len == max_size) {
126 return error.StreamTooLong;
127 }
128
129 try array_list.append(byte);
130 }
131 }
132
104133 /// Replaces the `std.ArrayList` contents by reading from the stream until `delimiter` is found.
105134 /// Does not include the delimiter in the result.
106135 /// If the `std.ArrayList` length would exceed `max_size`, `error.StreamTooLong` is returned and the
......@@ -143,6 +172,22 @@ pub fn Reader(
143172 return array_list.toOwnedSlice();
144173 }
145174
175 /// Allocates enough memory to read until `delimiter` or end-of-stream.
176 /// If the allocated memory would be greater than `max_size`, returns `error.StreamTooLong`.
177 /// Caller owns returned memory.
178 /// If this function returns an error, the contents from the stream read so far are lost.
179 pub fn readUntilDelimiterOrEofAlloc(
180 self: Self,
181 allocator: *mem.Allocator,
182 delimiter: u8,
183 max_size: usize,
184 ) ![]u8 {
185 var array_list = std.ArrayList(u8).init(allocator);
186 defer array_list.deinit();
187 try self.readUntilDelimiterOrEofArrayList(&array_list, delimiter, max_size);
188 return array_list.toOwnedSlice();
189 }
190
146191 /// Reads from the stream until specified byte is found. If the buffer is not
147192 /// large enough to hold the entire contents, `error.StreamTooLong` is returned.
148193 /// If end-of-stream is found, returns the rest of the stream. If this