authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-28 22:12:46-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-31 22:10:11-07:00
log05ce1f99a60df0bcede00af1c98a1e5fdce35051
treeb9dfb4f32f94125bda0a1ad925fec8a66179f9ed
parent2569f4ff8514f47730c1abd42691f8fc1cdd22d5

compiler: update to new flate API


7 files changed, 122 insertions(+), 107 deletions(-)

lib/std/Io/Reader.zig+9
......@@ -1709,6 +1709,15 @@ fn failingDiscard(r: *Reader, limit: Limit) Error!usize {
17091709 return error.ReadFailed;
17101710}
17111711
1712pub fn adaptToOldInterface(r: *Reader) std.Io.AnyReader {
1713 return .{ .context = r, .readFn = derpRead };
1714}
1715
1716fn derpRead(context: *const anyopaque, buffer: []u8) anyerror!usize {
1717 const r: *Reader = @constCast(@alignCast(@ptrCast(context)));
1718 return r.readSliceShort(buffer);
1719}
1720
17121721test "readAlloc when the backing reader provides one byte at a time" {
17131722 const str = "This is a test";
17141723 var tiny_buffer: [1]u8 = undefined;
lib/std/compress/flate/Decompress.zig+5-5
......@@ -23,7 +23,7 @@ dst_dec: DistanceDecoder,
2323final_block: bool,
2424state: State,
2525
26read_err: ?Error,
26err: ?Error,
2727
2828const BlockType = enum(u2) {
2929 stored = 0,
......@@ -74,7 +74,7 @@ pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress {
7474 .dst_dec = .{},
7575 .final_block = false,
7676 .state = .protocol_header,
77 .read_err = null,
77 .err = null,
7878 };
7979}
8080
......@@ -153,7 +153,7 @@ pub fn stream(r: *Reader, w: *Writer, limit: std.Io.Limit) Reader.StreamError!us
153153 if (d.state == .end) {
154154 return error.EndOfStream;
155155 } else {
156 d.read_err = error.EndOfStream;
156 d.err = error.EndOfStream;
157157 return error.ReadFailed;
158158 }
159159 },
......@@ -161,7 +161,7 @@ pub fn stream(r: *Reader, w: *Writer, limit: std.Io.Limit) Reader.StreamError!us
161161 else => |e| {
162162 // In the event of an error, state is unmodified so that it can be
163163 // better used to diagnose the failure.
164 d.read_err = e;
164 d.err = e;
165165 return error.ReadFailed;
166166 },
167167 };
......@@ -1179,7 +1179,7 @@ fn testFailure(container: Container, in: []const u8, expected_err: anyerror) !vo
11791179
11801180 var decompress: Decompress = .init(&reader, container, &.{});
11811181 try testing.expectError(error.ReadFailed, decompress.reader.streamRemaining(&aw.writer));
1182 try testing.expectEqual(expected_err, decompress.read_err orelse return error.TestFailed);
1182 try testing.expectEqual(expected_err, decompress.err orelse return error.TestFailed);
11831183}
11841184
11851185fn testDecompress(container: Container, compressed: []const u8, expected_plain: []const u8) !void {
lib/std/http/Client.zig+9-10
......@@ -405,8 +405,8 @@ pub const RequestTransfer = union(enum) {
405405
406406/// The decompressor for response messages.
407407pub const Compression = union(enum) {
408 deflate: std.compress.flate.Decompress,
409 gzip: std.compress.flate.Decompress,
408 //deflate: std.compress.flate.Decompress,
409 //gzip: std.compress.flate.Decompress,
410410 // https://github.com/ziglang/zig/issues/18937
411411 //zstd: ZstdDecompressor,
412412 none: void,
......@@ -1074,12 +1074,10 @@ pub const Request = struct {
10741074 switch (req.response.transfer_compression) {
10751075 .identity => req.response.compression = .none,
10761076 .compress, .@"x-compress" => return error.CompressionUnsupported,
1077 .deflate => req.response.compression = .{
1078 .deflate = std.compress.zlib.decompressor(req.transferReader()),
1079 },
1080 .gzip, .@"x-gzip" => req.response.compression = .{
1081 .gzip = std.compress.gzip.decompressor(req.transferReader()),
1082 },
1077 // I'm about to upstream my http.Client rewrite
1078 .deflate => return error.CompressionUnsupported,
1079 // I'm about to upstream my http.Client rewrite
1080 .gzip, .@"x-gzip" => return error.CompressionUnsupported,
10831081 // https://github.com/ziglang/zig/issues/18937
10841082 //.zstd => req.response.compression = .{
10851083 // .zstd = std.compress.zstd.decompressStream(req.client.allocator, req.transferReader()),
......@@ -1105,8 +1103,9 @@ pub const Request = struct {
11051103 /// Reads data from the response body. Must be called after `wait`.
11061104 pub fn read(req: *Request, buffer: []u8) ReadError!usize {
11071105 const out_index = switch (req.response.compression) {
1108 .deflate => |*deflate| deflate.read(buffer) catch return error.DecompressionFailure,
1109 .gzip => |*gzip| gzip.read(buffer) catch return error.DecompressionFailure,
1106 // I'm about to upstream my http client rewrite
1107 //.deflate => |*deflate| deflate.readSlice(buffer) catch return error.DecompressionFailure,
1108 //.gzip => |*gzip| gzip.read(buffer) catch return error.DecompressionFailure,
11101109 // https://github.com/ziglang/zig/issues/18937
11111110 //.zstd => |*zstd| zstd.read(buffer) catch return error.DecompressionFailure,
11121111 else => try req.transferRead(buffer),
lib/std/zip.zig+45-39
......@@ -7,8 +7,9 @@ const builtin = @import("builtin");
77const std = @import("std");
88const File = std.fs.File;
99const is_le = builtin.target.cpu.arch.endian() == .little;
10const Writer = std.io.Writer;
11const Reader = std.io.Reader;
10const Writer = std.Io.Writer;
11const Reader = std.Io.Reader;
12const flate = std.compress.flate;
1213
1314pub const CompressionMethod = enum(u16) {
1415 store = 0,
......@@ -117,6 +118,7 @@ pub const EndRecord = extern struct {
117118 pub const FindFileError = File.GetEndPosError || File.SeekError || File.ReadError || error{
118119 ZipNoEndRecord,
119120 EndOfStream,
121 ReadFailed,
120122 };
121123
122124 pub fn findFile(fr: *File.Reader) FindFileError!EndRecord {
......@@ -137,8 +139,7 @@ pub const EndRecord = extern struct {
137139
138140 try fr.seekTo(end_pos - @as(u64, new_loaded_len));
139141 const read_buf: []u8 = buf[buf.len - new_loaded_len ..][0..read_len];
140 var br = fr.interface().unbuffered();
141 br.readSlice(read_buf) catch |err| switch (err) {
142 fr.interface.readSliceAll(read_buf) catch |err| switch (err) {
142143 error.ReadFailed => return fr.err.?,
143144 error.EndOfStream => return error.EndOfStream,
144145 };
......@@ -164,7 +165,7 @@ pub const EndRecord = extern struct {
164165pub const Decompress = struct {
165166 interface: Reader,
166167 state: union {
167 inflate: std.compress.flate.Decompress,
168 inflate: flate.Decompress,
168169 store: *Reader,
169170 },
170171
......@@ -201,7 +202,7 @@ pub const Decompress = struct {
201202
202203 fn streamDeflate(r: *Reader, w: *Writer, limit: std.io.Limit) Reader.StreamError!usize {
203204 const d: *Decompress = @fieldParentPtr("interface", r);
204 return std.compress.flate.Decompress.read(&d.inflate, w, limit);
205 return flate.Decompress.read(&d.inflate, w, limit);
205206 }
206207};
207208
......@@ -305,7 +306,7 @@ pub const Iterator = struct {
305306 if (locator_end_offset > stream_len)
306307 return error.ZipTruncated;
307308 try input.seekTo(stream_len - locator_end_offset);
308 const locator = input.interface.takeStructEndian(EndLocator64, .little) catch |err| switch (err) {
309 const locator = input.interface.takeStruct(EndLocator64, .little) catch |err| switch (err) {
309310 error.ReadFailed => return input.err.?,
310311 error.EndOfStream => return error.EndOfStream,
311312 };
......@@ -318,7 +319,7 @@ pub const Iterator = struct {
318319
319320 try input.seekTo(locator.record_file_offset);
320321
321 const record64 = input.interface.takeStructEndian(EndRecord64, .little) catch |err| switch (err) {
322 const record64 = input.interface.takeStruct(EndRecord64, .little) catch |err| switch (err) {
322323 error.ReadFailed => return input.err.?,
323324 error.EndOfStream => return error.EndOfStream,
324325 };
......@@ -374,7 +375,7 @@ pub const Iterator = struct {
374375 const header_zip_offset = self.cd_zip_offset + self.cd_record_offset;
375376 const input = self.input;
376377 try input.seekTo(header_zip_offset);
377 const header = input.interface.takeStructEndian(CentralDirectoryFileHeader, .little) catch |err| switch (err) {
378 const header = input.interface.takeStruct(CentralDirectoryFileHeader, .little) catch |err| switch (err) {
378379 error.ReadFailed => return input.err.?,
379380 error.EndOfStream => return error.EndOfStream,
380381 };
......@@ -405,7 +406,7 @@ pub const Iterator = struct {
405406 const extra = extra_buf[0..header.extra_len];
406407
407408 try input.seekTo(header_zip_offset + @sizeOf(CentralDirectoryFileHeader) + header.filename_len);
408 input.interface.readSlice(extra) catch |err| switch (err) {
409 input.interface.readSliceAll(extra) catch |err| switch (err) {
409410 error.ReadFailed => return input.err.?,
410411 error.EndOfStream => return error.EndOfStream,
411412 };
......@@ -460,7 +461,7 @@ pub const Iterator = struct {
460461 options: ExtractOptions,
461462 filename_buf: []u8,
462463 dest: std.fs.Dir,
463 ) !u32 {
464 ) !void {
464465 if (filename_buf.len < self.filename_len)
465466 return error.ZipInsufficientBuffer;
466467 switch (self.compression_method) {
......@@ -470,13 +471,13 @@ pub const Iterator = struct {
470471 const filename = filename_buf[0..self.filename_len];
471472 {
472473 try stream.seekTo(self.header_zip_offset + @sizeOf(CentralDirectoryFileHeader));
473 try stream.interface.readSlice(filename);
474 try stream.interface.readSliceAll(filename);
474475 }
475476
476477 const local_data_header_offset: u64 = local_data_header_offset: {
477478 const local_header = blk: {
478479 try stream.seekTo(self.file_offset);
479 break :blk try stream.interface.takeStructEndian(LocalFileHeader, .little);
480 break :blk try stream.interface.takeStruct(LocalFileHeader, .little);
480481 };
481482 if (!std.mem.eql(u8, &local_header.signature, &local_file_header_sig))
482483 return error.ZipBadFileOffset;
......@@ -502,7 +503,7 @@ pub const Iterator = struct {
502503
503504 {
504505 try stream.seekTo(self.file_offset + @sizeOf(LocalFileHeader) + local_header.filename_len);
505 try stream.interface.readSlice(extra);
506 try stream.interface.readSliceAll(extra);
506507 }
507508
508509 var extra_offset: usize = 0;
......@@ -550,7 +551,7 @@ pub const Iterator = struct {
550551 if (self.uncompressed_size != 0)
551552 return error.ZipBadDirectorySize;
552553 try dest.makePath(filename[0 .. filename.len - 1]);
553 return std.hash.Crc32.hash(&.{});
554 return;
554555 }
555556
556557 const out_file = blk: {
......@@ -564,31 +565,36 @@ pub const Iterator = struct {
564565 break :blk try dest.createFile(filename, .{ .exclusive = true });
565566 };
566567 defer out_file.close();
567 var file_writer = out_file.writer();
568 var file_bw = file_writer.writer(&.{});
568 var out_file_buffer: [1024]u8 = undefined;
569 var file_writer = out_file.writer(&out_file_buffer);
569570 const local_data_file_offset: u64 =
570571 @as(u64, self.file_offset) +
571572 @as(u64, @sizeOf(LocalFileHeader)) +
572573 local_data_header_offset;
573574 try stream.seekTo(local_data_file_offset);
574 var limited_file_reader = stream.interface.limited(.limited(self.compressed_size));
575 var file_read_buffer: [1000]u8 = undefined;
576 var decompress_read_buffer: [1000]u8 = undefined;
577 var limited_br = limited_file_reader.reader().buffered(&file_read_buffer);
578 var decompress: Decompress = undefined;
579 var decompress_br = decompress.readable(&limited_br, self.compression_method, &decompress_read_buffer);
580 const start_out = file_bw.count;
581 var hash_writer = file_bw.hashed(std.hash.Crc32.init());
582 var hash_bw = hash_writer.writer(&.{});
583 decompress_br.readAll(&hash_bw, .limited(self.uncompressed_size)) catch |err| switch (err) {
584 error.ReadFailed => return stream.err.?,
585 error.WriteFailed => return file_writer.err.?,
586 error.EndOfStream => return error.ZipDecompressTruncated,
587 };
588 if (limited_file_reader.remaining.nonzero()) return error.ZipDecompressTruncated;
589 const written = file_bw.count - start_out;
590 if (written != self.uncompressed_size) return error.ZipUncompressSizeMismatch;
591 return hash_writer.hasher.final();
575
576 // TODO limit based on self.compressed_size
577
578 switch (self.compression_method) {
579 .store => {
580 stream.interface.streamExact(&file_writer.interface, self.uncompressed_size) catch |err| switch (err) {
581 error.ReadFailed => return stream.err.?,
582 error.WriteFailed => return file_writer.err.?,
583 error.EndOfStream => return error.ZipDecompressTruncated,
584 };
585 },
586 .deflate => {
587 var flate_buffer: [flate.max_window_len]u8 = undefined;
588 var decompress: flate.Decompress = .init(&stream.interface, .raw, &flate_buffer);
589 decompress.reader.streamExact(&file_writer.interface, self.uncompressed_size) catch |err| switch (err) {
590 error.ReadFailed => return stream.err.?,
591 error.WriteFailed => return file_writer.err orelse decompress.err.?,
592 error.EndOfStream => return error.ZipDecompressTruncated,
593 };
594 },
595 else => return error.UnsupportedCompressionMethod,
596 }
597 try file_writer.end();
592598 }
593599 };
594600};
......@@ -636,19 +642,19 @@ pub const ExtractOptions = struct {
636642 /// Allow filenames within the zip to use backslashes. Back slashes are normalized
637643 /// to forward slashes before forwarding them to platform APIs.
638644 allow_backslashes: bool = false,
639
640645 diagnostics: ?*Diagnostics = null,
646 verify_checksums: bool = false,
641647};
642648
643649/// Extract the zipped files to the given `dest` directory.
644650pub fn extract(dest: std.fs.Dir, fr: *File.Reader, options: ExtractOptions) !void {
651 if (options.verify_checksums) @panic("TODO unimplemented");
652
645653 var iter = try Iterator.init(fr);
646654
647655 var filename_buf: [std.fs.max_path_bytes]u8 = undefined;
648656 while (try iter.next()) |entry| {
649 const crc32 = try entry.extract(fr, options, &filename_buf, dest);
650 if (crc32 != entry.crc32)
651 return error.ZipCrcMismatch;
657 try entry.extract(fr, options, &filename_buf, dest);
652658 if (options.diagnostics) |d| {
653659 try d.nextFilename(filename_buf[0..entry.filename_len]);
654660 }
src/Package/Fetch.zig+15-10
......@@ -1203,12 +1203,11 @@ fn unpackResource(
12031203 return unpackTarball(f, tmp_directory.handle, &adapter.new_interface);
12041204 },
12051205 .@"tar.gz" => {
1206 const reader = resource.reader();
1207 var br = std.io.bufferedReaderSize(std.crypto.tls.max_ciphertext_record_len, reader);
1208 var dcp = std.compress.gzip.decompressor(br.reader());
1209 var adapter_buffer: [1024]u8 = undefined;
1210 var adapter = dcp.reader().adaptToNewApi(&adapter_buffer);
1211 return try unpackTarball(f, tmp_directory.handle, &adapter.new_interface);
1206 var adapter_buffer: [std.crypto.tls.max_ciphertext_record_len]u8 = undefined;
1207 var adapter = resource.reader().adaptToNewApi(&adapter_buffer);
1208 var flate_buffer: [std.compress.flate.max_window_len]u8 = undefined;
1209 var decompress: std.compress.flate.Decompress = .init(&adapter.new_interface, .gzip, &flate_buffer);
1210 return try unpackTarball(f, tmp_directory.handle, &decompress.reader);
12121211 },
12131212 .@"tar.xz" => {
12141213 const gpa = f.arena.child_allocator;
......@@ -1352,7 +1351,10 @@ fn unzip(f: *Fetch, out_dir: fs.Dir, reader: anytype) RunError!UnpackResult {
13521351 ));
13531352 defer zip_file.close();
13541353
1355 std.zip.extract(out_dir, zip_file.seekableStream(), .{
1354 var zip_file_buffer: [1024]u8 = undefined;
1355 var zip_file_reader = zip_file.reader(&zip_file_buffer);
1356
1357 std.zip.extract(out_dir, &zip_file_reader, .{
13561358 .allow_backslashes = true,
13571359 .diagnostics = &diagnostics,
13581360 }) catch |err| return f.fail(f.location_tok, try eb.printString(
......@@ -1384,23 +1386,26 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource.Git) anyerror!U
13841386 defer pack_dir.close();
13851387 var pack_file = try pack_dir.createFile("pkg.pack", .{ .read = true });
13861388 defer pack_file.close();
1387 var fifo = std.fifo.LinearFifo(u8, .{ .Static = 4096 }).init();
1389 var pack_file_buffer: [4096]u8 = undefined;
1390 var fifo = std.fifo.LinearFifo(u8, .{ .Slice = {} }).init(&pack_file_buffer);
13881391 try fifo.pump(resource.fetch_stream.reader(), pack_file.deprecatedWriter());
13891392
1393 var pack_file_reader = pack_file.reader(&pack_file_buffer);
1394
13901395 var index_file = try pack_dir.createFile("pkg.idx", .{ .read = true });
13911396 defer index_file.close();
13921397 {
13931398 const index_prog_node = f.prog_node.start("Index pack", 0);
13941399 defer index_prog_node.end();
13951400 var index_buffered_writer = std.io.bufferedWriter(index_file.deprecatedWriter());
1396 try git.indexPack(gpa, object_format, pack_file, index_buffered_writer.writer());
1401 try git.indexPack(gpa, object_format, &pack_file_reader, index_buffered_writer.writer());
13971402 try index_buffered_writer.flush();
13981403 }
13991404
14001405 {
14011406 const checkout_prog_node = f.prog_node.start("Checkout", 0);
14021407 defer checkout_prog_node.end();
1403 var repository = try git.Repository.init(gpa, object_format, pack_file, index_file);
1408 var repository = try git.Repository.init(gpa, object_format, &pack_file_reader, index_file);
14041409 defer repository.deinit();
14051410 var diagnostics: git.Diagnostics = .{ .allocator = arena };
14061411 try repository.checkout(out_dir, resource.want_oid, &diagnostics);
src/Package/Fetch/git.zig+32-35
......@@ -73,7 +73,7 @@ pub const Oid = union(Format) {
7373 };
7474 }
7575
76 pub fn readBytes(oid_format: Format, reader: anytype) @TypeOf(reader).NoEofError!Oid {
76 pub fn readBytes(oid_format: Format, reader: anytype) !Oid {
7777 return switch (oid_format) {
7878 inline else => |tag| @unionInit(Oid, @tagName(tag), try reader.readBytesNoEof(tag.byteLength())),
7979 };
......@@ -166,7 +166,7 @@ pub const Diagnostics = struct {
166166pub const Repository = struct {
167167 odb: Odb,
168168
169 pub fn init(allocator: Allocator, format: Oid.Format, pack_file: std.fs.File, index_file: std.fs.File) !Repository {
169 pub fn init(allocator: Allocator, format: Oid.Format, pack_file: *std.fs.File.Reader, index_file: std.fs.File) !Repository {
170170 return .{ .odb = try Odb.init(allocator, format, pack_file, index_file) };
171171 }
172172
......@@ -335,14 +335,14 @@ pub const Repository = struct {
335335/// [pack-format](https://git-scm.com/docs/pack-format).
336336const Odb = struct {
337337 format: Oid.Format,
338 pack_file: std.fs.File,
338 pack_file: *std.fs.File.Reader,
339339 index_header: IndexHeader,
340340 index_file: std.fs.File,
341341 cache: ObjectCache = .{},
342342 allocator: Allocator,
343343
344344 /// Initializes the database from open pack and index files.
345 fn init(allocator: Allocator, format: Oid.Format, pack_file: std.fs.File, index_file: std.fs.File) !Odb {
345 fn init(allocator: Allocator, format: Oid.Format, pack_file: *std.fs.File.Reader, index_file: std.fs.File) !Odb {
346346 try pack_file.seekTo(0);
347347 try index_file.seekTo(0);
348348 const index_header = try IndexHeader.read(index_file.deprecatedReader());
......@@ -362,14 +362,14 @@ const Odb = struct {
362362
363363 /// Reads the object at the current position in the database.
364364 fn readObject(odb: *Odb) !Object {
365 var base_offset = try odb.pack_file.getPos();
365 var base_offset = odb.pack_file.logicalPos();
366366 var base_header: EntryHeader = undefined;
367367 var delta_offsets: std.ArrayListUnmanaged(u64) = .empty;
368368 defer delta_offsets.deinit(odb.allocator);
369369 const base_object = while (true) {
370370 if (odb.cache.get(base_offset)) |base_object| break base_object;
371371
372 base_header = try EntryHeader.read(odb.format, odb.pack_file.deprecatedReader());
372 base_header = try EntryHeader.read(odb.format, odb.pack_file.interface.adaptToOldInterface());
373373 switch (base_header) {
374374 .ofs_delta => |ofs_delta| {
375375 try delta_offsets.append(odb.allocator, base_offset);
......@@ -379,10 +379,10 @@ const Odb = struct {
379379 .ref_delta => |ref_delta| {
380380 try delta_offsets.append(odb.allocator, base_offset);
381381 try odb.seekOid(ref_delta.base_object);
382 base_offset = try odb.pack_file.getPos();
382 base_offset = odb.pack_file.logicalPos();
383383 },
384384 else => {
385 const base_data = try readObjectRaw(odb.allocator, odb.pack_file.deprecatedReader(), base_header.uncompressedLength());
385 const base_data = try readObjectRaw(odb.allocator, &odb.pack_file.interface, base_header.uncompressedLength());
386386 errdefer odb.allocator.free(base_data);
387387 const base_object: Object = .{ .type = base_header.objectType(), .data = base_data };
388388 try odb.cache.put(odb.allocator, base_offset, base_object);
......@@ -1227,7 +1227,7 @@ const IndexEntry = struct {
12271227
12281228/// Writes out a version 2 index for the given packfile, as documented in
12291229/// [pack-format](https://git-scm.com/docs/pack-format).
1230pub fn indexPack(allocator: Allocator, format: Oid.Format, pack: std.fs.File, index_writer: anytype) !void {
1230pub fn indexPack(allocator: Allocator, format: Oid.Format, pack: *std.fs.File.Reader, index_writer: anytype) !void {
12311231 try pack.seekTo(0);
12321232
12331233 var index_entries: std.AutoHashMapUnmanaged(Oid, IndexEntry) = .empty;
......@@ -1324,12 +1324,11 @@ pub fn indexPack(allocator: Allocator, format: Oid.Format, pack: std.fs.File, in
13241324fn indexPackFirstPass(
13251325 allocator: Allocator,
13261326 format: Oid.Format,
1327 pack: std.fs.File,
1327 pack: *std.fs.File.Reader,
13281328 index_entries: *std.AutoHashMapUnmanaged(Oid, IndexEntry),
13291329 pending_deltas: *std.ArrayListUnmanaged(IndexEntry),
13301330) !Oid {
1331 var pack_buffered_reader = std.io.bufferedReader(pack.deprecatedReader());
1332 var pack_counting_reader = std.io.countingReader(pack_buffered_reader.reader());
1331 var pack_counting_reader = std.io.countingReader(pack.interface.adaptToOldInterface());
13331332 var pack_hashed_reader = hashedReader(pack_counting_reader.reader(), Oid.Hasher.init(format));
13341333 const pack_reader = pack_hashed_reader.reader();
13351334
......@@ -1340,15 +1339,19 @@ fn indexPackFirstPass(
13401339 const entry_offset = pack_counting_reader.bytes_read;
13411340 var entry_crc32_reader = hashedReader(pack_reader, std.hash.Crc32.init());
13421341 const entry_header = try EntryHeader.read(format, entry_crc32_reader.reader());
1342 var adapter_buffer: [1024]u8 = undefined;
1343 var adapter = entry_crc32_reader.reader().adaptToNewApi(&adapter_buffer);
1344 var flate_buffer: [std.compress.flate.max_window_len]u8 = undefined;
1345 var entry_decompress_stream: std.compress.flate.Decompress = .init(&adapter.new_interface, .zlib, &flate_buffer);
1346 const old = entry_decompress_stream.reader.adaptToOldInterface();
1347 var entry_counting_reader = std.io.countingReader(old);
13431348 switch (entry_header) {
13441349 .commit, .tree, .blob, .tag => |object| {
1345 var entry_decompress_stream = std.compress.zlib.decompressor(entry_crc32_reader.reader());
1346 var entry_counting_reader = std.io.countingReader(entry_decompress_stream.reader());
13471350 var entry_hashed_writer = hashedWriter(std.io.null_writer, Oid.Hasher.init(format));
13481351 const entry_writer = entry_hashed_writer.writer();
13491352 // The object header is not included in the pack data but is
13501353 // part of the object's ID
1351 try entry_writer.print("{s} {}\x00", .{ @tagName(entry_header), object.uncompressed_length });
1354 try entry_writer.print("{s} {d}\x00", .{ @tagName(entry_header), object.uncompressed_length });
13521355 var fifo = std.fifo.LinearFifo(u8, .{ .Static = 4096 }).init();
13531356 try fifo.pump(entry_counting_reader.reader(), entry_writer);
13541357 if (entry_counting_reader.bytes_read != object.uncompressed_length) {
......@@ -1361,8 +1364,6 @@ fn indexPackFirstPass(
13611364 });
13621365 },
13631366 inline .ofs_delta, .ref_delta => |delta| {
1364 var entry_decompress_stream = std.compress.zlib.decompressor(entry_crc32_reader.reader());
1365 var entry_counting_reader = std.io.countingReader(entry_decompress_stream.reader());
13661367 var fifo = std.fifo.LinearFifo(u8, .{ .Static = 4096 }).init();
13671368 try fifo.pump(entry_counting_reader.reader(), std.io.null_writer);
13681369 if (entry_counting_reader.bytes_read != delta.uncompressed_length) {
......@@ -1377,7 +1378,7 @@ fn indexPackFirstPass(
13771378 }
13781379
13791380 const pack_checksum = pack_hashed_reader.hasher.finalResult();
1380 const recorded_checksum = try Oid.readBytes(format, pack_buffered_reader.reader());
1381 const recorded_checksum = try Oid.readBytes(format, pack.interface.adaptToOldInterface());
13811382 if (!mem.eql(u8, pack_checksum.slice(), recorded_checksum.slice())) {
13821383 return error.CorruptedPack;
13831384 }
......@@ -1394,7 +1395,7 @@ fn indexPackFirstPass(
13941395fn indexPackHashDelta(
13951396 allocator: Allocator,
13961397 format: Oid.Format,
1397 pack: std.fs.File,
1398 pack: *std.fs.File.Reader,
13981399 delta: IndexEntry,
13991400 index_entries: std.AutoHashMapUnmanaged(Oid, IndexEntry),
14001401 cache: *ObjectCache,
......@@ -1408,7 +1409,7 @@ fn indexPackHashDelta(
14081409 if (cache.get(base_offset)) |base_object| break base_object;
14091410
14101411 try pack.seekTo(base_offset);
1411 base_header = try EntryHeader.read(format, pack.deprecatedReader());
1412 base_header = try EntryHeader.read(format, pack.interface.adaptToOldInterface());
14121413 switch (base_header) {
14131414 .ofs_delta => |ofs_delta| {
14141415 try delta_offsets.append(allocator, base_offset);
......@@ -1419,7 +1420,7 @@ fn indexPackHashDelta(
14191420 base_offset = (index_entries.get(ref_delta.base_object) orelse return null).offset;
14201421 },
14211422 else => {
1422 const base_data = try readObjectRaw(allocator, pack.deprecatedReader(), base_header.uncompressedLength());
1423 const base_data = try readObjectRaw(allocator, &pack.interface, base_header.uncompressedLength());
14231424 errdefer allocator.free(base_data);
14241425 const base_object: Object = .{ .type = base_header.objectType(), .data = base_data };
14251426 try cache.put(allocator, base_offset, base_object);
......@@ -1444,7 +1445,7 @@ fn indexPackHashDelta(
14441445fn resolveDeltaChain(
14451446 allocator: Allocator,
14461447 format: Oid.Format,
1447 pack: std.fs.File,
1448 pack: *std.fs.File.Reader,
14481449 base_object: Object,
14491450 delta_offsets: []const u64,
14501451 cache: *ObjectCache,
......@@ -1456,8 +1457,8 @@ fn resolveDeltaChain(
14561457
14571458 const delta_offset = delta_offsets[i];
14581459 try pack.seekTo(delta_offset);
1459 const delta_header = try EntryHeader.read(format, pack.deprecatedReader());
1460 const delta_data = try readObjectRaw(allocator, pack.deprecatedReader(), delta_header.uncompressedLength());
1460 const delta_header = try EntryHeader.read(format, pack.interface.adaptToOldInterface());
1461 const delta_data = try readObjectRaw(allocator, &pack.interface, delta_header.uncompressedLength());
14611462 defer allocator.free(delta_data);
14621463 var delta_stream = std.io.fixedBufferStream(delta_data);
14631464 const delta_reader = delta_stream.reader();
......@@ -1481,18 +1482,14 @@ fn resolveDeltaChain(
14811482/// Reads the complete contents of an object from `reader`. This function may
14821483/// read more bytes than required from `reader`, so the reader position after
14831484/// returning is not reliable.
1484fn readObjectRaw(allocator: Allocator, reader: anytype, size: u64) ![]u8 {
1485fn readObjectRaw(allocator: Allocator, reader: *std.Io.Reader, size: u64) ![]u8 {
14851486 const alloc_size = std.math.cast(usize, size) orelse return error.ObjectTooLarge;
1486 var buffered_reader = std.io.bufferedReader(reader);
1487 var decompress_stream = std.compress.zlib.decompressor(buffered_reader.reader());
1488 const data = try allocator.alloc(u8, alloc_size);
1489 errdefer allocator.free(data);
1490 try decompress_stream.reader().readNoEof(data);
1491 _ = decompress_stream.reader().readByte() catch |e| switch (e) {
1492 error.EndOfStream => return data,
1493 else => |other| return other,
1494 };
1495 return error.InvalidFormat;
1487 var aw: std.Io.Writer.Allocating = .init(allocator);
1488 try aw.ensureTotalCapacity(alloc_size);
1489 defer aw.deinit();
1490 var decompress: std.compress.flate.Decompress = .init(reader, .zlib, &.{});
1491 try decompress.reader.streamExact(&aw.writer, alloc_size);
1492 return aw.toOwnedSlice();
14961493}
14971494
14981495/// Expands delta data from `delta_reader` to `writer`. `base_object` must
src/link/Elf/Object.zig+7-8
......@@ -1198,15 +1198,14 @@ pub fn codeDecompressAlloc(self: *Object, elf_file: *Elf, atom_index: Atom.Index
11981198 const chdr = @as(*align(1) const elf.Elf64_Chdr, @ptrCast(data.ptr)).*;
11991199 switch (chdr.ch_type) {
12001200 .ZLIB => {
1201 var stream = std.io.fixedBufferStream(data[@sizeOf(elf.Elf64_Chdr)..]);
1202 var zlib_stream = std.compress.zlib.decompressor(stream.reader());
1201 var stream: std.Io.Reader = .fixed(data[@sizeOf(elf.Elf64_Chdr)..]);
1202 var zlib_stream: std.compress.flate.Decompress = .init(&stream, .zlib, &.{});
12031203 const size = std.math.cast(usize, chdr.ch_size) orelse return error.Overflow;
1204 const decomp = try gpa.alloc(u8, size);
1205 const nread = zlib_stream.reader().readAll(decomp) catch return error.InputOutput;
1206 if (nread != decomp.len) {
1207 return error.InputOutput;
1208 }
1209 return decomp;
1204 var aw: std.Io.Writer.Allocating = .init(gpa);
1205 try aw.ensureUnusedCapacity(size);
1206 defer aw.deinit();
1207 _ = try zlib_stream.reader.streamRemaining(&aw.writer);
1208 return aw.toOwnedSlice();
12101209 },
12111210 else => @panic("TODO unhandled compression scheme"),
12121211 }