authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-04-21 22:01:37-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-01 16:35:28-07:00
log045c1c15576bdc283be40e0ce22ce0b7379e1bb7
treec094a0ba3f8e040980c471dffdbb918486a0a800
parentd9b9e3c2724a8ea5b66e231c4bd750c03e8f095c

std.io.AllocatingWriter.writeSplat: better implementation


1 files changed, 9 insertions(+), 11 deletions(-)

lib/std/io/AllocatingWriter.zig+9-11
...@@ -130,6 +130,7 @@ pub fn clearRetainingCapacity(aw: *AllocatingWriter) void {...@@ -130,6 +130,7 @@ pub fn clearRetainingCapacity(aw: *AllocatingWriter) void {
130}130}
131131
132fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize {132fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize {
133 if (data.len == 0 and splat == 0) return 0;
133 const aw: *AllocatingWriter = @alignCast(@ptrCast(context));134 const aw: *AllocatingWriter = @alignCast(@ptrCast(context));
134 const start_len = aw.written.len;135 const start_len = aw.written.len;
135 const bw = &aw.buffered_writer;136 const bw = &aw.buffered_writer;
...@@ -140,24 +141,21 @@ fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std....@@ -140,24 +141,21 @@ fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.
140 .capacity = start_len + bw.buffer.len,141 .capacity = start_len + bw.buffer.len,
141 };142 };
142 defer setArrayList(aw, list);143 defer setArrayList(aw, list);
143 const rest = data[1 .. data.len - 1];144 const rest = if (splat == 0) data[1 .. data.len - 1] else data[1..];
144 const pattern = data[data.len - 1];145 const pattern = data[data.len - 1];
145 var new_capacity: usize = list.capacity + pattern.len * splat;146 const remaining_splat = splat - 1;
147 var new_capacity: usize = list.capacity + pattern.len * remaining_splat;
146 for (rest) |bytes| new_capacity += bytes.len;148 for (rest) |bytes| new_capacity += bytes.len;
147 list.ensureTotalCapacity(aw.allocator, new_capacity + 1) catch return error.WriteFailed;149 list.ensureTotalCapacity(aw.allocator, new_capacity + 1) catch return error.WriteFailed;
148 for (rest) |bytes| list.appendSliceAssumeCapacity(bytes);150 for (rest) |bytes| list.appendSliceAssumeCapacity(bytes);
149 appendPatternAssumeCapacity(&list, pattern, splat);
150 aw.written = list.items;
151 bw.buffer = list.unusedCapacitySlice();
152 return list.items.len - start_len;
153}
154
155fn appendPatternAssumeCapacity(list: *std.ArrayListUnmanaged(u8), pattern: []const u8, splat: usize) void {
156 if (pattern.len == 1) {151 if (pattern.len == 1) {
157 list.appendNTimesAssumeCapacity(pattern[0], splat);152 list.appendNTimesAssumeCapacity(pattern[0], remaining_splat);
158 } else {153 } else {
159 for (0..splat) |_| list.appendSliceAssumeCapacity(pattern);154 for (0..remaining_splat) |_| list.appendSliceAssumeCapacity(pattern);
160 }155 }
156 aw.written = list.items;
157 bw.buffer = list.unusedCapacitySlice();
158 return list.items.len - start_len;
161}159}
162160
163fn writeFile(161fn writeFile(