| ... | ... | @@ -752,6 +752,11 @@ pub fn peekDelimiterInclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 { |
| 752 | 752 | @branchHint(.likely); |
| 753 | 753 | return buffer[seek .. end + 1]; |
| 754 | 754 | } |
| 755 | if (r.vtable.stream == &endingStream) { |
| 756 | // Protect the `@constCast` of `fixed`. |
| 757 | return error.EndOfStream; |
| 758 | } |
| 759 | r.rebase(); |
| 755 | 760 | while (r.buffer.len - r.end != 0) { |
| 756 | 761 | const end_cap = r.buffer[r.end..]; |
| 757 | 762 | var writer: Writer = .fixed(end_cap); |
| ... | ... | @@ -761,29 +766,9 @@ pub fn peekDelimiterInclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 { |
| 761 | 766 | }; |
| 762 | 767 | r.end += n; |
| 763 | 768 | if (std.mem.indexOfScalarPos(u8, end_cap[0..n], 0, delimiter)) |end| { |
| 764 | | return r.buffer[seek .. r.end - n + end + 1]; |
| 769 | return r.buffer[0 .. r.end - n + end + 1]; |
| 765 | 770 | } |
| 766 | 771 | } |
| 767 | | var i: usize = 0; |
| 768 | | while (seek - i != 0) { |
| 769 | | const begin_cap = r.buffer[i..seek]; |
| 770 | | var writer: Writer = .fixed(begin_cap); |
| 771 | | const n = r.vtable.stream(r, &writer, .limited(begin_cap.len)) catch |err| switch (err) { |
| 772 | | error.WriteFailed => unreachable, |
| 773 | | else => |e| return e, |
| 774 | | }; |
| 775 | | i += n; |
| 776 | | if (std.mem.indexOfScalarPos(u8, r.buffer[0..seek], i, delimiter)) |end| { |
| 777 | | std.mem.rotate(u8, r.buffer, seek); |
| 778 | | r.seek = 0; |
| 779 | | r.end += i; |
| 780 | | return r.buffer[0 .. seek + end + 1]; |
| 781 | | } |
| 782 | | } else if (i != 0) { |
| 783 | | std.mem.rotate(u8, r.buffer, seek); |
| 784 | | r.seek = 0; |
| 785 | | r.end += i; |
| 786 | | } |
| 787 | 772 | return error.StreamTooLong; |
| 788 | 773 | } |
| 789 | 774 | |
| ... | ... | @@ -1665,6 +1650,23 @@ test "readAlloc when the backing reader provides one byte at a time" { |
| 1665 | 1650 | try std.testing.expectEqualStrings(str, res); |
| 1666 | 1651 | } |
| 1667 | 1652 | |
| 1653 | test "takeDelimiterInclusive when it rebases" { |
| 1654 | const written_line = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n"; |
| 1655 | var buffer: [128]u8 = undefined; |
| 1656 | var tr: std.testing.Reader = .init(&buffer, &.{ |
| 1657 | .{ .buffer = written_line }, |
| 1658 | .{ .buffer = written_line }, |
| 1659 | .{ .buffer = written_line }, |
| 1660 | .{ .buffer = written_line }, |
| 1661 | .{ .buffer = written_line }, |
| 1662 | .{ .buffer = written_line }, |
| 1663 | }); |
| 1664 | const r = &tr.interface; |
| 1665 | for (0..6) |_| { |
| 1666 | try std.testing.expectEqualStrings(written_line, try r.takeDelimiterInclusive('\n')); |
| 1667 | } |
| 1668 | } |
| 1669 | |
| 1668 | 1670 | /// Provides a `Reader` implementation by passing data from an underlying |
| 1669 | 1671 | /// reader through `Hasher.update`. |
| 1670 | 1672 | /// |