Type Function BitWriter [src]

Alias for std.io.bit_writer.BitWriter

Creates a bit writer which allows for writing bits to an underlying standard writer

Prototype

pub fn BitWriter(comptime endian: std.builtin.Endian, comptime Writer: type) type

Parameters

endian: std.builtin.EndianWriter: type

Source

pub fn BitWriter(comptime endian: std.builtin.Endian, comptime Writer: type) type { return struct { writer: Writer, bits: u8 = 0, count: u4 = 0, const low_bit_mask = [9]u8{ 0b00000000, 0b00000001, 0b00000011, 0b00000111, 0b00001111, 0b00011111, 0b00111111, 0b01111111, 0b11111111, }; /// Write the specified number of bits to the writer from the least significant bits of /// the specified value. Bits will only be written to the writer when there /// are enough to fill a byte. pub fn writeBits(self: *@This(), value: anytype, num: u16) !void { const T = @TypeOf(value); const UT = std.meta.Int(.unsigned, @bitSizeOf(T)); const U = if (@bitSizeOf(T) < 8) u8 else UT; // 0) { //if we can't fill the buffer, add what we have const bits_free = 8 - self.count; if (num < bits_free) { self.addBits(@truncate(in), @intCast(num)); return; } //finish filling the buffer and flush it if (num == bits_free) { self.addBits(@truncate(in), @intCast(num)); return self.flushBits(); } switch (endian) { .big => { const bits = in >> @intCast(in_count - bits_free); self.addBits(@truncate(bits), bits_free); }, .little => { self.addBits(@truncate(in), bits_free); in >>= @intCast(bits_free); }, } in_count -= bits_free; try self.flushBits(); } //write full bytes while we can const full_bytes_left = in_count / 8; for (0..full_bytes_left) |_| { switch (endian) { .big => { const bits = in >> @intCast(in_count - 8); try self.writer.writeByte(@truncate(bits)); }, .little => { try self.writer.writeByte(@truncate(in)); if (U == u8) in = 0 else in >>= 8; }, } in_count -= 8; } //save the remaining bits in the buffer self.addBits(@truncate(in), @intCast(in_count)); } //convenience funciton for adding bits to the buffer //in the appropriate position based on endianess fn addBits(self: *@This(), bits: u8, num: u4) void { if (num == 8) self.bits = bits else switch (endian) { .big => { self.bits <<= @intCast(num); self.bits |= bits & low_bit_mask[num]; }, .little => { const pos = bits << @intCast(self.count); self.bits |= pos; }, } self.count += num; } /// Flush any remaining bits to the writer, filling /// unused bits with 0s. pub fn flushBits(self: *@This()) !void { if (self.count == 0) return; if (endian == .big) self.bits <<= @intCast(8 - self.count); try self.writer.writeByte(self.bits); self.bits = 0; self.count = 0; } }; }