| ... | ... | @@ -10,8 +10,8 @@ const Decompress = @This(); |
| 10 | 10 | const Token = @import("Token.zig"); |
| 11 | 11 | |
| 12 | 12 | input: *Reader, |
| 13 | | next_bits: usize, |
| 14 | | remaining_bits: std.math.Log2Int(usize), |
| 13 | next_bits: Bits, |
| 14 | remaining_bits: std.math.Log2Int(Bits), |
| 15 | 15 | |
| 16 | 16 | reader: Reader, |
| 17 | 17 | |
| ... | ... | @@ -25,6 +25,9 @@ state: State, |
| 25 | 25 | |
| 26 | 26 | err: ?Error, |
| 27 | 27 | |
| 28 | /// TODO: change this to usize |
| 29 | const Bits = u64; |
| 30 | |
| 28 | 31 | const BlockType = enum(u2) { |
| 29 | 32 | stored = 0, |
| 30 | 33 | fixed = 1, |
| ... | ... | @@ -498,14 +501,14 @@ fn takeBits(d: *Decompress, comptime U: type) !U { |
| 498 | 501 | return u; |
| 499 | 502 | } |
| 500 | 503 | const in = d.input; |
| 501 | | const next_int = in.takeInt(usize, .little) catch |err| switch (err) { |
| 504 | const next_int = in.takeInt(Bits, .little) catch |err| switch (err) { |
| 502 | 505 | error.ReadFailed => return error.ReadFailed, |
| 503 | 506 | error.EndOfStream => return takeBitsEnding(d, U), |
| 504 | 507 | }; |
| 505 | 508 | const needed_bits = @bitSizeOf(U) - remaining_bits; |
| 506 | | const u: U = @intCast(((next_int & ((@as(usize, 1) << needed_bits) - 1)) << remaining_bits) | next_bits); |
| 509 | const u: U = @intCast(((next_int & ((@as(Bits, 1) << needed_bits) - 1)) << remaining_bits) | next_bits); |
| 507 | 510 | d.next_bits = next_int >> needed_bits; |
| 508 | | d.remaining_bits = @intCast(@bitSizeOf(usize) - @as(usize, needed_bits)); |
| 511 | d.remaining_bits = @intCast(@bitSizeOf(Bits) - @as(usize, needed_bits)); |
| 509 | 512 | return u; |
| 510 | 513 | } |
| 511 | 514 | |
| ... | ... | @@ -514,14 +517,14 @@ fn takeBitsEnding(d: *Decompress, comptime U: type) !U { |
| 514 | 517 | const next_bits = d.next_bits; |
| 515 | 518 | const in = d.input; |
| 516 | 519 | const n = in.bufferedLen(); |
| 517 | | assert(n < @sizeOf(usize)); |
| 520 | assert(n < @sizeOf(Bits)); |
| 518 | 521 | const needed_bits = @bitSizeOf(U) - remaining_bits; |
| 519 | 522 | if (n * 8 < needed_bits) return error.EndOfStream; |
| 520 | | const next_int = in.takeVarInt(usize, .little, n) catch |err| switch (err) { |
| 523 | const next_int = in.takeVarInt(Bits, .little, n) catch |err| switch (err) { |
| 521 | 524 | error.ReadFailed => return error.ReadFailed, |
| 522 | 525 | error.EndOfStream => unreachable, |
| 523 | 526 | }; |
| 524 | | const u: U = @intCast(((next_int & ((@as(usize, 1) << needed_bits) - 1)) << remaining_bits) | next_bits); |
| 527 | const u: U = @intCast(((next_int & ((@as(Bits, 1) << needed_bits) - 1)) << remaining_bits) | next_bits); |
| 525 | 528 | d.next_bits = next_int >> needed_bits; |
| 526 | 529 | d.remaining_bits = @intCast(n * 8 - @as(usize, needed_bits)); |
| 527 | 530 | return u; |
| ... | ... | @@ -532,37 +535,37 @@ fn peekBits(d: *Decompress, comptime U: type) !U { |
| 532 | 535 | const next_bits = d.next_bits; |
| 533 | 536 | if (remaining_bits >= @bitSizeOf(U)) return @truncate(next_bits); |
| 534 | 537 | const in = d.input; |
| 535 | | const next_int = in.peekInt(usize, .little) catch |err| switch (err) { |
| 538 | const next_int = in.peekInt(Bits, .little) catch |err| switch (err) { |
| 536 | 539 | error.ReadFailed => return error.ReadFailed, |
| 537 | 540 | error.EndOfStream => return peekBitsEnding(d, U), |
| 538 | 541 | }; |
| 539 | 542 | const needed_bits = @bitSizeOf(U) - remaining_bits; |
| 540 | | return @intCast(((next_int & ((@as(usize, 1) << needed_bits) - 1)) << remaining_bits) | next_bits); |
| 543 | return @intCast(((next_int & ((@as(Bits, 1) << needed_bits) - 1)) << remaining_bits) | next_bits); |
| 541 | 544 | } |
| 542 | 545 | |
| 543 | 546 | fn peekBitsEnding(d: *Decompress, comptime U: type) !U { |
| 544 | 547 | const remaining_bits = d.remaining_bits; |
| 545 | 548 | const next_bits = d.next_bits; |
| 546 | 549 | const in = d.input; |
| 547 | | var u: usize = 0; |
| 550 | var u: Bits = 0; |
| 548 | 551 | var remaining_needed_bits = @bitSizeOf(U) - remaining_bits; |
| 549 | 552 | var i: usize = 0; |
| 550 | 553 | while (remaining_needed_bits >= 8) { |
| 551 | 554 | const byte = try specialPeek(in, next_bits, i); |
| 552 | | u |= @as(usize, byte) << @intCast(i * 8); |
| 555 | u |= @as(Bits, byte) << @intCast(i * 8); |
| 553 | 556 | remaining_needed_bits -= 8; |
| 554 | 557 | i += 1; |
| 555 | 558 | } |
| 556 | 559 | if (remaining_needed_bits != 0) { |
| 557 | 560 | const byte = try specialPeek(in, next_bits, i); |
| 558 | | u |= @as(usize, byte) << @intCast((i * 8) + remaining_needed_bits); |
| 561 | u |= @as(Bits, byte) << @intCast((i * 8) + remaining_needed_bits); |
| 559 | 562 | } |
| 560 | 563 | return @truncate((u << remaining_bits) | next_bits); |
| 561 | 564 | } |
| 562 | 565 | |
| 563 | 566 | /// If there is any unconsumed data, handles EndOfStream by pretending there |
| 564 | 567 | /// are zeroes afterwards. |
| 565 | | fn specialPeek(in: *Reader, next_bits: usize, i: usize) Reader.Error!u8 { |
| 568 | fn specialPeek(in: *Reader, next_bits: Bits, i: usize) Reader.Error!u8 { |
| 566 | 569 | const peeked = in.peek(i + 1) catch |err| switch (err) { |
| 567 | 570 | error.ReadFailed => return error.ReadFailed, |
| 568 | 571 | error.EndOfStream => if (next_bits == 0 and i == 0) return error.EndOfStream else return 0, |
| ... | ... | @@ -578,13 +581,13 @@ fn tossBits(d: *Decompress, n: u4) !void { |
| 578 | 581 | d.remaining_bits = remaining_bits - n; |
| 579 | 582 | } else { |
| 580 | 583 | const in = d.input; |
| 581 | | const next_int = in.takeInt(usize, .little) catch |err| switch (err) { |
| 584 | const next_int = in.takeInt(Bits, .little) catch |err| switch (err) { |
| 582 | 585 | error.ReadFailed => return error.ReadFailed, |
| 583 | 586 | error.EndOfStream => return tossBitsEnding(d, n), |
| 584 | 587 | }; |
| 585 | 588 | const needed_bits = n - remaining_bits; |
| 586 | 589 | d.next_bits = next_int >> needed_bits; |
| 587 | | d.remaining_bits = @intCast(@bitSizeOf(usize) - @as(usize, needed_bits)); |
| 590 | d.remaining_bits = @intCast(@bitSizeOf(Bits) - @as(usize, needed_bits)); |
| 588 | 591 | } |
| 589 | 592 | } |
| 590 | 593 | |
| ... | ... | @@ -593,9 +596,9 @@ fn tossBitsEnding(d: *Decompress, n: u4) !void { |
| 593 | 596 | const in = d.input; |
| 594 | 597 | const buffered_n = in.bufferedLen(); |
| 595 | 598 | if (buffered_n == 0) return error.EndOfStream; |
| 596 | | assert(buffered_n < @sizeOf(usize)); |
| 599 | assert(buffered_n < @sizeOf(Bits)); |
| 597 | 600 | const needed_bits = n - remaining_bits; |
| 598 | | const next_int = in.takeVarInt(usize, .little, buffered_n) catch |err| switch (err) { |
| 601 | const next_int = in.takeVarInt(Bits, .little, buffered_n) catch |err| switch (err) { |
| 599 | 602 | error.ReadFailed => return error.ReadFailed, |
| 600 | 603 | error.EndOfStream => unreachable, |
| 601 | 604 | }; |