Module: RLP::Decode

Includes:
Constant, Error, Utils
Included in:
RLP, DecodeLazy
Defined in:
lib/rlp/decode.rb

Constant Summary

Constants included from Constant

Constant::BYTE_EMPTY, Constant::BYTE_ZERO, Constant::LIST_PREFIX_OFFSET, Constant::LONG_LENGTH_LIMIT, Constant::PRIMITIVE_PREFIX_OFFSET, Constant::SHORT_LENGTH_LIMIT

Instance Method Summary collapse

Methods included from Utils

#big_endian_to_int, #bytes_to_str, #encode_hex, #int_to_big_endian, #list?, make_immutable!, #primitive?, #str_to_bytes

Instance Method Details

#decode(rlp, sedes: nil, strict: true, options: {}) ⇒ Object

Decode an RLP encoded object.

If the deserialized result `obj` has an attribute `_cached_rlp` (e.g. if `sedes` is a subclass of Sedes::Serializable), it will be set to `rlp`, which will improve performance on subsequent Encode#encode calls. Bear in mind however that `obj` needs to make sure that this value is updated whenever one of its fields changes or prevent such changes entirely (Sedes::Serializable does the latter).

Parameters:

  • sedes (#deserialize) (defaults to: nil)

    an object implementing a function `deserialize(code)` which will be applied after decoding, or `nil` if no deserialization should be performed

  • options (Hash) (defaults to: {})

    additional keyword arguments that will be passed to the deserializer

  • strict (Boolean) (defaults to: true)

    if false inputs that are longer than necessary don't cause an exception

Returns:

  • (Object)

    the decoded and maybe deserialized object

Raises:


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/rlp/decode.rb', line 31

def decode(rlp, sedes: nil, strict: true, options: {})
  rlp = str_to_bytes(rlp)

  begin
    item, next_start = consume_item(rlp, 0)
  rescue Exception => e
    raise DecodingError.new("Cannot decode rlp string: #{e}", rlp)
  end

  raise DecodingError.new("RLP string ends with #{rlp.size - next_start} superfluous bytes", rlp) if next_start != rlp.size && strict

  if sedes
    # FIXME: lazy man's kwargs
    obj = sedes.is_a?(Sedes::Serializable) ?
      sedes.deserialize(item, **options) :
      sedes.deserialize(item)

    if obj.respond_to?(:_cached_rlp)
      obj._cached_rlp = rlp
      raise "RLP::Sedes::Serializable object must be immutable after decode" if obj.is_a?(Sedes::Serializable) && obj.mutable?
    end

    obj
  else
    item
  end
end