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...@@ -162,28 +162,20 @@ pub fn writeSplat(w: *Writer, data: []const []const u8, splat: usize) Error!usiz
162 const buffer = w.buffer;162 const buffer = w.buffer;
163 const count = countSplat(data, splat);163 const count = countSplat(data, splat);
164 if (w.end + count > buffer.len) return w.vtable.drain(w, data, splat);164 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| {
166 @memcpy(buffer[w.end..][0..bytes.len], bytes);166 @memcpy(buffer[w.end..][0..bytes.len], bytes);
167 w.end += bytes.len;167 w.end += bytes.len;
168 }168 }
169 const pattern = data[data.len - 1];169 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;
176 switch (pattern.len) {170 switch (pattern.len) {
177 0 => {},171 0 => {},
178 1 => {172 1 => {
179 @memset(buffer[w.end..][0..remaining_splat], pattern[0]);173 @memset(buffer[w.end..][0..splat], pattern[0]);
180 w.end += remaining_splat;174 w.end += splat;
181 },175 },
182 else => {176 else => for (0..splat) |_| {
183 const new_end = w.end + pattern.len * remaining_splat;177 @memcpy(buffer[w.end..][0..pattern.len], pattern);
184 while (w.end < new_end) : (w.end += pattern.len) {178 w.end += pattern.len;
185 @memcpy(buffer[w.end..][0..pattern.len], pattern);
186 }
187 },179 },
188 }180 }
189 return count;181 return count;
...@@ -2118,6 +2110,13 @@ test "fixed output" {...@@ -2118,6 +2110,13 @@ test "fixed output" {
2118 try testing.expect(std.mem.eql(u8, w.buffered(), "Hello worl"));2110 try testing.expect(std.mem.eql(u8, w.buffered(), "Hello worl"));
2119}2111}
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
2121pub fn failingDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize {2120pub fn failingDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize {
2122 _ = w;2121 _ = w;
2123 _ = data;2122 _ = data;