| ... | @@ -1111,24 +1111,21 @@ fn indexPackFirstPass( | ... | @@ -1111,24 +1111,21 @@ fn indexPackFirstPass( |
| 1111 | index_entries: *std.AutoHashMapUnmanaged(Oid, IndexEntry), | 1111 | index_entries: *std.AutoHashMapUnmanaged(Oid, IndexEntry), |
| 1112 | pending_deltas: *std.ArrayListUnmanaged(IndexEntry), | 1112 | pending_deltas: *std.ArrayListUnmanaged(IndexEntry), |
| 1113 | ) ![Sha1.digest_length]u8 { | 1113 | ) ![Sha1.digest_length]u8 { |
| 1114 | var pack_counting_writer = std.io.countingWriter(std.io.null_writer); | 1114 | var pack_buffered_reader = std.io.bufferedReader(pack.reader()); |
| 1115 | var pack_hashed_writer = std.compress.hashedWriter(pack_counting_writer.writer(), Sha1.init(.{})); | 1115 | var pack_counting_reader = std.io.countingReader(pack_buffered_reader.reader()); |
| 1116 | var entry_crc32_writer = std.compress.hashedWriter(pack_hashed_writer.writer(), std.hash.Crc32.init()); | 1116 | var pack_hashed_reader = std.compress.hashedReader(pack_counting_reader.reader(), Sha1.init(.{})); |
| 1117 | var pack_buffered_reader = std.io.bufferedTee(4096, 8, pack.reader(), entry_crc32_writer.writer()); | 1117 | const pack_reader = pack_hashed_reader.reader(); |
| 1118 | const pack_reader = pack_buffered_reader.reader(); | | |
| 1119 | | 1118 | |
| 1120 | const pack_header = try PackHeader.read(pack_reader); | 1119 | const pack_header = try PackHeader.read(pack_reader); |
| 1121 | try pack_buffered_reader.flush(); | | |
| 1122 | | 1120 | |
| 1123 | var current_entry: u32 = 0; | 1121 | var current_entry: u32 = 0; |
| 1124 | while (current_entry < pack_header.total_objects) : (current_entry += 1) { | 1122 | while (current_entry < pack_header.total_objects) : (current_entry += 1) { |
| 1125 | const entry_offset = pack_counting_writer.bytes_written; | 1123 | const entry_offset = pack_counting_reader.bytes_read; |
| 1126 | entry_crc32_writer.hasher = std.hash.Crc32.init(); // reset hasher | 1124 | var entry_crc32_reader = std.compress.hashedReader(pack_reader, std.hash.Crc32.init()); |
| 1127 | const entry_header = try EntryHeader.read(pack_reader); | 1125 | const entry_header = try EntryHeader.read(entry_crc32_reader.reader()); |
| 1128 | | | |
| 1129 | switch (entry_header) { | 1126 | switch (entry_header) { |
| 1130 | .commit, .tree, .blob, .tag => |object| { | 1127 | .commit, .tree, .blob, .tag => |object| { |
| 1131 | var entry_decompress_stream = std.compress.zlib.decompressor(pack_reader); | 1128 | var entry_decompress_stream = std.compress.zlib.decompressor(entry_crc32_reader.reader()); |
| 1132 | var entry_counting_reader = std.io.countingReader(entry_decompress_stream.reader()); | 1129 | var entry_counting_reader = std.io.countingReader(entry_decompress_stream.reader()); |
| 1133 | var entry_hashed_writer = hashedWriter(std.io.null_writer, Sha1.init(.{})); | 1130 | var entry_hashed_writer = hashedWriter(std.io.null_writer, Sha1.init(.{})); |
| 1134 | const entry_writer = entry_hashed_writer.writer(); | 1131 | const entry_writer = entry_hashed_writer.writer(); |
| ... | @@ -1141,33 +1138,29 @@ fn indexPackFirstPass( | ... | @@ -1141,33 +1138,29 @@ fn indexPackFirstPass( |
| 1141 | return error.InvalidObject; | 1138 | return error.InvalidObject; |
| 1142 | } | 1139 | } |
| 1143 | const oid = entry_hashed_writer.hasher.finalResult(); | 1140 | const oid = entry_hashed_writer.hasher.finalResult(); |
| 1144 | pack_buffered_reader.putBack(entry_decompress_stream.unreadBytes()); | | |
| 1145 | try pack_buffered_reader.flush(); | | |
| 1146 | try index_entries.put(allocator, oid, .{ | 1141 | try index_entries.put(allocator, oid, .{ |
| 1147 | .offset = entry_offset, | 1142 | .offset = entry_offset, |
| 1148 | .crc32 = entry_crc32_writer.hasher.final(), | 1143 | .crc32 = entry_crc32_reader.hasher.final(), |
| 1149 | }); | 1144 | }); |
| 1150 | }, | 1145 | }, |
| 1151 | inline .ofs_delta, .ref_delta => |delta| { | 1146 | inline .ofs_delta, .ref_delta => |delta| { |
| 1152 | var entry_decompress_stream = std.compress.zlib.decompressor(pack_reader); | 1147 | var entry_decompress_stream = std.compress.zlib.decompressor(entry_crc32_reader.reader()); |
| 1153 | var entry_counting_reader = std.io.countingReader(entry_decompress_stream.reader()); | 1148 | var entry_counting_reader = std.io.countingReader(entry_decompress_stream.reader()); |
| 1154 | var fifo = std.fifo.LinearFifo(u8, .{ .Static = 4096 }).init(); | 1149 | var fifo = std.fifo.LinearFifo(u8, .{ .Static = 4096 }).init(); |
| 1155 | try fifo.pump(entry_counting_reader.reader(), std.io.null_writer); | 1150 | try fifo.pump(entry_counting_reader.reader(), std.io.null_writer); |
| 1156 | if (entry_counting_reader.bytes_read != delta.uncompressed_length) { | 1151 | if (entry_counting_reader.bytes_read != delta.uncompressed_length) { |
| 1157 | return error.InvalidObject; | 1152 | return error.InvalidObject; |
| 1158 | } | 1153 | } |
| 1159 | pack_buffered_reader.putBack(entry_decompress_stream.unreadBytes()); | | |
| 1160 | try pack_buffered_reader.flush(); | | |
| 1161 | try pending_deltas.append(allocator, .{ | 1154 | try pending_deltas.append(allocator, .{ |
| 1162 | .offset = entry_offset, | 1155 | .offset = entry_offset, |
| 1163 | .crc32 = entry_crc32_writer.hasher.final(), | 1156 | .crc32 = entry_crc32_reader.hasher.final(), |
| 1164 | }); | 1157 | }); |
| 1165 | }, | 1158 | }, |
| 1166 | } | 1159 | } |
| 1167 | } | 1160 | } |
| 1168 | | 1161 | |
| 1169 | const pack_checksum = pack_hashed_writer.hasher.finalResult(); | 1162 | const pack_checksum = pack_hashed_reader.hasher.finalResult(); |
| 1170 | const recorded_checksum = try pack_reader.readBytesNoEof(Sha1.digest_length); | 1163 | const recorded_checksum = try pack_buffered_reader.reader().readBytesNoEof(Sha1.digest_length); |
| 1171 | if (!mem.eql(u8, &pack_checksum, &recorded_checksum)) { | 1164 | if (!mem.eql(u8, &pack_checksum, &recorded_checksum)) { |
| 1172 | return error.CorruptedPack; | 1165 | return error.CorruptedPack; |
| 1173 | } | 1166 | } |