| ... | ... | @@ -56,7 +56,7 @@ pub fn BitReader(T: type, comptime ReaderType: type) type { |
| 56 | 56 | /// that number of bits available. If end of forward stream is reached |
| 57 | 57 | /// it may be some extra zero bits in buffer. |
| 58 | 58 | pub inline fn fill(self: *Self, nice: u6) !void { |
| 59 | | if (self.nbits >= nice) { |
| 59 | if (self.nbits >= nice and nice != 0) { |
| 60 | 60 | return; // We have enought bits |
| 61 | 61 | } |
| 62 | 62 | // Read more bits from forward reader |
| ... | ... | @@ -115,7 +115,7 @@ pub fn BitReader(T: type, comptime ReaderType: type) type { |
| 115 | 115 | assert(how == 0); |
| 116 | 116 | assert(self.alignBits() == 0); |
| 117 | 117 | try self.fill(@bitSizeOf(T)); |
| 118 | | assert(self.nbits == @bitSizeOf(T)); |
| 118 | if (self.nbits != @bitSizeOf(T)) return error.EndOfStream; |
| 119 | 119 | const v = self.bits; |
| 120 | 120 | self.nbits = 0; |
| 121 | 121 | self.bits = 0; |
| ... | ... | @@ -363,3 +363,60 @@ test "readFixedCode" { |
| 363 | 363 | try testing.expect(rdr.nbits == 0); |
| 364 | 364 | } |
| 365 | 365 | } |
| 366 | |
| 367 | test "u32 leaves no bits on u32 reads" { |
| 368 | const data = [_]u8{ |
| 369 | 0xff, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
| 370 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
| 371 | }; |
| 372 | var fbs = std.io.fixedBufferStream(&data); |
| 373 | var br = bitReader(u32, fbs.reader()); |
| 374 | |
| 375 | _ = try br.read(u3); |
| 376 | try testing.expectEqual(29, br.nbits); |
| 377 | br.alignToByte(); |
| 378 | try testing.expectEqual(24, br.nbits); |
| 379 | try testing.expectEqual(0x04_03_02_01, try br.read(u32)); |
| 380 | try testing.expectEqual(0, br.nbits); |
| 381 | try testing.expectEqual(0x08_07_06_05, try br.read(u32)); |
| 382 | try testing.expectEqual(0, br.nbits); |
| 383 | |
| 384 | _ = try br.read(u9); |
| 385 | try testing.expectEqual(23, br.nbits); |
| 386 | br.alignToByte(); |
| 387 | try testing.expectEqual(16, br.nbits); |
| 388 | try testing.expectEqual(0x0e_0d_0c_0b, try br.read(u32)); |
| 389 | try testing.expectEqual(0, br.nbits); |
| 390 | } |
| 391 | |
| 392 | test "u64 need fill after alignToByte" { |
| 393 | const data = [_]u8{ |
| 394 | 0xff, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
| 395 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
| 396 | }; |
| 397 | |
| 398 | // without fill |
| 399 | var fbs = std.io.fixedBufferStream(&data); |
| 400 | var br = bitReader(u64, fbs.reader()); |
| 401 | _ = try br.read(u23); |
| 402 | try testing.expectEqual(41, br.nbits); |
| 403 | br.alignToByte(); |
| 404 | try testing.expectEqual(40, br.nbits); |
| 405 | try testing.expectEqual(0x06_05_04_03, try br.read(u32)); |
| 406 | try testing.expectEqual(8, br.nbits); |
| 407 | try testing.expectEqual(0x0a_09_08_07, try br.read(u32)); |
| 408 | try testing.expectEqual(32, br.nbits); |
| 409 | |
| 410 | // fill after align ensures all bits filled |
| 411 | fbs.reset(); |
| 412 | br = bitReader(u64, fbs.reader()); |
| 413 | _ = try br.read(u23); |
| 414 | try testing.expectEqual(41, br.nbits); |
| 415 | br.alignToByte(); |
| 416 | try br.fill(0); |
| 417 | try testing.expectEqual(64, br.nbits); |
| 418 | try testing.expectEqual(0x06_05_04_03, try br.read(u32)); |
| 419 | try testing.expectEqual(32, br.nbits); |
| 420 | try testing.expectEqual(0x0a_09_08_07, try br.read(u32)); |
| 421 | try testing.expectEqual(0, br.nbits); |
| 422 | } |