| ... | ... | @@ -23,6 +23,7 @@ const State = union(enum) { |
| 23 | 23 | frame: Frame, |
| 24 | 24 | checksum: ?u32, |
| 25 | 25 | decompressed_size: usize, |
| 26 | decode: Frame.Zstandard.Decode, |
| 26 | 27 | }; |
| 27 | 28 | }; |
| 28 | 29 | |
| ... | ... | @@ -138,6 +139,7 @@ fn initFrame(d: *Decompress, window_size_max: usize, magic: Frame.Magic) !void { |
| 138 | 139 | .frame = try Frame.init(header, window_size_max, d.verify_checksum), |
| 139 | 140 | .checksum = null, |
| 140 | 141 | .decompressed_size = 0, |
| 142 | .decode = .init, |
| 141 | 143 | } }; |
| 142 | 144 | }, |
| 143 | 145 | .skippable => { |
| ... | ... | @@ -168,16 +170,13 @@ fn readInFrame(d: *Decompress, w: *Writer, limit: Limit, state: *State.InFrame) |
| 168 | 170 | bytes_written = block_size; |
| 169 | 171 | }, |
| 170 | 172 | .compressed => { |
| 171 | | var literal_fse_buffer: [zstd.table_size_max.literal]Table.Fse = undefined; |
| 172 | | var match_fse_buffer: [zstd.table_size_max.match]Table.Fse = undefined; |
| 173 | | var offset_fse_buffer: [zstd.table_size_max.offset]Table.Fse = undefined; |
| 174 | 173 | var literals_buffer: [zstd.block_size_max]u8 = undefined; |
| 175 | 174 | var sequence_buffer: [zstd.block_size_max]u8 = undefined; |
| 176 | | var decode: Frame.Zstandard.Decode = .init(&literal_fse_buffer, &match_fse_buffer, &offset_fse_buffer, window_len); |
| 177 | 175 | var remaining: Limit = .limited(block_size); |
| 178 | 176 | const literals = try LiteralsSection.decode(in, &remaining, &literals_buffer); |
| 179 | 177 | const sequences_header = try SequencesSection.Header.decode(in, &remaining); |
| 180 | 178 | |
| 179 | const decode = &state.decode; |
| 181 | 180 | try decode.prepare(in, &remaining, literals, sequences_header); |
| 182 | 181 | |
| 183 | 182 | { |
| ... | ... | @@ -370,16 +369,15 @@ pub const Frame = struct { |
| 370 | 369 | }; |
| 371 | 370 | |
| 372 | 371 | pub const Decode = struct { |
| 373 | | window_len: u32, |
| 374 | 372 | repeat_offsets: [3]u32, |
| 375 | 373 | |
| 376 | 374 | offset: StateData(8), |
| 377 | 375 | match: StateData(9), |
| 378 | 376 | literal: StateData(9), |
| 379 | 377 | |
| 380 | | offset_fse_buffer: []Table.Fse, |
| 381 | | match_fse_buffer: []Table.Fse, |
| 382 | | literal_fse_buffer: []Table.Fse, |
| 378 | literal_fse_buffer: [zstd.table_size_max.literal]Table.Fse, |
| 379 | match_fse_buffer: [zstd.table_size_max.match]Table.Fse, |
| 380 | offset_fse_buffer: [zstd.table_size_max.offset]Table.Fse, |
| 383 | 381 | |
| 384 | 382 | fse_tables_undefined: bool, |
| 385 | 383 | |
| ... | ... | @@ -401,38 +399,30 @@ pub const Frame = struct { |
| 401 | 399 | }; |
| 402 | 400 | } |
| 403 | 401 | |
| 404 | | pub fn init( |
| 405 | | literal_fse_buffer: []Table.Fse, |
| 406 | | match_fse_buffer: []Table.Fse, |
| 407 | | offset_fse_buffer: []Table.Fse, |
| 408 | | window_len: u32, |
| 409 | | ) Decode { |
| 410 | | return .{ |
| 411 | | .window_len = window_len, |
| 412 | | .repeat_offsets = .{ |
| 413 | | zstd.start_repeated_offset_1, |
| 414 | | zstd.start_repeated_offset_2, |
| 415 | | zstd.start_repeated_offset_3, |
| 416 | | }, |
| 402 | const init: Decode = .{ |
| 403 | .repeat_offsets = .{ |
| 404 | zstd.start_repeated_offset_1, |
| 405 | zstd.start_repeated_offset_2, |
| 406 | zstd.start_repeated_offset_3, |
| 407 | }, |
| 417 | 408 | |
| 418 | | .offset = undefined, |
| 419 | | .match = undefined, |
| 420 | | .literal = undefined, |
| 409 | .offset = undefined, |
| 410 | .match = undefined, |
| 411 | .literal = undefined, |
| 421 | 412 | |
| 422 | | .literal_fse_buffer = literal_fse_buffer, |
| 423 | | .match_fse_buffer = match_fse_buffer, |
| 424 | | .offset_fse_buffer = offset_fse_buffer, |
| 413 | .literal_fse_buffer = undefined, |
| 414 | .match_fse_buffer = undefined, |
| 415 | .offset_fse_buffer = undefined, |
| 425 | 416 | |
| 426 | | .fse_tables_undefined = true, |
| 417 | .fse_tables_undefined = true, |
| 427 | 418 | |
| 428 | | .literal_written_count = 0, |
| 429 | | .literal_header = undefined, |
| 430 | | .literal_streams = undefined, |
| 431 | | .literal_stream_reader = undefined, |
| 432 | | .literal_stream_index = undefined, |
| 433 | | .huffman_tree = null, |
| 434 | | }; |
| 435 | | } |
| 419 | .literal_written_count = 0, |
| 420 | .literal_header = undefined, |
| 421 | .literal_streams = undefined, |
| 422 | .literal_stream_reader = undefined, |
| 423 | .literal_stream_index = undefined, |
| 424 | .huffman_tree = null, |
| 425 | }; |
| 436 | 426 | |
| 437 | 427 | pub const PrepareError = error{ |
| 438 | 428 | /// the (reversed) literal bitstream's first byte does not have any bits set |
| ... | ... | @@ -514,12 +504,12 @@ pub const Frame = struct { |
| 514 | 504 | return self.repeat_offsets[0]; |
| 515 | 505 | } |
| 516 | 506 | |
| 517 | | const DataType = enum { offset, match, literal }; |
| 507 | const WhichFse = enum { offset, match, literal }; |
| 518 | 508 | |
| 519 | 509 | /// TODO: don't use `@field` |
| 520 | 510 | fn updateState( |
| 521 | 511 | self: *Decode, |
| 522 | | comptime choice: DataType, |
| 512 | comptime choice: WhichFse, |
| 523 | 513 | bit_reader: *ReverseBitReader, |
| 524 | 514 | ) error{ MalformedFseBits, EndOfStream }!void { |
| 525 | 515 | switch (@field(self, @tagName(choice)).table) { |
| ... | ... | @@ -549,7 +539,7 @@ pub const Frame = struct { |
| 549 | 539 | self: *Decode, |
| 550 | 540 | in: *Reader, |
| 551 | 541 | remaining: *Limit, |
| 552 | | comptime choice: DataType, |
| 542 | comptime choice: WhichFse, |
| 553 | 543 | mode: SequencesSection.Header.Mode, |
| 554 | 544 | ) !void { |
| 555 | 545 | const field_name = @tagName(choice); |
| ... | ... | @@ -576,10 +566,10 @@ pub const Frame = struct { |
| 576 | 566 | &bit_reader, |
| 577 | 567 | @field(zstd.table_symbol_count_max, field_name), |
| 578 | 568 | @field(zstd.table_accuracy_log_max, field_name), |
| 579 | | @field(self, field_name ++ "_fse_buffer"), |
| 569 | &@field(self, field_name ++ "_fse_buffer"), |
| 580 | 570 | ); |
| 581 | 571 | @field(self, field_name).table = .{ |
| 582 | | .fse = @field(self, field_name ++ "_fse_buffer")[0..table_size], |
| 572 | .fse = (&@field(self, field_name ++ "_fse_buffer"))[0..table_size], |
| 583 | 573 | }; |
| 584 | 574 | @field(self, field_name).accuracy_log = std.math.log2_int_ceil(usize, table_size); |
| 585 | 575 | in.toss(bit_reader.index); |
| ... | ... | @@ -762,7 +752,7 @@ pub const Frame = struct { |
| 762 | 752 | } |
| 763 | 753 | |
| 764 | 754 | /// TODO: don't use `@field` |
| 765 | | fn getCode(self: *Decode, comptime choice: DataType) u32 { |
| 755 | fn getCode(self: *Decode, comptime choice: WhichFse) u32 { |
| 766 | 756 | return switch (@field(self, @tagName(choice)).table) { |
| 767 | 757 | .rle => |value| value, |
| 768 | 758 | .fse => |table| table[@field(self, @tagName(choice)).state].symbol, |