class Ethereum::Trie::NibbleKey
Nibble is half-byte.
Constants
- HEX_VALUES
- NIBBLE_ODD_FLAG
- NIBBLE_TERMINATOR
- NIBBLE_TERM_FLAG
Public Class Methods
Decode bytes to {NibbleKey}, with flags processed.
@see `unpack_to_nibbles` in pyethereum
@param bytes [String] compact hex encoded string.
@return [NibbleKey] nibbles array, may have a terminator
# File lib/ethereum/trie/nibble_key.rb, line 57 def decode(bytes) o = from_string bytes flags = o[0] o.push NIBBLE_TERMINATOR if flags & NIBBLE_TERM_FLAG > 0 fill = flags & NIBBLE_ODD_FLAG > 0 ? 1 : 2 new o[fill..-1] end
Encode nibbles to string.
@see `pack_nibbles` in pyethereum
@param nibbles [Array] array of nibbles to encode
@return [String] encoded string
# File lib/ethereum/trie/nibble_key.rb, line 26 def encode(nibbles) flags = 0 if nibbles.last == NIBBLE_TERMINATOR flags |= NIBBLE_TERM_FLAG nibbles = nibbles[0...-1] end odd = nibbles.size % 2 flags |= odd if odd == 1 nibbles = [flags] + nibbles else nibbles = [flags, 0b0000] + nibbles end (nibbles.size/2).times.reduce('') do |s, i| base = 2*i s += (16*nibbles[base] + nibbles[base+1]).chr end end
Convert arbitrary string to {NibbleKey}.
@see `bin_to_nibbles` in pyethereum
@example
from_string('') # => [] from_string('h') # => [6, 8] from_string('he') # => [6, 8, 6, 5] from_string('hello') # => [6, 8, 6, 5, 6, 12, 6, 12, 6, 15]
@param s [String] any string
@return [NibbleKey] array of nibbles presented as interger smaller
than 16, has no terminator because plain string has no flags
# File lib/ethereum/trie/nibble_key.rb, line 83 def from_string(s) nibbles = RLP::Utils.encode_hex(s).each_char.map {|nibble| HEX_VALUES[nibble] } new nibbles end
# File lib/ethereum/trie/nibble_key.rb, line 112 def initialize(*args) super end
# File lib/ethereum/trie/nibble_key.rb, line 107 def terminator new([NIBBLE_TERMINATOR]) end
Convert array of nibbles to string.
@see `nibbles_to_bin` in pyethereum
@param nibbles [Array] array of nibbles
@return [String] string represented by nibbles
# File lib/ethereum/trie/nibble_key.rb, line 97 def to_string(nibbles) raise ArgumentError, "nibbles can only be in 0..15" if nibbles.any? {|x| x > 15 || x < 0 } raise ArgumentError, "nibbles must be of even numbers" if nibbles.size % 2 == 1 (nibbles.size/2).times.map do |i| base = i*2 (16*nibbles[base] + nibbles[base+1]).chr end.join end
Public Instance Methods
# File lib/ethereum/trie/nibble_key.rb, line 176 def +(array) self.class.new(super(array)) end
Find common prefix to another key.
@param another_key [Array] another array of nibbles
@return [Array] common prefix of both nibbles array
# File lib/ethereum/trie/nibble_key.rb, line 157 def common_prefix(another_key) prefix = [] [size, another_key.size].min.times do |i| break if self[i] != another_key[i] prefix.push self[i] end self.class.new prefix end
# File lib/ethereum/trie/nibble_key.rb, line 168 def encode self.class.encode self end
test whether this is prefix of another {NibbleKey}
@param another_key [NibbleKey] the full key to test
@return [Bool]
# File lib/ethereum/trie/nibble_key.rb, line 145 def prefix?(another_key) return false if another_key.size < size another_key.take(size) == self end
Get with or without terminator copy of this {NibbleKey}.
@param flag [Bool] set true to get a copy with terminator, otherwise
set false
@return [NibbleKey] a copy with or without terminator at end
# File lib/ethereum/trie/nibble_key.rb, line 128 def terminate(flag) dup.tap do |copy| if flag copy.push NIBBLE_TERMINATOR unless copy.terminate? else copy.pop if copy.terminate? end end end
# File lib/ethereum/trie/nibble_key.rb, line 116 def terminate? last == NIBBLE_TERMINATOR end
# File lib/ethereum/trie/nibble_key.rb, line 172 def to_string self.class.to_string self end