| ... | @@ -242,11 +242,10 @@ pub fn streamExactPreserve(r: *Reader, w: *Writer, preserve_len: usize, n: usize | ... | @@ -242,11 +242,10 @@ pub fn streamExactPreserve(r: *Reader, w: *Writer, preserve_len: usize, n: usize |
| 242 | remaining -= try r.stream(w, .limited(remaining - preserve_len)); | 242 | remaining -= try r.stream(w, .limited(remaining - preserve_len)); |
| 243 | if (w.end + remaining <= w.buffer.len) return streamExact(r, w, remaining); | 243 | if (w.end + remaining <= w.buffer.len) return streamExact(r, w, remaining); |
| 244 | } | 244 | } |
| 245 | // All the next bytes received must be preserved. | 245 | // Offset the amount preserved by the amount we have left to stream |
| 246 | if (preserve_len < w.end) { | 246 | // since the remaining bytes are always going to be part of that |
| 247 | @memmove(w.buffer[0..preserve_len], w.buffer[w.end - preserve_len ..][0..preserve_len]); | 247 | // preservation. |
| 248 | w.end = preserve_len; | 248 | try w.rebase(preserve_len -| remaining, remaining); |
| 249 | } | | |
| 250 | return streamExact(r, w, remaining); | 249 | return streamExact(r, w, remaining); |
| 251 | } | 250 | } |
| 252 | | 251 | |
| ... | @@ -2300,6 +2299,50 @@ fn testLeb128(comptime T: type, encoded: []const u8) !T { | ... | @@ -2300,6 +2299,50 @@ fn testLeb128(comptime T: type, encoded: []const u8) !T { |
| 2300 | return result; | 2299 | return result; |
| 2301 | } | 2300 | } |
| 2302 | | 2301 | |
| | 2302 | test streamExactPreserve { |
| | 2303 | try testStreamExactPreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 5, .stream_len = 5 }); |
| | 2304 | try testStreamExactPreserve(.{ .buf_len = 10, .fill_len = 9, .preserve = 5, .stream_len = 2 }); |
| | 2305 | try testStreamExactPreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 5, .stream_len = 6 }); |
| | 2306 | try testStreamExactPreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 6, .stream_len = 6 }); |
| | 2307 | try testStreamExactPreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 5, .stream_len = 10 }); |
| | 2308 | try testStreamExactPreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 6, .stream_len = 10 }); |
| | 2309 | try testStreamExactPreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 6, .stream_len = 11 }); |
| | 2310 | try testStreamExactPreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 6, .stream_len = 80 }); |
| | 2311 | try testStreamExactPreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 6, .stream_len = 85 }); |
| | 2312 | try testStreamExactPreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 10, .stream_len = 6 }); |
| | 2313 | try testStreamExactPreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 10, .stream_len = 11 }); |
| | 2314 | try testStreamExactPreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 10, .stream_len = 80 }); |
| | 2315 | try testStreamExactPreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 10, .stream_len = 85 }); |
| | 2316 | } |
| | 2317 | |
| | 2318 | fn testStreamExactPreserve(options: struct { buf_len: u4, fill_len: u4, preserve: u4, stream_len: u8 }) !void { |
| | 2319 | assert(options.fill_len <= options.buf_len); |
| | 2320 | assert(options.preserve <= options.buf_len); |
| | 2321 | |
| | 2322 | var input: [256]u8 = undefined; |
| | 2323 | for (&input, 0..) |*val, i| { |
| | 2324 | val.* = @as(u8, @intCast(i % 26)) + 'a'; |
| | 2325 | } |
| | 2326 | const expected_out = input[0 .. options.fill_len + options.stream_len]; |
| | 2327 | const expected_preserved = expected_out[expected_out.len -| options.preserve..]; |
| | 2328 | |
| | 2329 | var r: Reader = .fixed(&input); |
| | 2330 | var out_buf: [256]u8 = undefined; |
| | 2331 | var fw: Writer = .fixed(&out_buf); |
| | 2332 | var indirect_buffer: [16]u8 = undefined; |
| | 2333 | var twi: std.testing.WriterIndirect = .init(&fw, indirect_buffer[0..options.buf_len]); |
| | 2334 | const w = &twi.interface; |
| | 2335 | |
| | 2336 | try r.streamExact(w, options.fill_len); |
| | 2337 | try r.streamExactPreserve(w, options.preserve, options.stream_len); |
| | 2338 | |
| | 2339 | try std.testing.expectEqualStrings(expected_preserved, w.buffer[w.end -| options.preserve..w.end]); |
| | 2340 | |
| | 2341 | try w.flush(); |
| | 2342 | |
| | 2343 | try std.testing.expectEqualStrings(expected_out, fw.buffered()); |
| | 2344 | } |
| | 2345 | |
| 2303 | test { | 2346 | test { |
| 2304 | _ = Limited; | 2347 | _ = Limited; |
| 2305 | } | 2348 | } |