| ... | @@ -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 | } |
| 2120 | | 2112 | |
| | 2113 | test "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 | |
| 2121 | pub fn failingDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize { | 2120 | pub fn failingDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize { |
| 2122 | _ = w; | 2121 | _ = w; |
| 2123 | _ = data; | 2122 | _ = data; |