srctree

Andrew Kelley parent 17bad9f8 791c4491 ea8e9e66
Merge pull request #19289 from ianic/issue_19052

compress.xz: fix slow running read loop

inlinesplit
lib/std/compress/xz/block.zig added: 16, removed: 19, total 0
@@ -34,6 +34,7 @@ pub fn Decoder(comptime ReaderType: type) type {
check: xz.Check,
err: ?Error,
to_read: ArrayListUnmanaged(u8),
read_pos: usize,
block_count: usize,
 
fn init(allocator: Allocator, in_reader: ReaderType, check: xz.Check) !Self {
@@ -43,6 +44,7 @@ pub fn Decoder(comptime ReaderType: type) type {
.check = check,
.err = null,
.to_read = .{},
.read_pos = 0,
.block_count = 0,
};
}
@@ -57,25 +59,22 @@ pub fn Decoder(comptime ReaderType: type) type {
 
pub fn read(self: *Self, output: []u8) Error!usize {
while (true) {
if (self.to_read.items.len > 0) {
const input = self.to_read.items;
const n = @min(input.len, output.len);
@memcpy(output[0..n], input[0..n]);
std.mem.copyForwards(u8, input, input[n..]);
self.to_read.shrinkRetainingCapacity(input.len - n);
if (self.to_read.items.len == 0 and self.err != null) {
if (self.err.? == DecodeError.EndOfStreamWithNoError) {
return n;
}
return self.err.?;
}
const unread_len = self.to_read.items.len - self.read_pos;
if (unread_len > 0) {
const n = @min(unread_len, output.len);
@memcpy(output[0..n], self.to_read.items[self.read_pos..][0..n]);
self.read_pos += n;
return n;
}
if (self.err != null) {
if (self.err.? == DecodeError.EndOfStreamWithNoError) {
if (self.err) |e| {
if (e == DecodeError.EndOfStreamWithNoError) {
return 0;
}
return self.err.?;
return e;
}
if (self.read_pos > 0) {
self.to_read.shrinkRetainingCapacity(0);
self.read_pos = 0;
}
self.readBlock() catch |e| {
self.err = e;
@@ -84,8 +83,6 @@ pub fn Decoder(comptime ReaderType: type) type {
}
 
fn readBlock(self: *Self) Error!void {
const unpacked_pos = self.to_read.items.len;
 
var block_counter = std.io.countingReader(self.inner_reader);
const block_reader = block_counter.reader();
 
@@ -166,7 +163,7 @@ pub fn Decoder(comptime ReaderType: type) type {
return error.CorruptInput;
}
 
const unpacked_bytes = self.to_read.items[unpacked_pos..];
const unpacked_bytes = self.to_read.items;
if (unpacked_size) |s| {
if (s != unpacked_bytes.len)
return error.CorruptInput;