| ... | ... | @@ -593,48 +593,29 @@ pub fn readSliceAll(r: *Reader, buffer: []u8) Error!void { |
| 593 | 593 | /// See also: |
| 594 | 594 | /// * `readSliceAll` |
| 595 | 595 | pub fn readSliceShort(r: *Reader, buffer: []u8) ShortError!usize { |
| 596 | | const in_buffer = r.buffer[r.seek..r.end]; |
| 597 | | const copy_len = @min(buffer.len, in_buffer.len); |
| 598 | | @memcpy(buffer[0..copy_len], in_buffer[0..copy_len]); |
| 599 | | if (buffer.len - copy_len == 0) { |
| 600 | | r.seek += copy_len; |
| 601 | | return buffer.len; |
| 602 | | } |
| 603 | | var i: usize = copy_len; |
| 604 | | r.end = 0; |
| 605 | | r.seek = 0; |
| 596 | var i: usize = 0; |
| 606 | 597 | while (true) { |
| 598 | const buffer_contents = r.buffer[r.seek..r.end]; |
| 599 | const dest = buffer[i..]; |
| 600 | const copy_len = @min(dest.len, buffer_contents.len); |
| 601 | @memcpy(dest[0..copy_len], buffer_contents[0..copy_len]); |
| 602 | if (dest.len - copy_len == 0) { |
| 603 | @branchHint(.likely); |
| 604 | r.seek += copy_len; |
| 605 | return buffer.len; |
| 606 | } |
| 607 | i += copy_len; |
| 608 | r.end = 0; |
| 609 | r.seek = 0; |
| 607 | 610 | const remaining = buffer[i..]; |
| 608 | | var wrapper: Writer.VectorWrapper = .{ |
| 609 | | .it = .{ |
| 610 | | .first = remaining, |
| 611 | | .last = r.buffer, |
| 612 | | }, |
| 613 | | .writer = .{ |
| 614 | | .buffer = if (remaining.len >= r.buffer.len) remaining else r.buffer, |
| 615 | | .vtable = Writer.VectorWrapper.vtable, |
| 616 | | }, |
| 617 | | }; |
| 618 | | const n = r.vtable.stream(r, &wrapper.writer, .unlimited) catch |err| switch (err) { |
| 619 | | error.WriteFailed => { |
| 620 | | if (!wrapper.used) { |
| 621 | | assert(r.seek == 0); |
| 622 | | r.seek = remaining.len; |
| 623 | | r.end = wrapper.writer.end; |
| 624 | | @memcpy(remaining, r.buffer[0..remaining.len]); |
| 625 | | } |
| 626 | | return buffer.len; |
| 627 | | }, |
| 611 | const new_remaining_len = readVecInner(r, &.{}, remaining, remaining.len) catch |err| switch (err) { |
| 628 | 612 | error.EndOfStream => return i, |
| 629 | 613 | error.ReadFailed => return error.ReadFailed, |
| 630 | 614 | }; |
| 631 | | if (n < remaining.len) { |
| 632 | | i += n; |
| 633 | | continue; |
| 634 | | } |
| 635 | | r.end = n - remaining.len; |
| 636 | | return buffer.len; |
| 615 | if (new_remaining_len == 0) return buffer.len; |
| 616 | i += remaining.len - new_remaining_len; |
| 637 | 617 | } |
| 618 | return buffer.len; |
| 638 | 619 | } |
| 639 | 620 | |
| 640 | 621 | /// Fill `buffer` with the next `buffer.len` bytes from the stream, advancing |
| ... | ... | @@ -1640,6 +1621,19 @@ test readSliceShort { |
| 1640 | 1621 | try testing.expectEqual(0, try r.readSliceShort(&buf)); |
| 1641 | 1622 | } |
| 1642 | 1623 | |
| 1624 | test "readSliceShort with smaller buffer than Reader" { |
| 1625 | var reader_buf: [15]u8 = undefined; |
| 1626 | const str = "This is a test"; |
| 1627 | var one_byte_stream: testing.Reader = .init(&reader_buf, &.{ |
| 1628 | .{ .buffer = str }, |
| 1629 | }); |
| 1630 | one_byte_stream.artificial_limit = .limited(1); |
| 1631 | |
| 1632 | var buf: [14]u8 = undefined; |
| 1633 | try testing.expectEqual(14, try one_byte_stream.interface.readSliceShort(&buf)); |
| 1634 | try testing.expectEqualStrings(str, &buf); |
| 1635 | } |
| 1636 | |
| 1643 | 1637 | test readVec { |
| 1644 | 1638 | var r: Reader = .fixed(std.ascii.letters); |
| 1645 | 1639 | var flat_buffer: [52]u8 = undefined; |