authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-06 18:20:11-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-07 22:43:53-07:00
loga7387f0047a1bb67c31e947a251171834a3f9817
treeb252b8f17809cf952fa404ab680a65f32f7f93d7
parent9903587a6325f61a10e3cf9dbce53bf741d77595

fix std.io.Writer.VectorWrapper mechanism

previous implementation erroneously attempted to detect whether vector API was used via the buffer pointer. This implementation has an explicit flag.

2 files changed, 14 insertions(+), 4 deletions(-)

lib/std/io/Reader.zig+11-4
......@@ -328,17 +328,24 @@ pub fn readVecLimit(r: *Reader, data: []const []u8, limit: Limit) Error!usize {
328328 };
329329 var n = r.vtable.stream(r, &wrapper.writer, .limited(remaining)) catch |err| switch (err) {
330330 error.WriteFailed => {
331 assert(!wrapper.used);
331332 if (wrapper.writer.buffer.ptr == first.ptr) {
332333 remaining -= wrapper.writer.end;
333334 } else {
335 assert(wrapper.writer.end <= r.buffer.len);
334336 r.end = wrapper.writer.end;
335337 }
336338 break;
337339 },
338340 else => |e| return e,
339341 };
340 if (wrapper.writer.buffer.ptr != first.ptr) {
341 r.end = n;
342 if (!wrapper.used) {
343 if (wrapper.writer.buffer.ptr == first.ptr) {
344 remaining -= n;
345 } else {
346 assert(n <= r.buffer.len);
347 r.end = n;
348 }
342349 break;
343350 }
344351 if (n < first.len) {
......@@ -355,6 +362,7 @@ pub fn readVecLimit(r: *Reader, data: []const []u8, limit: Limit) Error!usize {
355362 remaining -= mid.len;
356363 n -= mid.len;
357364 }
365 assert(n <= r.buffer.len);
358366 r.end = n;
359367 break;
360368 }
......@@ -596,12 +604,11 @@ pub fn readSliceShort(r: *Reader, buffer: []u8) ShortError!usize {
596604 };
597605 const n = r.vtable.stream(r, &wrapper.writer, .unlimited) catch |err| switch (err) {
598606 error.WriteFailed => {
599 if (wrapper.writer.buffer.ptr != remaining.ptr) {
607 if (!wrapper.used) {
600608 assert(r.seek == 0);
601609 r.seek = remaining.len;
602610 r.end = wrapper.writer.end;
603611 @memcpy(remaining, r.buffer[0..remaining.len]);
604 return buffer.len;
605612 }
606613 return buffer.len;
607614 },
lib/std/io/Writer.zig+3
......@@ -390,12 +390,15 @@ pub const WritableVectorIterator = struct {
390390pub const VectorWrapper = struct {
391391 writer: Writer,
392392 it: WritableVectorIterator,
393 /// Tracks whether the "writable vector" API was used.
394 used: bool = false,
393395 pub const vtable: VTable = .{ .drain = fixedDrain };
394396};
395397
396398pub fn writableVectorIterator(w: *Writer) Error!WritableVectorIterator {
397399 if (w.vtable == &VectorWrapper.vtable) {
398400 const wrapper: *VectorWrapper = @fieldParentPtr("writer", w);
401 wrapper.used = true;
399402 return wrapper.it;
400403 }
401404 return .{ .first = try writableSliceGreedy(w, 1) };