@@ -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 ;
@@ -1702,33 +1696,13 @@ fn failingDiscard(r: *Reader, limit: Limit) Error!usize {
1702
1696
}
1703
1697
1704
1698
test "readAlloc when the backing reader provides one byte at a time" {
1705
- const OneByteReader = struct {
1706
- str : []const u8 ,
1707
- i : usize ,
1708
- reader : Reader ,
1709
-
1710
- fn stream (r : * Reader , w : * Writer , limit : Limit ) StreamError ! usize {
1711
- assert (@intFromEnum (limit ) >= 1 );
1712
- const self : * @This () = @fieldParentPtr ("reader" , r );
1713
- if (self .str .len - self .i == 0 ) return error .EndOfStream ;
1714
- try w .writeByte (self .str [self .i ]);
1715
- self .i += 1 ;
1716
- return 1 ;
1717
- }
1718
- };
1719
1699
const str = "This is a test" ;
1720
1700
var tiny_buffer : [1 ]u8 = undefined ;
1721
- var one_byte_stream : OneByteReader = .{
1722
- .str = str ,
1723
- .i = 0 ,
1724
- .reader = .{
1725
- .buffer = & tiny_buffer ,
1726
- .vtable = &.{ .stream = OneByteReader .stream },
1727
- .seek = 0 ,
1728
- .end = 0 ,
1729
- },
1730
- };
1731
- const res = try one_byte_stream .reader .allocRemaining (std .testing .allocator , .unlimited );
1701
+ var one_byte_stream : testing.Reader = .init (& tiny_buffer , &.{
1702
+ .{ .buffer = str },
1703
+ });
1704
+ one_byte_stream .artificial_limit = .limited (1 );
1705
+ const res = try one_byte_stream .interface .allocRemaining (std .testing .allocator , .unlimited );
1732
1706
defer std .testing .allocator .free (res );
1733
1707
try std .testing .expectEqualStrings (str , res );
1734
1708
}
0 commit comments