| ... | @@ -200,11 +200,17 @@ pub fn defaultDiscard(r: *Reader, limit: Limit) Error!usize { | ... | @@ -200,11 +200,17 @@ pub fn defaultDiscard(r: *Reader, limit: Limit) Error!usize { |
| 200 | r.seek = 0; | 200 | r.seek = 0; |
| 201 | r.end = 0; | 201 | r.end = 0; |
| 202 | var d: Writer.Discarding = .init(r.buffer); | 202 | var d: Writer.Discarding = .init(r.buffer); |
| 203 | const n = r.stream(&d.writer, limit) catch |err| switch (err) { | 203 | var n = r.stream(&d.writer, limit) catch |err| switch (err) { |
| 204 | error.WriteFailed => unreachable, | 204 | error.WriteFailed => unreachable, |
| 205 | error.ReadFailed => return error.ReadFailed, | 205 | error.ReadFailed => return error.ReadFailed, |
| 206 | error.EndOfStream => return error.EndOfStream, | 206 | error.EndOfStream => return error.EndOfStream, |
| 207 | }; | 207 | }; |
| | 208 | // If `stream` wrote to `r.buffer` without going through the writer, |
| | 209 | // we need to discard as much of the buffered data as possible. |
| | 210 | const remaining = @intFromEnum(limit) - n; |
| | 211 | const buffered_n_to_discard = @min(remaining, r.end - r.seek); |
| | 212 | n += buffered_n_to_discard; |
| | 213 | r.seek += buffered_n_to_discard; |
| 208 | assert(n <= @intFromEnum(limit)); | 214 | assert(n <= @intFromEnum(limit)); |
| 209 | return n; | 215 | return n; |
| 210 | } | 216 | } |
| ... | @@ -1720,6 +1726,18 @@ fn failingDiscard(r: *Reader, limit: Limit) Error!usize { | ... | @@ -1720,6 +1726,18 @@ fn failingDiscard(r: *Reader, limit: Limit) Error!usize { |
| 1720 | return error.ReadFailed; | 1726 | return error.ReadFailed; |
| 1721 | } | 1727 | } |
| 1722 | | 1728 | |
| | 1729 | test "discardAll that has to call discard multiple times on an indirect reader" { |
| | 1730 | var fr: Reader = .fixed("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); |
| | 1731 | var indirect_buffer: [3]u8 = undefined; |
| | 1732 | var tri: std.testing.ReaderIndirect = .init(&fr, &indirect_buffer); |
| | 1733 | const r = &tri.interface; |
| | 1734 | |
| | 1735 | try r.discardAll(10); |
| | 1736 | var remaining_buf: [16]u8 = undefined; |
| | 1737 | try r.readSliceAll(&remaining_buf); |
| | 1738 | try std.testing.expectEqualStrings(fr.buffer[10..], remaining_buf[0..]); |
| | 1739 | } |
| | 1740 | |
| 1723 | test "readAlloc when the backing reader provides one byte at a time" { | 1741 | test "readAlloc when the backing reader provides one byte at a time" { |
| 1724 | const str = "This is a test"; | 1742 | const str = "This is a test"; |
| 1725 | var tiny_buffer: [1]u8 = undefined; | 1743 | var tiny_buffer: [1]u8 = undefined; |