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 {
130130}
131131
132132fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize {
133 if (data.len == 0 and splat == 0) return 0;
133134 const aw: *AllocatingWriter = @alignCast(@ptrCast(context));
134135 const start_len = aw.written.len;
135136 const bw = &aw.buffered_writer;
......@@ -140,24 +141,21 @@ fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.
140141 .capacity = start_len + bw.buffer.len,
141142 };
142143 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..];
144145 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;
146148 for (rest) |bytes| new_capacity += bytes.len;
147149 list.ensureTotalCapacity(aw.allocator, new_capacity + 1) catch return error.WriteFailed;
148150 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 {
156151 if (pattern.len == 1) {
157 list.appendNTimesAssumeCapacity(pattern[0], splat);
152 list.appendNTimesAssumeCapacity(pattern[0], remaining_splat);
158153 } else {
159 for (0..splat) |_| list.appendSliceAssumeCapacity(pattern);
154 for (0..remaining_splat) |_| list.appendSliceAssumeCapacity(pattern);
160155 }
156 aw.written = list.items;
157 bw.buffer = list.unusedCapacitySlice();
158 return list.items.len - start_len;
161159}
162160
163161fn writeFile(