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
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
Decode an RLP encoded object.

 If the deserialized result `obj` has an attribute `_cached_rlp` (e.g. if
 `sedes` is a subclass of {RLP::Sedes::Serializable}), it will be set to
 `rlp`, which will improve performance on subsequent {RLP::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 ({RLP::Sedes::Serializable} does the latter).

 @param 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

 @return [Object] the decoded and maybe deserialized object

 @raise [RLP::Error::DecodingError] if the input string does not end after
   the root item and `strict` is true
 @raise [RLP::Error::DeserializationError] if the deserialization fails