diff options
Diffstat (limited to 'libgo/go/gob')
-rw-r--r-- | libgo/go/gob/codec_test.go | 550 | ||||
-rw-r--r-- | libgo/go/gob/decode.go | 169 | ||||
-rw-r--r-- | libgo/go/gob/decoder.go | 4 | ||||
-rw-r--r-- | libgo/go/gob/doc.go | 58 | ||||
-rw-r--r-- | libgo/go/gob/encode.go | 94 | ||||
-rw-r--r-- | libgo/go/gob/encoder.go | 6 | ||||
-rw-r--r-- | libgo/go/gob/encoder_test.go | 99 | ||||
-rw-r--r-- | libgo/go/gob/type.go | 129 | ||||
-rw-r--r-- | libgo/go/gob/type_test.go | 4 |
9 files changed, 572 insertions, 541 deletions
diff --git a/libgo/go/gob/codec_test.go b/libgo/go/gob/codec_test.go index a95cfa9929b..af941c629cd 100644 --- a/libgo/go/gob/codec_test.go +++ b/libgo/go/gob/codec_test.go @@ -53,7 +53,7 @@ func TestUintCodec(t *testing.T) { encState := newEncoderState(nil, b) for _, tt := range encodeT { b.Reset() - encodeUint(encState, tt.x) + encState.encodeUint(tt.x) if !bytes.Equal(tt.b, b.Bytes()) { t.Errorf("encodeUint: %#x encode: expected % x got % x", tt.x, tt.b, b.Bytes()) } @@ -61,8 +61,8 @@ func TestUintCodec(t *testing.T) { decState := newDecodeState(nil, &b) for u := uint64(0); ; u = (u + 1) * 7 { b.Reset() - encodeUint(encState, u) - v := decodeUint(decState) + encState.encodeUint(u) + v := decState.decodeUint() if u != v { t.Errorf("Encode/Decode: sent %#x received %#x", u, v) } @@ -76,10 +76,10 @@ func verifyInt(i int64, t *testing.T) { defer testError(t) var b = new(bytes.Buffer) encState := newEncoderState(nil, b) - encodeInt(encState, i) + encState.encodeInt(i) decState := newDecodeState(nil, &b) decState.buf = make([]byte, 8) - j := decodeInt(decState) + j := decState.decodeInt() if i != j { t.Errorf("Encode/Decode: sent %#x received %#x", uint64(i), uint64(j)) } @@ -254,18 +254,6 @@ func TestScalarEncInstructions(t *testing.T) { } } - // float - { - b.Reset() - data := struct{ a float }{17} - instr := &encInstr{encFloat, 6, 0, 0} - state := newencoderState(b) - instr.op(instr, state, unsafe.Pointer(&data)) - if !bytes.Equal(floatResult, b.Bytes()) { - t.Errorf("float enc instructions: expected % x got % x", floatResult, b.Bytes()) - } - } - // float32 { b.Reset() @@ -317,7 +305,7 @@ func TestScalarEncInstructions(t *testing.T) { func execDec(typ string, instr *decInstr, state *decodeState, t *testing.T, p unsafe.Pointer) { defer testError(t) - v := int(decodeUint(state)) + v := int(state.decodeUint()) if v+state.fieldnum != 6 { t.Fatalf("decoding field number %d, got %d", 6, v+state.fieldnum) } @@ -492,19 +480,6 @@ func TestScalarDecInstructions(t *testing.T) { } } - // float - { - var data struct { - a float - } - instr := &decInstr{decOpMap[reflect.Float], 6, 0, 0, ovfl} - state := newDecodeStateFromData(floatResult) - execDec("float", instr, state, t, unsafe.Pointer(&data)) - if data.a != 17 { - t.Errorf("float a = %v not 17", data.a) - } - } - // float32 { var data struct { @@ -531,19 +506,6 @@ func TestScalarDecInstructions(t *testing.T) { } } - // complex - { - var data struct { - a complex - } - instr := &decInstr{decOpMap[reflect.Complex], 6, 0, 0, ovfl} - state := newDecodeStateFromData(complexResult) - execDec("complex", instr, state, t, unsafe.Pointer(&data)) - if data.a != 17+19i { - t.Errorf("complex a = %v not 17+19i", data.a) - } - } - // complex64 { var data struct { @@ -599,35 +561,35 @@ func TestScalarDecInstructions(t *testing.T) { func TestEndToEnd(t *testing.T) { type T2 struct { - t string + T string } s1 := "string1" s2 := "string2" type T1 struct { - a, b, c int - m map[string]*float - n *[3]float - strs *[2]string - int64s *[]int64 - ri complex64 - s string - y []byte - t *T2 + A, B, C int + M map[string]*float64 + N *[3]float64 + Strs *[2]string + Int64s *[]int64 + RI complex64 + S string + Y []byte + T *T2 } pi := 3.14159 e := 2.71828 t1 := &T1{ - a: 17, - b: 18, - c: -5, - m: map[string]*float{"pi": &pi, "e": &e}, - n: &[3]float{1.5, 2.5, 3.5}, - strs: &[2]string{s1, s2}, - int64s: &[]int64{77, 89, 123412342134}, - ri: 17 - 23i, - s: "Now is the time", - y: []byte("hello, sailor"), - t: &T2{"this is T2"}, + A: 17, + B: 18, + C: -5, + M: map[string]*float64{"pi": &pi, "e": &e}, + N: &[3]float64{1.5, 2.5, 3.5}, + Strs: &[2]string{s1, s2}, + Int64s: &[]int64{77, 89, 123412342134}, + RI: 17 - 23i, + S: "Now is the time", + Y: []byte("hello, sailor"), + T: &T2{"this is T2"}, } b := new(bytes.Buffer) err := NewEncoder(b).Encode(t1) @@ -646,13 +608,13 @@ func TestEndToEnd(t *testing.T) { func TestOverflow(t *testing.T) { type inputT struct { - maxi int64 - mini int64 - maxu uint64 - maxf float64 - minf float64 - maxc complex128 - minc complex128 + Maxi int64 + Mini int64 + Maxu uint64 + Maxf float64 + Minf float64 + Maxc complex128 + Minc complex128 } var it inputT var err os.Error @@ -663,152 +625,152 @@ func TestOverflow(t *testing.T) { // int8 b.Reset() it = inputT{ - maxi: math.MaxInt8 + 1, + Maxi: math.MaxInt8 + 1, } type outi8 struct { - maxi int8 - mini int8 + Maxi int8 + Mini int8 } var o1 outi8 enc.Encode(it) err = dec.Decode(&o1) - if err == nil || err.String() != `value for "maxi" out of range` { + if err == nil || err.String() != `value for "Maxi" out of range` { t.Error("wrong overflow error for int8:", err) } it = inputT{ - mini: math.MinInt8 - 1, + Mini: math.MinInt8 - 1, } b.Reset() enc.Encode(it) err = dec.Decode(&o1) - if err == nil || err.String() != `value for "mini" out of range` { + if err == nil || err.String() != `value for "Mini" out of range` { t.Error("wrong underflow error for int8:", err) } // int16 b.Reset() it = inputT{ - maxi: math.MaxInt16 + 1, + Maxi: math.MaxInt16 + 1, } type outi16 struct { - maxi int16 - mini int16 + Maxi int16 + Mini int16 } var o2 outi16 enc.Encode(it) err = dec.Decode(&o2) - if err == nil || err.String() != `value for "maxi" out of range` { + if err == nil || err.String() != `value for "Maxi" out of range` { t.Error("wrong overflow error for int16:", err) } it = inputT{ - mini: math.MinInt16 - 1, + Mini: math.MinInt16 - 1, } b.Reset() enc.Encode(it) err = dec.Decode(&o2) - if err == nil || err.String() != `value for "mini" out of range` { + if err == nil || err.String() != `value for "Mini" out of range` { t.Error("wrong underflow error for int16:", err) } // int32 b.Reset() it = inputT{ - maxi: math.MaxInt32 + 1, + Maxi: math.MaxInt32 + 1, } type outi32 struct { - maxi int32 - mini int32 + Maxi int32 + Mini int32 } var o3 outi32 enc.Encode(it) err = dec.Decode(&o3) - if err == nil || err.String() != `value for "maxi" out of range` { + if err == nil || err.String() != `value for "Maxi" out of range` { t.Error("wrong overflow error for int32:", err) } it = inputT{ - mini: math.MinInt32 - 1, + Mini: math.MinInt32 - 1, } b.Reset() enc.Encode(it) err = dec.Decode(&o3) - if err == nil || err.String() != `value for "mini" out of range` { + if err == nil || err.String() != `value for "Mini" out of range` { t.Error("wrong underflow error for int32:", err) } // uint8 b.Reset() it = inputT{ - maxu: math.MaxUint8 + 1, + Maxu: math.MaxUint8 + 1, } type outu8 struct { - maxu uint8 + Maxu uint8 } var o4 outu8 enc.Encode(it) err = dec.Decode(&o4) - if err == nil || err.String() != `value for "maxu" out of range` { + if err == nil || err.String() != `value for "Maxu" out of range` { t.Error("wrong overflow error for uint8:", err) } // uint16 b.Reset() it = inputT{ - maxu: math.MaxUint16 + 1, + Maxu: math.MaxUint16 + 1, } type outu16 struct { - maxu uint16 + Maxu uint16 } var o5 outu16 enc.Encode(it) err = dec.Decode(&o5) - if err == nil || err.String() != `value for "maxu" out of range` { + if err == nil || err.String() != `value for "Maxu" out of range` { t.Error("wrong overflow error for uint16:", err) } // uint32 b.Reset() it = inputT{ - maxu: math.MaxUint32 + 1, + Maxu: math.MaxUint32 + 1, } type outu32 struct { - maxu uint32 + Maxu uint32 } var o6 outu32 enc.Encode(it) err = dec.Decode(&o6) - if err == nil || err.String() != `value for "maxu" out of range` { + if err == nil || err.String() != `value for "Maxu" out of range` { t.Error("wrong overflow error for uint32:", err) } // float32 b.Reset() it = inputT{ - maxf: math.MaxFloat32 * 2, + Maxf: math.MaxFloat32 * 2, } type outf32 struct { - maxf float32 - minf float32 + Maxf float32 + Minf float32 } var o7 outf32 enc.Encode(it) err = dec.Decode(&o7) - if err == nil || err.String() != `value for "maxf" out of range` { + if err == nil || err.String() != `value for "Maxf" out of range` { t.Error("wrong overflow error for float32:", err) } // complex64 b.Reset() it = inputT{ - maxc: cmplx(math.MaxFloat32*2, math.MaxFloat32*2), + Maxc: complex(math.MaxFloat32*2, math.MaxFloat32*2), } type outc64 struct { - maxc complex64 - minc complex64 + Maxc complex64 + Minc complex64 } var o8 outc64 enc.Encode(it) err = dec.Decode(&o8) - if err == nil || err.String() != `value for "maxc" out of range` { + if err == nil || err.String() != `value for "Maxc" out of range` { t.Error("wrong overflow error for complex64:", err) } } @@ -816,92 +778,92 @@ func TestOverflow(t *testing.T) { func TestNesting(t *testing.T) { type RT struct { - a string - next *RT + A string + Next *RT } rt := new(RT) - rt.a = "level1" - rt.next = new(RT) - rt.next.a = "level2" + rt.A = "level1" + rt.Next = new(RT) + rt.Next.A = "level2" b := new(bytes.Buffer) NewEncoder(b).Encode(rt) var drt RT dec := NewDecoder(b) err := dec.Decode(&drt) if err != nil { - t.Errorf("decoder error:", err) + t.Fatal("decoder error:", err) } - if drt.a != rt.a { + if drt.A != rt.A { t.Errorf("nesting: encode expected %v got %v", *rt, drt) } - if drt.next == nil { + if drt.Next == nil { t.Errorf("nesting: recursion failed") } - if drt.next.a != rt.next.a { - t.Errorf("nesting: encode expected %v got %v", *rt.next, *drt.next) + if drt.Next.A != rt.Next.A { + t.Errorf("nesting: encode expected %v got %v", *rt.Next, *drt.Next) } } // These three structures have the same data with different indirections type T0 struct { - a int - b int - c int - d int + A int + B int + C int + D int } type T1 struct { - a int - b *int - c **int - d ***int + A int + B *int + C **int + D ***int } type T2 struct { - a ***int - b **int - c *int - d int + A ***int + B **int + C *int + D int } func TestAutoIndirection(t *testing.T) { // First transfer t1 into t0 var t1 T1 - t1.a = 17 - t1.b = new(int) - *t1.b = 177 - t1.c = new(*int) - *t1.c = new(int) - **t1.c = 1777 - t1.d = new(**int) - *t1.d = new(*int) - **t1.d = new(int) - ***t1.d = 17777 + t1.A = 17 + t1.B = new(int) + *t1.B = 177 + t1.C = new(*int) + *t1.C = new(int) + **t1.C = 1777 + t1.D = new(**int) + *t1.D = new(*int) + **t1.D = new(int) + ***t1.D = 17777 b := new(bytes.Buffer) enc := NewEncoder(b) enc.Encode(t1) dec := NewDecoder(b) var t0 T0 dec.Decode(&t0) - if t0.a != 17 || t0.b != 177 || t0.c != 1777 || t0.d != 17777 { + if t0.A != 17 || t0.B != 177 || t0.C != 1777 || t0.D != 17777 { t.Errorf("t1->t0: expected {17 177 1777 17777}; got %v", t0) } // Now transfer t2 into t0 var t2 T2 - t2.d = 17777 - t2.c = new(int) - *t2.c = 1777 - t2.b = new(*int) - *t2.b = new(int) - **t2.b = 177 - t2.a = new(**int) - *t2.a = new(*int) - **t2.a = new(int) - ***t2.a = 17 + t2.D = 17777 + t2.C = new(int) + *t2.C = 1777 + t2.B = new(*int) + *t2.B = new(int) + **t2.B = 177 + t2.A = new(**int) + *t2.A = new(*int) + **t2.A = new(int) + ***t2.A = 17 b.Reset() enc.Encode(t2) t0 = T0{} dec.Decode(&t0) - if t0.a != 17 || t0.b != 177 || t0.c != 1777 || t0.d != 17777 { + if t0.A != 17 || t0.B != 177 || t0.C != 1777 || t0.D != 17777 { t.Errorf("t2->t0 expected {17 177 1777 17777}; got %v", t0) } @@ -911,8 +873,8 @@ func TestAutoIndirection(t *testing.T) { enc.Encode(t0) t1 = T1{} dec.Decode(&t1) - if t1.a != 17 || *t1.b != 177 || **t1.c != 1777 || ***t1.d != 17777 { - t.Errorf("t0->t1 expected {17 177 1777 17777}; got {%d %d %d %d}", t1.a, *t1.b, **t1.c, ***t1.d) + if t1.A != 17 || *t1.B != 177 || **t1.C != 1777 || ***t1.D != 17777 { + t.Errorf("t0->t1 expected {17 177 1777 17777}; got {%d %d %d %d}", t1.A, *t1.B, **t1.C, ***t1.D) } // Now transfer t0 into t2 @@ -920,40 +882,40 @@ func TestAutoIndirection(t *testing.T) { enc.Encode(t0) t2 = T2{} dec.Decode(&t2) - if ***t2.a != 17 || **t2.b != 177 || *t2.c != 1777 || t2.d != 17777 { - t.Errorf("t0->t2 expected {17 177 1777 17777}; got {%d %d %d %d}", ***t2.a, **t2.b, *t2.c, t2.d) + if ***t2.A != 17 || **t2.B != 177 || *t2.C != 1777 || t2.D != 17777 { + t.Errorf("t0->t2 expected {17 177 1777 17777}; got {%d %d %d %d}", ***t2.A, **t2.B, *t2.C, t2.D) } // Now do t2 again but without pre-allocated pointers. b.Reset() enc.Encode(t0) - ***t2.a = 0 - **t2.b = 0 - *t2.c = 0 - t2.d = 0 + ***t2.A = 0 + **t2.B = 0 + *t2.C = 0 + t2.D = 0 dec.Decode(&t2) - if ***t2.a != 17 || **t2.b != 177 || *t2.c != 1777 || t2.d != 17777 { - t.Errorf("t0->t2 expected {17 177 1777 17777}; got {%d %d %d %d}", ***t2.a, **t2.b, *t2.c, t2.d) + if ***t2.A != 17 || **t2.B != 177 || *t2.C != 1777 || t2.D != 17777 { + t.Errorf("t0->t2 expected {17 177 1777 17777}; got {%d %d %d %d}", ***t2.A, **t2.B, *t2.C, t2.D) } } type RT0 struct { - a int - b string - c float + A int + B string + C float64 } type RT1 struct { - c float - b string - a int - notSet string + C float64 + B string + A int + NotSet string } func TestReorderedFields(t *testing.T) { var rt0 RT0 - rt0.a = 17 - rt0.b = "hello" - rt0.c = 3.14159 + rt0.A = 17 + rt0.B = "hello" + rt0.C = 3.14159 b := new(bytes.Buffer) NewEncoder(b).Encode(rt0) dec := NewDecoder(b) @@ -961,41 +923,41 @@ func TestReorderedFields(t *testing.T) { // Wire type is RT0, local type is RT1. err := dec.Decode(&rt1) if err != nil { - t.Error("decode error:", err) + t.Fatal("decode error:", err) } - if rt0.a != rt1.a || rt0.b != rt1.b || rt0.c != rt1.c { + if rt0.A != rt1.A || rt0.B != rt1.B || rt0.C != rt1.C { t.Errorf("rt1->rt0: expected %v; got %v", rt0, rt1) } } // Like an RT0 but with fields we'll ignore on the decode side. type IT0 struct { - a int64 - b string - ignore_d []int - ignore_e [3]float - ignore_f bool - ignore_g string - ignore_h []byte - ignore_i *RT1 - ignore_m map[string]int - c float + A int64 + B string + Ignore_d []int + Ignore_e [3]float64 + Ignore_f bool + Ignore_g string + Ignore_h []byte + Ignore_i *RT1 + Ignore_m map[string]int + C float64 } func TestIgnoredFields(t *testing.T) { var it0 IT0 - it0.a = 17 - it0.b = "hello" - it0.c = 3.14159 - it0.ignore_d = []int{1, 2, 3} - it0.ignore_e[0] = 1.0 - it0.ignore_e[1] = 2.0 - it0.ignore_e[2] = 3.0 - it0.ignore_f = true - it0.ignore_g = "pay no attention" - it0.ignore_h = []byte("to the curtain") - it0.ignore_i = &RT1{3.1, "hi", 7, "hello"} - it0.ignore_m = map[string]int{"one": 1, "two": 2} + it0.A = 17 + it0.B = "hello" + it0.C = 3.14159 + it0.Ignore_d = []int{1, 2, 3} + it0.Ignore_e[0] = 1.0 + it0.Ignore_e[1] = 2.0 + it0.Ignore_e[2] = 3.0 + it0.Ignore_f = true + it0.Ignore_g = "pay no attention" + it0.Ignore_h = []byte("to the curtain") + it0.Ignore_i = &RT1{3.1, "hi", 7, "hello"} + it0.Ignore_m = map[string]int{"one": 1, "two": 2} b := new(bytes.Buffer) NewEncoder(b).Encode(it0) @@ -1006,14 +968,14 @@ func TestIgnoredFields(t *testing.T) { if err != nil { t.Error("error: ", err) } - if int(it0.a) != rt1.a || it0.b != rt1.b || it0.c != rt1.c { - t.Errorf("rt1->rt0: expected %v; got %v", it0, rt1) + if int(it0.A) != rt1.A || it0.B != rt1.B || it0.C != rt1.C { + t.Errorf("rt0->rt1: expected %v; got %v", it0, rt1) } } type Bad0 struct { ch chan int - c float + c float64 } var nilEncoder *Encoder @@ -1031,33 +993,33 @@ func TestInvalidField(t *testing.T) { } type Indirect struct { - a ***[3]int - s ***[]int - m ****map[string]int + A ***[3]int + S ***[]int + M ****map[string]int } type Direct struct { - a [3]int - s []int - m map[string]int + A [3]int + S []int + M map[string]int } func TestIndirectSliceMapArray(t *testing.T) { // Marshal indirect, unmarshal to direct. i := new(Indirect) - i.a = new(**[3]int) - *i.a = new(*[3]int) - **i.a = new([3]int) - ***i.a = [3]int{1, 2, 3} - i.s = new(**[]int) - *i.s = new(*[]int) - **i.s = new([]int) - ***i.s = []int{4, 5, 6} - i.m = new(***map[string]int) - *i.m = new(**map[string]int) - **i.m = new(*map[string]int) - ***i.m = new(map[string]int) - ****i.m = map[string]int{"one": 1, "two": 2, "three": 3} + i.A = new(**[3]int) + *i.A = new(*[3]int) + **i.A = new([3]int) + ***i.A = [3]int{1, 2, 3} + i.S = new(**[]int) + *i.S = new(*[]int) + **i.S = new([]int) + ***i.S = []int{4, 5, 6} + i.M = new(***map[string]int) + *i.M = new(**map[string]int) + **i.M = new(*map[string]int) + ***i.M = new(map[string]int) + ****i.M = map[string]int{"one": 1, "two": 2, "three": 3} b := new(bytes.Buffer) NewEncoder(b).Encode(i) dec := NewDecoder(b) @@ -1066,35 +1028,35 @@ func TestIndirectSliceMapArray(t *testing.T) { if err != nil { t.Error("error: ", err) } - if len(d.a) != 3 || d.a[0] != 1 || d.a[1] != 2 || d.a[2] != 3 { - t.Errorf("indirect to direct: d.a is %v not %v", d.a, ***i.a) + if len(d.A) != 3 || d.A[0] != 1 || d.A[1] != 2 || d.A[2] != 3 { + t.Errorf("indirect to direct: d.A is %v not %v", d.A, ***i.A) } - if len(d.s) != 3 || d.s[0] != 4 || d.s[1] != 5 || d.s[2] != 6 { - t.Errorf("indirect to direct: d.s is %v not %v", d.s, ***i.s) + if len(d.S) != 3 || d.S[0] != 4 || d.S[1] != 5 || d.S[2] != 6 { + t.Errorf("indirect to direct: d.S is %v not %v", d.S, ***i.S) } - if len(d.m) != 3 || d.m["one"] != 1 || d.m["two"] != 2 || d.m["three"] != 3 { - t.Errorf("indirect to direct: d.m is %v not %v", d.m, ***i.m) + if len(d.M) != 3 || d.M["one"] != 1 || d.M["two"] != 2 || d.M["three"] != 3 { + t.Errorf("indirect to direct: d.M is %v not %v", d.M, ***i.M) } // Marshal direct, unmarshal to indirect. - d.a = [3]int{11, 22, 33} - d.s = []int{44, 55, 66} - d.m = map[string]int{"four": 4, "five": 5, "six": 6} + d.A = [3]int{11, 22, 33} + d.S = []int{44, 55, 66} + d.M = map[string]int{"four": 4, "five": 5, "six": 6} i = new(Indirect) b.Reset() NewEncoder(b).Encode(d) dec = NewDecoder(b) err = dec.Decode(&i) if err != nil { - t.Error("error: ", err) + t.Fatal("error: ", err) } - if len(***i.a) != 3 || (***i.a)[0] != 11 || (***i.a)[1] != 22 || (***i.a)[2] != 33 { - t.Errorf("direct to indirect: ***i.a is %v not %v", ***i.a, d.a) + if len(***i.A) != 3 || (***i.A)[0] != 11 || (***i.A)[1] != 22 || (***i.A)[2] != 33 { + t.Errorf("direct to indirect: ***i.A is %v not %v", ***i.A, d.A) } - if len(***i.s) != 3 || (***i.s)[0] != 44 || (***i.s)[1] != 55 || (***i.s)[2] != 66 { - t.Errorf("direct to indirect: ***i.s is %v not %v", ***i.s, ***i.s) + if len(***i.S) != 3 || (***i.S)[0] != 44 || (***i.S)[1] != 55 || (***i.S)[2] != 66 { + t.Errorf("direct to indirect: ***i.S is %v not %v", ***i.S, ***i.S) } - if len(****i.m) != 3 || (****i.m)["four"] != 4 || (****i.m)["five"] != 5 || (****i.m)["six"] != 6 { - t.Errorf("direct to indirect: ****i.m is %v not %v", ****i.m, d.m) + if len(****i.M) != 3 || (****i.M)["four"] != 4 || (****i.M)["five"] != 5 || (****i.M)["six"] != 6 { + t.Errorf("direct to indirect: ****i.M is %v not %v", ****i.M, d.M) } } @@ -1109,7 +1071,7 @@ func (i Int) Square() int { return int(i * i) } -type Float float +type Float float64 func (f Float) Square() int { return int(f * f) @@ -1135,16 +1097,16 @@ func (p Point) Square() int { // A struct with interfaces in it. type InterfaceItem struct { - i int - sq1, sq2, sq3 Squarer - f float - sq []Squarer + I int + Sq1, Sq2, Sq3 Squarer + F float64 + Sq []Squarer } // The same struct without interfaces type NoInterfaceItem struct { - i int - f float + I int + F float64 } func TestInterface(t *testing.T) { @@ -1169,34 +1131,34 @@ func TestInterface(t *testing.T) { if err != nil { t.Fatal("decode:", err) } - if item2.i != item1.i { + if item2.I != item1.I { t.Error("normal int did not decode correctly") } - if item2.sq1 == nil || item2.sq1.Square() != iVal.Square() { + if item2.Sq1 == nil || item2.Sq1.Square() != iVal.Square() { t.Error("Int did not decode correctly") } - if item2.sq2 == nil || item2.sq2.Square() != fVal.Square() { + if item2.Sq2 == nil || item2.Sq2.Square() != fVal.Square() { t.Error("Float did not decode correctly") } - if item2.sq3 == nil || item2.sq3.Square() != vVal.Square() { + if item2.Sq3 == nil || item2.Sq3.Square() != vVal.Square() { t.Error("Vector did not decode correctly") } - if item2.f != item1.f { + if item2.F != item1.F { t.Error("normal float did not decode correctly") } // Now check that we received a slice of Squarers correctly, including a nil element - if len(item1.sq) != len(item2.sq) { - t.Fatalf("[]Squarer length wrong: got %d; expected %d", len(item2.sq), len(item1.sq)) + if len(item1.Sq) != len(item2.Sq) { + t.Fatalf("[]Squarer length wrong: got %d; expected %d", len(item2.Sq), len(item1.Sq)) } - for i, v1 := range item1.sq { - v2 := item2.sq[i] + for i, v1 := range item1.Sq { + v2 := item2.Sq[i] if v1 == nil || v2 == nil { if v1 != nil || v2 != nil { t.Errorf("item %d inconsistent nils", i) } continue if v1.Square() != v2.Square() { - t.Errorf("item %d inconsistent values: %v %v", v1, v2) + t.Errorf("item %d inconsistent values: %v %v", i, v1, v2) } } } @@ -1207,8 +1169,8 @@ func TestInterface(t *testing.T) { type BasicInterfaceItem struct { Int, Int8, Int16, Int32, Int64 interface{} Uint, Uint8, Uint16, Uint32, Uint64 interface{} - Float, Float32, Float64 interface{} - Complex, Complex64, Complex128 interface{} + Float32, Float64 interface{} + Complex64, Complex128 interface{} Bool interface{} String interface{} Bytes interface{} @@ -1219,8 +1181,8 @@ func TestInterfaceBasic(t *testing.T) { item1 := &BasicInterfaceItem{ int(1), int8(1), int16(1), int32(1), int64(1), uint(1), uint8(1), uint16(1), uint32(1), uint64(1), - float(1), float32(1), float64(1), - complex(0i), complex64(0i), complex128(0i), + float32(1), 1.0, + complex64(0i), complex128(0i), true, "hello", []byte("sailor"), @@ -1250,8 +1212,8 @@ func TestInterfaceBasic(t *testing.T) { type String string type PtrInterfaceItem struct { - str interface{} // basic - Str interface{} // derived + Str1 interface{} // basic + Str2 interface{} // derived } // We'll send pointers; should receive values. @@ -1277,10 +1239,10 @@ func TestInterfacePointer(t *testing.T) { t.Fatal("decode:", err) } // Hand test for correct types and values. - if v, ok := item2.str.(string); !ok || v != str1 { + if v, ok := item2.Str1.(string); !ok || v != str1 { t.Errorf("basic string failed: %q should be %q", v, str1) } - if v, ok := item2.Str.(String); !ok || v != str2 { + if v, ok := item2.Str2.(String); !ok || v != str2 { t.Errorf("derived type String failed: %q should be %q", v, str2) } } @@ -1307,30 +1269,60 @@ func TestIgnoreInterface(t *testing.T) { if err != nil { t.Fatal("decode:", err) } - if item2.i != item1.i { + if item2.I != item1.I { t.Error("normal int did not decode correctly") } - if item2.f != item2.f { + if item2.F != item2.F { t.Error("normal float did not decode correctly") } } +type U struct { + A int + B string + c float64 + D uint +} + +func TestUnexportedFields(t *testing.T) { + var u0 U + u0.A = 17 + u0.B = "hello" + u0.c = 3.14159 + u0.D = 23 + b := new(bytes.Buffer) + NewEncoder(b).Encode(u0) + dec := NewDecoder(b) + var u1 U + u1.c = 1234. + err := dec.Decode(&u1) + if err != nil { + t.Fatal("decode error:", err) + } + if u0.A != u0.A || u0.B != u1.B || u0.D != u1.D { + t.Errorf("u1->u0: expected %v; got %v", u0, u1) + } + if u1.c != 1234. { + t.Error("u1.c modified") + } +} + // A type that won't be defined in the gob until we send it in an interface value. type OnTheFly struct { - a int + A int } type DT struct { // X OnTheFly - a int - b string - c float - i interface{} - j interface{} - i_nil interface{} - m map[string]int - r [3]int - s []string + A int + B string + C float64 + I interface{} + J interface{} + I_nil interface{} + M map[string]int + T [3]int + S []string } func TestDebug(t *testing.T) { @@ -1339,15 +1331,15 @@ func TestDebug(t *testing.T) { } Register(OnTheFly{}) var dt DT - dt.a = 17 - dt.b = "hello" - dt.c = 3.14159 - dt.i = 271828 - dt.j = OnTheFly{3} - dt.i_nil = nil - dt.m = map[string]int{"one": 1, "two": 2} - dt.r = [3]int{11, 22, 33} - dt.s = []string{"hi", "joe"} + dt.A = 17 + dt.B = "hello" + dt.C = 3.14159 + dt.I = 271828 + dt.J = OnTheFly{3} + dt.I_nil = nil + dt.M = map[string]int{"one": 1, "two": 2} + dt.T = [3]int{11, 22, 33} + dt.S = []string{"hi", "joe"} b := new(bytes.Buffer) err := NewEncoder(b).Encode(dt) if err != nil { diff --git a/libgo/go/gob/decode.go b/libgo/go/gob/decode.go index 5a19b781971..2db75215c19 100644 --- a/libgo/go/gob/decode.go +++ b/libgo/go/gob/decode.go @@ -13,7 +13,9 @@ import ( "math" "os" "reflect" + "unicode" "unsafe" + "utf8" ) var ( @@ -79,7 +81,7 @@ func decodeUintReader(r io.Reader, buf []byte) (x uint64, err os.Error) { // decodeUint reads an encoded unsigned integer from state.r. // Does not check for overflow. -func decodeUint(state *decodeState) (x uint64) { +func (state *decodeState) decodeUint() (x uint64) { b, err := state.b.ReadByte() if err != nil { error(err) @@ -106,8 +108,8 @@ func decodeUint(state *decodeState) (x uint64) { // decodeInt reads an encoded signed integer from state.r. // Does not check for overflow. -func decodeInt(state *decodeState) int64 { - x := decodeUint(state) +func (state *decodeState) decodeInt() int64 { + x := state.decodeUint() if x&1 != 0 { return ^int64(x >> 1) } @@ -145,12 +147,12 @@ func decIndirect(p unsafe.Pointer, indir int) unsafe.Pointer { } func ignoreUint(i *decInstr, state *decodeState, p unsafe.Pointer) { - decodeUint(state) + state.decodeUint() } func ignoreTwoUints(i *decInstr, state *decodeState, p unsafe.Pointer) { - decodeUint(state) - decodeUint(state) + state.decodeUint() + state.decodeUint() } func decBool(i *decInstr, state *decodeState, p unsafe.Pointer) { @@ -160,7 +162,7 @@ func decBool(i *decInstr, state *decodeState, p unsafe.Pointer) { } p = *(*unsafe.Pointer)(p) } - *(*bool)(p) = decodeInt(state) != 0 + *(*bool)(p) = state.decodeInt() != 0 } func decInt8(i *decInstr, state *decodeState, p unsafe.Pointer) { @@ -170,7 +172,7 @@ func decInt8(i *decInstr, state *decodeState, p unsafe.Pointer) { } p = *(*unsafe.Pointer)(p) } - v := decodeInt(state) + v := state.decodeInt() if v < math.MinInt8 || math.MaxInt8 < v { error(i.ovfl) } else { @@ -185,7 +187,7 @@ func decUint8(i *decInstr, state *decodeState, p unsafe.Pointer) { } p = *(*unsafe.Pointer)(p) } - v := decodeUint(state) + v := state.decodeUint() if math.MaxUint8 < v { error(i.ovfl) } else { @@ -200,7 +202,7 @@ func decInt16(i *decInstr, state *decodeState, p unsafe.Pointer) { } p = *(*unsafe.Pointer)(p) } - v := decodeInt(state) + v := state.decodeInt() if v < math.MinInt16 || math.MaxInt16 < v { error(i.ovfl) } else { @@ -215,7 +217,7 @@ func decUint16(i *decInstr, state *decodeState, p unsafe.Pointer) { } p = *(*unsafe.Pointer)(p) } - v := decodeUint(state) + v := state.decodeUint() if math.MaxUint16 < v { error(i.ovfl) } else { @@ -230,7 +232,7 @@ func decInt32(i *decInstr, state *decodeState, p unsafe.Pointer) { } p = *(*unsafe.Pointer)(p) } - v := decodeInt(state) + v := state.decodeInt() if v < math.MinInt32 || math.MaxInt32 < v { error(i.ovfl) } else { @@ -245,7 +247,7 @@ func decUint32(i *decInstr, state *decodeState, p unsafe.Pointer) { } p = *(*unsafe.Pointer)(p) } - v := decodeUint(state) + v := state.decodeUint() if math.MaxUint32 < v { error(i.ovfl) } else { @@ -260,7 +262,7 @@ func decInt64(i *decInstr, state *decodeState, p unsafe.Pointer) { } p = *(*unsafe.Pointer)(p) } - *(*int64)(p) = int64(decodeInt(state)) + *(*int64)(p) = int64(state.decodeInt()) } func decUint64(i *decInstr, state *decodeState, p unsafe.Pointer) { @@ -270,7 +272,7 @@ func decUint64(i *decInstr, state *decodeState, p unsafe.Pointer) { } p = *(*unsafe.Pointer)(p) } - *(*uint64)(p) = uint64(decodeUint(state)) + *(*uint64)(p) = uint64(state.decodeUint()) } // Floating-point numbers are transmitted as uint64s holding the bits @@ -289,7 +291,7 @@ func floatFromBits(u uint64) float64 { } func storeFloat32(i *decInstr, state *decodeState, p unsafe.Pointer) { - v := floatFromBits(decodeUint(state)) + v := floatFromBits(state.decodeUint()) av := v if av < 0 { av = -av @@ -319,7 +321,7 @@ func decFloat64(i *decInstr, state *decodeState, p unsafe.Pointer) { } p = *(*unsafe.Pointer)(p) } - *(*float64)(p) = floatFromBits(uint64(decodeUint(state))) + *(*float64)(p) = floatFromBits(uint64(state.decodeUint())) } // Complex numbers are just a pair of floating-point numbers, real part first. @@ -331,7 +333,7 @@ func decComplex64(i *decInstr, state *decodeState, p unsafe.Pointer) { p = *(*unsafe.Pointer)(p) } storeFloat32(i, state, p) - storeFloat32(i, state, unsafe.Pointer(uintptr(p)+uintptr(unsafe.Sizeof(float(0))))) + storeFloat32(i, state, unsafe.Pointer(uintptr(p)+uintptr(unsafe.Sizeof(float32(0))))) } func decComplex128(i *decInstr, state *decodeState, p unsafe.Pointer) { @@ -341,9 +343,9 @@ func decComplex128(i *decInstr, state *decodeState, p unsafe.Pointer) { } p = *(*unsafe.Pointer)(p) } - real := floatFromBits(uint64(decodeUint(state))) - imag := floatFromBits(uint64(decodeUint(state))) - *(*complex128)(p) = cmplx(real, imag) + real := floatFromBits(uint64(state.decodeUint())) + imag := floatFromBits(uint64(state.decodeUint())) + *(*complex128)(p) = complex(real, imag) } // uint8 arrays are encoded as an unsigned count followed by the raw bytes. @@ -354,7 +356,7 @@ func decUint8Array(i *decInstr, state *decodeState, p unsafe.Pointer) { } p = *(*unsafe.Pointer)(p) } - b := make([]uint8, decodeUint(state)) + b := make([]uint8, state.decodeUint()) state.b.Read(b) *(*[]uint8)(p) = b } @@ -367,13 +369,13 @@ func decString(i *decInstr, state *decodeState, p unsafe.Pointer) { } p = *(*unsafe.Pointer)(p) } - b := make([]byte, decodeUint(state)) + b := make([]byte, state.decodeUint()) state.b.Read(b) *(*string)(p) = string(b) } func ignoreUint8Array(i *decInstr, state *decodeState, p unsafe.Pointer) { - b := make([]byte, decodeUint(state)) + b := make([]byte, state.decodeUint()) state.b.Read(b) } @@ -409,7 +411,7 @@ func (dec *Decoder) decodeSingle(engine *decEngine, rtyp reflect.Type, b **bytes state := newDecodeState(dec, b) state.fieldnum = singletonField basep := p - delta := int(decodeUint(state)) + delta := int(state.decodeUint()) if delta != 0 { errorf("gob decode: corrupted data: non-zero delta for singleton") } @@ -429,7 +431,7 @@ func (dec *Decoder) decodeStruct(engine *decEngine, rtyp *reflect.StructType, b state.fieldnum = -1 basep := p for state.b.Len() > 0 { - delta := int(decodeUint(state)) + delta := int(state.decodeUint()) if delta < 0 { errorf("gob decode: corrupted data: negative delta") } @@ -457,7 +459,7 @@ func (dec *Decoder) ignoreStruct(engine *decEngine, b **bytes.Buffer) (err os.Er state := newDecodeState(dec, b) state.fieldnum = -1 for state.b.Len() > 0 { - delta := int(decodeUint(state)) + delta := int(state.decodeUint()) if delta < 0 { errorf("gob ignore decode: corrupted data: negative delta") } @@ -491,7 +493,7 @@ func (dec *Decoder) decodeArray(atyp *reflect.ArrayType, state *decodeState, p u if indir > 0 { p = allocate(atyp, p, 1) // All but the last level has been allocated by dec.Indirect } - if n := decodeUint(state); n != uint64(length) { + if n := state.decodeUint(); n != uint64(length) { errorf("gob: length mismatch in decodeArray") } dec.decodeArrayHelper(state, p, elemOp, elemWid, length, elemIndir, ovfl) @@ -520,7 +522,7 @@ func (dec *Decoder) decodeMap(mtyp *reflect.MapType, state *decodeState, p uintp // that slices etc. can. We must recover a full reflection value for // the iteration. v := reflect.NewValue(unsafe.Unreflect(mtyp, unsafe.Pointer((p)))).(*reflect.MapValue) - n := int(decodeUint(state)) + n := int(state.decodeUint()) for i := 0; i < n; i++ { key := decodeIntoValue(state, keyOp, keyIndir, reflect.MakeZero(mtyp.Key()), ovfl) elem := decodeIntoValue(state, elemOp, elemIndir, reflect.MakeZero(mtyp.Elem()), ovfl) @@ -536,14 +538,14 @@ func (dec *Decoder) ignoreArrayHelper(state *decodeState, elemOp decOp, length i } func (dec *Decoder) ignoreArray(state *decodeState, elemOp decOp, length int) { - if n := decodeUint(state); n != uint64(length) { + if n := state.decodeUint(); n != uint64(length) { errorf("gob: length mismatch in ignoreArray") } dec.ignoreArrayHelper(state, elemOp, length) } func (dec *Decoder) ignoreMap(state *decodeState, keyOp, elemOp decOp) { - n := int(decodeUint(state)) + n := int(state.decodeUint()) keyInstr := &decInstr{keyOp, 0, 0, 0, os.ErrorString("no error")} elemInstr := &decInstr{elemOp, 0, 0, 0, os.ErrorString("no error")} for i := 0; i < n; i++ { @@ -553,7 +555,7 @@ func (dec *Decoder) ignoreMap(state *decodeState, keyOp, elemOp decOp) { } func (dec *Decoder) decodeSlice(atyp *reflect.SliceType, state *decodeState, p uintptr, elemOp decOp, elemWid uintptr, indir, elemIndir int, ovfl os.ErrorString) { - n := int(uintptr(decodeUint(state))) + n := int(uintptr(state.decodeUint())) if indir > 0 { up := unsafe.Pointer(p) if *(*unsafe.Pointer)(up) == nil { @@ -572,7 +574,7 @@ func (dec *Decoder) decodeSlice(atyp *reflect.SliceType, state *decodeState, p u } func (dec *Decoder) ignoreSlice(state *decodeState, elemOp decOp) { - dec.ignoreArrayHelper(state, elemOp, int(decodeUint(state))) + dec.ignoreArrayHelper(state, elemOp, int(state.decodeUint())) } // setInterfaceValue sets an interface value to a concrete value through @@ -596,7 +598,7 @@ func (dec *Decoder) decodeInterface(ityp *reflect.InterfaceType, state *decodeSt // Create an interface reflect.Value. We need one even for the nil case. ivalue := reflect.MakeZero(ityp).(*reflect.InterfaceValue) // Read the name of the concrete type. - b := make([]byte, decodeUint(state)) + b := make([]byte, state.decodeUint()) state.b.Read(b) name := string(b) if name == "" { @@ -630,7 +632,7 @@ func (dec *Decoder) decodeInterface(ityp *reflect.InterfaceType, state *decodeSt func (dec *Decoder) ignoreInterface(state *decodeState) { // Read the name of the concrete type. - b := make([]byte, decodeUint(state)) + b := make([]byte, state.decodeUint()) _, err := state.b.Read(b) if err != nil { error(err) @@ -684,7 +686,7 @@ func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string) (decOp switch t := typ.(type) { case *reflect.ArrayType: name = "element of " + name - elemId := dec.wireType[wireId].arrayT.Elem + elemId := dec.wireType[wireId].ArrayT.Elem elemOp, elemIndir := dec.decOpFor(elemId, t.Elem(), name) ovfl := overflow(name) op = func(i *decInstr, state *decodeState, p unsafe.Pointer) { @@ -693,8 +695,8 @@ func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string) (decOp case *reflect.MapType: name = "element of " + name - keyId := dec.wireType[wireId].mapT.Key - elemId := dec.wireType[wireId].mapT.Elem + keyId := dec.wireType[wireId].MapT.Key + elemId := dec.wireType[wireId].MapT.Elem keyOp, keyIndir := dec.decOpFor(keyId, t.Key(), name) elemOp, elemIndir := dec.decOpFor(elemId, t.Elem(), name) ovfl := overflow(name) @@ -713,7 +715,7 @@ func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string) (decOp if tt, ok := builtinIdToType[wireId]; ok { elemId = tt.(*sliceType).Elem } else { - elemId = dec.wireType[wireId].sliceT.Elem + elemId = dec.wireType[wireId].SliceT.Elem } elemOp, elemIndir := dec.decOpFor(elemId, t.Elem(), name) ovfl := overflow(name) @@ -763,30 +765,30 @@ func (dec *Decoder) decIgnoreOpFor(wireId typeId) decOp { switch { case wire == nil: panic("internal error: can't find ignore op for type " + wireId.string()) - case wire.arrayT != nil: - elemId := wire.arrayT.Elem + case wire.ArrayT != nil: + elemId := wire.ArrayT.Elem elemOp := dec.decIgnoreOpFor(elemId) op = func(i *decInstr, state *decodeState, p unsafe.Pointer) { - state.dec.ignoreArray(state, elemOp, wire.arrayT.Len) + state.dec.ignoreArray(state, elemOp, wire.ArrayT.Len) } - case wire.mapT != nil: - keyId := dec.wireType[wireId].mapT.Key - elemId := dec.wireType[wireId].mapT.Elem + case wire.MapT != nil: + keyId := dec.wireType[wireId].MapT.Key + elemId := dec.wireType[wireId].MapT.Elem keyOp := dec.decIgnoreOpFor(keyId) elemOp := dec.decIgnoreOpFor(elemId) op = func(i *decInstr, state *decodeState, p unsafe.Pointer) { state.dec.ignoreMap(state, keyOp, elemOp) } - case wire.sliceT != nil: - elemId := wire.sliceT.Elem + case wire.SliceT != nil: + elemId := wire.SliceT.Elem elemOp := dec.decIgnoreOpFor(elemId) op = func(i *decInstr, state *decodeState, p unsafe.Pointer) { state.dec.ignoreSlice(state, elemOp) } - case wire.structT != nil: + case wire.StructT != nil: // Generate a closure that calls out to the engine for the nested type. enginePtr, err := dec.getIgnoreEnginePtr(wireId) if err != nil { @@ -829,18 +831,18 @@ func (dec *Decoder) compatibleType(fr reflect.Type, fw typeId) bool { return fw == tInterface case *reflect.ArrayType: wire, ok := dec.wireType[fw] - if !ok || wire.arrayT == nil { + if !ok || wire.ArrayT == nil { return false } - array := wire.arrayT + array := wire.ArrayT return t.Len() == array.Len && dec.compatibleType(t.Elem(), array.Elem) case *reflect.MapType: wire, ok := dec.wireType[fw] - if !ok || wire.mapT == nil { + if !ok || wire.MapT == nil { return false } - mapType := wire.mapT - return dec.compatibleType(t.Key(), mapType.Key) && dec.compatibleType(t.Elem(), mapType.Elem) + MapType := wire.MapT + return dec.compatibleType(t.Key(), MapType.Key) && dec.compatibleType(t.Elem(), MapType.Elem) case *reflect.SliceType: // Is it an array of bytes? if t.Elem().Kind() == reflect.Uint8 { @@ -851,7 +853,7 @@ func (dec *Decoder) compatibleType(fr reflect.Type, fw typeId) bool { if tt, ok := builtinIdToType[fw]; ok { sw = tt.(*sliceType) } else { - sw = dec.wireType[fw].sliceT + sw = dec.wireType[fw].SliceT } elem, _ := indirect(t.Elem()) return sw != nil && dec.compatibleType(elem, sw.Elem) @@ -861,12 +863,22 @@ func (dec *Decoder) compatibleType(fr reflect.Type, fw typeId) bool { return true } +// typeString returns a human-readable description of the type identified by remoteId. +func (dec *Decoder) typeString(remoteId typeId) string { + if t := idToType[remoteId]; t != nil { + // globally known type. + return t.string() + } + return dec.wireType[remoteId].string() +} + + func (dec *Decoder) compileSingle(remoteId typeId, rt reflect.Type) (engine *decEngine, err os.Error) { engine = new(decEngine) engine.instr = make([]decInstr, 1) // one item name := rt.String() // best we can do if !dec.compatibleType(rt, remoteId) { - return nil, os.ErrorString("gob: wrong type received for local value " + name) + return nil, os.ErrorString("gob: wrong type received for local value " + name + ": " + dec.typeString(remoteId)) } op, indir := dec.decOpFor(remoteId, rt, name) ovfl := os.ErrorString(`value for "` + name + `" out of range`) @@ -875,6 +887,12 @@ func (dec *Decoder) compileSingle(remoteId typeId, rt reflect.Type) (engine *dec return } +// Is this an exported - upper case - name? +func isExported(name string) bool { + rune, _ := utf8.DecodeRuneInString(name) + return unicode.IsUpper(rune) +} + func (dec *Decoder) compileDec(remoteId typeId, rt reflect.Type) (engine *decEngine, err os.Error) { defer catchError(&err) srt, ok := rt.(*reflect.StructType) @@ -887,29 +905,32 @@ func (dec *Decoder) compileDec(remoteId typeId, rt reflect.Type) (engine *decEng if t, ok := builtinIdToType[remoteId]; ok { wireStruct, _ = t.(*structType) } else { - wireStruct = dec.wireType[remoteId].structT + wireStruct = dec.wireType[remoteId].StructT } if wireStruct == nil { errorf("gob: type mismatch in decoder: want struct type %s; got non-struct", rt.String()) } engine = new(decEngine) - engine.instr = make([]decInstr, len(wireStruct.field)) + engine.instr = make([]decInstr, len(wireStruct.Field)) // Loop over the fields of the wire type. - for fieldnum := 0; fieldnum < len(wireStruct.field); fieldnum++ { - wireField := wireStruct.field[fieldnum] + for fieldnum := 0; fieldnum < len(wireStruct.Field); fieldnum++ { + wireField := wireStruct.Field[fieldnum] + if wireField.Name == "" { + errorf("gob: empty name for remote field of type %s", wireStruct.Name) + } + ovfl := overflow(wireField.Name) // Find the field of the local type with the same name. - localField, present := srt.FieldByName(wireField.name) - ovfl := overflow(wireField.name) + localField, present := srt.FieldByName(wireField.Name) // TODO(r): anonymous names - if !present { - op := dec.decIgnoreOpFor(wireField.id) + if !present || !isExported(wireField.Name) { + op := dec.decIgnoreOpFor(wireField.Id) engine.instr[fieldnum] = decInstr{op, fieldnum, 0, 0, ovfl} continue } - if !dec.compatibleType(localField.Type, wireField.id) { - errorf("gob: wrong type (%s) for received field %s.%s", localField.Type, wireStruct.name, wireField.name) + if !dec.compatibleType(localField.Type, wireField.Id) { + errorf("gob: wrong type (%s) for received field %s.%s", localField.Type, wireStruct.Name, wireField.Name) } - op, indir := dec.decOpFor(wireField.id, localField.Type, localField.Name) + op, indir := dec.decOpFor(wireField.Id, localField.Type, localField.Name) engine.instr[fieldnum] = decInstr{op, fieldnum, indir, uintptr(localField.Offset), ovfl} engine.numInstr++ } @@ -962,7 +983,7 @@ func (dec *Decoder) decode(wireId typeId, val reflect.Value) os.Error { } engine := *enginePtr if st, ok := rt.(*reflect.StructType); ok { - if engine.numInstr == 0 && st.NumField() > 0 && len(dec.wireType[wireId].structT.field) > 0 { + if engine.numInstr == 0 && st.NumField() > 0 && len(dec.wireType[wireId].StructT.Field) > 0 { name := rt.Name() return os.ErrorString("gob: type mismatch: no fields matched compiling decoder for " + name) } @@ -972,20 +993,6 @@ func (dec *Decoder) decode(wireId typeId, val reflect.Value) os.Error { } func init() { - var fop, cop decOp - switch reflect.Typeof(float(0)).Bits() { - case 32: - fop = decFloat32 - cop = decComplex64 - case 64: - fop = decFloat64 - cop = decComplex128 - default: - panic("gob: unknown size of float") - } - decOpMap[reflect.Float] = fop - decOpMap[reflect.Complex] = cop - var iop, uop decOp switch reflect.Typeof(int(0)).Bits() { case 32: diff --git a/libgo/go/gob/decoder.go b/libgo/go/gob/decoder.go index af3e78a6d28..664001a4b21 100644 --- a/libgo/go/gob/decoder.go +++ b/libgo/go/gob/decoder.go @@ -107,7 +107,7 @@ func (dec *Decoder) recv() { func (dec *Decoder) decodeValueFromBuffer(value reflect.Value, ignoreInterfaceValue, countPresent bool) { for dec.state.b.Len() > 0 { // Receive a type id. - id := typeId(decodeInt(dec.state)) + id := typeId(dec.state.decodeInt()) // Is it a new type? if id < 0 { // 0 is the error state, handled above @@ -127,7 +127,7 @@ func (dec *Decoder) decodeValueFromBuffer(value reflect.Value, ignoreInterfaceVa } // An interface value is preceded by a byte count. if countPresent { - count := int(decodeUint(dec.state)) + count := int(dec.state.decodeUint()) if ignoreInterfaceValue { // An interface value is preceded by a byte count. Just skip that many bytes. dec.state.b.Next(int(count)) diff --git a/libgo/go/gob/doc.go b/libgo/go/gob/doc.go index 2e7232db51d..31253f16d09 100644 --- a/libgo/go/gob/doc.go +++ b/libgo/go/gob/doc.go @@ -70,7 +70,7 @@ operation will fail. Structs, arrays and slices are also supported. Strings and arrays of bytes are supported with a special, efficient representation (see below). -Interfaces, functions, and channels cannot be sent in a gob. Attempting +Functions and channels cannot be sent in a gob. Attempting to encode a value that contains one will fail. The rest of this comment documents the encoding, details that are not important @@ -149,31 +149,34 @@ pair (-type id, encoded-type) where encoded-type is the gob encoding of a wireTy description, constructed from these types: type wireType struct { - s structType + ArrayT *ArrayType + SliceT *SliceType + StructT *StructType + MapT *MapType } - type arrayType struct { - commonType + type ArrayType struct { + CommonType Elem typeId Len int } - type commonType { - name string // the name of the struct type - _id int // the id of the type, repeated for so it's inside the type + type CommonType { + Name string // the name of the struct type + Id int // the id of the type, repeated so it's inside the type } - type sliceType struct { - commonType + type SliceType struct { + CommonType Elem typeId } - type structType struct { - commonType - field []*fieldType // the fields of the struct. + type StructType struct { + CommonType + Field []*fieldType // the fields of the struct. } - type fieldType struct { - name string // the name of the field. - id int // the type id of the field, which must be already defined + type FieldType struct { + Name string // the name of the field. + Id int // the type id of the field, which must be already defined } - type mapType struct { - commonType + type MapType struct { + CommonType Key typeId Elem typeId } @@ -193,18 +196,23 @@ priori, as well as the basic gob types int, uint, etc. Their ids are: complex 7 interface 8 // gap for reserved ids. - wireType 16 - arrayType 17 - commonType 18 - sliceType 19 - structType 20 - fieldType 21 + WireType 16 + ArrayType 17 + CommonType 18 + SliceType 19 + StructType 20 + FieldType 21 // 22 is slice of fieldType. - mapType 23 + MapType 23 + +Finally, each message created by a call to Encode is preceded by an encoded +unsigned integer count of the number of bytes remaining in the message. After +the initial type name, interface values are wrapped the same way; in effect, the +interface value acts like a recursive invocation of Encode. In summary, a gob stream looks like - ((-type id, encoding of a wireType)* (type id, encoding of a value))* + (byteCount (-type id, encoding of a wireType)* (type id, encoding of a value))* where * signifies zero or more repetitions and the type id of a value must be predefined or be defined before the value in the stream. diff --git a/libgo/go/gob/encode.go b/libgo/go/gob/encode.go index 73938668020..d286a7e00b8 100644 --- a/libgo/go/gob/encode.go +++ b/libgo/go/gob/encode.go @@ -37,7 +37,7 @@ func newEncoderState(enc *Encoder, b *bytes.Buffer) *encoderState { // by the byte length, negated. // encodeUint writes an encoded unsigned integer to state.b. -func encodeUint(state *encoderState, x uint64) { +func (state *encoderState) encodeUint(x uint64) { if x <= 0x7F { err := state.b.WriteByte(uint8(x)) if err != nil { @@ -62,14 +62,14 @@ func encodeUint(state *encoderState, x uint64) { // encodeInt writes an encoded signed integer to state.w. // The low bit of the encoding says whether to bit complement the (other bits of the) // uint to recover the int. -func encodeInt(state *encoderState, i int64) { +func (state *encoderState) encodeInt(i int64) { var x uint64 if i < 0 { x = uint64(^i<<1) | 1 } else { x = uint64(i << 1) } - encodeUint(state, uint64(x)) + state.encodeUint(uint64(x)) } type encOp func(i *encInstr, state *encoderState, p unsafe.Pointer) @@ -86,7 +86,7 @@ type encInstr struct { // If the instruction pointer is nil, do nothing func (state *encoderState) update(instr *encInstr) { if instr != nil { - encodeUint(state, uint64(instr.field-state.fieldnum)) + state.encodeUint(uint64(instr.field - state.fieldnum)) state.fieldnum = instr.field } } @@ -112,9 +112,9 @@ func encBool(i *encInstr, state *encoderState, p unsafe.Pointer) { if b || state.sendZero { state.update(i) if b { - encodeUint(state, 1) + state.encodeUint(1) } else { - encodeUint(state, 0) + state.encodeUint(0) } } } @@ -123,7 +123,7 @@ func encInt(i *encInstr, state *encoderState, p unsafe.Pointer) { v := int64(*(*int)(p)) if v != 0 || state.sendZero { state.update(i) - encodeInt(state, v) + state.encodeInt(v) } } @@ -131,7 +131,7 @@ func encUint(i *encInstr, state *encoderState, p unsafe.Pointer) { v := uint64(*(*uint)(p)) if v != 0 || state.sendZero { state.update(i) - encodeUint(state, v) + state.encodeUint(v) } } @@ -139,7 +139,7 @@ func encInt8(i *encInstr, state *encoderState, p unsafe.Pointer) { v := int64(*(*int8)(p)) if v != 0 || state.sendZero { state.update(i) - encodeInt(state, v) + state.encodeInt(v) } } @@ -147,7 +147,7 @@ func encUint8(i *encInstr, state *encoderState, p unsafe.Pointer) { v := uint64(*(*uint8)(p)) if v != 0 || state.sendZero { state.update(i) - encodeUint(state, v) + state.encodeUint(v) } } @@ -155,7 +155,7 @@ func encInt16(i *encInstr, state *encoderState, p unsafe.Pointer) { v := int64(*(*int16)(p)) if v != 0 || state.sendZero { state.update(i) - encodeInt(state, v) + state.encodeInt(v) } } @@ -163,7 +163,7 @@ func encUint16(i *encInstr, state *encoderState, p unsafe.Pointer) { v := uint64(*(*uint16)(p)) if v != 0 || state.sendZero { state.update(i) - encodeUint(state, v) + state.encodeUint(v) } } @@ -171,7 +171,7 @@ func encInt32(i *encInstr, state *encoderState, p unsafe.Pointer) { v := int64(*(*int32)(p)) if v != 0 || state.sendZero { state.update(i) - encodeInt(state, v) + state.encodeInt(v) } } @@ -179,7 +179,7 @@ func encUint32(i *encInstr, state *encoderState, p unsafe.Pointer) { v := uint64(*(*uint32)(p)) if v != 0 || state.sendZero { state.update(i) - encodeUint(state, v) + state.encodeUint(v) } } @@ -187,7 +187,7 @@ func encInt64(i *encInstr, state *encoderState, p unsafe.Pointer) { v := *(*int64)(p) if v != 0 || state.sendZero { state.update(i) - encodeInt(state, v) + state.encodeInt(v) } } @@ -195,7 +195,7 @@ func encUint64(i *encInstr, state *encoderState, p unsafe.Pointer) { v := *(*uint64)(p) if v != 0 || state.sendZero { state.update(i) - encodeUint(state, v) + state.encodeUint(v) } } @@ -203,7 +203,7 @@ func encUintptr(i *encInstr, state *encoderState, p unsafe.Pointer) { v := uint64(*(*uintptr)(p)) if v != 0 || state.sendZero { state.update(i) - encodeUint(state, v) + state.encodeUint(v) } } @@ -223,21 +223,12 @@ func floatBits(f float64) uint64 { return v } -func encFloat(i *encInstr, state *encoderState, p unsafe.Pointer) { - f := *(*float)(p) - if f != 0 || state.sendZero { - v := floatBits(float64(f)) - state.update(i) - encodeUint(state, v) - } -} - func encFloat32(i *encInstr, state *encoderState, p unsafe.Pointer) { f := *(*float32)(p) if f != 0 || state.sendZero { v := floatBits(float64(f)) state.update(i) - encodeUint(state, v) + state.encodeUint(v) } } @@ -246,30 +237,19 @@ func encFloat64(i *encInstr, state *encoderState, p unsafe.Pointer) { if f != 0 || state.sendZero { state.update(i) v := floatBits(f) - encodeUint(state, v) + state.encodeUint(v) } } // Complex numbers are just a pair of floating-point numbers, real part first. -func encComplex(i *encInstr, state *encoderState, p unsafe.Pointer) { - c := *(*complex)(p) - if c != 0+0i || state.sendZero { - rpart := floatBits(float64(real(c))) - ipart := floatBits(float64(imag(c))) - state.update(i) - encodeUint(state, rpart) - encodeUint(state, ipart) - } -} - func encComplex64(i *encInstr, state *encoderState, p unsafe.Pointer) { c := *(*complex64)(p) if c != 0+0i || state.sendZero { rpart := floatBits(float64(real(c))) ipart := floatBits(float64(imag(c))) state.update(i) - encodeUint(state, rpart) - encodeUint(state, ipart) + state.encodeUint(rpart) + state.encodeUint(ipart) } } @@ -279,17 +259,20 @@ func encComplex128(i *encInstr, state *encoderState, p unsafe.Pointer) { rpart := floatBits(real(c)) ipart := floatBits(imag(c)) state.update(i) - encodeUint(state, rpart) - encodeUint(state, ipart) + state.encodeUint(rpart) + state.encodeUint(ipart) } } +func encNoOp(i *encInstr, state *encoderState, p unsafe.Pointer) { +} + // Byte arrays are encoded as an unsigned count followed by the raw bytes. func encUint8Array(i *encInstr, state *encoderState, p unsafe.Pointer) { b := *(*[]byte)(p) if len(b) > 0 || state.sendZero { state.update(i) - encodeUint(state, uint64(len(b))) + state.encodeUint(uint64(len(b))) state.b.Write(b) } } @@ -299,14 +282,14 @@ func encString(i *encInstr, state *encoderState, p unsafe.Pointer) { s := *(*string)(p) if len(s) > 0 || state.sendZero { state.update(i) - encodeUint(state, uint64(len(s))) + state.encodeUint(uint64(len(s))) io.WriteString(state.b, s) } } // The end of a struct is marked by a delta field number of 0. func encStructTerminator(i *encInstr, state *encoderState, p unsafe.Pointer) { - encodeUint(state, 0) + state.encodeUint(0) } // Execution engine @@ -354,7 +337,7 @@ func (enc *Encoder) encodeArray(b *bytes.Buffer, p uintptr, op encOp, elemWid ui state := newEncoderState(enc, b) state.fieldnum = -1 state.sendZero = true - encodeUint(state, uint64(length)) + state.encodeUint(uint64(length)) for i := 0; i < length; i++ { elemp := p up := unsafe.Pointer(elemp) @@ -384,7 +367,7 @@ func (enc *Encoder) encodeMap(b *bytes.Buffer, mv *reflect.MapValue, keyOp, elem state.fieldnum = -1 state.sendZero = true keys := mv.Keys() - encodeUint(state, uint64(len(keys))) + state.encodeUint(uint64(len(keys))) for _, key := range keys { encodeReflectValue(state, key, keyOp, keyIndir) encodeReflectValue(state, mv.Elem(key), elemOp, elemIndir) @@ -400,7 +383,7 @@ func (enc *Encoder) encodeInterface(b *bytes.Buffer, iv *reflect.InterfaceValue) state.fieldnum = -1 state.sendZero = true if iv.IsNil() { - encodeUint(state, 0) + state.encodeUint(0) return } @@ -410,7 +393,7 @@ func (enc *Encoder) encodeInterface(b *bytes.Buffer, iv *reflect.InterfaceValue) errorf("gob: type not registered for interface: %s", typ) } // Send the name. - encodeUint(state, uint64(len(name))) + state.encodeUint(uint64(len(name))) _, err := io.WriteString(state.b, name) if err != nil { error(err) @@ -423,7 +406,7 @@ func (enc *Encoder) encodeInterface(b *bytes.Buffer, iv *reflect.InterfaceValue) if err != nil { error(err) } - encodeUint(state, uint64(data.Len())) + state.encodeUint(uint64(data.Len())) _, err = state.b.Write(data.Bytes()) if err != nil { error(err) @@ -443,10 +426,8 @@ var encOpMap = []encOp{ reflect.Uint32: encUint32, reflect.Uint64: encUint64, reflect.Uintptr: encUintptr, - reflect.Float: encFloat, reflect.Float32: encFloat32, reflect.Float64: encFloat64, - reflect.Complex: encComplex, reflect.Complex64: encComplex64, reflect.Complex128: encComplex128, reflect.String: encString, @@ -473,7 +454,7 @@ func (enc *Encoder) encOpFor(rt reflect.Type) (encOp, int) { elemOp, indir := enc.encOpFor(t.Elem()) op = func(i *encInstr, state *encoderState, p unsafe.Pointer) { slice := (*reflect.SliceHeader)(p) - if slice.Len == 0 { + if !state.sendZero && slice.Len == 0 { return } state.update(i) @@ -495,7 +476,7 @@ func (enc *Encoder) encOpFor(rt reflect.Type) (encOp, int) { // the iteration. v := reflect.NewValue(unsafe.Unreflect(t, unsafe.Pointer((p)))) mv := reflect.Indirect(v).(*reflect.MapValue) - if mv.Len() == 0 { + if !state.sendZero && mv.Len() == 0 { return } state.update(i) @@ -539,6 +520,9 @@ func (enc *Encoder) compileEnc(rt reflect.Type) *encEngine { for fieldnum := 0; fieldnum < srt.NumField(); fieldnum++ { f := srt.Field(fieldnum) op, indir := enc.encOpFor(f.Type) + if !isExported(f.Name) { + op = encNoOp + } engine.instr[fieldnum] = encInstr{op, fieldnum, indir, uintptr(f.Offset)} } engine.instr[srt.NumField()] = encInstr{encStructTerminator, 0, 0, 0} diff --git a/libgo/go/gob/encoder.go b/libgo/go/gob/encoder.go index 340a6024106..8869b262982 100644 --- a/libgo/go/gob/encoder.go +++ b/libgo/go/gob/encoder.go @@ -48,7 +48,7 @@ func (enc *Encoder) setError(err os.Error) { // Send the data item preceded by a unsigned count of its length. func (enc *Encoder) send() { // Encode the length. - encodeUint(enc.countState, uint64(enc.state.b.Len())) + enc.countState.encodeUint(uint64(enc.state.b.Len())) // Build the buffer. countLen := enc.countState.b.Len() total := countLen + enc.state.b.Len() @@ -112,7 +112,7 @@ func (enc *Encoder) sendType(origt reflect.Type) (sent bool) { } // Send the pair (-id, type) // Id: - encodeInt(enc.state, -int64(info.id)) + enc.state.encodeInt(-int64(info.id)) // Type: enc.encode(enc.state.b, reflect.NewValue(info.wire)) enc.send() @@ -170,7 +170,7 @@ func (enc *Encoder) sendTypeDescriptor(rt reflect.Type) { } // Identify the type of this top-level value. - encodeInt(enc.state, int64(enc.sent[rt])) + enc.state.encodeInt(int64(enc.sent[rt])) } // EncodeValue transmits the data item represented by the reflection value, diff --git a/libgo/go/gob/encoder_test.go b/libgo/go/gob/encoder_test.go index 91d85bb7ad6..c2309352a09 100644 --- a/libgo/go/gob/encoder_test.go +++ b/libgo/go/gob/encoder_test.go @@ -14,35 +14,35 @@ import ( ) type ET2 struct { - x string + X string } type ET1 struct { - a int - et2 *ET2 - next *ET1 + A int + Et2 *ET2 + Next *ET1 } // Like ET1 but with a different name for a field type ET3 struct { - a int - et2 *ET2 - differentNext *ET1 + A int + Et2 *ET2 + DifferentNext *ET1 } // Like ET1 but with a different type for a field type ET4 struct { - a int - et2 float - next int + A int + Et2 float64 + Next int } func TestEncoderDecoder(t *testing.T) { b := new(bytes.Buffer) enc := NewEncoder(b) et1 := new(ET1) - et1.a = 7 - et1.et2 = new(ET2) + et1.A = 7 + et1.Et2 = new(ET2) err := enc.Encode(et1) if err != nil { t.Error("encoder fail:", err) @@ -92,8 +92,8 @@ func badTypeCheck(e interface{}, shouldFail bool, msg string, t *testing.T) { b := new(bytes.Buffer) enc := NewEncoder(b) et1 := new(ET1) - et1.a = 7 - et1.et2 = new(ET2) + et1.A = 7 + et1.Et2 = new(ET2) err := enc.Encode(et1) if err != nil { t.Error("encoder fail:", err) @@ -166,7 +166,7 @@ func encAndDec(in, out interface{}) os.Error { func TestTypeToPtrType(t *testing.T) { // Encode a T, decode a *T type Type0 struct { - a int + A int } t0 := Type0{7} t0p := (*Type0)(nil) @@ -178,7 +178,7 @@ func TestTypeToPtrType(t *testing.T) { func TestPtrTypeToType(t *testing.T) { // Encode a *T, decode a T type Type1 struct { - a uint + A uint } t1p := &Type1{17} var t1 Type1 @@ -189,26 +189,26 @@ func TestPtrTypeToType(t *testing.T) { func TestTypeToPtrPtrPtrPtrType(t *testing.T) { type Type2 struct { - a ****float + A ****float64 } t2 := Type2{} - t2.a = new(***float) - *t2.a = new(**float) - **t2.a = new(*float) - ***t2.a = new(float) - ****t2.a = 27.4 + t2.A = new(***float64) + *t2.A = new(**float64) + **t2.A = new(*float64) + ***t2.A = new(float64) + ****t2.A = 27.4 t2pppp := new(***Type2) if err := encAndDec(t2, t2pppp); err != nil { - t.Error(err) + t.Fatal(err) } - if ****(****t2pppp).a != ****t2.a { - t.Errorf("wrong value after decode: %g not %g", ****(****t2pppp).a, ****t2.a) + if ****(****t2pppp).A != ****t2.A { + t.Errorf("wrong value after decode: %g not %g", ****(****t2pppp).A, ****t2.A) } } func TestSlice(t *testing.T) { type Type3 struct { - a []string + A []string } t3p := &Type3{[]string{"hello", "world"}} var t3 Type3 @@ -231,11 +231,11 @@ func TestValueError(t *testing.T) { func TestArray(t *testing.T) { type Type5 struct { - a [3]string - b [3]byte + A [3]string + B [3]byte } type Type6 struct { - a [2]string // can't hold t5.a + A [2]string // can't hold t5.a } t5 := Type5{[3]string{"hello", ",", "world"}, [3]byte{1, 2, 3}} var t5p Type5 @@ -251,16 +251,16 @@ func TestArray(t *testing.T) { // Regression test for bug: must send zero values inside arrays func TestDefaultsInArray(t *testing.T) { type Type7 struct { - b []bool - i []int - s []string - f []float + B []bool + I []int + S []string + F []float64 } t7 := Type7{ []bool{false, false, true}, []int{0, 0, 1}, []string{"hi", "", "there"}, - []float{0, 0, 1}, + []float64{0, 0, 1}, } var t7p Type7 if err := encAndDec(t7, &t7p); err != nil { @@ -329,7 +329,7 @@ func TestSingletons(t *testing.T) { func TestStructNonStruct(t *testing.T) { type Struct struct { - a string + A string } type NonStruct string s := Struct{"hello"} @@ -354,3 +354,32 @@ func TestStructNonStruct(t *testing.T) { t.Error("for non-struct/struct expected type error; got", err) } } + +type interfaceIndirectTestI interface { + F() bool +} + +type interfaceIndirectTestT struct{} + +func (this *interfaceIndirectTestT) F() bool { + return true +} + +// A version of a bug reported on golang-nuts. Also tests top-level +// slice of interfaces. The issue was registering *T caused T to be +// stored as the concrete type. +func TestInterfaceIndirect(t *testing.T) { + Register(&interfaceIndirectTestT{}) + b := new(bytes.Buffer) + w := []interfaceIndirectTestI{&interfaceIndirectTestT{}} + err := NewEncoder(b).Encode(w) + if err != nil { + t.Fatal("encode error:", err) + } + + var r []interfaceIndirectTestI + err = NewDecoder(b).Decode(&r) + if err != nil { + t.Fatal("decode error:", err) + } +} diff --git a/libgo/go/gob/type.go b/libgo/go/gob/type.go index d68c8773cfd..22502a6e6b9 100644 --- a/libgo/go/gob/type.go +++ b/libgo/go/gob/type.go @@ -29,7 +29,7 @@ const firstUserId = 64 // lowest id number granted to user type gobType interface { id() typeId setId(id typeId) - Name() string + name() string string() string // not public; only for debugging safeString(seen map[typeId]bool) string } @@ -60,30 +60,30 @@ func (t typeId) string() string { } // Name returns the name of the type associated with the typeId. -func (t typeId) Name() string { +func (t typeId) name() string { if t.gobType() == nil { return "<nil>" } - return t.gobType().Name() + return t.gobType().name() } // Common elements of all types. -type commonType struct { - name string - _id typeId +type CommonType struct { + Name string + Id typeId } -func (t *commonType) id() typeId { return t._id } +func (t *CommonType) id() typeId { return t.Id } -func (t *commonType) setId(id typeId) { t._id = id } +func (t *CommonType) setId(id typeId) { t.Id = id } -func (t *commonType) string() string { return t.name } +func (t *CommonType) string() string { return t.Name } -func (t *commonType) safeString(seen map[typeId]bool) string { - return t.name +func (t *CommonType) safeString(seen map[typeId]bool) string { + return t.Name } -func (t *commonType) Name() string { return t.name } +func (t *CommonType) name() string { return t.Name } // Create and check predefined types // The string for tBytes is "bytes" not "[]byte" to signify its specialness. @@ -93,7 +93,7 @@ var ( tBool = bootstrapType("bool", false, 1) tInt = bootstrapType("int", int(0), 2) tUint = bootstrapType("uint", uint(0), 3) - tFloat = bootstrapType("float", float64(0), 4) + tFloat = bootstrapType("float", 0.0, 4) tBytes = bootstrapType("bytes", make([]byte, 0), 5) tString = bootstrapType("string", "", 6) tComplex = bootstrapType("complex", 0+0i, 7) @@ -115,7 +115,7 @@ func init() { // Some magic numbers to make sure there are no surprises. checkId(16, tWireType) checkId(17, mustGetTypeInfo(reflect.Typeof(arrayType{})).id) - checkId(18, mustGetTypeInfo(reflect.Typeof(commonType{})).id) + checkId(18, mustGetTypeInfo(reflect.Typeof(CommonType{})).id) checkId(19, mustGetTypeInfo(reflect.Typeof(sliceType{})).id) checkId(20, mustGetTypeInfo(reflect.Typeof(structType{})).id) checkId(21, mustGetTypeInfo(reflect.Typeof(fieldType{})).id) @@ -137,22 +137,22 @@ func init() { // Array type type arrayType struct { - commonType + CommonType Elem typeId Len int } func newArrayType(name string, elem gobType, length int) *arrayType { - a := &arrayType{commonType{name: name}, elem.id(), length} + a := &arrayType{CommonType{Name: name}, elem.id(), length} setTypeId(a) return a } func (a *arrayType) safeString(seen map[typeId]bool) string { - if seen[a._id] { - return a.name + if seen[a.Id] { + return a.Name } - seen[a._id] = true + seen[a.Id] = true return fmt.Sprintf("[%d]%s", a.Len, a.Elem.gobType().safeString(seen)) } @@ -160,22 +160,22 @@ func (a *arrayType) string() string { return a.safeString(make(map[typeId]bool)) // Map type type mapType struct { - commonType + CommonType Key typeId Elem typeId } func newMapType(name string, key, elem gobType) *mapType { - m := &mapType{commonType{name: name}, key.id(), elem.id()} + m := &mapType{CommonType{Name: name}, key.id(), elem.id()} setTypeId(m) return m } func (m *mapType) safeString(seen map[typeId]bool) string { - if seen[m._id] { - return m.name + if seen[m.Id] { + return m.Name } - seen[m._id] = true + seen[m.Id] = true key := m.Key.gobType().safeString(seen) elem := m.Elem.gobType().safeString(seen) return fmt.Sprintf("map[%s]%s", key, elem) @@ -185,21 +185,21 @@ func (m *mapType) string() string { return m.safeString(make(map[typeId]bool)) } // Slice type type sliceType struct { - commonType + CommonType Elem typeId } func newSliceType(name string, elem gobType) *sliceType { - s := &sliceType{commonType{name: name}, elem.id()} + s := &sliceType{CommonType{Name: name}, elem.id()} setTypeId(s) return s } func (s *sliceType) safeString(seen map[typeId]bool) string { - if seen[s._id] { - return s.name + if seen[s.Id] { + return s.Name } - seen[s._id] = true + seen[s.Id] = true return fmt.Sprintf("[]%s", s.Elem.gobType().safeString(seen)) } @@ -207,26 +207,26 @@ func (s *sliceType) string() string { return s.safeString(make(map[typeId]bool)) // Struct type type fieldType struct { - name string - id typeId + Name string + Id typeId } type structType struct { - commonType - field []*fieldType + CommonType + Field []*fieldType } func (s *structType) safeString(seen map[typeId]bool) string { if s == nil { return "<nil>" } - if _, ok := seen[s._id]; ok { - return s.name + if _, ok := seen[s.Id]; ok { + return s.Name } - seen[s._id] = true - str := s.name + " = struct { " - for _, f := range s.field { - str += fmt.Sprintf("%s %s; ", f.name, f.id.gobType().safeString(seen)) + seen[s.Id] = true + str := s.Name + " = struct { " + for _, f := range s.Field { + str += fmt.Sprintf("%s %s; ", f.Name, f.Id.gobType().safeString(seen)) } str += "}" return str @@ -235,7 +235,7 @@ func (s *structType) safeString(seen map[typeId]bool) string { func (s *structType) string() string { return s.safeString(make(map[typeId]bool)) } func newStructType(name string) *structType { - s := &structType{commonType{name: name}, nil} + s := &structType{CommonType{Name: name}, nil} setTypeId(s) return s } @@ -329,7 +329,7 @@ func newTypeObject(name string, rt reflect.Type) (gobType, os.Error) { } field[i] = &fieldType{f.Name, gt.id()} } - strType.field = field + strType.Field = field return strType, nil default: @@ -356,7 +356,7 @@ func getType(name string, rt reflect.Type) (gobType, os.Error) { func checkId(want, got typeId) { if want != got { fmt.Fprintf(os.Stderr, "checkId: %d should be %d\n", int(want), int(got)) - panic("bootstrap type wrong id: " + got.Name() + " " + got.string() + " not " + want.string()) + panic("bootstrap type wrong id: " + got.name() + " " + got.string() + " not " + want.string()) } } @@ -367,7 +367,7 @@ func bootstrapType(name string, e interface{}, expect typeId) typeId { if present { panic("bootstrap type already present: " + name + ", " + rt.String()) } - typ := &commonType{name: name} + typ := &CommonType{Name: name} types[rt] = typ setTypeId(typ) checkId(expect, nextId) @@ -386,17 +386,28 @@ func bootstrapType(name string, e interface{}, expect typeId) typeId { // To maintain binary compatibility, if you extend this type, always put // the new fields last. type wireType struct { - arrayT *arrayType - sliceT *sliceType - structT *structType - mapT *mapType + ArrayT *arrayType + SliceT *sliceType + StructT *structType + MapT *mapType } -func (w *wireType) name() string { - if w.structT != nil { - return w.structT.name +func (w *wireType) string() string { + const unknown = "unknown type" + if w == nil { + return unknown } - return "unknown" + switch { + case w.ArrayT != nil: + return w.ArrayT.Name + case w.SliceT != nil: + return w.SliceT.Name + case w.StructT != nil: + return w.StructT.Name + case w.MapT != nil: + return w.MapT.Name + } + return unknown } type typeInfo struct { @@ -425,16 +436,16 @@ func getTypeInfo(rt reflect.Type) (*typeInfo, os.Error) { t := info.id.gobType() switch typ := rt.(type) { case *reflect.ArrayType: - info.wire = &wireType{arrayT: t.(*arrayType)} + info.wire = &wireType{ArrayT: t.(*arrayType)} case *reflect.MapType: - info.wire = &wireType{mapT: t.(*mapType)} + info.wire = &wireType{MapT: t.(*mapType)} case *reflect.SliceType: // []byte == []uint8 is a special case handled separately if typ.Elem().Kind() != reflect.Uint8 { - info.wire = &wireType{sliceT: t.(*sliceType)} + info.wire = &wireType{SliceT: t.(*sliceType)} } case *reflect.StructType: - info.wire = &wireType{structT: t.(*structType)} + info.wire = &wireType{StructT: t.(*structType)} } typeInfoMap[rt] = info } @@ -470,7 +481,9 @@ func RegisterName(name string, value interface{}) { if n, ok := concreteTypeToName[rt]; ok && n != name { panic("gob: registering duplicate names for " + rt.String()) } - nameToConcreteType[name] = rt + // Store the name and type provided by the user.... + nameToConcreteType[name] = reflect.Typeof(value) + // but the flattened type in the type table, since that's what decode needs. concreteTypeToName[rt] = name } @@ -516,10 +529,8 @@ func registerBasics() { Register(uint16(0)) Register(uint32(0)) Register(uint64(0)) - Register(float(0)) Register(float32(0)) - Register(float64(0)) - Register(complex(0i)) + Register(0.0) Register(complex64(0i)) Register(complex128(0i)) Register(false) diff --git a/libgo/go/gob/type_test.go b/libgo/go/gob/type_test.go index 106e4f10b51..5aecde103a5 100644 --- a/libgo/go/gob/type_test.go +++ b/libgo/go/gob/type_test.go @@ -135,8 +135,8 @@ type Foo struct { b int32 // will become int c string d []byte - e *float // will become float - f ****float64 // will become float + e *float64 // will become float64 + f ****float64 // will become float64 g *Bar h *Bar // should not interpolate the definition of Bar again i *Foo // will not explode |