Module: RLP::Decode

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

Constant Summary

Constants included from Utils

Utils::BINARY_ENCODING

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?, #bytes_to_str, #decode_hex, #encode_hex, #int_to_big_endian, #list?, make_immutable!, #primitive?, #str_to_bytes

Instance Method Details

#decode(rlp, **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:

  • options (Hash)

    deserialization options:

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

    • strict (Boolean) if false inputs that are longer than necessary don't cause an exception

    • (any options left) (Hash) additional keyword arguments passed to the deserializer

Returns:

  • (Object)

    the decoded and maybe deserialized object

Raises:



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/rlp/decode.rb', line 35

def decode(rlp, **options)
  rlp = str_to_bytes(rlp)
  sedes = options.delete(:sedes)
  strict = options.has_key?(:strict) ? options.delete(:strict) : true

  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
    obj = sedes.instance_of?(Class) && sedes.include?(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