1
0
mirror of https://github.com/golang/go synced 2024-11-22 01:44:40 -07:00

gob: send empty but non-nil maps.

Fixes #2082.

R=golang-dev, dsymonds, r
CC=golang-dev
https://golang.org/cl/4798042
This commit is contained in:
Rob Pike 2011-07-21 10:27:11 +10:00
parent 4c03bf9c59
commit d11c0f1dbb
3 changed files with 37 additions and 21 deletions

View File

@ -573,30 +573,32 @@ func TestEndToEnd(t *testing.T) {
s1 := "string1" s1 := "string1"
s2 := "string2" s2 := "string2"
type T1 struct { type T1 struct {
A, B, C int A, B, C int
M map[string]*float64 M map[string]*float64
N *[3]float64 EmptyMap map[string]int // to check that we receive a non-nil map.
Strs *[2]string N *[3]float64
Int64s *[]int64 Strs *[2]string
RI complex64 Int64s *[]int64
S string RI complex64
Y []byte S string
T *T2 Y []byte
T *T2
} }
pi := 3.14159 pi := 3.14159
e := 2.71828 e := 2.71828
t1 := &T1{ t1 := &T1{
A: 17, A: 17,
B: 18, B: 18,
C: -5, C: -5,
M: map[string]*float64{"pi": &pi, "e": &e}, M: map[string]*float64{"pi": &pi, "e": &e},
N: &[3]float64{1.5, 2.5, 3.5}, EmptyMap: make(map[string]int),
Strs: &[2]string{s1, s2}, N: &[3]float64{1.5, 2.5, 3.5},
Int64s: &[]int64{77, 89, 123412342134}, Strs: &[2]string{s1, s2},
RI: 17 - 23i, Int64s: &[]int64{77, 89, 123412342134},
S: "Now is the time", RI: 17 - 23i,
Y: []byte("hello, sailor"), S: "Now is the time",
T: &T2{"this is T2"}, Y: []byte("hello, sailor"),
T: &T2{"this is T2"},
} }
b := new(bytes.Buffer) b := new(bytes.Buffer)
err := NewEncoder(b).Encode(t1) err := NewEncoder(b).Encode(t1)
@ -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) {

View File

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

View File

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