1
0
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:
Rob Pike 2011-08-04 14:39:44 +10:00
parent 946cb0ece1
commit ee9168d507
2 changed files with 46 additions and 0 deletions

View File

@ -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)
}

View File

@ -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)
}
}