]> Cypherpunks repositories - gostls13.git/commitdiff
gob: don't invoke GobEncoder on zero values.
authorRob Pike <r@golang.org>
Thu, 4 Aug 2011 04:39:44 +0000 (14:39 +1000)
committerRob Pike <r@golang.org>
Thu, 4 Aug 2011 04:39:44 +0000 (14:39 +1000)
R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/4801076

src/pkg/gob/encode.go
src/pkg/gob/gobencdec_test.go

index c4c8219cf3b91358ca0f521a11418d6ee4e017c0..576a83df0fef9319d16083e6718289f69ab659b0 100644 (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)
        }
index 25cb5d11b8e48b52e53b95fa8360043e18f7aea4..371a43c8f54f55c53e2e7a7bb985f42c0e9db0d6 100644 (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)
+       }
+}