When this function is called it usually means the buffer got full, so it's
time to return an error. However, we still need to make sure all of the
available buffer has been filled. Also, it may be called from flush in
which case it should return successfully.
pub fn fixedDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize
pub fn fixedDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize {
if (data.len == 0) return 0;
for (data[0 .. data.len - 1]) |bytes| {
const dest = w.buffer[w.end..];
const len = @min(bytes.len, dest.len);
@memcpy(dest[0..len], bytes[0..len]);
w.end += len;
if (bytes.len > dest.len) return error.WriteFailed;
}
const pattern = data[data.len - 1];
const dest = w.buffer[w.end..];
switch (pattern.len) {
0 => return 0,
1 => {
assert(splat >= dest.len);
@memset(dest, pattern[0]);
w.end += dest.len;
return error.WriteFailed;
},
else => {
for (0..splat) |i| {
const remaining = dest[i * pattern.len ..];
const len = @min(pattern.len, remaining.len);
@memcpy(remaining[0..len], pattern[0..len]);
w.end += len;
if (pattern.len > remaining.len) return error.WriteFailed;
}
unreachable;
},
}
}