Merge pull request #564 from fjl/rlp-nil-array
rlp: encode nil array pointers as empty list or string
This commit is contained in:
commit
65ea55bccd
@ -87,6 +87,8 @@ func (e flatenc) EncodeRLP(out io.Writer) error {
|
|||||||
// To encode a pointer, the value being pointed to is encoded. For nil
|
// To encode a pointer, the value being pointed to is encoded. For nil
|
||||||
// pointers, Encode will encode the zero value of the type. A nil
|
// pointers, Encode will encode the zero value of the type. A nil
|
||||||
// pointer to a struct type always encodes as an empty RLP list.
|
// pointer to a struct type always encodes as an empty RLP list.
|
||||||
|
// A nil pointer to an array encodes as an empty list (or empty string
|
||||||
|
// if the array has element type byte).
|
||||||
//
|
//
|
||||||
// Struct values are encoded as an RLP list of all their encoded
|
// Struct values are encoded as an RLP list of all their encoded
|
||||||
// public fields. Recursive struct types are supported.
|
// public fields. Recursive struct types are supported.
|
||||||
@ -532,21 +534,37 @@ func makePtrWriter(typ reflect.Type) (writer, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
zero := reflect.Zero(typ.Elem())
|
|
||||||
|
// determine nil pointer handler
|
||||||
|
var nilfunc func(*encbuf) error
|
||||||
kind := typ.Elem().Kind()
|
kind := typ.Elem().Kind()
|
||||||
writer := func(val reflect.Value, w *encbuf) error {
|
switch {
|
||||||
switch {
|
case kind == reflect.Array && isByte(typ.Elem().Elem()):
|
||||||
case !val.IsNil():
|
nilfunc = func(w *encbuf) error {
|
||||||
return etypeinfo.writer(val.Elem(), w)
|
w.str = append(w.str, 0x80)
|
||||||
case kind == reflect.Struct:
|
return nil
|
||||||
// encoding the zero value of a struct could trigger
|
}
|
||||||
|
case kind == reflect.Struct || kind == reflect.Array:
|
||||||
|
nilfunc = func(w *encbuf) error {
|
||||||
|
// encoding the zero value of a struct/array could trigger
|
||||||
// infinite recursion, avoid that.
|
// infinite recursion, avoid that.
|
||||||
w.listEnd(w.list())
|
w.listEnd(w.list())
|
||||||
return nil
|
return nil
|
||||||
default:
|
}
|
||||||
|
default:
|
||||||
|
zero := reflect.Zero(typ.Elem())
|
||||||
|
nilfunc = func(w *encbuf) error {
|
||||||
return etypeinfo.writer(zero, w)
|
return etypeinfo.writer(zero, w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writer := func(val reflect.Value, w *encbuf) error {
|
||||||
|
if val.IsNil() {
|
||||||
|
return nilfunc(w)
|
||||||
|
} else {
|
||||||
|
return etypeinfo.writer(val.Elem(), w)
|
||||||
|
}
|
||||||
|
}
|
||||||
return writer, err
|
return writer, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,8 +202,10 @@ var encTests = []encTest{
|
|||||||
{val: (*uint)(nil), output: "80"},
|
{val: (*uint)(nil), output: "80"},
|
||||||
{val: (*string)(nil), output: "80"},
|
{val: (*string)(nil), output: "80"},
|
||||||
{val: (*[]byte)(nil), output: "80"},
|
{val: (*[]byte)(nil), output: "80"},
|
||||||
|
{val: (*[10]byte)(nil), output: "80"},
|
||||||
{val: (*big.Int)(nil), output: "80"},
|
{val: (*big.Int)(nil), output: "80"},
|
||||||
{val: (*[]string)(nil), output: "C0"},
|
{val: (*[]string)(nil), output: "C0"},
|
||||||
|
{val: (*[10]string)(nil), output: "C0"},
|
||||||
{val: (*[]interface{})(nil), output: "C0"},
|
{val: (*[]interface{})(nil), output: "C0"},
|
||||||
{val: (*[]struct{ uint })(nil), output: "C0"},
|
{val: (*[]struct{ uint })(nil), output: "C0"},
|
||||||
{val: (*interface{})(nil), output: "C0"},
|
{val: (*interface{})(nil), output: "C0"},
|
||||||
|
Loading…
Reference in New Issue
Block a user