aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/gob/encode.go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-09-16 15:47:21 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-09-16 15:47:21 +0000
commitadb0401dac41c81571722312d4586b2693f95aa6 (patch)
treeea2b52e3c258d6b6d9356977c683c7f72a4a5fd5 /libgo/go/gob/encode.go
parent5548ca3540bccbc908a45942896d635ea5f1c23f (diff)
downloadgcc-adb0401dac41c81571722312d4586b2693f95aa6.zip
gcc-adb0401dac41c81571722312d4586b2693f95aa6.tar.gz
gcc-adb0401dac41c81571722312d4586b2693f95aa6.tar.bz2
Update Go library to r60.
From-SVN: r178910
Diffstat (limited to 'libgo/go/gob/encode.go')
-rw-r--r--libgo/go/gob/encode.go47
1 files changed, 31 insertions, 16 deletions
diff --git a/libgo/go/gob/encode.go b/libgo/go/gob/encode.go
index f9e691a..317014e 100644
--- a/libgo/go/gob/encode.go
+++ b/libgo/go/gob/encode.go
@@ -11,7 +11,7 @@ import (
"unsafe"
)
-const uint64Size = unsafe.Sizeof(uint64(0))
+const uint64Size = int(unsafe.Sizeof(uint64(0)))
// encoderState is the global execution state of an instance of the encoder.
// Field numbers are delta encoded and always increase. The field
@@ -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,9 +466,30 @@ 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, index int) {
+func (enc *Encoder) encodeGobEncoder(b *bytes.Buffer, v reflect.Value) {
// TODO: should we catch panics from the called method?
// We know it's a GobEncoder, so just call the method directly.
data, err := v.Interface().(GobEncoder).GobEncode()
@@ -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)
@@ -592,17 +615,6 @@ func (enc *Encoder) encOpFor(rt reflect.Type, inProgress map[reflect.Type]*encOp
return &op, indir
}
-// methodIndex returns which method of rt implements the method.
-func methodIndex(rt reflect.Type, method string) int {
- for i := 0; i < rt.NumMethod(); i++ {
- if rt.Method(i).Name == method {
- return i
- }
- }
- errorf("internal error: can't find method %s", method)
- return 0
-}
-
// gobEncodeOpFor returns the op for a type that is known to implement
// GobEncoder.
func (enc *Encoder) gobEncodeOpFor(ut *userTypeInfo) (*encOp, int) {
@@ -623,8 +635,11 @@ 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, methodIndex(rt, gobEncodeMethodName))
+ state.enc.encodeGobEncoder(state.b, v)
}
return &op, int(ut.encIndir) // encIndir: op will get called with p == address of receiver.
}