Commit d11c0f1d authored by Rob Pike's avatar Rob Pike

gob: send empty but non-nil maps.

Fixes #2082.

R=golang-dev, dsymonds, r
CC=golang-dev
https://golang.org/cl/4798042
parent 4c03bf9c
...@@ -575,6 +575,7 @@ func TestEndToEnd(t *testing.T) { ...@@ -575,6 +575,7 @@ func TestEndToEnd(t *testing.T) {
type T1 struct { type T1 struct {
A, B, C int A, B, C int
M map[string]*float64 M map[string]*float64
EmptyMap map[string]int // to check that we receive a non-nil map.
N *[3]float64 N *[3]float64
Strs *[2]string Strs *[2]string
Int64s *[]int64 Int64s *[]int64
...@@ -590,6 +591,7 @@ func TestEndToEnd(t *testing.T) { ...@@ -590,6 +591,7 @@ func TestEndToEnd(t *testing.T) {
B: 18, B: 18,
C: -5, C: -5,
M: map[string]*float64{"pi": &pi, "e": &e}, M: map[string]*float64{"pi": &pi, "e": &e},
EmptyMap: make(map[string]int),
N: &[3]float64{1.5, 2.5, 3.5}, N: &[3]float64{1.5, 2.5, 3.5},
Strs: &[2]string{s1, s2}, Strs: &[2]string{s1, s2},
Int64s: &[]int64{77, 89, 123412342134}, Int64s: &[]int64{77, 89, 123412342134},
...@@ -611,6 +613,13 @@ func TestEndToEnd(t *testing.T) { ...@@ -611,6 +613,13 @@ func TestEndToEnd(t *testing.T) {
if !reflect.DeepEqual(t1, &_t1) { if !reflect.DeepEqual(t1, &_t1) {
t.Errorf("encode expected %v got %v", *t1, _t1) t.Errorf("encode expected %v got %v", *t1, _t1)
} }
// Be absolutely sure the received map is non-nil.
if t1.EmptyMap == nil {
t.Errorf("nil map sent")
}
if _t1.EmptyMap == nil {
t.Errorf("nil map received")
}
} }
func TestOverflow(t *testing.T) { func TestOverflow(t *testing.T) {
......
...@@ -113,6 +113,11 @@ uninterpreted bytes of the value. ...@@ -113,6 +113,11 @@ uninterpreted bytes of the value.
All other slices and arrays are sent as an unsigned count followed by that many All other slices and arrays are sent as an unsigned count followed by that many
elements using the standard gob encoding for their type, recursively. elements using the standard gob encoding for their type, recursively.
Maps are sent as an unsigned count followed by that man key, element
pairs. Empty but non-nil maps are sent, so if the sender has allocated
a map, the receiver will allocate a map even no elements are
transmitted.
Structs are sent as a sequence of (field number, field value) pairs. The field Structs are sent as a sequence of (field number, field value) pairs. The field
value is sent using the standard gob encoding for its type, recursively. If a value is sent using the standard gob encoding for its type, recursively. If a
field has the zero value for its type, it is omitted from the transmission. The field has the zero value for its type, it is omitted from the transmission. The
......
...@@ -557,7 +557,9 @@ func (enc *Encoder) encOpFor(rt reflect.Type, inProgress map[reflect.Type]*encOp ...@@ -557,7 +557,9 @@ func (enc *Encoder) encOpFor(rt reflect.Type, inProgress map[reflect.Type]*encOp
// the iteration. // the iteration.
v := reflect.ValueOf(unsafe.Unreflect(t, unsafe.Pointer(p))) v := reflect.ValueOf(unsafe.Unreflect(t, unsafe.Pointer(p)))
mv := reflect.Indirect(v) 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 return
} }
state.update(i) state.update(i)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment