From fa410cc234f4db16f9bdff3f9b0d0d66caa54c6b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 27 Jul 2025 16:48:17 -0700 Subject: [PATCH] std.Io: delete BitReader --- lib/std/Io.zig | 5 - lib/std/Io/Reader.zig | 4 + lib/std/Io/bit_reader.zig | 238 -------------------------------------- 3 files changed, 4 insertions(+), 243 deletions(-) delete mode 100644 lib/std/Io/bit_reader.zig diff --git a/lib/std/Io.zig b/lib/std/Io.zig index bb50bb2f81..971a720f25 100644 --- a/lib/std/Io.zig +++ b/lib/std/Io.zig @@ -467,9 +467,6 @@ pub const CountingReader = @import("Io/counting_reader.zig").CountingReader; /// Deprecated with no replacement; inefficient pattern pub const countingReader = @import("Io/counting_reader.zig").countingReader; -pub const BitReader = @import("Io/bit_reader.zig").BitReader; -pub const bitReader = @import("Io/bit_reader.zig").bitReader; - pub const tty = @import("Io/tty.zig"); /// Deprecated in favor of `Writer.Discarding`. @@ -945,9 +942,7 @@ pub fn PollFiles(comptime StreamEnum: type) type { test { _ = Reader; - _ = Reader.Limited; _ = Writer; - _ = BitReader; _ = BufferedReader; _ = BufferedWriter; _ = CountingWriter; diff --git a/lib/std/Io/Reader.zig b/lib/std/Io/Reader.zig index 7ba58bfbf4..8b389d83c1 100644 --- a/lib/std/Io/Reader.zig +++ b/lib/std/Io/Reader.zig @@ -1874,3 +1874,7 @@ pub fn writableVectorWsa( } return .{ i, n }; } + +test { + _ = Limited; +} diff --git a/lib/std/Io/bit_reader.zig b/lib/std/Io/bit_reader.zig deleted file mode 100644 index 7823e47d43..0000000000 --- a/lib/std/Io/bit_reader.zig +++ /dev/null @@ -1,238 +0,0 @@ -const std = @import("../std.zig"); - -//General note on endianess: -//Big endian is packed starting in the most significant part of the byte and subsequent -// bytes contain less significant bits. Thus we always take bits from the high -// end and place them below existing bits in our output. -//Little endian is packed starting in the least significant part of the byte and -// subsequent bytes contain more significant bits. Thus we always take bits from -// the low end and place them above existing bits in our output. -//Regardless of endianess, within any given byte the bits are always in most -// to least significant order. -//Also regardless of endianess, the buffer always aligns bits to the low end -// of the byte. - -/// Creates a bit reader which allows for reading bits from an underlying standard reader -pub fn BitReader(comptime endian: std.builtin.Endian, comptime Reader: type) type { - return struct { - reader: Reader, - bits: u8 = 0, - count: u4 = 0, - - const low_bit_mask = [9]u8{ - 0b00000000, - 0b00000001, - 0b00000011, - 0b00000111, - 0b00001111, - 0b00011111, - 0b00111111, - 0b01111111, - 0b11111111, - }; - - fn Bits(comptime T: type) type { - return struct { - T, - u16, - }; - } - - fn initBits(comptime T: type, out: anytype, num: u16) Bits(T) { - const UT = std.meta.Int(.unsigned, @bitSizeOf(T)); - return .{ - @bitCast(@as(UT, @intCast(out))), - num, - }; - } - - /// Reads `bits` bits from the reader and returns a specified type - /// containing them in the least significant end, returning an error if the - /// specified number of bits could not be read. - pub fn readBitsNoEof(self: *@This(), comptime T: type, num: u16) !T { - const b, const c = try self.readBitsTuple(T, num); - if (c < num) return error.EndOfStream; - return b; - } - - /// Reads `bits` bits from the reader and returns a specified type - /// containing them in the least significant end. The number of bits successfully - /// read is placed in `out_bits`, as reaching the end of the stream is not an error. - pub fn readBits(self: *@This(), comptime T: type, num: u16, out_bits: *u16) !T { - const b, const c = try self.readBitsTuple(T, num); - out_bits.* = c; - return b; - } - - /// Reads `bits` bits from the reader and returns a tuple of the specified type - /// containing them in the least significant end, and the number of bits successfully - /// read. Reaching the end of the stream is not an error. - pub fn readBitsTuple(self: *@This(), comptime T: type, num: u16) !Bits(T) { - const UT = std.meta.Int(.unsigned, @bitSizeOf(T)); - const U = if (@bitSizeOf(T) < 8) u8 else UT; //it is a pain to work with return initBits(T, out, out_count), - else => |e| return e, - }; - - switch (endian) { - .big => { - if (U == u8) out = 0 else out <<= 8; //shifting u8 by 8 is illegal in Zig - out |= byte; - }, - .little => { - const pos = @as(U, byte) << @intCast(out_count); - out |= pos; - }, - } - out_count += 8; - } - - const bits_left = num - out_count; - const keep = 8 - bits_left; - - if (bits_left == 0) return initBits(T, out, out_count); - - const final_byte = self.reader.readByte() catch |err| switch (err) { - error.EndOfStream => return initBits(T, out, out_count), - else => |e| return e, - }; - - switch (endian) { - .big => { - out <<= @intCast(bits_left); - out |= final_byte >> @intCast(keep); - self.bits = final_byte & low_bit_mask[keep]; - }, - .little => { - const pos = @as(U, final_byte & low_bit_mask[bits_left]) << @intCast(out_count); - out |= pos; - self.bits = final_byte >> @intCast(bits_left); - }, - } - - self.count = @intCast(keep); - return initBits(T, out, num); - } - - //convenience function for removing bits from - //the appropriate part of the buffer based on - //endianess. - fn removeBits(self: *@This(), num: u4) u8 { - if (num == 8) { - self.count = 0; - return self.bits; - } - - const keep = self.count - num; - const bits = switch (endian) { - .big => self.bits >> @intCast(keep), - .little => self.bits & low_bit_mask[num], - }; - switch (endian) { - .big => self.bits &= low_bit_mask[keep], - .little => self.bits >>= @intCast(num), - } - - self.count = keep; - return bits; - } - - pub fn alignToByte(self: *@This()) void { - self.bits = 0; - self.count = 0; - } - }; -} - -pub fn bitReader(comptime endian: std.builtin.Endian, reader: anytype) BitReader(endian, @TypeOf(reader)) { - return .{ .reader = reader }; -} - -/////////////////////////////// - -test "api coverage" { - const mem_be = [_]u8{ 0b11001101, 0b00001011 }; - const mem_le = [_]u8{ 0b00011101, 0b10010101 }; - - var mem_in_be = std.io.fixedBufferStream(&mem_be); - var bit_stream_be = bitReader(.big, mem_in_be.reader()); - - var out_bits: u16 = undefined; - - const expect = std.testing.expect; - const expectError = std.testing.expectError; - - try expect(1 == try bit_stream_be.readBits(u2, 1, &out_bits)); - try expect(out_bits == 1); - try expect(2 == try bit_stream_be.readBits(u5, 2, &out_bits)); - try expect(out_bits == 2); - try expect(3 == try bit_stream_be.readBits(u128, 3, &out_bits)); - try expect(out_bits == 3); - try expect(4 == try bit_stream_be.readBits(u8, 4, &out_bits)); - try expect(out_bits == 4); - try expect(5 == try bit_stream_be.readBits(u9, 5, &out_bits)); - try expect(out_bits == 5); - try expect(1 == try bit_stream_be.readBits(u1, 1, &out_bits)); - try expect(out_bits == 1); - - mem_in_be.pos = 0; - bit_stream_be.count = 0; - try expect(0b110011010000101 == try bit_stream_be.readBits(u15, 15, &out_bits)); - try expect(out_bits == 15); - - mem_in_be.pos = 0; - bit_stream_be.count = 0; - try expect(0b1100110100001011 == try bit_stream_be.readBits(u16, 16, &out_bits)); - try expect(out_bits == 16); - - _ = try bit_stream_be.readBits(u0, 0, &out_bits); - - try expect(0 == try bit_stream_be.readBits(u1, 1, &out_bits)); - try expect(out_bits == 0); - try expectError(error.EndOfStream, bit_stream_be.readBitsNoEof(u1, 1)); - - var mem_in_le = std.io.fixedBufferStream(&mem_le); - var bit_stream_le = bitReader(.little, mem_in_le.reader()); - - try expect(1 == try bit_stream_le.readBits(u2, 1, &out_bits)); - try expect(out_bits == 1); - try expect(2 == try bit_stream_le.readBits(u5, 2, &out_bits)); - try expect(out_bits == 2); - try expect(3 == try bit_stream_le.readBits(u128, 3, &out_bits)); - try expect(out_bits == 3); - try expect(4 == try bit_stream_le.readBits(u8, 4, &out_bits)); - try expect(out_bits == 4); - try expect(5 == try bit_stream_le.readBits(u9, 5, &out_bits)); - try expect(out_bits == 5); - try expect(1 == try bit_stream_le.readBits(u1, 1, &out_bits)); - try expect(out_bits == 1); - - mem_in_le.pos = 0; - bit_stream_le.count = 0; - try expect(0b001010100011101 == try bit_stream_le.readBits(u15, 15, &out_bits)); - try expect(out_bits == 15); - - mem_in_le.pos = 0; - bit_stream_le.count = 0; - try expect(0b1001010100011101 == try bit_stream_le.readBits(u16, 16, &out_bits)); - try expect(out_bits == 16); - - _ = try bit_stream_le.readBits(u0, 0, &out_bits); - - try expect(0 == try bit_stream_le.readBits(u1, 1, &out_bits)); - try expect(out_bits == 0); - try expectError(error.EndOfStream, bit_stream_le.readBitsNoEof(u1, 1)); -}