Class: BitUnpacker
- Inherits:
-
Object
- Object
- BitUnpacker
- Defined in:
- lib/bit_unpacker.rb
Overview
The BitUnPacker class unpacks the byte-packed format used in Flash files. In most cases data types are stored as a number of complete bytes, in file formats where size matters a lot some people choose to store information as packed bytes. This means that the boundary of a value can lie within a byte.
Class Method Summary collapse
-
.uunpack(bytes, size, parts = nil, skip = nil) ⇒ Object
Unpack a byte-packed string and interpret the values as a signed integer.
Instance Method Summary collapse
-
#initialize(bytes, size, parts = nil, skip = nil) ⇒ BitUnpacker
constructor
Initialize a new BitUnpacker, note that the BitUnpacker is a parse class with a lot of internal state variables.
-
#take(bits) ⇒ Object
Take a number of bits from the current byte and shift them away.
-
#uunpack ⇒ Object
Unpack by treating every consecutive block of bits as a signed integer.
Constructor Details
#initialize(bytes, size, parts = nil, skip = nil) ⇒ BitUnpacker
Initialize a new BitUnpacker, note that the BitUnpacker is a parse class with a lot of internal state variables. You probably only want to use the class methods.
bytes: A string with the bytes to unpack size: The number of bits per entry parts: The number of entries to unpack from the string, default is (bytes.length*8)/size skip: The number of bits to skip from the start of the string, default is 0
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/bit_unpacker.rb', line 12 def initialize(bytes, size, parts=nil, skip=nil) # Input @bytes = bytes @size = size @parts = parts || (bytes.length*8)/size @skip = skip || 0 # Reader state @bytes_offset = 0 @current = @bytes[0] @have = 8 if @skip # TODO: skip more than 8 bytes take @skip @have -= @skip end end |
Class Method Details
.uunpack(bytes, size, parts = nil, skip = nil) ⇒ Object
Unpack a byte-packed string and interpret the values as a signed integer
bytes: A string with the bytes to unpack size: The number of bits per entry parts: The number of entries to unpack from the string, default is (bytes.length*8)/size skip: The number of bits to skip from the start of the string, default is 0
71 72 73 |
# File 'lib/bit_unpacker.rb', line 71 def self.uunpack(bytes, size, parts=nil, skip=nil) BitUnpacker.new(bytes, size, parts, skip).uunpack end |
Instance Method Details
#take(bits) ⇒ Object
Take a number of bits from the current byte and shift them away
30 31 32 33 34 |
# File 'lib/bit_unpacker.rb', line 30 def take(bits) value = @current >> 8 - bits @current = (@current & (0xff >> bits)) << bits value end |
#uunpack ⇒ Object
Unpack by treating every consecutive block of bits as a signed integer
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/bit_unpacker.rb', line 37 def uunpack unpacked = [] value = 0 @parts.times do # It's signed, so we need the first byte to determine the sign want = @size - 1 is_negative = take(1) == 1 ? true : false @have -= 1 while want > 0 if want < @have value = (value << want) + take(want) @have -= want want = 0 else # want > @have value = (value << @have) + take(@have) want -= @have @have = 8 @bytes_offset += 1 @current = @bytes[@bytes_offset] end end unpacked << (is_negative ? -value : value) value = 0 end unpacked end |