authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-09 17:52:36-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-09 17:52:36-07:00
log09cdcf67e1fb6cc05b1b35710c1652682541c915
treebc38b27f2a057a31741de96c3aba45ca17f253ab
parentab84dcc824220d884177cd7abc2e038d21a8e407

std.io.Writer.writeSplat: simplify and fix


1 files changed, 13 insertions(+), 14 deletions(-)

lib/std/io/Writer.zig+13-14
......@@ -162,28 +162,20 @@ pub fn writeSplat(w: *Writer, data: []const []const u8, splat: usize) Error!usiz
162162 const buffer = w.buffer;
163163 const count = countSplat(data, splat);
164164 if (w.end + count > buffer.len) return w.vtable.drain(w, data, splat);
165 for (data) |bytes| {
165 for (data[0 .. data.len - 1]) |bytes| {
166166 @memcpy(buffer[w.end..][0..bytes.len], bytes);
167167 w.end += bytes.len;
168168 }
169169 const pattern = data[data.len - 1];
170 if (splat == 0) {
171 @branchHint(.unlikely);
172 w.end -= pattern.len;
173 return count;
174 }
175 const remaining_splat = splat - 1;
176170 switch (pattern.len) {
177171 0 => {},
178172 1 => {
179 @memset(buffer[w.end..][0..remaining_splat], pattern[0]);
180 w.end += remaining_splat;
173 @memset(buffer[w.end..][0..splat], pattern[0]);
174 w.end += splat;
181175 },
182 else => {
183 const new_end = w.end + pattern.len * remaining_splat;
184 while (w.end < new_end) : (w.end += pattern.len) {
185 @memcpy(buffer[w.end..][0..pattern.len], pattern);
186 }
176 else => for (0..splat) |_| {
177 @memcpy(buffer[w.end..][0..pattern.len], pattern);
178 w.end += pattern.len;
187179 },
188180 }
189181 return count;
......@@ -2118,6 +2110,13 @@ test "fixed output" {
21182110 try testing.expect(std.mem.eql(u8, w.buffered(), "Hello worl"));
21192111}
21202112
2113test "writeSplat 0 len splat larger than capacity" {
2114 var buf: [8]u8 = undefined;
2115 var w: std.io.Writer = .fixed(&buf);
2116 const n = try w.writeSplat(&.{"something that overflows buf"}, 0);
2117 try testing.expectEqual(0, n);
2118}
2119
21212120pub fn failingDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize {
21222121 _ = w;
21232122 _ = data;