#! /usr/local/bin/ruby class BitIO def initialize(data) @data = data @byte_offset = 0 @bit_offset = 0 end def incr_offset!(byte_width, bit_width) @byte_offset = @byte_offset + byte_width @bit_offset = @bit_offset + bit_width while (7 < @bit_offset) @byte_offset = @byte_offset + 1; @bit_offset = @bit_offset - 8; end end # peek bit def get_bit if (@data.length <= @byte_offset) return -1; end byte = @data[@byte_offset].ord (byte >> (7 - @bit_offset)) & 1 end # get and incr bit def get_bit! bit = get_bit() if (0 <= bit) incr_offset!(0, 1) end bit end end # test routine data = "foobaabaz" $io = BitIO.new(data) data.each_byte { |b| (1..8).each { bit = $io.get_bit!() printf("%d", bit); } printf(" %c\n", b); }