class Origami::Filter::Utils::BitReader
Class used to read a String
as a stream of bits. Internally used by some filters.
Constants
- BRUIJIN_TABLE
Public Class Methods
new(data)
click to toggle source
# File lib/origami/filters.rb, line 174 def initialize(data) @data = data reset end
Public Instance Methods
clo()
click to toggle source
Used for bit scanning. Count leading ones. Does not advance read pointer.
# File lib/origami/filters.rb, line 288 def clo count = 0 if @ptr_bit != 0 bits = peek(8 - @ptr_bit) count = clz32(~(bits << (32 - (8 - @ptr_bit))) & 0xff) return count if count < (8 - @ptr_bit) end delta = 0 while @data.size > @ptr_byte + delta * 4 word = @data[@ptr_byte + delta * 4, 4] # next 32 bits z = clz32(~((word << (4 - word.size)).unpack("N")[0]) & 0xffff_ffff) count += z delta += 1 return count if z < 32 - ((4 - word.size) << 3) end count end
clz()
click to toggle source
Used for bit scanning. Counts leading zeros. Does not advance read pointer.
# File lib/origami/filters.rb, line 261 def clz count = 0 if @ptr_bit != 0 bits = peek(8 - @ptr_bit) count = clz32(bits << (32 - (8 - @ptr_bit))) return count if count < (8 - @ptr_bit) end delta = 0 while @data.size > @ptr_byte + delta * 4 word = @data[@ptr_byte + delta * 4, 4] # next 32 bits z = clz32((word << (4 - word.size)).unpack("N")[0]) count += z delta += 1 return count if z < 32 - ((4 - word.size) << 3) end count end
eod?()
click to toggle source
Returns true if end of data has been reached.
# File lib/origami/filters.rb, line 190 def eod? @ptr_byte >= @data.size end
peek(length)
click to toggle source
Reads length bits as a Fixnum. Does not advance read pointer.
# File lib/origami/filters.rb, line 232 def peek(length) return BitReaderError, "Invalid read length" unless length > 0 return BitReaderError, "Insufficient data" if self.pos + length > self.size n = 0 ptr_byte, ptr_bit = @ptr_byte, @ptr_bit while length > 0 byte = @data[ptr_byte].ord if length > 8 - ptr_bit length -= 8 - ptr_bit n |= ( byte & ((1 << (8 - ptr_bit)) - 1) ) << length ptr_byte += 1 ptr_bit = 0 else n |= (byte >> (8 - ptr_bit - length)) & ((1 << length) - 1) length = 0 end end n end
pos()
click to toggle source
Returns the read pointer position in bits.
# File lib/origami/filters.rb, line 197 def pos (@ptr_byte << 3) + @ptr_bit end
pos=(bits)
click to toggle source
Sets the read pointer position in bits.
# File lib/origami/filters.rb, line 211 def pos=(bits) raise BitReaderError, "Pointer position out of data" if bits > self.size pbyte = bits >> 3 pbit = bits - (pbyte << 3) @ptr_byte, @ptr_bit = pbyte, pbit end
read(length)
click to toggle source
Reads length bits as a Fixnum and advances read pointer.
# File lib/origami/filters.rb, line 222 def read(length) n = self.peek(length) self.pos += length n end
reset()
click to toggle source
Resets the read pointer.
# File lib/origami/filters.rb, line 182 def reset @ptr_byte, @ptr_bit = 0, 0 self end
size()
click to toggle source
Returns the data size in bits.
# File lib/origami/filters.rb, line 204 def size @data.size << 3 end
Private Instance Methods
bitswap8(i)
click to toggle source
# File lib/origami/filters.rb, line 313 def bitswap8(i) #:nodoc ((i * 0x0202020202) & 0x010884422010) % 1023 end