LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // This file contains tests of the GobEncoder/GobDecoder support. | 5 // This file contains tests of the GobEncoder/GobDecoder support. |
6 | 6 |
7 package gob | 7 package gob |
8 | 8 |
9 import ( | 9 import ( |
10 "bytes" | 10 "bytes" |
(...skipping 16 matching lines...) Expand all Loading... |
27 } | 27 } |
28 | 28 |
29 type ArrayStruct struct { | 29 type ArrayStruct struct { |
30 a [8192]byte // not an exported field | 30 a [8192]byte // not an exported field |
31 } | 31 } |
32 | 32 |
33 type Gobber int | 33 type Gobber int |
34 | 34 |
35 type ValueGobber string // encodes with a value, decodes with a pointer. | 35 type ValueGobber string // encodes with a value, decodes with a pointer. |
36 | 36 |
| 37 type BinaryGobber int |
| 38 |
| 39 type BinaryValueGobber string |
| 40 |
| 41 type TextGobber int |
| 42 |
| 43 type TextValueGobber string |
| 44 |
37 // The relevant methods | 45 // The relevant methods |
38 | 46 |
39 func (g *ByteStruct) GobEncode() ([]byte, error) { | 47 func (g *ByteStruct) GobEncode() ([]byte, error) { |
40 b := make([]byte, 3) | 48 b := make([]byte, 3) |
41 b[0] = g.a | 49 b[0] = g.a |
42 b[1] = g.a + 1 | 50 b[1] = g.a + 1 |
43 b[2] = g.a + 2 | 51 b[2] = g.a + 2 |
44 return b, nil | 52 return b, nil |
45 } | 53 } |
46 | 54 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 | 102 |
95 func (g *Gobber) GobEncode() ([]byte, error) { | 103 func (g *Gobber) GobEncode() ([]byte, error) { |
96 return []byte(fmt.Sprintf("VALUE=%d", *g)), nil | 104 return []byte(fmt.Sprintf("VALUE=%d", *g)), nil |
97 } | 105 } |
98 | 106 |
99 func (g *Gobber) GobDecode(data []byte) error { | 107 func (g *Gobber) GobDecode(data []byte) error { |
100 _, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g)) | 108 _, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g)) |
101 return err | 109 return err |
102 } | 110 } |
103 | 111 |
| 112 func (g *BinaryGobber) MarshalBinary() ([]byte, error) { |
| 113 return []byte(fmt.Sprintf("VALUE=%d", *g)), nil |
| 114 } |
| 115 |
| 116 func (g *BinaryGobber) UnmarshalBinary(data []byte) error { |
| 117 _, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g)) |
| 118 return err |
| 119 } |
| 120 |
| 121 func (g *TextGobber) MarshalText() ([]byte, error) { |
| 122 return []byte(fmt.Sprintf("VALUE=%d", *g)), nil |
| 123 } |
| 124 |
| 125 func (g *TextGobber) UnmarshalText(data []byte) error { |
| 126 _, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g)) |
| 127 return err |
| 128 } |
| 129 |
104 func (v ValueGobber) GobEncode() ([]byte, error) { | 130 func (v ValueGobber) GobEncode() ([]byte, error) { |
105 return []byte(fmt.Sprintf("VALUE=%s", v)), nil | 131 return []byte(fmt.Sprintf("VALUE=%s", v)), nil |
106 } | 132 } |
107 | 133 |
108 func (v *ValueGobber) GobDecode(data []byte) error { | 134 func (v *ValueGobber) GobDecode(data []byte) error { |
109 _, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v)) | 135 _, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v)) |
110 return err | 136 return err |
111 } | 137 } |
112 | 138 |
| 139 func (v BinaryValueGobber) MarshalBinary() ([]byte, error) { |
| 140 return []byte(fmt.Sprintf("VALUE=%s", v)), nil |
| 141 } |
| 142 |
| 143 func (v *BinaryValueGobber) UnmarshalBinary(data []byte) error { |
| 144 _, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v)) |
| 145 return err |
| 146 } |
| 147 |
| 148 func (v TextValueGobber) MarshalText() ([]byte, error) { |
| 149 return []byte(fmt.Sprintf("VALUE=%s", v)), nil |
| 150 } |
| 151 |
| 152 func (v *TextValueGobber) UnmarshalText(data []byte) error { |
| 153 _, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v)) |
| 154 return err |
| 155 } |
| 156 |
113 // Structs that include GobEncodable fields. | 157 // Structs that include GobEncodable fields. |
114 | 158 |
115 type GobTest0 struct { | 159 type GobTest0 struct { |
116 X int // guarantee we have something in common with GobTest* | 160 X int // guarantee we have something in common with GobTest* |
117 G *ByteStruct | 161 G *ByteStruct |
118 } | 162 } |
119 | 163 |
120 type GobTest1 struct { | 164 type GobTest1 struct { |
121 X int // guarantee we have something in common with GobTest* | 165 X int // guarantee we have something in common with GobTest* |
122 G *StringStruct | 166 G *StringStruct |
123 } | 167 } |
124 | 168 |
125 type GobTest2 struct { | 169 type GobTest2 struct { |
126 X int // guarantee we have something in common with GobTest* | 170 X int // guarantee we have something in common with GobTest* |
127 G string // not a GobEncoder - should give us errors | 171 G string // not a GobEncoder - should give us errors |
128 } | 172 } |
129 | 173 |
130 type GobTest3 struct { | 174 type GobTest3 struct { |
131 X int // guarantee we have something in common with GobTest* | 175 X int // guarantee we have something in common with GobTest* |
132 G *Gobber | 176 G *Gobber |
| 177 B *BinaryGobber |
| 178 T *TextGobber |
133 } | 179 } |
134 | 180 |
135 type GobTest4 struct { | 181 type GobTest4 struct { |
136 » X int // guarantee we have something in common with GobTest* | 182 » X int // guarantee we have something in common with GobTest* |
137 » V ValueGobber | 183 » V ValueGobber |
| 184 » BV BinaryValueGobber |
| 185 » TV TextValueGobber |
138 } | 186 } |
139 | 187 |
140 type GobTest5 struct { | 188 type GobTest5 struct { |
141 » X int // guarantee we have something in common with GobTest* | 189 » X int // guarantee we have something in common with GobTest* |
142 » V *ValueGobber | 190 » V *ValueGobber |
| 191 » BV *BinaryValueGobber |
| 192 » TV *TextValueGobber |
143 } | 193 } |
144 | 194 |
145 type GobTest6 struct { | 195 type GobTest6 struct { |
146 » X int // guarantee we have something in common with GobTest* | 196 » X int // guarantee we have something in common with GobTest* |
147 » V ValueGobber | 197 » V ValueGobber |
148 » W *ValueGobber | 198 » W *ValueGobber |
| 199 » BV BinaryValueGobber |
| 200 » BW *BinaryValueGobber |
| 201 » TV TextValueGobber |
| 202 » TW *TextValueGobber |
149 } | 203 } |
150 | 204 |
151 type GobTest7 struct { | 205 type GobTest7 struct { |
152 » X int // guarantee we have something in common with GobTest* | 206 » X int // guarantee we have something in common with GobTest* |
153 » V *ValueGobber | 207 » V *ValueGobber |
154 » W ValueGobber | 208 » W ValueGobber |
| 209 » BV *BinaryValueGobber |
| 210 » BW BinaryValueGobber |
| 211 » TV *TextValueGobber |
| 212 » TW TextValueGobber |
155 } | 213 } |
156 | 214 |
157 type GobTestIgnoreEncoder struct { | 215 type GobTestIgnoreEncoder struct { |
158 X int // guarantee we have something in common with GobTest* | 216 X int // guarantee we have something in common with GobTest* |
159 } | 217 } |
160 | 218 |
161 type GobTestValueEncDec struct { | 219 type GobTestValueEncDec struct { |
162 X int // guarantee we have something in common with GobTest* | 220 X int // guarantee we have something in common with GobTest* |
163 G StringStruct // not a pointer. | 221 G StringStruct // not a pointer. |
164 } | 222 } |
(...skipping 26 matching lines...) Expand all Loading... |
191 err = dec.Decode(x) | 249 err = dec.Decode(x) |
192 if err != nil { | 250 if err != nil { |
193 t.Fatal("decode error:", err) | 251 t.Fatal("decode error:", err) |
194 } | 252 } |
195 if x.G.a != 'A' { | 253 if x.G.a != 'A' { |
196 t.Errorf("expected 'A' got %c", x.G.a) | 254 t.Errorf("expected 'A' got %c", x.G.a) |
197 } | 255 } |
198 // Now a field that's not a structure. | 256 // Now a field that's not a structure. |
199 b.Reset() | 257 b.Reset() |
200 gobber := Gobber(23) | 258 gobber := Gobber(23) |
201 » err = enc.Encode(GobTest3{17, &gobber}) | 259 » bgobber := BinaryGobber(24) |
| 260 » tgobber := TextGobber(25) |
| 261 » err = enc.Encode(GobTest3{17, &gobber, &bgobber, &tgobber}) |
202 if err != nil { | 262 if err != nil { |
203 t.Fatal("encode error:", err) | 263 t.Fatal("encode error:", err) |
204 } | 264 } |
205 y := new(GobTest3) | 265 y := new(GobTest3) |
206 err = dec.Decode(y) | 266 err = dec.Decode(y) |
207 if err != nil { | 267 if err != nil { |
208 t.Fatal("decode error:", err) | 268 t.Fatal("decode error:", err) |
209 } | 269 } |
210 » if *y.G != 23 { | 270 » if *y.G != 23 || *y.B != 24 || *y.T != 25 { |
211 t.Errorf("expected '23 got %d", *y.G) | 271 t.Errorf("expected '23 got %d", *y.G) |
212 } | 272 } |
213 } | 273 } |
214 | 274 |
215 // Even though the field is a value, we can still take its address | 275 // Even though the field is a value, we can still take its address |
216 // and should be able to call the methods. | 276 // and should be able to call the methods. |
217 func TestGobEncoderValueField(t *testing.T) { | 277 func TestGobEncoderValueField(t *testing.T) { |
218 b := new(bytes.Buffer) | 278 b := new(bytes.Buffer) |
219 // First a field that's a structure. | 279 // First a field that's a structure. |
220 enc := NewEncoder(b) | 280 enc := NewEncoder(b) |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 if y.G.s != "XYZ" { | 410 if y.G.s != "XYZ" { |
351 t.Fatalf("expected `XYZ` got %q", y.G.s) | 411 t.Fatalf("expected `XYZ` got %q", y.G.s) |
352 } | 412 } |
353 } | 413 } |
354 | 414 |
355 // Test that we can encode a value and decode into a pointer. | 415 // Test that we can encode a value and decode into a pointer. |
356 func TestGobEncoderValueEncoder(t *testing.T) { | 416 func TestGobEncoderValueEncoder(t *testing.T) { |
357 // first, string in field to byte in field | 417 // first, string in field to byte in field |
358 b := new(bytes.Buffer) | 418 b := new(bytes.Buffer) |
359 enc := NewEncoder(b) | 419 enc := NewEncoder(b) |
360 » err := enc.Encode(GobTest4{17, ValueGobber("hello")}) | 420 » err := enc.Encode(GobTest4{17, ValueGobber("hello"), BinaryValueGobber("
Καλημέρα"), TextValueGobber("こんにちは")}) |
361 if err != nil { | 421 if err != nil { |
362 t.Fatal("encode error:", err) | 422 t.Fatal("encode error:", err) |
363 } | 423 } |
364 dec := NewDecoder(b) | 424 dec := NewDecoder(b) |
365 x := new(GobTest5) | 425 x := new(GobTest5) |
366 err = dec.Decode(x) | 426 err = dec.Decode(x) |
367 if err != nil { | 427 if err != nil { |
368 t.Fatal("decode error:", err) | 428 t.Fatal("decode error:", err) |
369 } | 429 } |
370 » if *x.V != "hello" { | 430 » if *x.V != "hello" || *x.BV != "Καλημέρα" || *x.TV != "こんにちは" { |
371 t.Errorf("expected `hello` got %s", x.V) | 431 t.Errorf("expected `hello` got %s", x.V) |
372 } | 432 } |
373 } | 433 } |
374 | 434 |
375 // Test that we can use a value then a pointer type of a GobEncoder | 435 // Test that we can use a value then a pointer type of a GobEncoder |
376 // in the same encoded value. Bug 4647. | 436 // in the same encoded value. Bug 4647. |
377 func TestGobEncoderValueThenPointer(t *testing.T) { | 437 func TestGobEncoderValueThenPointer(t *testing.T) { |
378 v := ValueGobber("forty-two") | 438 v := ValueGobber("forty-two") |
379 w := ValueGobber("six-by-nine") | 439 w := ValueGobber("six-by-nine") |
| 440 bv := BinaryValueGobber("1nanocentury") |
| 441 bw := BinaryValueGobber("πseconds") |
| 442 tv := TextValueGobber("gravitationalacceleration") |
| 443 tw := TextValueGobber("π²ft/s²") |
380 | 444 |
381 // this was a bug: encoding a GobEncoder by value before a GobEncoder | 445 // this was a bug: encoding a GobEncoder by value before a GobEncoder |
382 // pointer would cause duplicate type definitions to be sent. | 446 // pointer would cause duplicate type definitions to be sent. |
383 | 447 |
384 b := new(bytes.Buffer) | 448 b := new(bytes.Buffer) |
385 enc := NewEncoder(b) | 449 enc := NewEncoder(b) |
386 » if err := enc.Encode(GobTest6{42, v, &w}); err != nil { | 450 » if err := enc.Encode(GobTest6{42, v, &w, bv, &bw, tv, &tw}); err != nil
{ |
387 t.Fatal("encode error:", err) | 451 t.Fatal("encode error:", err) |
388 } | 452 } |
389 dec := NewDecoder(b) | 453 dec := NewDecoder(b) |
390 x := new(GobTest6) | 454 x := new(GobTest6) |
391 if err := dec.Decode(x); err != nil { | 455 if err := dec.Decode(x); err != nil { |
392 t.Fatal("decode error:", err) | 456 t.Fatal("decode error:", err) |
393 } | 457 } |
| 458 |
394 if got, want := x.V, v; got != want { | 459 if got, want := x.V, v; got != want { |
395 t.Errorf("v = %q, want %q", got, want) | 460 t.Errorf("v = %q, want %q", got, want) |
396 } | 461 } |
397 if got, want := x.W, w; got == nil { | 462 if got, want := x.W, w; got == nil { |
398 t.Errorf("w = nil, want %q", want) | 463 t.Errorf("w = nil, want %q", want) |
399 } else if *got != want { | 464 } else if *got != want { |
400 t.Errorf("w = %q, want %q", *got, want) | 465 t.Errorf("w = %q, want %q", *got, want) |
| 466 } |
| 467 |
| 468 if got, want := x.BV, bv; got != want { |
| 469 t.Errorf("bv = %q, want %q", got, want) |
| 470 } |
| 471 if got, want := x.BW, bw; got == nil { |
| 472 t.Errorf("bw = nil, want %q", want) |
| 473 } else if *got != want { |
| 474 t.Errorf("bw = %q, want %q", *got, want) |
| 475 } |
| 476 |
| 477 if got, want := x.TV, tv; got != want { |
| 478 t.Errorf("tv = %q, want %q", got, want) |
| 479 } |
| 480 if got, want := x.TW, tw; got == nil { |
| 481 t.Errorf("tw = nil, want %q", want) |
| 482 } else if *got != want { |
| 483 t.Errorf("tw = %q, want %q", *got, want) |
401 } | 484 } |
402 } | 485 } |
403 | 486 |
404 // Test that we can use a pointer then a value type of a GobEncoder | 487 // Test that we can use a pointer then a value type of a GobEncoder |
405 // in the same encoded value. | 488 // in the same encoded value. |
406 func TestGobEncoderPointerThenValue(t *testing.T) { | 489 func TestGobEncoderPointerThenValue(t *testing.T) { |
407 v := ValueGobber("forty-two") | 490 v := ValueGobber("forty-two") |
408 w := ValueGobber("six-by-nine") | 491 w := ValueGobber("six-by-nine") |
409 | 492 » bv := BinaryValueGobber("1nanocentury") |
410 » b := new(bytes.Buffer) | 493 » bw := BinaryValueGobber("πseconds") |
411 » enc := NewEncoder(b) | 494 » tv := TextValueGobber("gravitationalacceleration") |
412 » if err := enc.Encode(GobTest7{42, &v, w}); err != nil { | 495 » tw := TextValueGobber("π²ft/s²") |
| 496 |
| 497 » b := new(bytes.Buffer) |
| 498 » enc := NewEncoder(b) |
| 499 » if err := enc.Encode(GobTest7{42, &v, w, &bv, bw, &tv, tw}); err != nil
{ |
413 t.Fatal("encode error:", err) | 500 t.Fatal("encode error:", err) |
414 } | 501 } |
415 dec := NewDecoder(b) | 502 dec := NewDecoder(b) |
416 x := new(GobTest7) | 503 x := new(GobTest7) |
417 if err := dec.Decode(x); err != nil { | 504 if err := dec.Decode(x); err != nil { |
418 t.Fatal("decode error:", err) | 505 t.Fatal("decode error:", err) |
419 } | 506 } |
| 507 |
420 if got, want := x.V, v; got == nil { | 508 if got, want := x.V, v; got == nil { |
421 t.Errorf("v = nil, want %q", want) | 509 t.Errorf("v = nil, want %q", want) |
422 } else if *got != want { | 510 } else if *got != want { |
423 » » t.Errorf("v = %q, want %q", got, want) | 511 » » t.Errorf("v = %q, want %q", *got, want) |
424 } | 512 } |
425 if got, want := x.W, w; got != want { | 513 if got, want := x.W, w; got != want { |
426 t.Errorf("w = %q, want %q", got, want) | 514 t.Errorf("w = %q, want %q", got, want) |
| 515 } |
| 516 |
| 517 if got, want := x.BV, bv; got == nil { |
| 518 t.Errorf("bv = nil, want %q", want) |
| 519 } else if *got != want { |
| 520 t.Errorf("bv = %q, want %q", *got, want) |
| 521 } |
| 522 if got, want := x.BW, bw; got != want { |
| 523 t.Errorf("bw = %q, want %q", got, want) |
| 524 } |
| 525 |
| 526 if got, want := x.TV, tv; got == nil { |
| 527 t.Errorf("tv = nil, want %q", want) |
| 528 } else if *got != want { |
| 529 t.Errorf("tv = %q, want %q", *got, want) |
| 530 } |
| 531 if got, want := x.TW, tw; got != want { |
| 532 t.Errorf("tw = %q, want %q", got, want) |
427 } | 533 } |
428 } | 534 } |
429 | 535 |
430 func TestGobEncoderFieldTypeError(t *testing.T) { | 536 func TestGobEncoderFieldTypeError(t *testing.T) { |
431 // GobEncoder to non-decoder: error | 537 // GobEncoder to non-decoder: error |
432 b := new(bytes.Buffer) | 538 b := new(bytes.Buffer) |
433 enc := NewEncoder(b) | 539 enc := NewEncoder(b) |
434 err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}}) | 540 err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}}) |
435 if err != nil { | 541 if err != nil { |
436 t.Fatal("encode error:", err) | 542 t.Fatal("encode error:", err) |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 if x.X != 17 { | 620 if x.X != 17 { |
515 t.Errorf("expected 17 got %c", x.X) | 621 t.Errorf("expected 17 got %c", x.X) |
516 } | 622 } |
517 } | 623 } |
518 | 624 |
519 func TestGobEncoderIgnoreNonStructField(t *testing.T) { | 625 func TestGobEncoderIgnoreNonStructField(t *testing.T) { |
520 b := new(bytes.Buffer) | 626 b := new(bytes.Buffer) |
521 // First a field that's a structure. | 627 // First a field that's a structure. |
522 enc := NewEncoder(b) | 628 enc := NewEncoder(b) |
523 gobber := Gobber(23) | 629 gobber := Gobber(23) |
524 » err := enc.Encode(GobTest3{17, &gobber}) | 630 » bgobber := BinaryGobber(24) |
| 631 » tgobber := TextGobber(25) |
| 632 » err := enc.Encode(GobTest3{17, &gobber, &bgobber, &tgobber}) |
525 if err != nil { | 633 if err != nil { |
526 t.Fatal("encode error:", err) | 634 t.Fatal("encode error:", err) |
527 } | 635 } |
528 dec := NewDecoder(b) | 636 dec := NewDecoder(b) |
529 x := new(GobTestIgnoreEncoder) | 637 x := new(GobTestIgnoreEncoder) |
530 err = dec.Decode(x) | 638 err = dec.Decode(x) |
531 if err != nil { | 639 if err != nil { |
532 t.Fatal("decode error:", err) | 640 t.Fatal("decode error:", err) |
533 } | 641 } |
534 if x.X != 17 { | 642 if x.X != 17 { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 dec := NewDecoder(b) | 760 dec := NewDecoder(b) |
653 err2 := fmt.Errorf("foo") | 761 err2 := fmt.Errorf("foo") |
654 err = dec.Decode(&err2) | 762 err = dec.Decode(&err2) |
655 if err != nil { | 763 if err != nil { |
656 t.Fatal("decode:", err) | 764 t.Fatal("decode:", err) |
657 } | 765 } |
658 if err2 != nil { | 766 if err2 != nil { |
659 t.Fatalf("expected nil, got %v", err2) | 767 t.Fatalf("expected nil, got %v", err2) |
660 } | 768 } |
661 } | 769 } |
LEFT | RIGHT |