| ... | ... | @@ -45,6 +45,7 @@ pub const DecodeState = struct { |
| 45 | 45 | huffman_tree: ?LiteralsSection.HuffmanTree, |
| 46 | 46 | |
| 47 | 47 | literal_written_count: usize, |
| 48 | written_count: usize = 0, |
| 48 | 49 | |
| 49 | 50 | fn StateData(comptime max_accuracy_log: comptime_int) type { |
| 50 | 51 | return struct { |
| ... | ... | @@ -84,6 +85,8 @@ pub const DecodeState = struct { |
| 84 | 85 | .literal_stream_reader = undefined, |
| 85 | 86 | .literal_stream_index = undefined, |
| 86 | 87 | .huffman_tree = null, |
| 88 | |
| 89 | .written_count = 0, |
| 87 | 90 | }; |
| 88 | 91 | } |
| 89 | 92 | |
| ... | ... | @@ -296,6 +299,7 @@ pub const DecodeState = struct { |
| 296 | 299 | // NOTE: we ignore the usage message for std.mem.copy and copy with dest.ptr >= src.ptr |
| 297 | 300 | // to allow repeats |
| 298 | 301 | std.mem.copy(u8, dest[write_pos + sequence.literal_length ..], dest[copy_start..copy_end]); |
| 302 | self.written_count += sequence.match_length; |
| 299 | 303 | } |
| 300 | 304 | |
| 301 | 305 | fn executeSequenceRingBuffer( |
| ... | ... | @@ -303,7 +307,8 @@ pub const DecodeState = struct { |
| 303 | 307 | dest: *RingBuffer, |
| 304 | 308 | sequence: Sequence, |
| 305 | 309 | ) (error{MalformedSequence} || DecodeLiteralsError)!void { |
| 306 | | if (sequence.offset > dest.data.len) return error.MalformedSequence; |
| 310 | if (sequence.offset > @min(dest.data.len, self.written_count + sequence.literal_length)) |
| 311 | return error.MalformedSequence; |
| 307 | 312 | |
| 308 | 313 | try self.decodeLiteralsRingBuffer(dest, sequence.literal_length); |
| 309 | 314 | const copy_start = dest.write_index + dest.data.len - sequence.offset; |
| ... | ... | @@ -311,6 +316,7 @@ pub const DecodeState = struct { |
| 311 | 316 | // TODO: would std.mem.copy and figuring out dest slice be better/faster? |
| 312 | 317 | for (copy_slice.first) |b| dest.writeAssumeCapacity(b); |
| 313 | 318 | for (copy_slice.second) |b| dest.writeAssumeCapacity(b); |
| 319 | self.written_count += sequence.match_length; |
| 314 | 320 | } |
| 315 | 321 | |
| 316 | 322 | const DecodeSequenceError = error{ |
| ... | ... | @@ -444,6 +450,7 @@ pub const DecodeState = struct { |
| 444 | 450 | const literal_data = self.literal_streams.one[self.literal_written_count..literals_end]; |
| 445 | 451 | std.mem.copy(u8, dest, literal_data); |
| 446 | 452 | self.literal_written_count += len; |
| 453 | self.written_count += len; |
| 447 | 454 | }, |
| 448 | 455 | .rle => { |
| 449 | 456 | var i: usize = 0; |
| ... | ... | @@ -451,6 +458,7 @@ pub const DecodeState = struct { |
| 451 | 458 | dest[i] = self.literal_streams.one[0]; |
| 452 | 459 | } |
| 453 | 460 | self.literal_written_count += len; |
| 461 | self.written_count += len; |
| 454 | 462 | }, |
| 455 | 463 | .compressed, .treeless => { |
| 456 | 464 | // const written_bytes_per_stream = (literals.header.regenerated_size + 3) / 4; |
| ... | ... | @@ -497,6 +505,7 @@ pub const DecodeState = struct { |
| 497 | 505 | } |
| 498 | 506 | } |
| 499 | 507 | self.literal_written_count += len; |
| 508 | self.written_count += len; |
| 500 | 509 | }, |
| 501 | 510 | } |
| 502 | 511 | } |
| ... | ... | @@ -516,6 +525,7 @@ pub const DecodeState = struct { |
| 516 | 525 | const literal_data = self.literal_streams.one[self.literal_written_count..literals_end]; |
| 517 | 526 | dest.writeSliceAssumeCapacity(literal_data); |
| 518 | 527 | self.literal_written_count += len; |
| 528 | self.written_count += len; |
| 519 | 529 | }, |
| 520 | 530 | .rle => { |
| 521 | 531 | var i: usize = 0; |
| ... | ... | @@ -523,6 +533,7 @@ pub const DecodeState = struct { |
| 523 | 533 | dest.writeAssumeCapacity(self.literal_streams.one[0]); |
| 524 | 534 | } |
| 525 | 535 | self.literal_written_count += len; |
| 536 | self.written_count += len; |
| 526 | 537 | }, |
| 527 | 538 | .compressed, .treeless => { |
| 528 | 539 | // const written_bytes_per_stream = (literals.header.regenerated_size + 3) / 4; |
| ... | ... | @@ -565,6 +576,7 @@ pub const DecodeState = struct { |
| 565 | 576 | } |
| 566 | 577 | } |
| 567 | 578 | self.literal_written_count += len; |
| 579 | self.written_count += len; |
| 568 | 580 | }, |
| 569 | 581 | } |
| 570 | 582 | } |
| ... | ... | @@ -612,6 +624,7 @@ pub fn decodeBlock( |
| 612 | 624 | const data = src[0..block_size]; |
| 613 | 625 | std.mem.copy(u8, dest[written_count..], data); |
| 614 | 626 | consumed_count.* += block_size; |
| 627 | decode_state.written_count += block_size; |
| 615 | 628 | return block_size; |
| 616 | 629 | }, |
| 617 | 630 | .rle => { |
| ... | ... | @@ -622,6 +635,7 @@ pub fn decodeBlock( |
| 622 | 635 | dest[write_pos] = src[0]; |
| 623 | 636 | } |
| 624 | 637 | consumed_count.* += 1; |
| 638 | decode_state.written_count += block_size; |
| 625 | 639 | return block_size; |
| 626 | 640 | }, |
| 627 | 641 | .compressed => { |
| ... | ... | @@ -712,6 +726,7 @@ pub fn decodeBlockRingBuffer( |
| 712 | 726 | const data = src[0..block_size]; |
| 713 | 727 | dest.writeSliceAssumeCapacity(data); |
| 714 | 728 | consumed_count.* += block_size; |
| 729 | decode_state.written_count += block_size; |
| 715 | 730 | return block_size; |
| 716 | 731 | }, |
| 717 | 732 | .rle => { |
| ... | ... | @@ -721,6 +736,7 @@ pub fn decodeBlockRingBuffer( |
| 721 | 736 | dest.writeAssumeCapacity(src[0]); |
| 722 | 737 | } |
| 723 | 738 | consumed_count.* += 1; |
| 739 | decode_state.written_count += block_size; |
| 724 | 740 | return block_size; |
| 725 | 741 | }, |
| 726 | 742 | .compressed => { |
| ... | ... | @@ -814,6 +830,7 @@ pub fn decodeBlockReader( |
| 814 | 830 | try source.readNoEof(slice.first); |
| 815 | 831 | try source.readNoEof(slice.second); |
| 816 | 832 | dest.write_index = dest.mask2(dest.write_index + block_size); |
| 833 | decode_state.written_count += block_size; |
| 817 | 834 | }, |
| 818 | 835 | .rle => { |
| 819 | 836 | const byte = try source.readByte(); |
| ... | ... | @@ -821,6 +838,7 @@ pub fn decodeBlockReader( |
| 821 | 838 | while (i < block_size) : (i += 1) { |
| 822 | 839 | dest.writeAssumeCapacity(byte); |
| 823 | 840 | } |
| 841 | decode_state.written_count += block_size; |
| 824 | 842 | }, |
| 825 | 843 | .compressed => { |
| 826 | 844 | const literals = try decodeLiteralsSection(block_reader, literals_buffer); |