| ... | @@ -56,7 +56,7 @@ pub fn BitReader(T: type, comptime ReaderType: type) type { | ... | @@ -56,7 +56,7 @@ pub fn BitReader(T: type, comptime ReaderType: type) type { |
| 56 | /// that number of bits available. If end of forward stream is reached | 56 | /// that number of bits available. If end of forward stream is reached |
| 57 | /// it may be some extra zero bits in buffer. | 57 | /// it may be some extra zero bits in buffer. |
| 58 | pub inline fn fill(self: *Self, nice: u6) !void { | 58 | pub inline fn fill(self: *Self, nice: u6) !void { |
| 59 | if (self.nbits >= nice) { | 59 | if (self.nbits >= nice and nice != 0) { |
| 60 | return; // We have enought bits | 60 | return; // We have enought bits |
| 61 | } | 61 | } |
| 62 | // Read more bits from forward reader | 62 | // Read more bits from forward reader |
| ... | @@ -115,7 +115,7 @@ pub fn BitReader(T: type, comptime ReaderType: type) type { | ... | @@ -115,7 +115,7 @@ pub fn BitReader(T: type, comptime ReaderType: type) type { |
| 115 | assert(how == 0); | 115 | assert(how == 0); |
| 116 | assert(self.alignBits() == 0); | 116 | assert(self.alignBits() == 0); |
| 117 | try self.fill(@bitSizeOf(T)); | 117 | try self.fill(@bitSizeOf(T)); |
| 118 | assert(self.nbits == @bitSizeOf(T)); | 118 | if (self.nbits != @bitSizeOf(T)) return error.EndOfStream; |
| 119 | const v = self.bits; | 119 | const v = self.bits; |
| 120 | self.nbits = 0; | 120 | self.nbits = 0; |
| 121 | self.bits = 0; | 121 | self.bits = 0; |
| ... | @@ -363,3 +363,60 @@ test "readFixedCode" { | ... | @@ -363,3 +363,60 @@ test "readFixedCode" { |
| 363 | try testing.expect(rdr.nbits == 0); | 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 | } |