mirror of
https://github.com/golang/go
synced 2024-11-23 08:10:03 -07:00
encoding/gob: handle encoding of different indirects of GobEncoder
Fixes #4647. R=r, golang-dev CC=golang-dev https://golang.org/cl/7085051
This commit is contained in:
parent
f31f9a61c5
commit
bc1152a32e
@ -137,8 +137,8 @@ func (enc *Encoder) sendType(w io.Writer, state *encoderState, origt reflect.Typ
|
||||
ut := userType(origt)
|
||||
if ut.isGobEncoder {
|
||||
// The rules are different: regardless of the underlying type's representation,
|
||||
// we need to tell the other side that this exact type is a GobEncoder.
|
||||
return enc.sendActualType(w, state, ut, ut.user)
|
||||
// we need to tell the other side that the base type is a GobEncoder.
|
||||
return enc.sendActualType(w, state, ut, ut.base)
|
||||
}
|
||||
|
||||
// It's a concrete value, so drill down to the base type.
|
||||
|
@ -142,6 +142,18 @@ type GobTest5 struct {
|
||||
V *ValueGobber
|
||||
}
|
||||
|
||||
type GobTest6 struct {
|
||||
X int // guarantee we have something in common with GobTest*
|
||||
V ValueGobber
|
||||
W *ValueGobber
|
||||
}
|
||||
|
||||
type GobTest7 struct {
|
||||
X int // guarantee we have something in common with GobTest*
|
||||
V *ValueGobber
|
||||
W ValueGobber
|
||||
}
|
||||
|
||||
type GobTestIgnoreEncoder struct {
|
||||
X int // guarantee we have something in common with GobTest*
|
||||
}
|
||||
@ -360,6 +372,61 @@ func TestGobEncoderValueEncoder(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Test that we can use a value then a pointer type of a GobEncoder
|
||||
// in the same encoded value. Bug 4647.
|
||||
func TestGobEncoderValueThenPointer(t *testing.T) {
|
||||
v := ValueGobber("forty-two")
|
||||
w := ValueGobber("six-by-nine")
|
||||
|
||||
// this was a bug: encoding a GobEncoder by value before a GobEncoder
|
||||
// pointer would cause duplicate type definitions to be sent.
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
enc := NewEncoder(b)
|
||||
if err := enc.Encode(GobTest6{42, v, &w}); err != nil {
|
||||
t.Fatal("encode error:", err)
|
||||
}
|
||||
dec := NewDecoder(b)
|
||||
x := new(GobTest6)
|
||||
if err := dec.Decode(x); err != nil {
|
||||
t.Fatal("decode error:", err)
|
||||
}
|
||||
if got, want := x.V, v; got != want {
|
||||
t.Errorf("v = %q, want %q", got, want)
|
||||
}
|
||||
if got, want := v.W, w; got == nil {
|
||||
t.Errorf("w = nil, want %q", want)
|
||||
} else if *got != want {
|
||||
t.Errorf("w = %q, want %q", *got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// Test that we can use a pointer then a value type of a GobEncoder
|
||||
// in the same encoded value.
|
||||
func TestGobEncoderPointerThenValue(t *testing.T) {
|
||||
v := ValueGobber("forty-two")
|
||||
w := ValueGobber("six-by-nine")
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
enc := NewEncoder(b)
|
||||
if err := enc.Encode(GobTest7{42, &v, w}); err != nil {
|
||||
t.Fatal("encode error:", err)
|
||||
}
|
||||
dec := NewDecoder(b)
|
||||
x := new(GobTest7)
|
||||
if err := dec.Decode(x); err != nil {
|
||||
t.Fatal("decode error:", err)
|
||||
}
|
||||
if got, want := x.V, v; got == nil {
|
||||
t.Errorf("v = nil, want %q", want)
|
||||
} else if *got != want {
|
||||
t.Errorf("v = %q, want %q", got, want)
|
||||
}
|
||||
if got, want := v.W, w; got != want {
|
||||
t.Errorf("w = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGobEncoderFieldTypeError(t *testing.T) {
|
||||
// GobEncoder to non-decoder: error
|
||||
b := new(bytes.Buffer)
|
||||
|
Loading…
Reference in New Issue
Block a user