lib/quic/src/connection/stream/ring.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2
3 /// Copies the input into the buffer from `index` on, carrying on at the buffer start where it runs
4 /// off the end. The index sits inside the buffer and the input fits. The sending and receiving
5 /// parts both buffer stream bytes through this write.
6 pub fn write(ring: []u8, index: usize, input: []const u8) void {
7 std.debug.assert(index < ring.len);
8 std.debug.assert(input.len <= ring.len);
9 const first = @min(input.len, ring.len - index);
10 @memcpy(ring[index..][0..first], input[0..first]);
11 @memcpy(ring[0 .. input.len - first], input[first..]);
12 }
13
14 /// Fills the output from the buffer from `index` on, carrying on at the buffer start where it runs
15 /// off the end. The index sits inside the buffer and the output fits. The receiving part hands an
16 /// application its bytes through this read.
17 pub fn read(ring: []const u8, index: usize, output: []u8) void {
18 std.debug.assert(index < ring.len);
19 std.debug.assert(output.len <= ring.len);
20 const first = @min(output.len, ring.len - index);
21 @memcpy(output[0..first], ring[index..][0..first]);
22 @memcpy(output[first..], ring[0 .. output.len - first]);
23 }
24
25 test "ring copies wrap once at the buffer end" {
26 var ring: [4]u8 = @splat(0);
27 write(&ring, 3, "abc");
28 try std.testing.expectEqualSlices(u8, &.{ 'b', 'c', 0, 'a' }, &ring);
29 var output: [3]u8 = undefined;
30 read(&ring, 3, &output);
31 try std.testing.expectEqualStrings("abc", &output);
32 write(&ring, 0, "wxyz");
33 try std.testing.expectEqualStrings("wxyz", &ring);
34 }