This commit is contained in:
Igor Anić 2025-11-23 22:57:18 +00:00 committed by GitHub
commit 6c44e4634f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -234,6 +234,7 @@ pub fn streamExact64(r: *Reader, w: *Writer, n: u64) StreamError!void {
/// ///
/// Asserts `Writer.buffer` capacity exceeds `preserve_len`. /// Asserts `Writer.buffer` capacity exceeds `preserve_len`.
pub fn streamExactPreserve(r: *Reader, w: *Writer, preserve_len: usize, n: usize) StreamError!void { pub fn streamExactPreserve(r: *Reader, w: *Writer, preserve_len: usize, n: usize) StreamError!void {
assert(w.buffer.len >= preserve_len);
if (w.end + n <= w.buffer.len) { if (w.end + n <= w.buffer.len) {
@branchHint(.likely); @branchHint(.likely);
return streamExact(r, w, n); return streamExact(r, w, n);
@ -245,11 +246,8 @@ pub fn streamExactPreserve(r: *Reader, w: *Writer, preserve_len: usize, n: usize
remaining -= try r.stream(w, .limited(remaining - preserve_len)); remaining -= try r.stream(w, .limited(remaining - preserve_len));
if (w.end + remaining <= w.buffer.len) return streamExact(r, w, remaining); if (w.end + remaining <= w.buffer.len) return streamExact(r, w, remaining);
} }
// All the next bytes received must be preserved. assert(remaining == preserve_len);
if (preserve_len < w.end) { try w.flush();
@memmove(w.buffer[0..preserve_len], w.buffer[w.end - preserve_len ..][0..preserve_len]);
w.end = preserve_len;
}
return streamExact(r, w, remaining); return streamExact(r, w, remaining);
} }
@ -2068,3 +2066,29 @@ fn testLeb128(comptime T: type, encoded: []const u8) !T {
test { test {
_ = Limited; _ = Limited;
} }
test streamExactPreserve {
const reader_buffer = "0123456789abcdef";
for (1..reader_buffer.len) |preserve| {
for (preserve..reader_buffer.len) |writer_buffer_len| {
const writter_buffer = try testing.allocator.alloc(u8, writer_buffer_len);
defer testing.allocator.free(writter_buffer);
var dw: Writer.Discarding = .init(writter_buffer);
var r: Reader = .fixed(reader_buffer);
var w = &dw.writer;
const n = r.buffer.len;
try r.streamExactPreserve(w, preserve, n);
// written bytes
try testing.expectEqual(n, dw.count + w.buffered().len);
// preserved bytes in writer buffer
try testing.expectEqualSlices(
u8,
r.buffer[n - preserve ..],
w.buffered()[w.buffered().len - preserve ..],
);
}
}
}