diff options
Diffstat (limited to 'src/pkg/gob/encode.go')
-rw-r--r-- | src/pkg/gob/encode.go | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/src/pkg/gob/encode.go b/src/pkg/gob/encode.go index 941e26052..317014efd 100644 --- a/src/pkg/gob/encode.go +++ b/src/pkg/gob/encode.go @@ -62,7 +62,7 @@ func (state *encoderState) encodeUint(x uint64) { var n, m int m = uint64Size for n = 1; x > 0; n++ { - state.buf[m] = uint8(x & 0xFF) + state.buf[m] = uint8(x) x >>= 8 m-- } @@ -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) { @@ -557,7 +578,9 @@ func (enc *Encoder) encOpFor(rt reflect.Type, inProgress map[reflect.Type]*encOp // the iteration. v := reflect.ValueOf(unsafe.Unreflect(t, unsafe.Pointer(p))) mv := reflect.Indirect(v) - if !state.sendZero && mv.Len() == 0 { + // We send zero-length (but non-nil) maps because the + // receiver might want to use the map. (Maps don't use append.) + if !state.sendZero && mv.IsNil() { return } state.update(i) @@ -612,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) } |