| ... | ... | @@ -372,7 +372,10 @@ fn takeBits(d: *Decompress, comptime T: type) !T { |
| 372 | 372 | }; |
| 373 | 373 | } |
| 374 | 374 | const in = d.input; |
| 375 | | const next_int = try in.takeInt(usize, .little); |
| 375 | const next_int = in.takeInt(usize, .little) catch |err| switch (err) { |
| 376 | error.ReadFailed => return error.ReadFailed, |
| 377 | error.EndOfStream => return takeBitsEnding(d, T), |
| 378 | }; |
| 376 | 379 | const needed_bits = @bitSizeOf(T) - remaining_bits; |
| 377 | 380 | const u: U = @intCast((next_bits << needed_bits) | (next_int & ((@as(usize, 1) << needed_bits) - 1))); |
| 378 | 381 | d.next_bits = next_int >> needed_bits; |
| ... | ... | @@ -384,6 +387,35 @@ fn takeBits(d: *Decompress, comptime T: type) !T { |
| 384 | 387 | }; |
| 385 | 388 | } |
| 386 | 389 | |
| 390 | fn takeBitsEnding(d: *Decompress, comptime T: type) !T { |
| 391 | const remaining_bits = d.remaining_bits; |
| 392 | const next_bits = d.next_bits; |
| 393 | const in = d.input; |
| 394 | const U = @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(T) } }); |
| 395 | var u: U = 0; |
| 396 | var remaining_needed_bits = @bitSizeOf(U) - remaining_bits; |
| 397 | while (@bitSizeOf(U) >= 8 and remaining_needed_bits >= 8) { |
| 398 | const byte = try in.takeByte(); |
| 399 | u = (u << 8) | byte; |
| 400 | remaining_needed_bits -= 8; |
| 401 | } |
| 402 | if (remaining_needed_bits == 0) { |
| 403 | d.next_bits = 0; |
| 404 | d.remaining_bits = 0; |
| 405 | } else { |
| 406 | const byte = try in.takeByte(); |
| 407 | u = @intCast((@as(usize, u) << remaining_needed_bits) | (byte & ((@as(usize, 1) << remaining_needed_bits) - 1))); |
| 408 | d.next_bits = @as(usize, byte) >> remaining_needed_bits; |
| 409 | d.remaining_bits = @intCast(8 - remaining_needed_bits); |
| 410 | } |
| 411 | u = @intCast((@as(usize, u) << remaining_bits) | next_bits); |
| 412 | return switch (@typeInfo(T)) { |
| 413 | .int => u, |
| 414 | .@"enum" => @enumFromInt(u), |
| 415 | else => @bitCast(u), |
| 416 | }; |
| 417 | } |
| 418 | |
| 387 | 419 | fn peekBits(d: *Decompress, comptime T: type) !T { |
| 388 | 420 | const U = @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(T) } }); |
| 389 | 421 | const remaining_bits = d.remaining_bits; |
| ... | ... | @@ -397,7 +429,10 @@ fn peekBits(d: *Decompress, comptime T: type) !T { |
| 397 | 429 | }; |
| 398 | 430 | } |
| 399 | 431 | const in = d.input; |
| 400 | | const next_int = try in.peekInt(usize, .little); |
| 432 | const next_int = in.peekInt(usize, .little) catch |err| switch (err) { |
| 433 | error.ReadFailed => return error.ReadFailed, |
| 434 | error.EndOfStream => return peekBitsEnding(d, T), |
| 435 | }; |
| 401 | 436 | const needed_bits = @bitSizeOf(T) - remaining_bits; |
| 402 | 437 | const u: U = @intCast((next_bits << needed_bits) | (next_int & ((@as(usize, 1) << needed_bits) - 1))); |
| 403 | 438 | return switch (@typeInfo(T)) { |
| ... | ... | @@ -407,6 +442,11 @@ fn peekBits(d: *Decompress, comptime T: type) !T { |
| 407 | 442 | }; |
| 408 | 443 | } |
| 409 | 444 | |
| 445 | fn peekBitsEnding(d: *Decompress, comptime T: type) !T { |
| 446 | _ = d; |
| 447 | @panic("TODO"); |
| 448 | } |
| 449 | |
| 410 | 450 | fn tossBits(d: *Decompress, n: u6) !void { |
| 411 | 451 | const remaining_bits = d.remaining_bits; |
| 412 | 452 | const next_bits = d.next_bits; |
| ... | ... | @@ -415,13 +455,22 @@ fn tossBits(d: *Decompress, n: u6) !void { |
| 415 | 455 | d.remaining_bits = remaining_bits - n; |
| 416 | 456 | } else { |
| 417 | 457 | const in = d.input; |
| 418 | | const next_int = try in.takeInt(usize, .little); |
| 458 | const next_int = in.takeInt(usize, .little) catch |err| switch (err) { |
| 459 | error.ReadFailed => return error.ReadFailed, |
| 460 | error.EndOfStream => return tossBitsEnding(d, n), |
| 461 | }; |
| 419 | 462 | const needed_bits = n - remaining_bits; |
| 420 | 463 | d.next_bits = next_int >> needed_bits; |
| 421 | 464 | d.remaining_bits = @intCast(@bitSizeOf(usize) - @as(usize, needed_bits)); |
| 422 | 465 | } |
| 423 | 466 | } |
| 424 | 467 | |
| 468 | fn tossBitsEnding(d: *Decompress, n: u6) !void { |
| 469 | _ = d; |
| 470 | _ = n; |
| 471 | @panic("TODO"); |
| 472 | } |
| 473 | |
| 425 | 474 | fn takeNBitsBuffered(d: *Decompress, n: u4) !u16 { |
| 426 | 475 | _ = d; |
| 427 | 476 | _ = n; |