@@ -7,6 +7,7 @@ package gob
7
7
import (
8
8
"bufio"
9
9
"errors"
10
+ "fmt"
10
11
"io"
11
12
"reflect"
12
13
"sync"
@@ -25,15 +26,16 @@ const tooBig = (1 << 30) << (^uint(0) >> 62)
25
26
// and its limits are not configurable. Take caution when decoding gob data
26
27
// from untrusted sources.
27
28
type Decoder struct {
28
- mutex sync.Mutex // each item must be received atomically
29
- r io.Reader // source of the data
30
- buf decBuffer // buffer for more efficient i/o from r
31
- wireType map [typeId ]* wireType // map from remote ID to local description
32
- decoderCache map [reflect.Type ]map [typeId ]* * decEngine // cache of compiled engines
33
- ignorerCache map [typeId ]* * decEngine // ditto for ignored objects
34
- freeList * decoderState // list of free decoderStates; avoids reallocation
35
- countBuf []byte // used for decoding integers while parsing messages
36
- err error
29
+ mutex sync.Mutex // each item must be received atomically
30
+ r io.Reader // source of the data
31
+ buf decBuffer // buffer for more efficient i/o from r
32
+ wireType map [typeId ]* wireType // map from remote ID to local description
33
+ decoderCache map [reflect.Type ]map [typeId ]* * decEngine // cache of compiled engines
34
+ ignorerCache map [typeId ]* * decEngine // ditto for ignored objects
35
+ freeList * decoderState // list of free decoderStates; avoids reallocation
36
+ countBuf []byte // used for decoding integers while parsing messages
37
+ err error
38
+ nameToConcreteType * sync.Map // map[string]reflect.Type
37
39
}
38
40
39
41
// NewDecoder returns a new decoder that reads from the io.Reader.
@@ -54,6 +56,27 @@ func NewDecoder(r io.Reader) *Decoder {
54
56
return dec
55
57
}
56
58
59
+ func (dec * Decoder ) RegisterName (name string , value interface {}) {
60
+ if name == "" {
61
+ // reserved for nil
62
+ panic ("attempt to register empty name" )
63
+ }
64
+
65
+ if dec .nameToConcreteType == nil {
66
+ dec .nameToConcreteType = & sync.Map {}
67
+ }
68
+
69
+ ut := userType (reflect .TypeOf (value ))
70
+
71
+ // Check for incompatible duplicates. The name must refer to the
72
+ // same user type, and vice versa.
73
+
74
+ // Store the name and type provided by the user....
75
+ if t , dup := dec .nameToConcreteType .LoadOrStore (name , reflect .TypeOf (value )); dup && t != ut .user {
76
+ panic (fmt .Sprintf ("gob: registering duplicate types for %q: %s != %s" , name , t , ut .user ))
77
+ }
78
+ }
79
+
57
80
// recvType loads the definition of a type.
58
81
func (dec * Decoder ) recvType (id typeId ) {
59
82
// Have we already seen this type? That's an error
0 commit comments