|
|
@ -63,11 +63,12 @@ type Decoder interface { |
|
|
|
// must contain an element for each decoded field. Decode returns an
|
|
|
|
// must contain an element for each decoded field. Decode returns an
|
|
|
|
// error if there are too few or too many elements.
|
|
|
|
// error if there are too few or too many elements.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// The decoding of struct fields honours one particular struct tag,
|
|
|
|
// The decoding of struct fields honours two struct tags, "tail" and
|
|
|
|
// "nil". This tag applies to pointer-typed fields and changes the
|
|
|
|
// "nil". For an explanation of "tail", see the example.
|
|
|
|
|
|
|
|
// The "nil" tag applies to pointer-typed fields and changes the
|
|
|
|
// decoding rules for the field such that input values of size zero
|
|
|
|
// decoding rules for the field such that input values of size zero
|
|
|
|
// decode as a nil pointer. This tag can be useful when decoding recursive
|
|
|
|
// decode as a nil pointer. This tag can be useful when decoding
|
|
|
|
// types.
|
|
|
|
// recursive types.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// type StructWithEmptyOK struct {
|
|
|
|
// type StructWithEmptyOK struct {
|
|
|
|
// Foo *[20]byte `rlp:"nil"`
|
|
|
|
// Foo *[20]byte `rlp:"nil"`
|
|
|
@ -190,7 +191,7 @@ func makeDecoder(typ reflect.Type, tags tags) (dec decoder, err error) { |
|
|
|
case kind == reflect.String: |
|
|
|
case kind == reflect.String: |
|
|
|
return decodeString, nil |
|
|
|
return decodeString, nil |
|
|
|
case kind == reflect.Slice || kind == reflect.Array: |
|
|
|
case kind == reflect.Slice || kind == reflect.Array: |
|
|
|
return makeListDecoder(typ) |
|
|
|
return makeListDecoder(typ, tags) |
|
|
|
case kind == reflect.Struct: |
|
|
|
case kind == reflect.Struct: |
|
|
|
return makeStructDecoder(typ) |
|
|
|
return makeStructDecoder(typ) |
|
|
|
case kind == reflect.Ptr: |
|
|
|
case kind == reflect.Ptr: |
|
|
@ -264,7 +265,7 @@ func decodeBigInt(s *Stream, val reflect.Value) error { |
|
|
|
return nil |
|
|
|
return nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func makeListDecoder(typ reflect.Type) (decoder, error) { |
|
|
|
func makeListDecoder(typ reflect.Type, tag tags) (decoder, error) { |
|
|
|
etype := typ.Elem() |
|
|
|
etype := typ.Elem() |
|
|
|
if etype.Kind() == reflect.Uint8 && !reflect.PtrTo(etype).Implements(decoderInterface) { |
|
|
|
if etype.Kind() == reflect.Uint8 && !reflect.PtrTo(etype).Implements(decoderInterface) { |
|
|
|
if typ.Kind() == reflect.Array { |
|
|
|
if typ.Kind() == reflect.Array { |
|
|
@ -277,15 +278,26 @@ func makeListDecoder(typ reflect.Type) (decoder, error) { |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
var dec decoder |
|
|
|
isArray := typ.Kind() == reflect.Array |
|
|
|
switch { |
|
|
|
return func(s *Stream, val reflect.Value) error { |
|
|
|
case typ.Kind() == reflect.Array: |
|
|
|
if isArray { |
|
|
|
dec = func(s *Stream, val reflect.Value) error { |
|
|
|
return decodeListArray(s, val, etypeinfo.decoder) |
|
|
|
return decodeListArray(s, val, etypeinfo.decoder) |
|
|
|
} else { |
|
|
|
} |
|
|
|
|
|
|
|
case tag.tail: |
|
|
|
|
|
|
|
// A slice with "tail" tag can occur as the last field
|
|
|
|
|
|
|
|
// of a struct and is upposed to swallow all remaining
|
|
|
|
|
|
|
|
// list elements. The struct decoder already called s.List,
|
|
|
|
|
|
|
|
// proceed directly to decoding the elements.
|
|
|
|
|
|
|
|
dec = func(s *Stream, val reflect.Value) error { |
|
|
|
|
|
|
|
return decodeSliceElems(s, val, etypeinfo.decoder) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
dec = func(s *Stream, val reflect.Value) error { |
|
|
|
return decodeListSlice(s, val, etypeinfo.decoder) |
|
|
|
return decodeListSlice(s, val, etypeinfo.decoder) |
|
|
|
} |
|
|
|
} |
|
|
|
}, nil |
|
|
|
} |
|
|
|
|
|
|
|
return dec, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func decodeListSlice(s *Stream, val reflect.Value, elemdec decoder) error { |
|
|
|
func decodeListSlice(s *Stream, val reflect.Value, elemdec decoder) error { |
|
|
@ -297,7 +309,13 @@ func decodeListSlice(s *Stream, val reflect.Value, elemdec decoder) error { |
|
|
|
val.Set(reflect.MakeSlice(val.Type(), 0, 0)) |
|
|
|
val.Set(reflect.MakeSlice(val.Type(), 0, 0)) |
|
|
|
return s.ListEnd() |
|
|
|
return s.ListEnd() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if err := decodeSliceElems(s, val, elemdec); err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return s.ListEnd() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func decodeSliceElems(s *Stream, val reflect.Value, elemdec decoder) error { |
|
|
|
i := 0 |
|
|
|
i := 0 |
|
|
|
for ; ; i++ { |
|
|
|
for ; ; i++ { |
|
|
|
// grow slice if necessary
|
|
|
|
// grow slice if necessary
|
|
|
@ -323,12 +341,11 @@ func decodeListSlice(s *Stream, val reflect.Value, elemdec decoder) error { |
|
|
|
if i < val.Len() { |
|
|
|
if i < val.Len() { |
|
|
|
val.SetLen(i) |
|
|
|
val.SetLen(i) |
|
|
|
} |
|
|
|
} |
|
|
|
return s.ListEnd() |
|
|
|
return nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func decodeListArray(s *Stream, val reflect.Value, elemdec decoder) error { |
|
|
|
func decodeListArray(s *Stream, val reflect.Value, elemdec decoder) error { |
|
|
|
_, err := s.List() |
|
|
|
if _, err := s.List(); err != nil { |
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return wrapStreamError(err, val.Type()) |
|
|
|
return wrapStreamError(err, val.Type()) |
|
|
|
} |
|
|
|
} |
|
|
|
vlen := val.Len() |
|
|
|
vlen := val.Len() |
|
|
@ -398,11 +415,11 @@ func makeStructDecoder(typ reflect.Type) (decoder, error) { |
|
|
|
return nil, err |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
|
dec := func(s *Stream, val reflect.Value) (err error) { |
|
|
|
dec := func(s *Stream, val reflect.Value) (err error) { |
|
|
|
if _, err = s.List(); err != nil { |
|
|
|
if _, err := s.List(); err != nil { |
|
|
|
return wrapStreamError(err, typ) |
|
|
|
return wrapStreamError(err, typ) |
|
|
|
} |
|
|
|
} |
|
|
|
for _, f := range fields { |
|
|
|
for _, f := range fields { |
|
|
|
err = f.info.decoder(s, val.Field(f.index)) |
|
|
|
err := f.info.decoder(s, val.Field(f.index)) |
|
|
|
if err == EOL { |
|
|
|
if err == EOL { |
|
|
|
return &decodeError{msg: "too few elements", typ: typ} |
|
|
|
return &decodeError{msg: "too few elements", typ: typ} |
|
|
|
} else if err != nil { |
|
|
|
} else if err != nil { |
|
|
|