module Ciri::RLP::Encode
Public Instance Methods
encode(input, type = nil)
click to toggle source
Encode
input to rlp encoding
Examples:
Ciri::RLP.encode("hello world")
# File lib/ciri/rlp/encode.rb, line 41 def encode(input, type = nil) type ? encode_with_type(input, type) : encode_simple(input) end
encode_simple(input)
click to toggle source
# File lib/ciri/rlp/encode.rb, line 45 def encode_simple(input) if input.is_a?(Array) encode_list(input) {|i| encode_simple(i)} elsif input.is_a?(Integer) encode_with_type(input, Integer) elsif input.class.respond_to?(:rlp_encode) input.class.rlp_encode(input) else encode_with_type(input, Raw) end end
encode_with_type(item, type, zero: '')
click to toggle source
Use this method before RLP.encode, this method encode ruby objects to rlp friendly format, string or array. see Ciri::RLP::Serializable::TYPES for supported types
Examples:
item = Ciri::RLP.encode_with_type(number, :int, zero: "\x00".b) encoded_text = Ciri::RLP.encode(item)
# File lib/ciri/rlp/encode.rb, line 65 def encode_with_type(item, type, zero: '') if type == Integer if item == 0 "\x80".b elsif item < 0x80 Ciri::Utils.big_endian_encode(item, zero) else buf = Ciri::Utils.big_endian_encode(item, zero) [0x80 + buf.size].pack("c*") + buf end elsif type == Bool item ? Bool::ENCODED_TRUE : Bool::ENCODED_FALSE elsif type.is_a?(Class) && type.respond_to?(:rlp_encode) type.rlp_encode(item) elsif type.is_a?(Array) if type.size == 1 # array type encode_list(item) {|i| encode_with_type(i, type[0])} else # unknown raise RLP::InvalidError.new "type size should be 1, got #{type}" end elsif type == Raw encode_raw(item) elsif type == Bytes raise RLP::InvalidError.new "expect String, got #{item.class}" unless item.is_a?(String) encode_raw(item) elsif type == List raise RLP::InvalidError.new "expect Array, got #{item.class}" unless item.is_a?(Array) encode_raw(item) else raise RLP::InvalidError.new "unknown type #{type}" end rescue error "when encoding #{Utils.to_hex item.to_s} into #{type}" raise end
Protected Instance Methods
encode_list(input, &encoder)
click to toggle source
# File lib/ciri/rlp/encode.rb, line 128 def encode_list(input, &encoder) input ||= [] # allow nil list output = encoder ? input.map {|item| encoder.call(item)}.join : input.join length = output.length if length < 56 to_binary(0xc0 + length) + output elsif length < 256 ** 8 binary_length = to_binary(length) to_binary(0xf7 + binary_length.size) + binary_length + output else raise InputOverflow.new("input length #{input.size} is too long") end end
encode_raw(input)
click to toggle source
# File lib/ciri/rlp/encode.rb, line 103 def encode_raw(input) result = if input.is_a?(String) encode_string(input) elsif input.is_a?(Array) encode_list(input) {|item| encode(item)} else raise ArgumentError.new("input must be a String or Array, #{input.inspect}") end result.b end
encode_string(input)
click to toggle source
# File lib/ciri/rlp/encode.rb, line 114 def encode_string(input) length = input.length if length == 1 && input.ord < 0x80 input elsif length < 56 to_binary(0x80 + length) + input elsif length < 256 ** 8 binary_length = to_binary(length) to_binary(0xb7 + binary_length.size) + binary_length + input else raise InputOverflow.new("input length #{input.size} is too long") end end
Private Instance Methods
to_binary(n)
click to toggle source
# File lib/ciri/rlp/encode.rb, line 144 def to_binary(n) Ciri::Utils.big_endian_encode(n) end