OSDN Git Service

Update to current version of Go library.
[pf3gnuchains/gcc-fork.git] / libgo / go / gob / type.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package gob
6
7 import (
8         "fmt"
9         "os"
10         "reflect"
11         "sync"
12         "unicode"
13         "utf8"
14 )
15
16 // userTypeInfo stores the information associated with a type the user has handed
17 // to the package.  It's computed once and stored in a map keyed by reflection
18 // type.
19 type userTypeInfo struct {
20         user         reflect.Type // the type the user handed us
21         base         reflect.Type // the base type after all indirections
22         indir        int          // number of indirections to reach the base type
23         isGobEncoder bool         // does the type implement GobEncoder?
24         isGobDecoder bool         // does the type implement GobDecoder?
25         encIndir     int8         // number of indirections to reach the receiver type; may be negative
26         decIndir     int8         // number of indirections to reach the receiver type; may be negative
27 }
28
29 var (
30         // Protected by an RWMutex because we read it a lot and write
31         // it only when we see a new type, typically when compiling.
32         userTypeLock  sync.RWMutex
33         userTypeCache = make(map[reflect.Type]*userTypeInfo)
34 )
35
36 // validType returns, and saves, the information associated with user-provided type rt.
37 // If the user type is not valid, err will be non-nil.  To be used when the error handler
38 // is not set up.
39 func validUserType(rt reflect.Type) (ut *userTypeInfo, err os.Error) {
40         userTypeLock.RLock()
41         ut = userTypeCache[rt]
42         userTypeLock.RUnlock()
43         if ut != nil {
44                 return
45         }
46         // Now set the value under the write lock.
47         userTypeLock.Lock()
48         defer userTypeLock.Unlock()
49         if ut = userTypeCache[rt]; ut != nil {
50                 // Lost the race; not a problem.
51                 return
52         }
53         ut = new(userTypeInfo)
54         ut.base = rt
55         ut.user = rt
56         // A type that is just a cycle of pointers (such as type T *T) cannot
57         // be represented in gobs, which need some concrete data.  We use a
58         // cycle detection algorithm from Knuth, Vol 2, Section 3.1, Ex 6,
59         // pp 539-540.  As we step through indirections, run another type at
60         // half speed. If they meet up, there's a cycle.
61         slowpoke := ut.base // walks half as fast as ut.base
62         for {
63                 pt, ok := ut.base.(*reflect.PtrType)
64                 if !ok {
65                         break
66                 }
67                 ut.base = pt.Elem()
68                 if ut.base == slowpoke { // ut.base lapped slowpoke
69                         // recursive pointer type.
70                         return nil, os.ErrorString("can't represent recursive pointer type " + ut.base.String())
71                 }
72                 if ut.indir%2 == 0 {
73                         slowpoke = slowpoke.(*reflect.PtrType).Elem()
74                 }
75                 ut.indir++
76         }
77         ut.isGobEncoder, ut.encIndir = implementsInterface(ut.user, gobEncoderCheck)
78         ut.isGobDecoder, ut.decIndir = implementsInterface(ut.user, gobDecoderCheck)
79         userTypeCache[rt] = ut
80         return
81 }
82
83 const (
84         gobEncodeMethodName = "GobEncode"
85         gobDecodeMethodName = "GobDecode"
86 )
87
88 // implements returns whether the type implements the interface, as encoded
89 // in the check function.
90 func implements(typ reflect.Type, check func(typ reflect.Type) bool) bool {
91         if typ.NumMethod() == 0 { // avoid allocations etc. unless there's some chance
92                 return false
93         }
94         return check(typ)
95 }
96
97 // gobEncoderCheck makes the type assertion a boolean function.
98 func gobEncoderCheck(typ reflect.Type) bool {
99         _, ok := reflect.MakeZero(typ).Interface().(GobEncoder)
100         return ok
101 }
102
103 // gobDecoderCheck makes the type assertion a boolean function.
104 func gobDecoderCheck(typ reflect.Type) bool {
105         _, ok := reflect.MakeZero(typ).Interface().(GobDecoder)
106         return ok
107 }
108
109 // implementsInterface reports whether the type implements the
110 // interface. (The actual check is done through the provided function.)
111 // It also returns the number of indirections required to get to the
112 // implementation.
113 func implementsInterface(typ reflect.Type, check func(typ reflect.Type) bool) (success bool, indir int8) {
114         if typ == nil {
115                 return
116         }
117         rt := typ
118         // The type might be a pointer and we need to keep
119         // dereferencing to the base type until we find an implementation.
120         for {
121                 if implements(rt, check) {
122                         return true, indir
123                 }
124                 if p, ok := rt.(*reflect.PtrType); ok {
125                         indir++
126                         if indir > 100 { // insane number of indirections
127                                 return false, 0
128                         }
129                         rt = p.Elem()
130                         continue
131                 }
132                 break
133         }
134         // No luck yet, but if this is a base type (non-pointer), the pointer might satisfy.
135         if _, ok := typ.(*reflect.PtrType); !ok {
136                 // Not a pointer, but does the pointer work?
137                 if implements(reflect.PtrTo(typ), check) {
138                         return true, -1
139                 }
140         }
141         return false, 0
142 }
143
144 // userType returns, and saves, the information associated with user-provided type rt.
145 // If the user type is not valid, it calls error.
146 func userType(rt reflect.Type) *userTypeInfo {
147         ut, err := validUserType(rt)
148         if err != nil {
149                 error(err)
150         }
151         return ut
152 }
153 // A typeId represents a gob Type as an integer that can be passed on the wire.
154 // Internally, typeIds are used as keys to a map to recover the underlying type info.
155 type typeId int32
156
157 var nextId typeId       // incremented for each new type we build
158 var typeLock sync.Mutex // set while building a type
159 const firstUserId = 64  // lowest id number granted to user
160
161 type gobType interface {
162         id() typeId
163         setId(id typeId)
164         name() string
165         string() string // not public; only for debugging
166         safeString(seen map[typeId]bool) string
167 }
168
169 var types = make(map[reflect.Type]gobType)
170 var idToType = make(map[typeId]gobType)
171 var builtinIdToType map[typeId]gobType // set in init() after builtins are established
172
173 func setTypeId(typ gobType) {
174         nextId++
175         typ.setId(nextId)
176         idToType[nextId] = typ
177 }
178
179 func (t typeId) gobType() gobType {
180         if t == 0 {
181                 return nil
182         }
183         return idToType[t]
184 }
185
186 // string returns the string representation of the type associated with the typeId.
187 func (t typeId) string() string {
188         if t.gobType() == nil {
189                 return "<nil>"
190         }
191         return t.gobType().string()
192 }
193
194 // Name returns the name of the type associated with the typeId.
195 func (t typeId) name() string {
196         if t.gobType() == nil {
197                 return "<nil>"
198         }
199         return t.gobType().name()
200 }
201
202 // Common elements of all types.
203 type CommonType struct {
204         Name string
205         Id   typeId
206 }
207
208 func (t *CommonType) id() typeId { return t.Id }
209
210 func (t *CommonType) setId(id typeId) { t.Id = id }
211
212 func (t *CommonType) string() string { return t.Name }
213
214 func (t *CommonType) safeString(seen map[typeId]bool) string {
215         return t.Name
216 }
217
218 func (t *CommonType) name() string { return t.Name }
219
220 // Create and check predefined types
221 // The string for tBytes is "bytes" not "[]byte" to signify its specialness.
222
223 var (
224         // Primordial types, needed during initialization.
225         // Always passed as pointers so the interface{} type
226         // goes through without losing its interfaceness.
227         tBool      = bootstrapType("bool", (*bool)(nil), 1)
228         tInt       = bootstrapType("int", (*int)(nil), 2)
229         tUint      = bootstrapType("uint", (*uint)(nil), 3)
230         tFloat     = bootstrapType("float", (*float64)(nil), 4)
231         tBytes     = bootstrapType("bytes", (*[]byte)(nil), 5)
232         tString    = bootstrapType("string", (*string)(nil), 6)
233         tComplex   = bootstrapType("complex", (*complex128)(nil), 7)
234         tInterface = bootstrapType("interface", (*interface{})(nil), 8)
235         // Reserve some Ids for compatible expansion
236         tReserved7 = bootstrapType("_reserved1", (*struct{ r7 int })(nil), 9)
237         tReserved6 = bootstrapType("_reserved1", (*struct{ r6 int })(nil), 10)
238         tReserved5 = bootstrapType("_reserved1", (*struct{ r5 int })(nil), 11)
239         tReserved4 = bootstrapType("_reserved1", (*struct{ r4 int })(nil), 12)
240         tReserved3 = bootstrapType("_reserved1", (*struct{ r3 int })(nil), 13)
241         tReserved2 = bootstrapType("_reserved1", (*struct{ r2 int })(nil), 14)
242         tReserved1 = bootstrapType("_reserved1", (*struct{ r1 int })(nil), 15)
243 )
244
245 // Predefined because it's needed by the Decoder
246 var tWireType = mustGetTypeInfo(reflect.Typeof(wireType{})).id
247 var wireTypeUserInfo *userTypeInfo // userTypeInfo of (*wireType)
248
249 func init() {
250         // Some magic numbers to make sure there are no surprises.
251         checkId(16, tWireType)
252         checkId(17, mustGetTypeInfo(reflect.Typeof(arrayType{})).id)
253         checkId(18, mustGetTypeInfo(reflect.Typeof(CommonType{})).id)
254         checkId(19, mustGetTypeInfo(reflect.Typeof(sliceType{})).id)
255         checkId(20, mustGetTypeInfo(reflect.Typeof(structType{})).id)
256         checkId(21, mustGetTypeInfo(reflect.Typeof(fieldType{})).id)
257         checkId(23, mustGetTypeInfo(reflect.Typeof(mapType{})).id)
258
259         builtinIdToType = make(map[typeId]gobType)
260         for k, v := range idToType {
261                 builtinIdToType[k] = v
262         }
263
264         // Move the id space upwards to allow for growth in the predefined world
265         // without breaking existing files.
266         if nextId > firstUserId {
267                 panic(fmt.Sprintln("nextId too large:", nextId))
268         }
269         nextId = firstUserId
270         registerBasics()
271         wireTypeUserInfo = userType(reflect.Typeof((*wireType)(nil)))
272 }
273
274 // Array type
275 type arrayType struct {
276         CommonType
277         Elem typeId
278         Len  int
279 }
280
281 func newArrayType(name string) *arrayType {
282         a := &arrayType{CommonType{Name: name}, 0, 0}
283         return a
284 }
285
286 func (a *arrayType) init(elem gobType, len int) {
287         // Set our type id before evaluating the element's, in case it's our own.
288         setTypeId(a)
289         a.Elem = elem.id()
290         a.Len = len
291 }
292
293 func (a *arrayType) safeString(seen map[typeId]bool) string {
294         if seen[a.Id] {
295                 return a.Name
296         }
297         seen[a.Id] = true
298         return fmt.Sprintf("[%d]%s", a.Len, a.Elem.gobType().safeString(seen))
299 }
300
301 func (a *arrayType) string() string { return a.safeString(make(map[typeId]bool)) }
302
303 // GobEncoder type (something that implements the GobEncoder interface)
304 type gobEncoderType struct {
305         CommonType
306 }
307
308 func newGobEncoderType(name string) *gobEncoderType {
309         g := &gobEncoderType{CommonType{Name: name}}
310         setTypeId(g)
311         return g
312 }
313
314 func (g *gobEncoderType) safeString(seen map[typeId]bool) string {
315         return g.Name
316 }
317
318 func (g *gobEncoderType) string() string { return g.Name }
319
320 // Map type
321 type mapType struct {
322         CommonType
323         Key  typeId
324         Elem typeId
325 }
326
327 func newMapType(name string) *mapType {
328         m := &mapType{CommonType{Name: name}, 0, 0}
329         return m
330 }
331
332 func (m *mapType) init(key, elem gobType) {
333         // Set our type id before evaluating the element's, in case it's our own.
334         setTypeId(m)
335         m.Key = key.id()
336         m.Elem = elem.id()
337 }
338
339 func (m *mapType) safeString(seen map[typeId]bool) string {
340         if seen[m.Id] {
341                 return m.Name
342         }
343         seen[m.Id] = true
344         key := m.Key.gobType().safeString(seen)
345         elem := m.Elem.gobType().safeString(seen)
346         return fmt.Sprintf("map[%s]%s", key, elem)
347 }
348
349 func (m *mapType) string() string { return m.safeString(make(map[typeId]bool)) }
350
351 // Slice type
352 type sliceType struct {
353         CommonType
354         Elem typeId
355 }
356
357 func newSliceType(name string) *sliceType {
358         s := &sliceType{CommonType{Name: name}, 0}
359         return s
360 }
361
362 func (s *sliceType) init(elem gobType) {
363         // Set our type id before evaluating the element's, in case it's our own.
364         setTypeId(s)
365         s.Elem = elem.id()
366 }
367
368 func (s *sliceType) safeString(seen map[typeId]bool) string {
369         if seen[s.Id] {
370                 return s.Name
371         }
372         seen[s.Id] = true
373         return fmt.Sprintf("[]%s", s.Elem.gobType().safeString(seen))
374 }
375
376 func (s *sliceType) string() string { return s.safeString(make(map[typeId]bool)) }
377
378 // Struct type
379 type fieldType struct {
380         Name string
381         Id   typeId
382 }
383
384 type structType struct {
385         CommonType
386         Field []*fieldType
387 }
388
389 func (s *structType) safeString(seen map[typeId]bool) string {
390         if s == nil {
391                 return "<nil>"
392         }
393         if _, ok := seen[s.Id]; ok {
394                 return s.Name
395         }
396         seen[s.Id] = true
397         str := s.Name + " = struct { "
398         for _, f := range s.Field {
399                 str += fmt.Sprintf("%s %s; ", f.Name, f.Id.gobType().safeString(seen))
400         }
401         str += "}"
402         return str
403 }
404
405 func (s *structType) string() string { return s.safeString(make(map[typeId]bool)) }
406
407 func newStructType(name string) *structType {
408         s := &structType{CommonType{Name: name}, nil}
409         // For historical reasons we set the id here rather than init.
410         // Se the comment in newTypeObject for details.
411         setTypeId(s)
412         return s
413 }
414
415 // newTypeObject allocates a gobType for the reflection type rt.
416 // Unless ut represents a GobEncoder, rt should be the base type
417 // of ut.
418 // This is only called from the encoding side. The decoding side
419 // works through typeIds and userTypeInfos alone.
420 func newTypeObject(name string, ut *userTypeInfo, rt reflect.Type) (gobType, os.Error) {
421         // Does this type implement GobEncoder?
422         if ut.isGobEncoder {
423                 return newGobEncoderType(name), nil
424         }
425         var err os.Error
426         var type0, type1 gobType
427         defer func() {
428                 if err != nil {
429                         types[rt] = nil, false
430                 }
431         }()
432         // Install the top-level type before the subtypes (e.g. struct before
433         // fields) so recursive types can be constructed safely.
434         switch t := rt.(type) {
435         // All basic types are easy: they are predefined.
436         case *reflect.BoolType:
437                 return tBool.gobType(), nil
438
439         case *reflect.IntType:
440                 return tInt.gobType(), nil
441
442         case *reflect.UintType:
443                 return tUint.gobType(), nil
444
445         case *reflect.FloatType:
446                 return tFloat.gobType(), nil
447
448         case *reflect.ComplexType:
449                 return tComplex.gobType(), nil
450
451         case *reflect.StringType:
452                 return tString.gobType(), nil
453
454         case *reflect.InterfaceType:
455                 return tInterface.gobType(), nil
456
457         case *reflect.ArrayType:
458                 at := newArrayType(name)
459                 types[rt] = at
460                 type0, err = getBaseType("", t.Elem())
461                 if err != nil {
462                         return nil, err
463                 }
464                 // Historical aside:
465                 // For arrays, maps, and slices, we set the type id after the elements
466                 // are constructed. This is to retain the order of type id allocation after
467                 // a fix made to handle recursive types, which changed the order in
468                 // which types are built.  Delaying the setting in this way preserves
469                 // type ids while allowing recursive types to be described. Structs,
470                 // done below, were already handling recursion correctly so they
471                 // assign the top-level id before those of the field.
472                 at.init(type0, t.Len())
473                 return at, nil
474
475         case *reflect.MapType:
476                 mt := newMapType(name)
477                 types[rt] = mt
478                 type0, err = getBaseType("", t.Key())
479                 if err != nil {
480                         return nil, err
481                 }
482                 type1, err = getBaseType("", t.Elem())
483                 if err != nil {
484                         return nil, err
485                 }
486                 mt.init(type0, type1)
487                 return mt, nil
488
489         case *reflect.SliceType:
490                 // []byte == []uint8 is a special case
491                 if t.Elem().Kind() == reflect.Uint8 {
492                         return tBytes.gobType(), nil
493                 }
494                 st := newSliceType(name)
495                 types[rt] = st
496                 type0, err = getBaseType(t.Elem().Name(), t.Elem())
497                 if err != nil {
498                         return nil, err
499                 }
500                 st.init(type0)
501                 return st, nil
502
503         case *reflect.StructType:
504                 st := newStructType(name)
505                 types[rt] = st
506                 idToType[st.id()] = st
507                 for i := 0; i < t.NumField(); i++ {
508                         f := t.Field(i)
509                         if !isExported(f.Name) {
510                                 continue
511                         }
512                         typ := userType(f.Type).base
513                         tname := typ.Name()
514                         if tname == "" {
515                                 t := userType(f.Type).base
516                                 tname = t.String()
517                         }
518                         gt, err := getBaseType(tname, f.Type)
519                         if err != nil {
520                                 return nil, err
521                         }
522                         st.Field = append(st.Field, &fieldType{f.Name, gt.id()})
523                 }
524                 return st, nil
525
526         default:
527                 return nil, os.ErrorString("gob NewTypeObject can't handle type: " + rt.String())
528         }
529         return nil, nil
530 }
531
532 // isExported reports whether this is an exported - upper case - name.
533 func isExported(name string) bool {
534         rune, _ := utf8.DecodeRuneInString(name)
535         return unicode.IsUpper(rune)
536 }
537
538 // getBaseType returns the Gob type describing the given reflect.Type's base type.
539 // typeLock must be held.
540 func getBaseType(name string, rt reflect.Type) (gobType, os.Error) {
541         ut := userType(rt)
542         return getType(name, ut, ut.base)
543 }
544
545 // getType returns the Gob type describing the given reflect.Type.
546 // Should be called only when handling GobEncoders/Decoders,
547 // which may be pointers.  All other types are handled through the
548 //  base type, never a pointer.
549 // typeLock must be held.
550 func getType(name string, ut *userTypeInfo, rt reflect.Type) (gobType, os.Error) {
551         typ, present := types[rt]
552         if present {
553                 return typ, nil
554         }
555         typ, err := newTypeObject(name, ut, rt)
556         if err == nil {
557                 types[rt] = typ
558         }
559         return typ, err
560 }
561
562 func checkId(want, got typeId) {
563         if want != got {
564                 fmt.Fprintf(os.Stderr, "checkId: %d should be %d\n", int(want), int(got))
565                 panic("bootstrap type wrong id: " + got.name() + " " + got.string() + " not " + want.string())
566         }
567 }
568
569 // used for building the basic types; called only from init().  the incoming
570 // interface always refers to a pointer.
571 func bootstrapType(name string, e interface{}, expect typeId) typeId {
572         rt := reflect.Typeof(e).(*reflect.PtrType).Elem()
573         _, present := types[rt]
574         if present {
575                 panic("bootstrap type already present: " + name + ", " + rt.String())
576         }
577         typ := &CommonType{Name: name}
578         types[rt] = typ
579         setTypeId(typ)
580         checkId(expect, nextId)
581         userType(rt) // might as well cache it now
582         return nextId
583 }
584
585 // Representation of the information we send and receive about this type.
586 // Each value we send is preceded by its type definition: an encoded int.
587 // However, the very first time we send the value, we first send the pair
588 // (-id, wireType).
589 // For bootstrapping purposes, we assume that the recipient knows how
590 // to decode a wireType; it is exactly the wireType struct here, interpreted
591 // using the gob rules for sending a structure, except that we assume the
592 // ids for wireType and structType etc. are known.  The relevant pieces
593 // are built in encode.go's init() function.
594 // To maintain binary compatibility, if you extend this type, always put
595 // the new fields last.
596 type wireType struct {
597         ArrayT      *arrayType
598         SliceT      *sliceType
599         StructT     *structType
600         MapT        *mapType
601         GobEncoderT *gobEncoderType
602 }
603
604 func (w *wireType) string() string {
605         const unknown = "unknown type"
606         if w == nil {
607                 return unknown
608         }
609         switch {
610         case w.ArrayT != nil:
611                 return w.ArrayT.Name
612         case w.SliceT != nil:
613                 return w.SliceT.Name
614         case w.StructT != nil:
615                 return w.StructT.Name
616         case w.MapT != nil:
617                 return w.MapT.Name
618         case w.GobEncoderT != nil:
619                 return w.GobEncoderT.Name
620         }
621         return unknown
622 }
623
624 type typeInfo struct {
625         id      typeId
626         encoder *encEngine
627         wire    *wireType
628 }
629
630 var typeInfoMap = make(map[reflect.Type]*typeInfo) // protected by typeLock
631
632 // typeLock must be held.
633 func getTypeInfo(ut *userTypeInfo) (*typeInfo, os.Error) {
634         rt := ut.base
635         if ut.isGobEncoder {
636                 // We want the user type, not the base type.
637                 rt = ut.user
638         }
639         info, ok := typeInfoMap[rt]
640         if ok {
641                 return info, nil
642         }
643         info = new(typeInfo)
644         gt, err := getBaseType(rt.Name(), rt)
645         if err != nil {
646                 return nil, err
647         }
648         info.id = gt.id()
649
650         if ut.isGobEncoder {
651                 userType, err := getType(rt.Name(), ut, rt)
652                 if err != nil {
653                         return nil, err
654                 }
655                 info.wire = &wireType{GobEncoderT: userType.id().gobType().(*gobEncoderType)}
656                 typeInfoMap[ut.user] = info
657                 return info, nil
658         }
659
660         t := info.id.gobType()
661         switch typ := rt.(type) {
662         case *reflect.ArrayType:
663                 info.wire = &wireType{ArrayT: t.(*arrayType)}
664         case *reflect.MapType:
665                 info.wire = &wireType{MapT: t.(*mapType)}
666         case *reflect.SliceType:
667                 // []byte == []uint8 is a special case handled separately
668                 if typ.Elem().Kind() != reflect.Uint8 {
669                         info.wire = &wireType{SliceT: t.(*sliceType)}
670                 }
671         case *reflect.StructType:
672                 info.wire = &wireType{StructT: t.(*structType)}
673         }
674         typeInfoMap[rt] = info
675         return info, nil
676 }
677
678 // Called only when a panic is acceptable and unexpected.
679 func mustGetTypeInfo(rt reflect.Type) *typeInfo {
680         t, err := getTypeInfo(userType(rt))
681         if err != nil {
682                 panic("getTypeInfo: " + err.String())
683         }
684         return t
685 }
686
687 // GobEncoder is the interface describing data that provides its own
688 // representation for encoding values for transmission to a GobDecoder.
689 // A type that implements GobEncoder and GobDecoder has complete
690 // control over the representation of its data and may therefore
691 // contain things such as private fields, channels, and functions,
692 // which are not usually transmissable in gob streams.
693 //
694 // Note: Since gobs can be stored permanently, It is good design
695 // to guarantee the encoding used by a GobEncoder is stable as the
696 // software evolves.  For instance, it might make sense for GobEncode
697 // to include a version number in the encoding.
698 type GobEncoder interface {
699         // GobEncode returns a byte slice representing the encoding of the
700         // receiver for transmission to a GobDecoder, usually of the same
701         // concrete type.
702         GobEncode() ([]byte, os.Error)
703 }
704
705 // GobDecoder is the interface describing data that provides its own
706 // routine for decoding transmitted values sent by a GobEncoder.
707 type GobDecoder interface {
708         // GobDecode overwrites the receiver, which must be a pointer,
709         // with the value represented by the byte slice, which was written
710         // by GobEncode, usually for the same concrete type.
711         GobDecode([]byte) os.Error
712 }
713
714 var (
715         nameToConcreteType = make(map[string]reflect.Type)
716         concreteTypeToName = make(map[reflect.Type]string)
717 )
718
719 // RegisterName is like Register but uses the provided name rather than the
720 // type's default.
721 func RegisterName(name string, value interface{}) {
722         if name == "" {
723                 // reserved for nil
724                 panic("attempt to register empty name")
725         }
726         base := userType(reflect.Typeof(value)).base
727         // Check for incompatible duplicates.
728         if t, ok := nameToConcreteType[name]; ok && t != base {
729                 panic("gob: registering duplicate types for " + name)
730         }
731         if n, ok := concreteTypeToName[base]; ok && n != name {
732                 panic("gob: registering duplicate names for " + base.String())
733         }
734         // Store the name and type provided by the user....
735         nameToConcreteType[name] = reflect.Typeof(value)
736         // but the flattened type in the type table, since that's what decode needs.
737         concreteTypeToName[base] = name
738 }
739
740 // Register records a type, identified by a value for that type, under its
741 // internal type name.  That name will identify the concrete type of a value
742 // sent or received as an interface variable.  Only types that will be
743 // transferred as implementations of interface values need to be registered.
744 // Expecting to be used only during initialization, it panics if the mapping
745 // between types and names is not a bijection.
746 func Register(value interface{}) {
747         // Default to printed representation for unnamed types
748         rt := reflect.Typeof(value)
749         name := rt.String()
750
751         // But for named types (or pointers to them), qualify with import path.
752         // Dereference one pointer looking for a named type.
753         star := ""
754         if rt.Name() == "" {
755                 if pt, ok := rt.(*reflect.PtrType); ok {
756                         star = "*"
757                         rt = pt
758                 }
759         }
760         if rt.Name() != "" {
761                 if rt.PkgPath() == "" {
762                         name = star + rt.Name()
763                 } else {
764                         name = star + rt.PkgPath() + "." + rt.Name()
765                 }
766         }
767
768         RegisterName(name, value)
769 }
770
771 func registerBasics() {
772         Register(int(0))
773         Register(int8(0))
774         Register(int16(0))
775         Register(int32(0))
776         Register(int64(0))
777         Register(uint(0))
778         Register(uint8(0))
779         Register(uint16(0))
780         Register(uint32(0))
781         Register(uint64(0))
782         Register(float32(0))
783         Register(float64(0))
784         Register(complex64(0i))
785         Register(complex128(0i))
786         Register(false)
787         Register("")
788         Register([]byte(nil))
789 }