| ... | @@ -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 and | 65 | /// 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 | } |
| 69 | | 74 | |
| | 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; |
| 75 | | 84 | |
| 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 | } |
| 80 | | 89 | |
| 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 | } |
| 86 | | 95 | |
| ... | @@ -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(); |
| 94 | | 103 | 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 | } |
| 98 | | 106 | |
| 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 contents | 109 | /// 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 | } |
| 105 | | 118 | |
| | 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(); |
| 108 | | 126 | |
| ... | @@ -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 | } |
| 112 | | 130 | |
| 113 | if (buffer.len() == max_size) { | 131 | if (array_list.len == max_size) { |
| 114 | return error.StreamTooLong; | 132 | return error.StreamTooLong; |
| 115 | } | 133 | } |
| 116 | | 134 | |
| 117 | try buffer.appendByte(byte); | 135 | try array_list.append(byte); |
| 118 | } | 136 | } |
| 119 | } | 137 | } |
| 120 | | 138 | |
| ... | @@ -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(); |
| 128 | | 146 | 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 | } |
| 132 | | 149 | |
| 133 | /// Reads from the stream until specified byte is found. If the buffer is not | 150 | /// Reads from the stream until specified byte is found. If the buffer is not |