mirror of
https://github.com/golang/go
synced 2024-11-24 22:57:57 -07:00
gob: don't invoke GobEncoder on zero values.
R=golang-dev, dsymonds CC=golang-dev https://golang.org/cl/4801076
This commit is contained in:
parent
946cb0ece1
commit
ee9168d507
@ -466,6 +466,27 @@ func (enc *Encoder) encodeInterface(b *bytes.Buffer, iv reflect.Value) {
|
||||
enc.freeEncoderState(state)
|
||||
}
|
||||
|
||||
// isZero returns whether the value is the zero of its type.
|
||||
func isZero(val reflect.Value) bool {
|
||||
switch val.Kind() {
|
||||
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
||||
return val.Len() == 0
|
||||
case reflect.Bool:
|
||||
return !val.Bool()
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
return val.Complex() == 0
|
||||
case reflect.Chan, reflect.Func, reflect.Ptr:
|
||||
return val.IsNil()
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return val.Int() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return val.Float() == 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return val.Uint() == 0
|
||||
}
|
||||
panic("unknown type in isZero" + val.Type().String())
|
||||
}
|
||||
|
||||
// encGobEncoder encodes a value that implements the GobEncoder interface.
|
||||
// The data is sent as a byte array.
|
||||
func (enc *Encoder) encodeGobEncoder(b *bytes.Buffer, v reflect.Value) {
|
||||
@ -614,6 +635,9 @@ func (enc *Encoder) gobEncodeOpFor(ut *userTypeInfo) (*encOp, int) {
|
||||
} else {
|
||||
v = reflect.ValueOf(unsafe.Unreflect(rt, p))
|
||||
}
|
||||
if !state.sendZero && isZero(v) {
|
||||
return
|
||||
}
|
||||
state.update(i)
|
||||
state.enc.encodeGobEncoder(state.b, v)
|
||||
}
|
||||
|
@ -466,3 +466,25 @@ func TestGobEncoderIgnoreNonStructField(t *testing.T) {
|
||||
t.Errorf("expected 17 got %c", x.X)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGobEncoderIgnoreNilEncoder(t *testing.T) {
|
||||
b := new(bytes.Buffer)
|
||||
// First a field that's a structure.
|
||||
enc := NewEncoder(b)
|
||||
err := enc.Encode(GobTest0{X: 18}) // G is nil
|
||||
if err != nil {
|
||||
t.Fatal("encode error:", err)
|
||||
}
|
||||
dec := NewDecoder(b)
|
||||
x := new(GobTest0)
|
||||
err = dec.Decode(x)
|
||||
if err != nil {
|
||||
t.Fatal("decode error:", err)
|
||||
}
|
||||
if x.X != 18 {
|
||||
t.Errorf("expected x.X = 18, got %v", x.X)
|
||||
}
|
||||
if x.G != nil {
|
||||
t.Errorf("expected x.G = nil, got %v", x.G)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user