authorgravatar for quae@daurnimator.comdaurnimator <quae@daurnimator.com> 2020-02-07 14:43:09+11:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-06 18:49:12-05:00
logbcf56c32eb11306613c92128c1b95ff280ba4f68
treec9339d7953a3f99e4f2c4a9f0ea5961a9297d66a
parentfd23decbd9dc39b044867993b67607e33ec9de45
signaturelock-open Commit is signed but in an unrecognized format.

std: use ArrayList rather than Buffer for in_stream helper functions

Buffer's behaviour of retaining a trailing 0 isn't helpful here

1 files changed, 34 insertions(+), 17 deletions(-)

lib/std/io/in_stream.zig+34-17
...@@ -65,22 +65,31 @@ pub fn InStream(comptime ReadError: type) type {...@@ -65,22 +65,31 @@ pub fn InStream(comptime ReadError: type) type {
65 /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and65 /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and
66 /// the contents read from the stream are lost.66 /// the contents read from the stream are lost.
67 pub fn readAllBuffer(self: *Self, buffer: *Buffer, max_size: usize) !void {67 pub fn readAllBuffer(self: *Self, buffer: *Buffer, max_size: usize) !void {
68 try buffer.resize(0);68 try buffer.list.ensureCapacity(1);
69 buffer.list.len = 0;
70 errdefer buffer.resize(0) catch unreachable; // make sure we leave buffer in a valid state on error
71 try self.readAllArrayList(&buffer.list, max_size);
72 try buffer.list.append(0);
73 }
6974
75 /// Appends to the ArrayList contents by reading from the stream until end of stream is found.
76 /// If the ArrayList length would exceed `max_size`, `error.StreamTooLong` is returned and the contents
77 /// read from the stream so far are lost.
78 pub fn readAllArrayList(self: *Self, array_list: *std.ArrayList(u8), max_size: usize) !void {
70 var actual_buf_len: usize = 0;79 var actual_buf_len: usize = 0;
71 while (true) {80 while (true) {
72 const dest_slice = buffer.toSlice()[actual_buf_len..];81 const dest_slice = array_list.toSlice()[actual_buf_len..];
73 const bytes_read = try self.readFull(dest_slice);82 const bytes_read = try self.readFull(dest_slice);
74 actual_buf_len += bytes_read;83 actual_buf_len += bytes_read;
7584
76 if (bytes_read != dest_slice.len) {85 if (bytes_read != dest_slice.len) {
77 buffer.shrink(actual_buf_len);86 array_list.shrink(actual_buf_len);
78 return;87 return;
79 }88 }
8089
81 const new_buf_size = math.min(max_size, actual_buf_len + mem.page_size);90 const new_buf_size = math.min(max_size, actual_buf_len + mem.page_size);
82 if (new_buf_size == actual_buf_len) return error.StreamTooLong;91 if (new_buf_size == actual_buf_len) return error.StreamTooLong;
83 try buffer.resize(new_buf_size);92 try array_list.resize(new_buf_size);
84 }93 }
85 }94 }
8695
...@@ -89,11 +98,10 @@ pub fn InStream(comptime ReadError: type) type {...@@ -89,11 +98,10 @@ pub fn InStream(comptime ReadError: type) type {
89 /// Caller owns returned memory.98 /// Caller owns returned memory.
90 /// If this function returns an error, the contents from the stream read so far are lost.99 /// If this function returns an error, the contents from the stream read so far are lost.
91 pub fn readAllAlloc(self: *Self, allocator: *mem.Allocator, max_size: usize) ![]u8 {100 pub fn readAllAlloc(self: *Self, allocator: *mem.Allocator, max_size: usize) ![]u8 {
92 var buf = Buffer.initNull(allocator);101 var array_list = std.ArrayList(u8).init(allocator);
93 defer buf.deinit();102 defer array_list.deinit();
94103 try self.readAllArrayList(&array_list, max_size);
95 try self.readAllBuffer(&buf, max_size);104 return array_list.toOwnedSlice();
96 return buf.toOwnedSlice();
97 }105 }
98106
99 /// Replaces `buffer` contents by reading from the stream until `delimiter` is found.107 /// Replaces `buffer` contents by reading from the stream until `delimiter` is found.
...@@ -101,8 +109,18 @@ pub fn InStream(comptime ReadError: type) type {...@@ -101,8 +109,18 @@ pub fn InStream(comptime ReadError: type) type {
101 /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and the contents109 /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and the contents
102 /// read from the stream so far are lost.110 /// read from the stream so far are lost.
103 pub fn readUntilDelimiterBuffer(self: *Self, buffer: *Buffer, delimiter: u8, max_size: usize) !void {111 pub fn readUntilDelimiterBuffer(self: *Self, buffer: *Buffer, delimiter: u8, max_size: usize) !void {
104 try buffer.resize(0);112 try buffer.list.ensureCapacity(1);
113 buffer.list.len = 0;
114 errdefer buffer.resize(0) catch unreachable; // make sure we leave buffer in a valid state on error
115 try self.readUntilDelimiterArrayList(&buffer.list, delimiter, max_size);
116 try buffer.list.append(0);
117 }
105118
119 /// Appends to the ArrayList contents by reading from the stream until `delimiter` is found.
120 /// Does not include the delimiter in the result.
121 /// If the ArrayList length would exceed `max_size`, `error.StreamTooLong` is returned and the contents
122 /// read from the stream so far are lost.
123 pub fn readUntilDelimiterArrayList(self: *Self, array_list: *std.ArrayList(u8), delimiter: u8, max_size: usize) !void {
106 while (true) {124 while (true) {
107 var byte: u8 = try self.readByte();125 var byte: u8 = try self.readByte();
108126
...@@ -110,11 +128,11 @@ pub fn InStream(comptime ReadError: type) type {...@@ -110,11 +128,11 @@ pub fn InStream(comptime ReadError: type) type {
110 return;128 return;
111 }129 }
112130
113 if (buffer.len() == max_size) {131 if (array_list.len == max_size) {
114 return error.StreamTooLong;132 return error.StreamTooLong;
115 }133 }
116134
117 try buffer.appendByte(byte);135 try array_list.append(byte);
118 }136 }
119 }137 }
120138
...@@ -123,11 +141,10 @@ pub fn InStream(comptime ReadError: type) type {...@@ -123,11 +141,10 @@ pub fn InStream(comptime ReadError: type) type {
123 /// Caller owns returned memory.141 /// Caller owns returned memory.
124 /// If this function returns an error, the contents from the stream read so far are lost.142 /// If this function returns an error, the contents from the stream read so far are lost.
125 pub fn readUntilDelimiterAlloc(self: *Self, allocator: *mem.Allocator, delimiter: u8, max_size: usize) ![]u8 {143 pub fn readUntilDelimiterAlloc(self: *Self, allocator: *mem.Allocator, delimiter: u8, max_size: usize) ![]u8 {
126 var buf = Buffer.initNull(allocator);144 var array_list = std.ArrayList(u8).init(allocator);
127 defer buf.deinit();145 defer array_list.deinit();
128146 try self.readUntilDelimiterArrayList(&array_list, delimiter, max_size);
129 try self.readUntilDelimiterBuffer(&buf, delimiter, max_size);147 return array_list.toOwnedSlice();
130 return buf.toOwnedSlice();
131 }148 }
132149
133 /// Reads from the stream until specified byte is found. If the buffer is not150 /// Reads from the stream until specified byte is found. If the buffer is not