Class: ErlangBitstream
- Inherits:
-
Object
- Object
- ErlangBitstream
- Defined in:
- lib/inspec/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.
81 82 83 84 |
# File 'lib/inspec/utils/erlang_parser.rb', line 81 def initialize @data = [] # a stream of 8-bit numbers @cur_bits = "" # a string of binary bits 10010010... end |
Instance Method Details
#add(i) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/inspec/utils/erlang_parser.rb', line 101 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
136 137 138 139 140 |
# File 'lib/inspec/utils/erlang_parser.rb', line 136 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
131 132 133 134 |
# File 'lib/inspec/utils/erlang_parser.rb', line 131 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
94 95 96 97 98 99 |
# File 'lib/inspec/utils/erlang_parser.rb', line 94 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
127 128 129 |
# File 'lib/inspec/utils/erlang_parser.rb', line 127 def int2bits(i, len) format("%0#{len}b", i) end |
#str2int(s, type) ⇒ Object
117 118 119 120 121 122 123 124 125 |
# File 'lib/inspec/utils/erlang_parser.rb', line 117 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
142 143 144 145 146 147 148 149 |
# File 'lib/inspec/utils/erlang_parser.rb', line 142 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 |