Class: ErlangBitstream
- Inherits:
-
Object
- Object
- ErlangBitstream
- Defined in:
- lib/utils/erlang_parser.rb
Constant Summary collapse
- TYPES =
{ 'integer' => 8, 'float' => 8*8, 'utf8' => 8, 'utf16' => 8*2, 'utf32' => 8*4, }.freeze
Instance Method Summary collapse
- #add(i) ⇒ Object
- #add_bits(s) ⇒ Object
- #add_int(v, size) ⇒ Object
- #bit_size(size, type) ⇒ Object
-
#initialize ⇒ ErlangBitstream
constructor
A new instance of ErlangBitstream.
- #int2bits(i, len) ⇒ Object
- #str2int(s, type) ⇒ Object
- #value(encoding = 'utf-8') ⇒ Object
Constructor Details
#initialize ⇒ ErlangBitstream
Returns a new instance of ErlangBitstream.
85 86 87 88 |
# File 'lib/utils/erlang_parser.rb', line 85 def initialize @data = [] # a stream of 8-bit numbers @cur_bits = '' # a string of binary bits 10010010... end |
Instance Method Details
#add(i) ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/utils/erlang_parser.rb', line 104 def add(i) if i[:integer].nil? && i[:string].nil? raise 'No data provided, internal error for binary-stream processing!' end s = bit_size(i[:size], i[:type]) unless i[:string].nil? str2int(i[:string].to_s, i[:type]).map { |e| add_bits(int2bits(e, 8)) } else add_int(i[:integer], s) end rescue RuntimeError => e raise 'Error processing Erlang bit string '\ "'#{i[:string] || i[:integer]}:#{i[:size]}/#{i[:type]}'. #{e.}" end |
#add_bits(s) ⇒ Object
138 139 140 141 142 |
# File 'lib/utils/erlang_parser.rb', line 138 def add_bits(s) b = (@cur_bits + s).scan(/.{1,8}/) @data += b[0..-2].map { |x| x.to_i(2) } @cur_bits = b.last end |
#add_int(v, size) ⇒ Object
133 134 135 136 |
# File 'lib/utils/erlang_parser.rb', line 133 def add_int(v, size) x = v.to_i & (2**size - 1) # only get the bits specified in size add_bits(int2bits(x, size)) end |
#bit_size(size, type) ⇒ Object
98 99 100 101 102 |
# File 'lib/utils/erlang_parser.rb', line 98 def bit_size(size, type) raise 'Cannot specify size and type at the same time.' if !type.nil? && !size.nil? return (size || 8).to_i if type.nil? TYPES[type] || raise("Cannot handle binary-stream type #{type}") end |
#int2bits(i, len) ⇒ Object
129 130 131 |
# File 'lib/utils/erlang_parser.rb', line 129 def int2bits(i, len) format("%0#{len}b", i) end |
#str2int(s, type) ⇒ Object
119 120 121 122 123 124 125 126 127 |
# File 'lib/utils/erlang_parser.rb', line 119 def str2int(s, type) case type when 'utf8' then s.encode('utf-8').unpack('C*') when 'utf16' then s.encode('utf-16').unpack('C*').drop(2) when 'utf32' then s.encode('utf-32').unpack('C*').drop(4) when 'integer', 'float' then raise "Cannot handle bit string as type #{type}" else s.split('').map { |x| x.ord & 0xff } end end |
#value(encoding = 'utf-8') ⇒ Object
144 145 146 147 148 149 150 151 |
# File 'lib/utils/erlang_parser.rb', line 144 def value(encoding = 'utf-8') # fill in the rest rest = '0' * (8 - @cur_bits.length) + @cur_bits arr = @data + [rest.to_i(2)] s = arr.pack('C*') s.force_encoding(encoding) unless encoding.nil? s end |