authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-06-22 00:58:32-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-01 16:35:29-07:00
log52b3275eb2cc11a9d81510f465458208eddfd796
tree9fec2cae59198233cc7becc6a5f5a6f58ebdd9fa
parenta249cc1c7e5d9ac580d8f0cace9c7e3bfffffe57

readable -> reader / writable -> writer


10 files changed, 53 insertions(+), 80 deletions(-)

lib/std/compress/flate/Compress.zig+3-11
...@@ -70,12 +70,10 @@ hasher: Container.Hasher,...@@ -70,12 +70,10 @@ hasher: Container.Hasher,
70prev_match: ?Token = null,70prev_match: ?Token = null,
71prev_literal: ?u8 = null,71prev_literal: ?u8 = null,
7272
73pub fn readable(c: *Compress, buffer: []u8) std.io.Reader {73pub fn reader(c: *Compress, buffer: []u8) std.io.Reader {
74 return .{74 return .{
75 .unbuffered_reader = .{75 .context = c,
76 .context = c,76 .vtable = .{ .read = read },
77 .vtable = .{ .read = read },
78 },
79 .buffer = buffer,77 .buffer = buffer,
80 };78 };
81}79}
...@@ -337,12 +335,6 @@ pub const Huffman = SimpleCompressor(.huffman, .raw);...@@ -337,12 +335,6 @@ pub const Huffman = SimpleCompressor(.huffman, .raw);
337/// store blocks. That adds 9 bytes of header for each block. Max stored block335/// store blocks. That adds 9 bytes of header for each block. Max stored block
338/// size is 64K. Block is emitted when flush is called on on finish.336/// size is 64K. Block is emitted when flush is called on on finish.
339pub const store = struct {337pub const store = struct {
340 pub fn compress(comptime container: Container, reader: anytype, writer: anytype) !void {
341 var c = try store.compressor(container, writer);
342 try c.compress(reader);
343 try c.finish();
344 }
345
346 pub fn Compressor(comptime container: Container, comptime WriterType: type) type {338 pub fn Compressor(comptime container: Container, comptime WriterType: type) type {
347 return SimpleCompressor(.store, container, WriterType);339 return SimpleCompressor(.store, container, WriterType);
348 }340 }
lib/std/compress/flate/Decompress.zig+2-5
...@@ -355,17 +355,14 @@ fn writeMatch(bw: *Writer, length: u16, distance: u16) !void {...@@ -355,17 +355,14 @@ fn writeMatch(bw: *Writer, length: u16, distance: u16) !void {
355 @panic("TODO");355 @panic("TODO");
356}356}
357357
358pub fn reader(self: *Decompress) std.io.Reader {358pub fn reader(self: *Decompress, buffer: []u8) std.io.Reader {
359 return .{359 return .{
360 .context = self,360 .context = self,
361 .vtable = &.{ .read = read },361 .vtable = &.{ .read = read },
362 .buffer = buffer,
362 };363 };
363}364}
364365
365pub fn readable(self: *Decompress, buffer: []u8) std.io.Reader {
366 return reader(self).buffered(buffer);
367}
368
369fn takeBits(d: *Decompress, comptime T: type) !T {366fn takeBits(d: *Decompress, comptime T: type) !T {
370 _ = d;367 _ = d;
371 @panic("TODO");368 @panic("TODO");
lib/std/crypto/Sha1.zig+1-1
...@@ -413,7 +413,7 @@ test "splat" {...@@ -413,7 +413,7 @@ test "splat" {
413 };413 };
414 const stream_result = r: {414 const stream_result = r: {
415 var sha1: Sha1 = .init(.{});415 var sha1: Sha1 = .init(.{});
416 var bw = sha1.writable(&.{});416 var bw = sha1.writer(&.{});
417 try bw.writeSplatAll(&vecs, splat_len);417 try bw.writeSplatAll(&vecs, splat_len);
418 try std.testing.expectEqual(vecs[0].len + vecs[1].len + vecs[2].len * splat_len, sha1.total_len);418 try std.testing.expectEqual(vecs[0].len + vecs[1].len + vecs[2].len * splat_len, sha1.total_len);
419 break :r sha1.finalResult();419 break :r sha1.finalResult();
lib/std/elf.zig+4-8
...@@ -594,8 +594,7 @@ pub const ProgramHeaderIterator = struct {...@@ -594,8 +594,7 @@ pub const ProgramHeaderIterator = struct {
594 var phdr: Elf64_Phdr = undefined;594 var phdr: Elf64_Phdr = undefined;
595 const offset = it.elf_header.phoff + @sizeOf(@TypeOf(phdr)) * it.index;595 const offset = it.elf_header.phoff + @sizeOf(@TypeOf(phdr)) * it.index;
596 try it.file_reader.seekTo(offset);596 try it.file_reader.seekTo(offset);
597 var br = it.file_reader.readable(&.{});597 try it.file_reader.interface.readSlice(@ptrCast(&phdr));
598 try br.readSlice(@ptrCast(&phdr));
599 if (it.elf_header.endian != native_endian)598 if (it.elf_header.endian != native_endian)
600 mem.byteSwapAllFields(Elf64_Phdr, &phdr);599 mem.byteSwapAllFields(Elf64_Phdr, &phdr);
601 return phdr;600 return phdr;
...@@ -604,8 +603,7 @@ pub const ProgramHeaderIterator = struct {...@@ -604,8 +603,7 @@ pub const ProgramHeaderIterator = struct {
604 var phdr: Elf32_Phdr = undefined;603 var phdr: Elf32_Phdr = undefined;
605 const offset = it.elf_header.phoff + @sizeOf(@TypeOf(phdr)) * it.index;604 const offset = it.elf_header.phoff + @sizeOf(@TypeOf(phdr)) * it.index;
606 try it.file_reader.seekTo(offset);605 try it.file_reader.seekTo(offset);
607 var br = it.file_reader.readable(&.{});606 try it.file_reader.interface.readSlice(@ptrCast(&phdr));
608 try br.readSlice(@ptrCast(&phdr));
609 if (it.elf_header.endian != native_endian)607 if (it.elf_header.endian != native_endian)
610 mem.byteSwapAllFields(Elf32_Phdr, &phdr);608 mem.byteSwapAllFields(Elf32_Phdr, &phdr);
611 return .{609 return .{
...@@ -634,8 +632,7 @@ pub const SectionHeaderIterator = struct {...@@ -634,8 +632,7 @@ pub const SectionHeaderIterator = struct {
634 var shdr: Elf64_Shdr = undefined;632 var shdr: Elf64_Shdr = undefined;
635 const offset = it.elf_header.shoff + @sizeOf(@TypeOf(shdr)) * it.index;633 const offset = it.elf_header.shoff + @sizeOf(@TypeOf(shdr)) * it.index;
636 try it.file_reader.seekTo(offset);634 try it.file_reader.seekTo(offset);
637 var br = it.file_reader.readable(&.{});635 try it.file_reader.interface.readSlice(@ptrCast(&shdr));
638 try br.readSlice(@ptrCast(&shdr));
639 if (it.elf_header.endian != native_endian)636 if (it.elf_header.endian != native_endian)
640 mem.byteSwapAllFields(Elf64_Shdr, &shdr);637 mem.byteSwapAllFields(Elf64_Shdr, &shdr);
641 return shdr;638 return shdr;
...@@ -644,8 +641,7 @@ pub const SectionHeaderIterator = struct {...@@ -644,8 +641,7 @@ pub const SectionHeaderIterator = struct {
644 var shdr: Elf32_Shdr = undefined;641 var shdr: Elf32_Shdr = undefined;
645 const offset = it.elf_header.shoff + @sizeOf(@TypeOf(shdr)) * it.index;642 const offset = it.elf_header.shoff + @sizeOf(@TypeOf(shdr)) * it.index;
646 try it.file_reader.seekTo(offset);643 try it.file_reader.seekTo(offset);
647 var br = it.file_reader.readable(&.{});644 try it.file_reader.interface.readSlice(@ptrCast(&shdr));
648 try br.readSlice(@ptrCast(&shdr));
649 if (it.elf_header.endian != native_endian)645 if (it.elf_header.endian != native_endian)
650 mem.byteSwapAllFields(Elf32_Shdr, &shdr);646 mem.byteSwapAllFields(Elf32_Shdr, &shdr);
651 return .{647 return .{
lib/std/fs/Dir.zig+1-1
...@@ -2617,7 +2617,7 @@ pub fn updateFile(...@@ -2617,7 +2617,7 @@ pub fn updateFile(
2617 .size = src_stat.size,2617 .size = src_stat.size,
2618 };2618 };
2619 var buffer: [2000]u8 = undefined;2619 var buffer: [2000]u8 = undefined;
2620 var dest_writer = atomic_file.file_writer.writable(&buffer);2620 var dest_writer = atomic_file.file_writer.writer(&buffer);
26212621
2622 dest_writer.writeFileAll(&src_reader, .{}) catch |err| switch (err) {2622 dest_writer.writeFileAll(&src_reader, .{}) catch |err| switch (err) {
2623 error.ReadFailed => return src_reader.err.?,2623 error.ReadFailed => return src_reader.err.?,
lib/std/io/Reader.zig+1-1
...@@ -1448,7 +1448,7 @@ pub fn Hashed(comptime Hasher: type) type {...@@ -1448,7 +1448,7 @@ pub fn Hashed(comptime Hasher: type) type {
14481448
1449 fn discard(r: *Reader, limit: Limit) Error!usize {1449 fn discard(r: *Reader, limit: Limit) Error!usize {
1450 const this: *@This() = @alignCast(@fieldParentPtr("interface", r));1450 const this: *@This() = @alignCast(@fieldParentPtr("interface", r));
1451 var w = this.hasher.writable(&.{});1451 var w = this.hasher.writer(&.{});
1452 const n = this.in.read(&w, limit) catch |err| switch (err) {1452 const n = this.in.read(&w, limit) catch |err| switch (err) {
1453 error.WriteFailed => unreachable,1453 error.WriteFailed => unreachable,
1454 else => |e| return e,1454 else => |e| return e,
lib/std/zip.zig+2-2
...@@ -571,7 +571,7 @@ pub const Iterator = struct {...@@ -571,7 +571,7 @@ pub const Iterator = struct {
571 };571 };
572 defer out_file.close();572 defer out_file.close();
573 var file_writer = out_file.writer();573 var file_writer = out_file.writer();
574 var file_bw = file_writer.writable(&.{});574 var file_bw = file_writer.writer(&.{});
575 const local_data_file_offset: u64 =575 const local_data_file_offset: u64 =
576 @as(u64, self.file_offset) +576 @as(u64, self.file_offset) +
577 @as(u64, @sizeOf(LocalFileHeader)) +577 @as(u64, @sizeOf(LocalFileHeader)) +
...@@ -585,7 +585,7 @@ pub const Iterator = struct {...@@ -585,7 +585,7 @@ pub const Iterator = struct {
585 var decompress_br = decompress.readable(&limited_br, self.compression_method, &decompress_read_buffer);585 var decompress_br = decompress.readable(&limited_br, self.compression_method, &decompress_read_buffer);
586 const start_out = file_bw.count;586 const start_out = file_bw.count;
587 var hash_writer = file_bw.hashed(std.hash.Crc32.init());587 var hash_writer = file_bw.hashed(std.hash.Crc32.init());
588 var hash_bw = hash_writer.writable(&.{});588 var hash_bw = hash_writer.writer(&.{});
589 decompress_br.readAll(&hash_bw, .limited(self.uncompressed_size)) catch |err| switch (err) {589 decompress_br.readAll(&hash_bw, .limited(self.uncompressed_size)) catch |err| switch (err) {
590 error.ReadFailed => return stream.err.?,590 error.ReadFailed => return stream.err.?,
591 error.WriteFailed => return file_writer.err.?,591 error.WriteFailed => return file_writer.err.?,
lib/std/zip/test.zig+14-15
...@@ -34,10 +34,9 @@ fn expectFiles(...@@ -34,10 +34,9 @@ fn expectFiles(
34 std.mem.replaceScalar(u8, normalized_sub_path, '\\', '/');34 std.mem.replaceScalar(u8, normalized_sub_path, '\\', '/');
35 var file = try dir.openFile(normalized_sub_path, .{});35 var file = try dir.openFile(normalized_sub_path, .{});
36 defer file.close();36 defer file.close();
37 var file_reader = file.reader();
38 var file_br = file_reader.readable(&.{});
39 var content_buf: [4096]u8 = undefined;37 var content_buf: [4096]u8 = undefined;
40 const n = try file_br.readSliceShort(&content_buf);38 var file_reader = file.reader(&content_buf);
39 const n = try file_reader.interface.readSliceShort(&content_buf);
41 try testing.expectEqualStrings(test_file.content, content_buf[0..n]);40 try testing.expectEqualStrings(test_file.content, content_buf[0..n]);
42 }41 }
43}42}
...@@ -65,7 +64,7 @@ fn makeZipWithStore(...@@ -65,7 +64,7 @@ fn makeZipWithStore(
65 store: []FileStore,64 store: []FileStore,
66) !void {65) !void {
67 var buffer: [200]u8 = undefined;66 var buffer: [200]u8 = undefined;
68 var bw = file_writer.writable(&buffer);67 var bw = file_writer.writer(&buffer);
69 try writeZip(&bw, files, store, options);68 try writeZip(&bw, files, store, options);
70}69}
7170
...@@ -201,7 +200,7 @@ const Zipper = struct {...@@ -201,7 +200,7 @@ const Zipper = struct {
201 const offset = writer.count;200 const offset = writer.count;
202 var br: std.io.Reader = .fixed(opt.content);201 var br: std.io.Reader = .fixed(opt.content);
203 var compress: std.compress.flate.Compress = .init(&br, .{});202 var compress: std.compress.flate.Compress = .init(&br, .{});
204 var compress_br = compress.readable(&.{});203 var compress_br = compress.reader(&.{});
205 const n = try compress_br.readRemaining(writer);204 const n = try compress_br.readRemaining(writer);
206 assert(br.seek == opt.content.len);205 assert(br.seek == opt.content.len);
207 try testing.expectEqual(n, writer.count - offset);206 try testing.expectEqual(n, writer.count - offset);
...@@ -431,7 +430,7 @@ test "bad zip files" {...@@ -431,7 +430,7 @@ test "bad zip files" {
431 {430 {
432 const tmp_file = tmp.createFile();431 const tmp_file = tmp.createFile();
433 defer tmp_file.close();432 defer tmp_file.close();
434 var file_writer = tmp_file.writable(&buffer);433 var file_writer = tmp_file.writer(&buffer);
435 try makeZip(&file_writer, &.{}, .{ .end = .{ .sig = [_]u8{ 1, 2, 3, 4 } } });434 try makeZip(&file_writer, &.{}, .{ .end = .{ .sig = [_]u8{ 1, 2, 3, 4 } } });
436 var file_reader = file_writer.moveToReader();435 var file_reader = file_writer.moveToReader();
437 try testing.expectError(error.ZipNoEndRecord, zip.extract(tmp.dir, &file_reader, .{}));436 try testing.expectError(error.ZipNoEndRecord, zip.extract(tmp.dir, &file_reader, .{}));
...@@ -439,7 +438,7 @@ test "bad zip files" {...@@ -439,7 +438,7 @@ test "bad zip files" {
439 {438 {
440 const tmp_file = tmp.createFile();439 const tmp_file = tmp.createFile();
441 defer tmp_file.close();440 defer tmp_file.close();
442 var file_writer = tmp_file.writable(&buffer);441 var file_writer = tmp_file.writer(&buffer);
443 try makeZip(&file_writer, &.{}, .{ .end = .{ .comment_len = 1 } });442 try makeZip(&file_writer, &.{}, .{ .end = .{ .comment_len = 1 } });
444 var file_reader = file_writer.moveToReader();443 var file_reader = file_writer.moveToReader();
445 try testing.expectError(error.ZipNoEndRecord, zip.extract(tmp.dir, &file_reader, .{}));444 try testing.expectError(error.ZipNoEndRecord, zip.extract(tmp.dir, &file_reader, .{}));
...@@ -447,7 +446,7 @@ test "bad zip files" {...@@ -447,7 +446,7 @@ test "bad zip files" {
447 {446 {
448 const tmp_file = tmp.createFile();447 const tmp_file = tmp.createFile();
449 defer tmp_file.close();448 defer tmp_file.close();
450 var file_writer = tmp_file.writable(&buffer);449 var file_writer = tmp_file.writer(&buffer);
451 try makeZip(&file_writer, &.{}, .{ .end = .{ .comment = "a", .comment_len = 0 } });450 try makeZip(&file_writer, &.{}, .{ .end = .{ .comment = "a", .comment_len = 0 } });
452 var file_reader = file_writer.moveToReader();451 var file_reader = file_writer.moveToReader();
453 try testing.expectError(error.ZipNoEndRecord, zip.extract(tmp.dir, &file_reader, .{}));452 try testing.expectError(error.ZipNoEndRecord, zip.extract(tmp.dir, &file_reader, .{}));
...@@ -455,7 +454,7 @@ test "bad zip files" {...@@ -455,7 +454,7 @@ test "bad zip files" {
455 {454 {
456 const tmp_file = tmp.createFile();455 const tmp_file = tmp.createFile();
457 defer tmp_file.close();456 defer tmp_file.close();
458 var file_writer = tmp_file.writable(&buffer);457 var file_writer = tmp_file.writer(&buffer);
459 try makeZip(&file_writer, &.{}, .{ .end = .{ .disk_number = 1 } });458 try makeZip(&file_writer, &.{}, .{ .end = .{ .disk_number = 1 } });
460 var file_reader = file_writer.moveToReader();459 var file_reader = file_writer.moveToReader();
461 try testing.expectError(error.ZipMultiDiskUnsupported, zip.extract(tmp.dir, &file_reader, .{}));460 try testing.expectError(error.ZipMultiDiskUnsupported, zip.extract(tmp.dir, &file_reader, .{}));
...@@ -463,7 +462,7 @@ test "bad zip files" {...@@ -463,7 +462,7 @@ test "bad zip files" {
463 {462 {
464 const tmp_file = tmp.createFile();463 const tmp_file = tmp.createFile();
465 defer tmp_file.close();464 defer tmp_file.close();
466 var file_writer = tmp_file.writable(&buffer);465 var file_writer = tmp_file.writer(&buffer);
467 try makeZip(&file_writer, &.{}, .{ .end = .{ .central_directory_disk_number = 1 } });466 try makeZip(&file_writer, &.{}, .{ .end = .{ .central_directory_disk_number = 1 } });
468 var file_reader = file_writer.moveToReader();467 var file_reader = file_writer.moveToReader();
469 try testing.expectError(error.ZipMultiDiskUnsupported, zip.extract(tmp.dir, &file_reader, .{}));468 try testing.expectError(error.ZipMultiDiskUnsupported, zip.extract(tmp.dir, &file_reader, .{}));
...@@ -471,7 +470,7 @@ test "bad zip files" {...@@ -471,7 +470,7 @@ test "bad zip files" {
471 {470 {
472 const tmp_file = tmp.createFile();471 const tmp_file = tmp.createFile();
473 defer tmp_file.close();472 defer tmp_file.close();
474 var file_writer = tmp_file.writable(&buffer);473 var file_writer = tmp_file.writer(&buffer);
475 try makeZip(&file_writer, &.{}, .{ .end = .{ .record_count_disk = 1 } });474 try makeZip(&file_writer, &.{}, .{ .end = .{ .record_count_disk = 1 } });
476 var file_reader = file_writer.moveToReader();475 var file_reader = file_writer.moveToReader();
477 try testing.expectError(error.ZipDiskRecordCountTooLarge, zip.extract(tmp.dir, &file_reader, .{}));476 try testing.expectError(error.ZipDiskRecordCountTooLarge, zip.extract(tmp.dir, &file_reader, .{}));
...@@ -479,7 +478,7 @@ test "bad zip files" {...@@ -479,7 +478,7 @@ test "bad zip files" {
479 {478 {
480 const tmp_file = tmp.createFile();479 const tmp_file = tmp.createFile();
481 defer tmp_file.close();480 defer tmp_file.close();
482 var file_writer = tmp_file.writable(&buffer);481 var file_writer = tmp_file.writer(&buffer);
483 try makeZip(&file_writer, &.{}, .{ .end = .{ .central_directory_size = 1 } });482 try makeZip(&file_writer, &.{}, .{ .end = .{ .central_directory_size = 1 } });
484 var file_reader = file_writer.moveToReader();483 var file_reader = file_writer.moveToReader();
485 try testing.expectError(error.ZipCdOversized, zip.extract(tmp.dir, &file_reader, .{}));484 try testing.expectError(error.ZipCdOversized, zip.extract(tmp.dir, &file_reader, .{}));
...@@ -487,7 +486,7 @@ test "bad zip files" {...@@ -487,7 +486,7 @@ test "bad zip files" {
487 {486 {
488 const tmp_file = tmp.createFile();487 const tmp_file = tmp.createFile();
489 defer tmp_file.close();488 defer tmp_file.close();
490 var file_writer = tmp_file.writable(&buffer);489 var file_writer = tmp_file.writer(&buffer);
491 try makeZip(&file_writer, &file_a, .{ .end = .{ .central_directory_size = 0 } });490 try makeZip(&file_writer, &file_a, .{ .end = .{ .central_directory_size = 0 } });
492 var file_reader = file_writer.moveToReader();491 var file_reader = file_writer.moveToReader();
493 try testing.expectError(error.ZipCdUndersized, zip.extract(tmp.dir, &file_reader, .{}));492 try testing.expectError(error.ZipCdUndersized, zip.extract(tmp.dir, &file_reader, .{}));
...@@ -495,7 +494,7 @@ test "bad zip files" {...@@ -495,7 +494,7 @@ test "bad zip files" {
495 {494 {
496 const tmp_file = tmp.createFile();495 const tmp_file = tmp.createFile();
497 defer tmp_file.close();496 defer tmp_file.close();
498 var file_writer = tmp_file.writable(&buffer);497 var file_writer = tmp_file.writer(&buffer);
499 try makeZip(&file_writer, &file_a, .{ .end = .{ .central_directory_offset = 0 } });498 try makeZip(&file_writer, &file_a, .{ .end = .{ .central_directory_offset = 0 } });
500 var file_reader = file_writer.moveToReader();499 var file_reader = file_writer.moveToReader();
501 try testing.expectError(error.ZipBadCdOffset, zip.extract(tmp.dir, &file_reader, .{}));500 try testing.expectError(error.ZipBadCdOffset, zip.extract(tmp.dir, &file_reader, .{}));
...@@ -503,7 +502,7 @@ test "bad zip files" {...@@ -503,7 +502,7 @@ test "bad zip files" {
503 {502 {
504 const tmp_file = tmp.createFile();503 const tmp_file = tmp.createFile();
505 defer tmp_file.close();504 defer tmp_file.close();
506 var file_writer = tmp_file.writable(&buffer);505 var file_writer = tmp_file.writer(&buffer);
507 try makeZip(&file_writer, &file_a, .{506 try makeZip(&file_writer, &file_a, .{
508 .end = .{507 .end = .{
509 .zip64 = .{ .locator_sig = [_]u8{ 1, 2, 3, 4 } },508 .zip64 = .{ .locator_sig = [_]u8{ 1, 2, 3, 4 } },
src/Package/Fetch/git.zig+22-32
...@@ -68,7 +68,7 @@ pub const Oid = union(Format) {...@@ -68,7 +68,7 @@ pub const Oid = union(Format) {
6868
69 pub fn writer(hasher: *Hasher, buffer: []u8) Writer {69 pub fn writer(hasher: *Hasher, buffer: []u8) Writer {
70 return switch (hasher.*) {70 return switch (hasher.*) {
71 inline else => |*inner| inner.writable(buffer),71 inline else => |*inner| inner.writer(buffer),
72 };72 };
73 }73 }
74 };74 };
...@@ -383,9 +383,7 @@ const Odb = struct {...@@ -383,9 +383,7 @@ const Odb = struct {
383 .index_file = index_file,383 .index_file = index_file,
384 .allocator = allocator,384 .allocator = allocator,
385 };385 };
386 var buffer: [1032]u8 = undefined;386 try odb.index_header.read(&index_file.interface);
387 var index_file_br = index_file.readable(&buffer);
388 try odb.index_header.read(&index_file_br);
389 }387 }
390388
391 fn deinit(odb: *Odb) void {389 fn deinit(odb: *Odb) void {
...@@ -395,22 +393,20 @@ const Odb = struct {...@@ -395,22 +393,20 @@ const Odb = struct {
395393
396 /// Reads the object at the current position in the database.394 /// Reads the object at the current position in the database.
397 fn readObject(odb: *Odb) !Object {395 fn readObject(odb: *Odb) !Object {
398 var pack_read_buffer: [64]u8 = undefined;
399 var base_offset = odb.pack_file.pos;396 var base_offset = odb.pack_file.pos;
400 var pack_br = odb.pack_file.readable(&pack_read_buffer);397 const pack_br = &odb.pack_file.interface;
401 var base_header: EntryHeader = undefined;398 var base_header: EntryHeader = undefined;
402 var delta_offsets: std.ArrayListUnmanaged(u64) = .empty;399 var delta_offsets: std.ArrayListUnmanaged(u64) = .empty;
403 defer delta_offsets.deinit(odb.allocator);400 defer delta_offsets.deinit(odb.allocator);
404 const base_object = while (true) {401 const base_object = while (true) {
405 if (odb.cache.get(base_offset)) |base_object| break base_object;402 if (odb.cache.get(base_offset)) |base_object| break base_object;
406403
407 base_header = try EntryHeader.read(odb.format, &pack_br);404 base_header = try EntryHeader.read(odb.format, pack_br);
408 switch (base_header) {405 switch (base_header) {
409 .ofs_delta => |ofs_delta| {406 .ofs_delta => |ofs_delta| {
410 try delta_offsets.append(odb.allocator, base_offset);407 try delta_offsets.append(odb.allocator, base_offset);
411 base_offset = std.math.sub(u64, base_offset, ofs_delta.offset) catch return error.InvalidFormat;408 base_offset = std.math.sub(u64, base_offset, ofs_delta.offset) catch return error.InvalidFormat;
412 try odb.pack_file.seekTo(base_offset);409 try odb.pack_file.seekTo(base_offset);
413 pack_br = odb.pack_file.readable(&pack_read_buffer);
414 },410 },
415 .ref_delta => |ref_delta| {411 .ref_delta => |ref_delta| {
416 try delta_offsets.append(odb.allocator, base_offset);412 try delta_offsets.append(odb.allocator, base_offset);
...@@ -418,7 +414,7 @@ const Odb = struct {...@@ -418,7 +414,7 @@ const Odb = struct {
418 base_offset = odb.pack_file.pos - pack_br.bufferedLen();414 base_offset = odb.pack_file.pos - pack_br.bufferedLen();
419 },415 },
420 else => {416 else => {
421 const base_data = try readObjectRaw(odb.allocator, &pack_br, base_header.uncompressedLength());417 const base_data = try readObjectRaw(odb.allocator, pack_br, base_header.uncompressedLength());
422 errdefer odb.allocator.free(base_data);418 errdefer odb.allocator.free(base_data);
423 const base_object: Object = .{ .type = base_header.objectType(), .data = base_data };419 const base_object: Object = .{ .type = base_header.objectType(), .data = base_data };
424 try odb.cache.put(odb.allocator, base_offset, base_object);420 try odb.cache.put(odb.allocator, base_offset, base_object);
...@@ -1294,10 +1290,10 @@ pub fn indexPack(...@@ -1294,10 +1290,10 @@ pub fn indexPack(
1294 }1290 }
1295 @memset(fan_out_table[fan_out_index..], count);1291 @memset(fan_out_table[fan_out_index..], count);
12961292
1297 var index_writer_bw = index_writer.writable(&.{});1293 var index_writer_bw = index_writer.writer(&.{});
1298 var index_hashed_writer = index_writer_bw.hashed(Oid.Hasher.init(format));1294 var index_hashed_writer = index_writer_bw.hashed(Oid.Hasher.init(format));
1299 var write_buffer: [256]u8 = undefined;1295 var write_buffer: [256]u8 = undefined;
1300 var writer = index_hashed_writer.writable(&write_buffer);1296 var writer = index_hashed_writer.writer(&write_buffer);
1301 try writer.writeAll(IndexHeader.signature);1297 try writer.writeAll(IndexHeader.signature);
1302 try writer.writeInt(u32, IndexHeader.supported_version, .big);1298 try writer.writeInt(u32, IndexHeader.supported_version, .big);
1303 for (fan_out_table) |fan_out_entry| {1299 for (fan_out_table) |fan_out_entry| {
...@@ -1345,27 +1341,25 @@ fn indexPackFirstPass(...@@ -1345,27 +1341,25 @@ fn indexPackFirstPass(
1345 index_entries: *std.AutoHashMapUnmanaged(Oid, IndexEntry),1341 index_entries: *std.AutoHashMapUnmanaged(Oid, IndexEntry),
1346 pending_deltas: *std.ArrayListUnmanaged(IndexEntry),1342 pending_deltas: *std.ArrayListUnmanaged(IndexEntry),
1347) !Oid {1343) !Oid {
1348 var pack_br = pack.readable(&.{});
1349 var pack_hashed_reader = pack_br.hashed(Oid.Hasher.init(format));
1350 var pack_buffer: [2048]u8 = undefined; // Reasonably large buffer for file system.1344 var pack_buffer: [2048]u8 = undefined; // Reasonably large buffer for file system.
1351 var pack_hashed_br = pack_hashed_reader.readable(&pack_buffer);1345 var pack_hashed = pack.interface.hashed(Oid.Hasher.init(format), &pack_buffer);
13521346
1353 const pack_header = try PackHeader.read(&pack_hashed_br);1347 const pack_header = try PackHeader.read(&pack_hashed.interface);
13541348
1355 for (0..pack_header.total_objects) |_| {1349 for (0..pack_header.total_objects) |_| {
1356 const entry_offset = pack.pos - pack_hashed_br.bufferContents().len;1350 const entry_offset = pack.pos - pack_hashed.interface.bufferContents().len;
1357 var entry_crc32_reader = pack_hashed_br.hashed(std.hash.Crc32.init());
1358 var entry_buffer: [64]u8 = undefined; // Buffer only needed for loading EntryHeader.1351 var entry_buffer: [64]u8 = undefined; // Buffer only needed for loading EntryHeader.
1359 var entry_crc32_br = entry_crc32_reader.readable(&entry_buffer);1352 var entry_crc32_reader = pack_hashed.interface.hashed(std.hash.Crc32.init(), &entry_buffer);
1353 const entry_crc32_br = &entry_crc32_reader.interface;
1360 const entry_header = try EntryHeader.read(format, &entry_crc32_br);1354 const entry_header = try EntryHeader.read(format, &entry_crc32_br);
1361 var entry_decompress_stream: zlib.Decompressor = .init(&entry_crc32_br);1355 var entry_decompress_stream: zlib.Decompressor = .init(&entry_crc32_br);
1362 // Decompress uses large output buffer; no input buffer needed.1356 // Decompress uses large output buffer; no input buffer needed.
1363 var entry_decompress_br = entry_decompress_stream.readable(&.{});1357 var entry_decompress_br = entry_decompress_stream.reader(&.{});
1364 switch (entry_header) {1358 switch (entry_header) {
1365 .commit, .tree, .blob, .tag => |object| {1359 .commit, .tree, .blob, .tag => |object| {
1366 var oid_hasher = Oid.Hasher.init(format);1360 var oid_hasher = Oid.Hasher.init(format);
1367 var oid_hasher_buffer: [zlib.max_window_len]u8 = undefined;1361 var oid_hasher_buffer: [zlib.max_window_len]u8 = undefined;
1368 var oid_hasher_bw = oid_hasher.writable(&oid_hasher_buffer);1362 var oid_hasher_bw = oid_hasher.writer(&oid_hasher_buffer);
1369 // The object header is not included in the pack data but is1363 // The object header is not included in the pack data but is
1370 // part of the object's ID.1364 // part of the object's ID.
1371 try oid_hasher_bw.print("{s} {d}\x00", .{ @tagName(entry_header), object.uncompressed_length });1365 try oid_hasher_bw.print("{s} {d}\x00", .{ @tagName(entry_header), object.uncompressed_length });
...@@ -1389,8 +1383,8 @@ fn indexPackFirstPass(...@@ -1389,8 +1383,8 @@ fn indexPackFirstPass(
1389 }1383 }
1390 }1384 }
13911385
1392 const pack_checksum = pack_hashed_reader.hasher.finalResult();1386 const pack_checksum = pack_hashed.hasher.finalResult();
1393 const recorded_checksum = try Oid.readBytes(format, &pack_br);1387 const recorded_checksum = try Oid.readBytes(format, &pack.interface);
1394 if (!mem.eql(u8, pack_checksum.slice(), recorded_checksum.slice())) {1388 if (!mem.eql(u8, pack_checksum.slice(), recorded_checksum.slice())) {
1395 return error.CorruptedPack;1389 return error.CorruptedPack;
1396 }1390 }
...@@ -1417,9 +1411,7 @@ fn indexPackHashDelta(...@@ -1417,9 +1411,7 @@ fn indexPackHashDelta(
1417 if (cache.get(base_offset)) |base_object| break base_object;1411 if (cache.get(base_offset)) |base_object| break base_object;
14181412
1419 try pack.seekTo(base_offset);1413 try pack.seekTo(base_offset);
1420 var pack_read_buffer: [64]u8 = undefined;1414 base_header = try EntryHeader.read(format, &pack.interface);
1421 var pack_br = pack.readable(&pack_read_buffer);
1422 base_header = try EntryHeader.read(format, &pack_br);
1423 switch (base_header) {1415 switch (base_header) {
1424 .ofs_delta => |ofs_delta| {1416 .ofs_delta => |ofs_delta| {
1425 try delta_offsets.append(allocator, base_offset);1417 try delta_offsets.append(allocator, base_offset);
...@@ -1430,7 +1422,7 @@ fn indexPackHashDelta(...@@ -1430,7 +1422,7 @@ fn indexPackHashDelta(
1430 base_offset = (index_entries.get(ref_delta.base_object) orelse return null).offset;1422 base_offset = (index_entries.get(ref_delta.base_object) orelse return null).offset;
1431 },1423 },
1432 else => {1424 else => {
1433 const base_data = try readObjectRaw(allocator, &pack_br, base_header.uncompressedLength());1425 const base_data = try readObjectRaw(allocator, &pack.interface, base_header.uncompressedLength());
1434 errdefer allocator.free(base_data);1426 errdefer allocator.free(base_data);
1435 const base_object: Object = .{ .type = base_header.objectType(), .data = base_data };1427 const base_object: Object = .{ .type = base_header.objectType(), .data = base_data };
1436 try cache.put(allocator, base_offset, base_object);1428 try cache.put(allocator, base_offset, base_object);
...@@ -1443,7 +1435,7 @@ fn indexPackHashDelta(...@@ -1443,7 +1435,7 @@ fn indexPackHashDelta(
14431435
1444 var entry_hasher: Oid.Hasher = .init(format);1436 var entry_hasher: Oid.Hasher = .init(format);
1445 var entry_hasher_buffer: [64]u8 = undefined;1437 var entry_hasher_buffer: [64]u8 = undefined;
1446 var entry_hasher_bw = entry_hasher.writable(&entry_hasher_buffer);1438 var entry_hasher_bw = entry_hasher.writer(&entry_hasher_buffer);
1447 // Writes to hashers cannot fail.1439 // Writes to hashers cannot fail.
1448 entry_hasher_bw.print("{s} {d}\x00", .{ @tagName(base_object.type), base_data.len }) catch unreachable;1440 entry_hasher_bw.print("{s} {d}\x00", .{ @tagName(base_object.type), base_data.len }) catch unreachable;
1449 entry_hasher_bw.writeAll(base_data) catch unreachable;1441 entry_hasher_bw.writeAll(base_data) catch unreachable;
...@@ -1470,13 +1462,11 @@ fn resolveDeltaChain(...@@ -1470,13 +1462,11 @@ fn resolveDeltaChain(
14701462
1471 const delta_offset = delta_offsets[i];1463 const delta_offset = delta_offsets[i];
1472 try pack.seekTo(delta_offset);1464 try pack.seekTo(delta_offset);
1473 var pack_read_buffer: [64]u8 = undefined;1465 const delta_header = try EntryHeader.read(format, &pack.interface);
1474 var pack_br = pack.readable(&pack_read_buffer);
1475 const delta_header = try EntryHeader.read(format, &pack_br);
1476 _ = delta_header;1466 _ = delta_header;
1477 var delta_decompress: zlib.Decompressor = .init(&pack_br);1467 var delta_decompress: zlib.Decompressor = .init(&pack.interface);
1478 var delta_decompress_buffer: [zlib.max_window_len]u8 = undefined;1468 var delta_decompress_buffer: [zlib.max_window_len]u8 = undefined;
1479 var delta_reader = delta_decompress.readable(&delta_decompress_buffer);1469 var delta_reader = delta_decompress.reader(&delta_decompress_buffer);
1480 _ = try readSizeVarInt(&delta_reader); // base object size1470 _ = try readSizeVarInt(&delta_reader); // base object size
1481 const expanded_size = try readSizeVarInt(&delta_reader);1471 const expanded_size = try readSizeVarInt(&delta_reader);
1482 const expanded_alloc_size = std.math.cast(usize, expanded_size) orelse return error.ObjectTooLarge;1472 const expanded_alloc_size = std.math.cast(usize, expanded_size) orelse return error.ObjectTooLarge;
src/main.zig+3-4
...@@ -3330,11 +3330,10 @@ fn buildOutputType(...@@ -3330,11 +3330,10 @@ fn buildOutputType(
3330 // for the hashing algorithm here and in the cache are the same.3330 // for the hashing algorithm here and in the cache are the same.
3331 // We are providing our own cache key, because this file has nothing3331 // We are providing our own cache key, because this file has nothing
3332 // to do with the cache manifest.3332 // to do with the cache manifest.
3333 var file_writer = f.writer();3333 var file_writer = f.writer(&.{});
3334 var file_writer_bw = file_writer.writable(&.{});3334 var hasher_writer = file_writer.interface.hashed(Cache.Hasher.init("0123456789abcdef"));
3335 var hasher_writer = file_writer_bw.hashed(Cache.Hasher.init("0123456789abcdef"));
3336 var buffer: [1000]u8 = undefined;3335 var buffer: [1000]u8 = undefined;
3337 var bw = hasher_writer.writable(&buffer);3336 var bw = hasher_writer.writer(&buffer);
3338 bw.writeFileAll(.stdin(), .{}) catch |err| switch (err) {3337 bw.writeFileAll(.stdin(), .{}) catch |err| switch (err) {
3339 error.WriteFailed => fatal("failed to write {s}: {s}", .{ dump_path, file_writer.err.? }),3338 error.WriteFailed => fatal("failed to write {s}: {s}", .{ dump_path, file_writer.err.? }),
3340 else => fatal("failed to pipe stdin to {s}: {s}", .{ dump_path, err }),3339 else => fatal("failed to pipe stdin to {s}: {s}", .{ dump_path, err }),