authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-06-24 11:35:03-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-01 16:35:30-07:00
logc27ab8b45d767388eba5c3e69fc4b4764ae5e1c4
tree2e9e42a25fbf0aed4c683ea61723ff82aba769c1
parent743326f8e929238a843697397d21361c4081fead

std: update zstd to new API


5 files changed, 59 insertions(+), 41 deletions(-)

lib/std/compress/zstd.zig+6-4
...@@ -81,10 +81,11 @@ pub const table_size_max = struct {...@@ -81,10 +81,11 @@ pub const table_size_max = struct {
81fn testDecompress(gpa: std.mem.Allocator, compressed: []const u8) ![]u8 {81fn testDecompress(gpa: std.mem.Allocator, compressed: []const u8) ![]u8 {
82 var out: std.ArrayListUnmanaged(u8) = .empty;82 var out: std.ArrayListUnmanaged(u8) = .empty;
83 defer out.deinit(gpa);83 defer out.deinit(gpa);
84 try out.ensureUnusedCapacity(gpa, default_window_len);
8485
85 var in: std.io.Reader = .fixed(compressed);86 var in: std.io.Reader = .fixed(compressed);
86 var zstd_stream: Decompress = .init(&in, .{});87 var zstd_stream: Decompress = .init(&in, &.{}, .{});
87 try zstd_stream.reader().readRemainingArrayList(gpa, null, &out, .unlimited, default_window_len);88 try zstd_stream.interface.appendRemaining(gpa, null, &out, .unlimited);
8889
89 return out.toOwnedSlice(gpa);90 return out.toOwnedSlice(gpa);
90}91}
...@@ -101,12 +102,13 @@ fn testExpectDecompressError(err: anyerror, compressed: []const u8) !void {...@@ -101,12 +102,13 @@ fn testExpectDecompressError(err: anyerror, compressed: []const u8) !void {
101102
102 var out: std.ArrayListUnmanaged(u8) = .empty;103 var out: std.ArrayListUnmanaged(u8) = .empty;
103 defer out.deinit(gpa);104 defer out.deinit(gpa);
105 try out.ensureUnusedCapacity(gpa, default_window_len);
104106
105 var in: std.io.Reader = .fixed(compressed);107 var in: std.io.Reader = .fixed(compressed);
106 var zstd_stream: Decompress = .init(&in, .{});108 var zstd_stream: Decompress = .init(&in, &.{}, .{});
107 try std.testing.expectError(109 try std.testing.expectError(
108 error.ReadFailed,110 error.ReadFailed,
109 zstd_stream.reader().readRemainingArrayList(gpa, null, &out, .unlimited, default_window_len),111 zstd_stream.interface.appendRemaining(gpa, null, &out, .unlimited),
110 );112 );
111 try std.testing.expectError(err, zstd_stream.err orelse {});113 try std.testing.expectError(err, zstd_stream.err orelse {});
112}114}
lib/std/compress/zstd/Decompress.zig+13-13
...@@ -7,6 +7,7 @@ const zstd = @import("../zstd.zig");...@@ -7,6 +7,7 @@ const zstd = @import("../zstd.zig");
7const Writer = std.io.Writer;7const Writer = std.io.Writer;
88
9input: *Reader,9input: *Reader,
10interface: Reader,
10state: State,11state: State,
11verify_checksum: bool,12verify_checksum: bool,
12err: ?Error = null,13err: ?Error = null,
...@@ -62,34 +63,33 @@ pub const Error = error{...@@ -62,34 +63,33 @@ pub const Error = error{
62 WindowSizeUnknown,63 WindowSizeUnknown,
63};64};
6465
65pub fn init(input: *Reader, options: Options) Decompress {66pub fn init(input: *Reader, buffer: []u8, options: Options) Decompress {
66 return .{67 return .{
67 .input = input,68 .input = input,
68 .state = .new_frame,69 .state = .new_frame,
69 .verify_checksum = options.verify_checksum,70 .verify_checksum = options.verify_checksum,
71 .interface = .{
72 .vtable = &.{ .stream = stream },
73 .buffer = buffer,
74 .seek = 0,
75 .end = 0,
76 },
70 };77 };
71}78}
7279
73pub fn reader(self: *Decompress) Reader {80fn stream(r: *Reader, w: *Writer, limit: Limit) Reader.StreamError!usize {
74 return .{81 const d: *Decompress = @alignCast(@fieldParentPtr("interface", r));
75 .context = self,
76 .vtable = &.{ .read = read },
77 };
78}
79
80fn read(context: ?*anyopaque, bw: *Writer, limit: Limit) Reader.StreamError!usize {
81 const d: *Decompress = @ptrCast(@alignCast(context));
82 const in = d.input;82 const in = d.input;
8383
84 switch (d.state) {84 switch (d.state) {
85 .new_frame => {85 .new_frame => {
86 // Allow error.EndOfStream only on the frame magic.86 // Allow error.EndOfStream only on the frame magic.
87 const magic = try in.takeEnumNonexhaustive(Frame.Magic, .little);87 const magic = try in.takeEnumNonexhaustive(Frame.Magic, .little);
88 initFrame(d, bw.buffer.len, magic) catch |err| {88 initFrame(d, w.buffer.len, magic) catch |err| {
89 d.err = err;89 d.err = err;
90 return error.ReadFailed;90 return error.ReadFailed;
91 };91 };
92 return readInFrame(d, bw, limit, &d.state.in_frame) catch |err| switch (err) {92 return readInFrame(d, w, limit, &d.state.in_frame) catch |err| switch (err) {
93 error.ReadFailed => return error.ReadFailed,93 error.ReadFailed => return error.ReadFailed,
94 error.WriteFailed => return error.WriteFailed,94 error.WriteFailed => return error.WriteFailed,
95 else => |e| {95 else => |e| {
...@@ -99,7 +99,7 @@ fn read(context: ?*anyopaque, bw: *Writer, limit: Limit) Reader.StreamError!usiz...@@ -99,7 +99,7 @@ fn read(context: ?*anyopaque, bw: *Writer, limit: Limit) Reader.StreamError!usiz
99 };99 };
100 },100 },
101 .in_frame => |*in_frame| {101 .in_frame => |*in_frame| {
102 return readInFrame(d, bw, limit, in_frame) catch |err| switch (err) {102 return readInFrame(d, w, limit, in_frame) catch |err| switch (err) {
103 error.ReadFailed => return error.ReadFailed,103 error.ReadFailed => return error.ReadFailed,
104 error.WriteFailed => return error.WriteFailed,104 error.WriteFailed => return error.WriteFailed,
105 else => |e| {105 else => |e| {
lib/std/fs/File.zig+10-3
...@@ -1047,12 +1047,11 @@ pub const Reader = struct {...@@ -1047,12 +1047,11 @@ pub const Reader = struct {
1047 const r: *Reader = @fieldParentPtr("interface", io_reader);1047 const r: *Reader = @fieldParentPtr("interface", io_reader);
1048 switch (r.mode) {1048 switch (r.mode) {
1049 .positional, .streaming => return w.sendFile(r, limit) catch |write_err| switch (write_err) {1049 .positional, .streaming => return w.sendFile(r, limit) catch |write_err| switch (write_err) {
1050 error.ReadFailed => return error.ReadFailed,
1051 error.WriteFailed => return error.WriteFailed,
1052 error.Unimplemented => {1050 error.Unimplemented => {
1053 r.mode = r.mode.toReading();1051 r.mode = r.mode.toReading();
1054 return 0;1052 return 0;
1055 },1053 },
1054 else => |e| return e,
1056 },1055 },
1057 .positional_reading => {1056 .positional_reading => {
1058 if (is_windows) {1057 if (is_windows) {
...@@ -1239,7 +1238,7 @@ pub const Reader = struct {...@@ -1239,7 +1238,7 @@ pub const Reader = struct {
12391238
1240 pub fn atEnd(r: *Reader) bool {1239 pub fn atEnd(r: *Reader) bool {
1241 // Even if stat fails, size is set when end is encountered.1240 // Even if stat fails, size is set when end is encountered.
1242 const size = r.getSize() orelse return false;1241 const size = r.size orelse return false;
1243 return size - r.pos == 0;1242 return size - r.pos == 0;
1244 }1243 }
1245};1244};
...@@ -1460,6 +1459,10 @@ pub const Writer = struct {...@@ -1460,6 +1459,10 @@ pub const Writer = struct {
1460 return 0;1459 return 0;
1461 },1460 },
1462 };1461 };
1462 if (n == 0) {
1463 file_reader.size = file_reader.pos;
1464 return error.EndOfStream;
1465 }
1463 file_reader.pos += n;1466 file_reader.pos += n;
1464 w.pos += n;1467 w.pos += n;
1465 return n;1468 return n;
...@@ -1497,6 +1500,10 @@ pub const Writer = struct {...@@ -1497,6 +1500,10 @@ pub const Writer = struct {
1497 w.copy_file_range_err = err;1500 w.copy_file_range_err = err;
1498 return 0;1501 return 0;
1499 };1502 };
1503 if (n == 0) {
1504 file_reader.size = file_reader.pos;
1505 return error.EndOfStream;
1506 }
1500 file_reader.pos += n;1507 file_reader.pos += n;
1501 w.pos += n;1508 w.pos += n;
1502 return n;1509 return n;
lib/std/io/Reader.zig+3-3
...@@ -146,7 +146,7 @@ pub fn discard(r: *Reader, limit: Limit) Error!usize {...@@ -146,7 +146,7 @@ pub fn discard(r: *Reader, limit: Limit) Error!usize {
146 } else .unlimited;146 } else .unlimited;
147 r.seek = 0;147 r.seek = 0;
148 r.end = 0;148 r.end = 0;
149 const n = r.vtable.discard(r, remaining);149 const n = try r.vtable.discard(r, remaining);
150 assert(n <= @intFromEnum(remaining));150 assert(n <= @intFromEnum(remaining));
151 return buffered_len + n;151 return buffered_len + n;
152}152}
...@@ -386,7 +386,7 @@ pub fn readVecAll(r: *Reader, data: [][]u8) Error!void {...@@ -386,7 +386,7 @@ pub fn readVecAll(r: *Reader, data: [][]u8) Error!void {
386pub fn readAll(r: *Reader, w: *Writer, limit: Limit) StreamError!void {386pub fn readAll(r: *Reader, w: *Writer, limit: Limit) StreamError!void {
387 var remaining = limit;387 var remaining = limit;
388 while (remaining.nonzero()) {388 while (remaining.nonzero()) {
389 const n = try r.read(w, remaining);389 const n = try r.stream(w, remaining);
390 remaining = remaining.subtract(n).?;390 remaining = remaining.subtract(n).?;
391 }391 }
392}392}
...@@ -1472,7 +1472,7 @@ pub fn Hashed(comptime Hasher: type) type {...@@ -1472,7 +1472,7 @@ pub fn Hashed(comptime Hasher: type) type {
1472 fn discard(r: *Reader, limit: Limit) Error!usize {1472 fn discard(r: *Reader, limit: Limit) Error!usize {
1473 const this: *@This() = @alignCast(@fieldParentPtr("interface", r));1473 const this: *@This() = @alignCast(@fieldParentPtr("interface", r));
1474 var w = this.hasher.writer(&.{});1474 var w = this.hasher.writer(&.{});
1475 const n = this.in.read(&w, limit) catch |err| switch (err) {1475 const n = this.in.stream(&w, limit) catch |err| switch (err) {
1476 error.WriteFailed => unreachable,1476 error.WriteFailed => unreachable,
1477 else => |e| return e,1477 else => |e| return e,
1478 };1478 };
lib/std/io/Writer.zig+27-18
...@@ -84,18 +84,29 @@ pub const Error = error{...@@ -84,18 +84,29 @@ pub const Error = error{
84 WriteFailed,84 WriteFailed,
85};85};
8686
87pub const ReadingFileError = error{87pub const FileAllError = error{
88 /// Detailed diagnostics are found on the `File.Reader` struct.88 /// Detailed diagnostics are found on the `File.Reader` struct.
89 ReadFailed,89 ReadFailed,
90 /// See the `Writer` implementation for detailed diagnostics.90 /// See the `Writer` implementation for detailed diagnostics.
91 WriteFailed,91 WriteFailed,
92};92};
9393
94pub const FileReadingError = error{
95 /// Detailed diagnostics are found on the `File.Reader` struct.
96 ReadFailed,
97 /// See the `Writer` implementation for detailed diagnostics.
98 WriteFailed,
99 /// Reached the end of the file being read.
100 EndOfStream,
101};
102
94pub const FileError = error{103pub const FileError = error{
95 /// Detailed diagnostics are found on the `File.Reader` struct.104 /// Detailed diagnostics are found on the `File.Reader` struct.
96 ReadFailed,105 ReadFailed,
97 /// See the `Writer` implementation for detailed diagnostics.106 /// See the `Writer` implementation for detailed diagnostics.
98 WriteFailed,107 WriteFailed,
108 /// Reached the end of the file being read.
109 EndOfStream,
99 /// Indicates the caller should do its own file reading; the callee cannot110 /// Indicates the caller should do its own file reading; the callee cannot
100 /// offer a more efficient implementation.111 /// offer a more efficient implementation.
101 Unimplemented,112 Unimplemented,
...@@ -642,28 +653,24 @@ pub fn sendFileTo(w: *Writer, other: *Writer, file_reader: *File.Reader, limit:...@@ -642,28 +653,24 @@ pub fn sendFileTo(w: *Writer, other: *Writer, file_reader: *File.Reader, limit:
642}653}
643654
644/// Asserts nonzero buffer capacity.655/// Asserts nonzero buffer capacity.
645pub fn sendFileReading(w: *Writer, file_reader: *File.Reader, limit: Limit) ReadingFileError!usize {656pub fn sendFileReading(w: *Writer, file_reader: *File.Reader, limit: Limit) FileReadingError!usize {
646 const dest = limit.slice(try w.writableSliceGreedy(1));657 const dest = limit.slice(try w.writableSliceGreedy(1));
647 const n = file_reader.read(dest) catch |err| switch (err) {658 const n = try file_reader.read(dest);
648 error.EndOfStream => 0,
649 error.ReadFailed => return error.ReadFailed,
650 };
651 w.advance(n);659 w.advance(n);
652 return n;660 return n;
653}661}
654662
655pub fn sendFileAll(w: *Writer, file_reader: *File.Reader, limit: Limit) ReadingFileError!usize {663pub fn sendFileAll(w: *Writer, file_reader: *File.Reader, limit: Limit) FileAllError!usize {
656 var remaining = @intFromEnum(limit);664 var remaining = @intFromEnum(limit);
657 while (remaining > 0) {665 while (remaining > 0) {
658 const n = sendFile(w, file_reader, .limited(remaining)) catch |err| switch (err) {666 const n = sendFile(w, file_reader, .limited(remaining)) catch |err| switch (err) {
659 error.EndOfStream => return 0,667 error.EndOfStream => break,
660 error.ReadFailed => return error.ReadFailed,
661 error.WriteFailed => return error.WriteFailed,
662 error.Unimplemented => {668 error.Unimplemented => {
663 file_reader.mode = file_reader.mode.toReading();669 file_reader.mode = file_reader.mode.toReading();
664 try w.sendFileReadingAll(file_reader, remaining);670 remaining -= try w.sendFileReadingAll(file_reader, .limited(remaining));
665 return;671 break;
666 },672 },
673 else => |e| return e,
667 };674 };
668 remaining -= n;675 remaining -= n;
669 }676 }
...@@ -676,13 +683,15 @@ pub fn sendFileAll(w: *Writer, file_reader: *File.Reader, limit: Limit) ReadingF...@@ -676,13 +683,15 @@ pub fn sendFileAll(w: *Writer, file_reader: *File.Reader, limit: Limit) ReadingF
676/// that error code does not appear in this function's error set.683/// that error code does not appear in this function's error set.
677///684///
678/// Asserts nonzero buffer capacity.685/// Asserts nonzero buffer capacity.
679pub fn sendFileReadingAll(w: *Writer, file_reader: *File.Reader, limit: Limit) ReadingFileError!void {686pub fn sendFileReadingAll(w: *Writer, file_reader: *File.Reader, limit: Limit) FileAllError!usize {
680 var remaining = limit;687 var remaining = @intFromEnum(limit);
681 while (remaining.nonzero()) {688 while (remaining > 0) {
682 const n = try sendFileReading(w, file_reader, remaining);689 remaining -= sendFileReading(w, file_reader, .limited(remaining)) catch |err| switch (err) {
683 if (n == 0) return;690 error.EndOfStream => break,
684 remaining = remaining.subtract(n).?;691 else => |e| return e,
692 };
685 }693 }
694 return @intFromEnum(limit) - remaining;
686}695}
687696
688pub fn alignBuffer(697pub fn alignBuffer(