Module: Ciri::RLP::Decode

Includes:
Utils::Logger
Included in:
Ciri::RLP, Serializable::Schema
Defined in:
lib/ciri/rlp/decode.rb

Instance Method Summary collapse

Instance Method Details

#decode(input, type = Raw) ⇒ Object

Decode input from rlp encoding, only produce string or array

Examples:

Ciri::RLP.decode(input)


38
39
40
# File 'lib/ciri/rlp/decode.rb', line 38

def decode(input, type = Raw)
  decode_with_type(input, type)
end

#decode_with_type(s, type) ⇒ Object

Use this method after RLP.decode, decode values from string or array to specific types see Ciri::RLP::Serializable::TYPES for supported types

Examples:

item = Ciri::RLP.decode(encoded_text)
decode_with_type(item, Integer)


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/ciri/rlp/decode.rb', line 50

def decode_with_type(s, type)
  s = StringIO.new(s) if s.is_a?(String)
  if type == Integer
    item = s.read(1)
    if item.nil?
      raise InvalidError.new "invalid Integer value nil"
    elsif item == "\x80".b || item.empty?
      0
    elsif item.ord < 0x80
      item.ord
    else
      size = item[0].ord - 0x80
      Ciri::Utils.big_endian_decode(s.read(size))
    end
  elsif type == Bool
    item = s.read(1)
    if item == Bool::ENCODED_TRUE
      true
    elsif item == Bool::ENCODED_FALSE
      false
    else
      raise InvalidError.new "invalid bool value #{item}"
    end
  elsif type.is_a?(Class) && type.respond_to?(:rlp_decode)
    type.rlp_decode(s)
  elsif type.is_a?(Array)
    decode_list(s) do |list, s2|
      i = 0
      until s2.eof?
        t = type.size > i ? type[i] : type[-1]
        list << decode_with_type(s2, t)
        i += 1
      end
    end
  elsif type == Bytes
    str = decode_stream(s)
    raise RLP::InvalidError.new "decode #{str.class} from Bytes" unless str.is_a?(String)
    str
  elsif type == List
    list = decode_stream(s)
    raise RLP::InvalidError.new "decode #{list.class} from List" unless list.is_a?(Array)
    list
  elsif type == Raw
    decode_stream(s)
  else
    raise RLP::InvalidError.new "unknown type #{type}"
  end
rescue
  error "when decoding #{s} into #{type}"
  raise
end