authorgravatar for leecannon@leecannon.xyzLee Cannon <leecannon@leecannon.xyz> 2020-12-02 12:53:38+00:00
committergravatar for leecannon@leecannon.xyzLee Cannon <leecannon@leecannon.xyz> 2020-12-02 12:55:54+00:00
log76f39215447e0eec4cf00e7c2916ff189a82a37f
tree657382c9de89c191ef254b77233c557b75bc1cf2
parentdb0cb54f4ea023869d955449ba5e3eb86981d413

Add `readUntilDelimiterOrEofArrayList` & `readUntilDelimiterOrEofAlloc`


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

lib/std/io/reader.zig+46-6
...@@ -60,12 +60,7 @@ pub fn Reader(...@@ -60,12 +60,7 @@ pub fn Reader(
60 return self.readAllArrayListAligned(null, array_list, max_append_size);60 return self.readAllArrayListAligned(null, array_list, max_append_size);
61 }61 }
6262
63 pub fn readAllArrayListAligned(63 pub fn readAllArrayListAligned(self: Self, comptime alignment: ?u29, array_list: *std.ArrayListAligned(u8, alignment), max_append_size: usize) !void {
64 self: Self,
65 comptime alignment: ?u29,
66 array_list: *std.ArrayListAligned(u8, alignment),
67 max_append_size: usize
68 ) !void {
69 try array_list.ensureCapacity(math.min(max_append_size, 4096));64 try array_list.ensureCapacity(math.min(max_append_size, 4096));
70 const original_len = array_list.items.len;65 const original_len = array_list.items.len;
71 var start_index: usize = original_len;66 var start_index: usize = original_len;
...@@ -101,6 +96,35 @@ pub fn Reader(...@@ -101,6 +96,35 @@ pub fn Reader(
101 return array_list.toOwnedSlice();96 return array_list.toOwnedSlice();
102 }97 }
10398
99 /// Replaces the `std.ArrayList` contents by reading from the stream until `delimiter` or end-of-stream is found.
100 /// Does not include the delimiter in the result.
101 /// If the `std.ArrayList` length would exceed `max_size`, `error.StreamTooLong` is returned and the
102 /// `std.ArrayList` is populated with `max_size` bytes from the stream.
103 pub fn readUntilDelimiterOrEofArrayList(
104 self: Self,
105 array_list: *std.ArrayList(u8),
106 delimiter: u8,
107 max_size: usize,
108 ) !void {
109 array_list.shrink(0);
110 while (true) {
111 var byte: u8 = self.readByte() catch |err| switch (err) {
112 error.EndOfStream => return,
113 else => |e| return e,
114 };
115
116 if (byte == delimiter) {
117 return;
118 }
119
120 if (array_list.items.len == max_size) {
121 return error.StreamTooLong;
122 }
123
124 try array_list.append(byte);
125 }
126 }
127
104 /// Replaces the `std.ArrayList` contents by reading from the stream until `delimiter` is found.128 /// Replaces the `std.ArrayList` contents by reading from the stream until `delimiter` is found.
105 /// Does not include the delimiter in the result.129 /// Does not include the delimiter in the result.
106 /// If the `std.ArrayList` length would exceed `max_size`, `error.StreamTooLong` is returned and the130 /// If the `std.ArrayList` length would exceed `max_size`, `error.StreamTooLong` is returned and the
...@@ -143,6 +167,22 @@ pub fn Reader(...@@ -143,6 +167,22 @@ pub fn Reader(
143 return array_list.toOwnedSlice();167 return array_list.toOwnedSlice();
144 }168 }
145169
170 /// Allocates enough memory to read until `delimiter` or end-of-stream.
171 /// If the allocated memory would be greater than `max_size`, returns `error.StreamTooLong`.
172 /// Caller owns returned memory.
173 /// If this function returns an error, the contents from the stream read so far are lost.
174 pub fn readUntilDelimiterOrEofAlloc(
175 self: Self,
176 allocator: *mem.Allocator,
177 delimiter: u8,
178 max_size: usize,
179 ) ![]u8 {
180 var array_list = std.ArrayList(u8).init(allocator);
181 defer array_list.deinit();
182 try self.readUntilDelimiterOrEofArrayList(&array_list, delimiter, max_size);
183 return array_list.toOwnedSlice();
184 }
185
146 /// Reads from the stream until specified byte is found. If the buffer is not186 /// Reads from the stream until specified byte is found. If the buffer is not
147 /// large enough to hold the entire contents, `error.StreamTooLong` is returned.187 /// large enough to hold the entire contents, `error.StreamTooLong` is returned.
148 /// If end-of-stream is found, returns the rest of the stream. If this188 /// If end-of-stream is found, returns the rest of the stream. If this