mirror of
https://github.com/ziglang/zig.git
synced 2025-12-24 07:03:11 +00:00
std.Io.Reader: fix readSliceShort with smaller buffer than Reader
closes #24443
This commit is contained in:
parent
86699acbb9
commit
5784500572
@ -593,48 +593,29 @@ pub fn readSliceAll(r: *Reader, buffer: []u8) Error!void {
|
|||||||
/// See also:
|
/// See also:
|
||||||
/// * `readSliceAll`
|
/// * `readSliceAll`
|
||||||
pub fn readSliceShort(r: *Reader, buffer: []u8) ShortError!usize {
|
pub fn readSliceShort(r: *Reader, buffer: []u8) ShortError!usize {
|
||||||
const in_buffer = r.buffer[r.seek..r.end];
|
var i: usize = 0;
|
||||||
const copy_len = @min(buffer.len, in_buffer.len);
|
while (true) {
|
||||||
@memcpy(buffer[0..copy_len], in_buffer[0..copy_len]);
|
const buffer_contents = r.buffer[r.seek..r.end];
|
||||||
if (buffer.len - copy_len == 0) {
|
const dest = buffer[i..];
|
||||||
|
const copy_len = @min(dest.len, buffer_contents.len);
|
||||||
|
@memcpy(dest[0..copy_len], buffer_contents[0..copy_len]);
|
||||||
|
if (dest.len - copy_len == 0) {
|
||||||
|
@branchHint(.likely);
|
||||||
r.seek += copy_len;
|
r.seek += copy_len;
|
||||||
return buffer.len;
|
return buffer.len;
|
||||||
}
|
}
|
||||||
var i: usize = copy_len;
|
i += copy_len;
|
||||||
r.end = 0;
|
r.end = 0;
|
||||||
r.seek = 0;
|
r.seek = 0;
|
||||||
while (true) {
|
|
||||||
const remaining = buffer[i..];
|
const remaining = buffer[i..];
|
||||||
var wrapper: Writer.VectorWrapper = .{
|
const new_remaining_len = readVecInner(r, &.{}, remaining, remaining.len) catch |err| switch (err) {
|
||||||
.it = .{
|
|
||||||
.first = remaining,
|
|
||||||
.last = r.buffer,
|
|
||||||
},
|
|
||||||
.writer = .{
|
|
||||||
.buffer = if (remaining.len >= r.buffer.len) remaining else r.buffer,
|
|
||||||
.vtable = Writer.VectorWrapper.vtable,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const n = r.vtable.stream(r, &wrapper.writer, .unlimited) catch |err| switch (err) {
|
|
||||||
error.WriteFailed => {
|
|
||||||
if (!wrapper.used) {
|
|
||||||
assert(r.seek == 0);
|
|
||||||
r.seek = remaining.len;
|
|
||||||
r.end = wrapper.writer.end;
|
|
||||||
@memcpy(remaining, r.buffer[0..remaining.len]);
|
|
||||||
}
|
|
||||||
return buffer.len;
|
|
||||||
},
|
|
||||||
error.EndOfStream => return i,
|
error.EndOfStream => return i,
|
||||||
error.ReadFailed => return error.ReadFailed,
|
error.ReadFailed => return error.ReadFailed,
|
||||||
};
|
};
|
||||||
if (n < remaining.len) {
|
if (new_remaining_len == 0) return buffer.len;
|
||||||
i += n;
|
i += remaining.len - new_remaining_len;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
r.end = n - remaining.len;
|
|
||||||
return buffer.len;
|
return buffer.len;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fill `buffer` with the next `buffer.len` bytes from the stream, advancing
|
/// Fill `buffer` with the next `buffer.len` bytes from the stream, advancing
|
||||||
@ -1640,6 +1621,19 @@ test readSliceShort {
|
|||||||
try testing.expectEqual(0, try r.readSliceShort(&buf));
|
try testing.expectEqual(0, try r.readSliceShort(&buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "readSliceShort with smaller buffer than Reader" {
|
||||||
|
var reader_buf: [15]u8 = undefined;
|
||||||
|
const str = "This is a test";
|
||||||
|
var one_byte_stream: testing.Reader = .init(&reader_buf, &.{
|
||||||
|
.{ .buffer = str },
|
||||||
|
});
|
||||||
|
one_byte_stream.artificial_limit = .limited(1);
|
||||||
|
|
||||||
|
var buf: [14]u8 = undefined;
|
||||||
|
try testing.expectEqual(14, try one_byte_stream.interface.readSliceShort(&buf));
|
||||||
|
try testing.expectEqualStrings(str, &buf);
|
||||||
|
}
|
||||||
|
|
||||||
test readVec {
|
test readVec {
|
||||||
var r: Reader = .fixed(std.ascii.letters);
|
var r: Reader = .fixed(std.ascii.letters);
|
||||||
var flat_buffer: [52]u8 = undefined;
|
var flat_buffer: [52]u8 = undefined;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user