1
2
3
4
5 package gob
6
7 import (
8 "encoding"
9 "errors"
10 "fmt"
11 "os"
12 "reflect"
13 "sync"
14 "sync/atomic"
15 "unicode"
16 "unicode/utf8"
17 )
18
19
20
21
22 type userTypeInfo struct {
23 user reflect.Type
24 base reflect.Type
25 indir int
26 externalEnc int
27 externalDec int
28 encIndir int8
29 decIndir int8
30 }
31
32
33 const (
34 xGob = 1 + iota
35 xBinary
36 xText
37 )
38
39 var userTypeCache sync.Map
40
41
42
43
44 func validUserType(rt reflect.Type) (*userTypeInfo, error) {
45 if ui, ok := userTypeCache.Load(rt); ok {
46 return ui.(*userTypeInfo), nil
47 }
48
49
50
51
52
53 ut := new(userTypeInfo)
54 ut.base = rt
55 ut.user = rt
56
57
58
59
60
61 slowpoke := ut.base
62 for {
63 pt := ut.base
64 if pt.Kind() != reflect.Ptr {
65 break
66 }
67 ut.base = pt.Elem()
68 if ut.base == slowpoke {
69
70 return nil, errors.New("can't represent recursive pointer type " + ut.base.String())
71 }
72 if ut.indir%2 == 0 {
73 slowpoke = slowpoke.Elem()
74 }
75 ut.indir++
76 }
77
78 if ok, indir := implementsInterface(ut.user, gobEncoderInterfaceType); ok {
79 ut.externalEnc, ut.encIndir = xGob, indir
80 } else if ok, indir := implementsInterface(ut.user, binaryMarshalerInterfaceType); ok {
81 ut.externalEnc, ut.encIndir = xBinary, indir
82 }
83
84
85
86
87
88
89
90 if ok, indir := implementsInterface(ut.user, gobDecoderInterfaceType); ok {
91 ut.externalDec, ut.decIndir = xGob, indir
92 } else if ok, indir := implementsInterface(ut.user, binaryUnmarshalerInterfaceType); ok {
93 ut.externalDec, ut.decIndir = xBinary, indir
94 }
95
96
97
98
99
100
101 ui, _ := userTypeCache.LoadOrStore(rt, ut)
102 return ui.(*userTypeInfo), nil
103 }
104
105 var (
106 gobEncoderInterfaceType = reflect.TypeOf((*GobEncoder)(nil)).Elem()
107 gobDecoderInterfaceType = reflect.TypeOf((*GobDecoder)(nil)).Elem()
108 binaryMarshalerInterfaceType = reflect.TypeOf((*encoding.BinaryMarshaler)(nil)).Elem()
109 binaryUnmarshalerInterfaceType = reflect.TypeOf((*encoding.BinaryUnmarshaler)(nil)).Elem()
110 textMarshalerInterfaceType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
111 textUnmarshalerInterfaceType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
112 )
113
114
115
116
117
118 func implementsInterface(typ, gobEncDecType reflect.Type) (success bool, indir int8) {
119 if typ == nil {
120 return
121 }
122 rt := typ
123
124
125 for {
126 if rt.Implements(gobEncDecType) {
127 return true, indir
128 }
129 if p := rt; p.Kind() == reflect.Ptr {
130 indir++
131 if indir > 100 {
132 return false, 0
133 }
134 rt = p.Elem()
135 continue
136 }
137 break
138 }
139
140 if typ.Kind() != reflect.Ptr {
141
142 if reflect.PtrTo(typ).Implements(gobEncDecType) {
143 return true, -1
144 }
145 }
146 return false, 0
147 }
148
149
150
151 func userType(rt reflect.Type) *userTypeInfo {
152 ut, err := validUserType(rt)
153 if err != nil {
154 error_(err)
155 }
156 return ut
157 }
158
159
160
161 type typeId int32
162
163 var nextId typeId
164 var typeLock sync.Mutex
165 const firstUserId = 64
166
167 type gobType interface {
168 id() typeId
169 setId(id typeId)
170 name() string
171 string() string
172 safeString(seen map[typeId]bool) string
173 }
174
175 var types = make(map[reflect.Type]gobType)
176 var idToType = make(map[typeId]gobType)
177 var builtinIdToType map[typeId]gobType
178
179 func setTypeId(typ gobType) {
180
181 if typ.id() != 0 {
182 return
183 }
184 nextId++
185 typ.setId(nextId)
186 idToType[nextId] = typ
187 }
188
189 func (t typeId) gobType() gobType {
190 if t == 0 {
191 return nil
192 }
193 return idToType[t]
194 }
195
196
197 func (t typeId) string() string {
198 if t.gobType() == nil {
199 return "<nil>"
200 }
201 return t.gobType().string()
202 }
203
204
205 func (t typeId) name() string {
206 if t.gobType() == nil {
207 return "<nil>"
208 }
209 return t.gobType().name()
210 }
211
212
213
214
215
216 type CommonType struct {
217 Name string
218 Id typeId
219 }
220
221 func (t *CommonType) id() typeId { return t.Id }
222
223 func (t *CommonType) setId(id typeId) { t.Id = id }
224
225 func (t *CommonType) string() string { return t.Name }
226
227 func (t *CommonType) safeString(seen map[typeId]bool) string {
228 return t.Name
229 }
230
231 func (t *CommonType) name() string { return t.Name }
232
233
234
235
236 var (
237
238
239
240 tBool = bootstrapType("bool", (*bool)(nil), 1)
241 tInt = bootstrapType("int", (*int)(nil), 2)
242 tUint = bootstrapType("uint", (*uint)(nil), 3)
243 tFloat = bootstrapType("float", (*float64)(nil), 4)
244 tBytes = bootstrapType("bytes", (*[]byte)(nil), 5)
245 tString = bootstrapType("string", (*string)(nil), 6)
246 tComplex = bootstrapType("complex", (*complex128)(nil), 7)
247 tInterface = bootstrapType("interface", (*interface{})(nil), 8)
248
249 tReserved7 = bootstrapType("_reserved1", (*struct{ r7 int })(nil), 9)
250 tReserved6 = bootstrapType("_reserved1", (*struct{ r6 int })(nil), 10)
251 tReserved5 = bootstrapType("_reserved1", (*struct{ r5 int })(nil), 11)
252 tReserved4 = bootstrapType("_reserved1", (*struct{ r4 int })(nil), 12)
253 tReserved3 = bootstrapType("_reserved1", (*struct{ r3 int })(nil), 13)
254 tReserved2 = bootstrapType("_reserved1", (*struct{ r2 int })(nil), 14)
255 tReserved1 = bootstrapType("_reserved1", (*struct{ r1 int })(nil), 15)
256 )
257
258
259 var tWireType = mustGetTypeInfo(reflect.TypeOf(wireType{})).id
260 var wireTypeUserInfo *userTypeInfo
261
262 func init() {
263
264 checkId(16, tWireType)
265 checkId(17, mustGetTypeInfo(reflect.TypeOf(arrayType{})).id)
266 checkId(18, mustGetTypeInfo(reflect.TypeOf(CommonType{})).id)
267 checkId(19, mustGetTypeInfo(reflect.TypeOf(sliceType{})).id)
268 checkId(20, mustGetTypeInfo(reflect.TypeOf(structType{})).id)
269 checkId(21, mustGetTypeInfo(reflect.TypeOf(fieldType{})).id)
270 checkId(23, mustGetTypeInfo(reflect.TypeOf(mapType{})).id)
271
272 builtinIdToType = make(map[typeId]gobType)
273 for k, v := range idToType {
274 builtinIdToType[k] = v
275 }
276
277
278
279 if nextId > firstUserId {
280 panic(fmt.Sprintln("nextId too large:", nextId))
281 }
282 nextId = firstUserId
283 registerBasics()
284 wireTypeUserInfo = userType(reflect.TypeOf((*wireType)(nil)))
285 }
286
287
288 type arrayType struct {
289 CommonType
290 Elem typeId
291 Len int
292 }
293
294 func newArrayType(name string) *arrayType {
295 a := &arrayType{CommonType{Name: name}, 0, 0}
296 return a
297 }
298
299 func (a *arrayType) init(elem gobType, len int) {
300
301 setTypeId(a)
302 a.Elem = elem.id()
303 a.Len = len
304 }
305
306 func (a *arrayType) safeString(seen map[typeId]bool) string {
307 if seen[a.Id] {
308 return a.Name
309 }
310 seen[a.Id] = true
311 return fmt.Sprintf("[%d]%s", a.Len, a.Elem.gobType().safeString(seen))
312 }
313
314 func (a *arrayType) string() string { return a.safeString(make(map[typeId]bool)) }
315
316
317 type gobEncoderType struct {
318 CommonType
319 }
320
321 func newGobEncoderType(name string) *gobEncoderType {
322 g := &gobEncoderType{CommonType{Name: name}}
323 setTypeId(g)
324 return g
325 }
326
327 func (g *gobEncoderType) safeString(seen map[typeId]bool) string {
328 return g.Name
329 }
330
331 func (g *gobEncoderType) string() string { return g.Name }
332
333
334 type mapType struct {
335 CommonType
336 Key typeId
337 Elem typeId
338 }
339
340 func newMapType(name string) *mapType {
341 m := &mapType{CommonType{Name: name}, 0, 0}
342 return m
343 }
344
345 func (m *mapType) init(key, elem gobType) {
346
347 setTypeId(m)
348 m.Key = key.id()
349 m.Elem = elem.id()
350 }
351
352 func (m *mapType) safeString(seen map[typeId]bool) string {
353 if seen[m.Id] {
354 return m.Name
355 }
356 seen[m.Id] = true
357 key := m.Key.gobType().safeString(seen)
358 elem := m.Elem.gobType().safeString(seen)
359 return fmt.Sprintf("map[%s]%s", key, elem)
360 }
361
362 func (m *mapType) string() string { return m.safeString(make(map[typeId]bool)) }
363
364
365 type sliceType struct {
366 CommonType
367 Elem typeId
368 }
369
370 func newSliceType(name string) *sliceType {
371 s := &sliceType{CommonType{Name: name}, 0}
372 return s
373 }
374
375 func (s *sliceType) init(elem gobType) {
376
377 setTypeId(s)
378
379
380 if elem.id() == 0 {
381 setTypeId(elem)
382 }
383 s.Elem = elem.id()
384 }
385
386 func (s *sliceType) safeString(seen map[typeId]bool) string {
387 if seen[s.Id] {
388 return s.Name
389 }
390 seen[s.Id] = true
391 return fmt.Sprintf("[]%s", s.Elem.gobType().safeString(seen))
392 }
393
394 func (s *sliceType) string() string { return s.safeString(make(map[typeId]bool)) }
395
396
397 type fieldType struct {
398 Name string
399 Id typeId
400 }
401
402 type structType struct {
403 CommonType
404 Field []*fieldType
405 }
406
407 func (s *structType) safeString(seen map[typeId]bool) string {
408 if s == nil {
409 return "<nil>"
410 }
411 if _, ok := seen[s.Id]; ok {
412 return s.Name
413 }
414 seen[s.Id] = true
415 str := s.Name + " = struct { "
416 for _, f := range s.Field {
417 str += fmt.Sprintf("%s %s; ", f.Name, f.Id.gobType().safeString(seen))
418 }
419 str += "}"
420 return str
421 }
422
423 func (s *structType) string() string { return s.safeString(make(map[typeId]bool)) }
424
425 func newStructType(name string) *structType {
426 s := &structType{CommonType{Name: name}, nil}
427
428
429 setTypeId(s)
430 return s
431 }
432
433
434
435
436
437
438 func newTypeObject(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
439
440 if ut.externalEnc != 0 {
441 return newGobEncoderType(name), nil
442 }
443 var err error
444 var type0, type1 gobType
445 defer func() {
446 if err != nil {
447 delete(types, rt)
448 }
449 }()
450
451
452 switch t := rt; t.Kind() {
453
454 case reflect.Bool:
455 return tBool.gobType(), nil
456
457 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
458 return tInt.gobType(), nil
459
460 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
461 return tUint.gobType(), nil
462
463 case reflect.Float32, reflect.Float64:
464 return tFloat.gobType(), nil
465
466 case reflect.Complex64, reflect.Complex128:
467 return tComplex.gobType(), nil
468
469 case reflect.String:
470 return tString.gobType(), nil
471
472 case reflect.Interface:
473 return tInterface.gobType(), nil
474
475 case reflect.Array:
476 at := newArrayType(name)
477 types[rt] = at
478 type0, err = getBaseType("", t.Elem())
479 if err != nil {
480 return nil, err
481 }
482
483
484
485
486
487
488
489
490 at.init(type0, t.Len())
491 return at, nil
492
493 case reflect.Map:
494 mt := newMapType(name)
495 types[rt] = mt
496 type0, err = getBaseType("", t.Key())
497 if err != nil {
498 return nil, err
499 }
500 type1, err = getBaseType("", t.Elem())
501 if err != nil {
502 return nil, err
503 }
504 mt.init(type0, type1)
505 return mt, nil
506
507 case reflect.Slice:
508
509 if t.Elem().Kind() == reflect.Uint8 {
510 return tBytes.gobType(), nil
511 }
512 st := newSliceType(name)
513 types[rt] = st
514 type0, err = getBaseType(t.Elem().Name(), t.Elem())
515 if err != nil {
516 return nil, err
517 }
518 st.init(type0)
519 return st, nil
520
521 case reflect.Struct:
522 st := newStructType(name)
523 types[rt] = st
524 idToType[st.id()] = st
525 for i := 0; i < t.NumField(); i++ {
526 f := t.Field(i)
527 if !isSent(&f) {
528 continue
529 }
530 typ := userType(f.Type).base
531 tname := typ.Name()
532 if tname == "" {
533 t := userType(f.Type).base
534 tname = t.String()
535 }
536 gt, err := getBaseType(tname, f.Type)
537 if err != nil {
538 return nil, err
539 }
540
541
542
543
544 if gt.id() == 0 {
545 setTypeId(gt)
546 }
547 st.Field = append(st.Field, &fieldType{f.Name, gt.id()})
548 }
549 return st, nil
550
551 default:
552 return nil, errors.New("gob NewTypeObject can't handle type: " + rt.String())
553 }
554 }
555
556
557 func isExported(name string) bool {
558 rune, _ := utf8.DecodeRuneInString(name)
559 return unicode.IsUpper(rune)
560 }
561
562
563
564
565 func isSent(field *reflect.StructField) bool {
566 if !isExported(field.Name) {
567 return false
568 }
569
570
571 typ := field.Type
572 for typ.Kind() == reflect.Ptr {
573 typ = typ.Elem()
574 }
575 if typ.Kind() == reflect.Chan || typ.Kind() == reflect.Func {
576 return false
577 }
578 return true
579 }
580
581
582
583 func getBaseType(name string, rt reflect.Type) (gobType, error) {
584 ut := userType(rt)
585 return getType(name, ut, ut.base)
586 }
587
588
589
590
591
592
593 func getType(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
594 typ, present := types[rt]
595 if present {
596 return typ, nil
597 }
598 typ, err := newTypeObject(name, ut, rt)
599 if err == nil {
600 types[rt] = typ
601 }
602 return typ, err
603 }
604
605 func checkId(want, got typeId) {
606 if want != got {
607 fmt.Fprintf(os.Stderr, "checkId: %d should be %d\n", int(got), int(want))
608 panic("bootstrap type wrong id: " + got.name() + " " + got.string() + " not " + want.string())
609 }
610 }
611
612
613
614 func bootstrapType(name string, e interface{}, expect typeId) typeId {
615 rt := reflect.TypeOf(e).Elem()
616 _, present := types[rt]
617 if present {
618 panic("bootstrap type already present: " + name + ", " + rt.String())
619 }
620 typ := &CommonType{Name: name}
621 types[rt] = typ
622 setTypeId(typ)
623 checkId(expect, nextId)
624 userType(rt)
625 return nextId
626 }
627
628
629
630
631
632
633
634
635
636
637
638
639 type wireType struct {
640 ArrayT *arrayType
641 SliceT *sliceType
642 StructT *structType
643 MapT *mapType
644 GobEncoderT *gobEncoderType
645 BinaryMarshalerT *gobEncoderType
646 TextMarshalerT *gobEncoderType
647 }
648
649 func (w *wireType) string() string {
650 const unknown = "unknown type"
651 if w == nil {
652 return unknown
653 }
654 switch {
655 case w.ArrayT != nil:
656 return w.ArrayT.Name
657 case w.SliceT != nil:
658 return w.SliceT.Name
659 case w.StructT != nil:
660 return w.StructT.Name
661 case w.MapT != nil:
662 return w.MapT.Name
663 case w.GobEncoderT != nil:
664 return w.GobEncoderT.Name
665 case w.BinaryMarshalerT != nil:
666 return w.BinaryMarshalerT.Name
667 case w.TextMarshalerT != nil:
668 return w.TextMarshalerT.Name
669 }
670 return unknown
671 }
672
673 type typeInfo struct {
674 id typeId
675 encInit sync.Mutex
676 encoder atomic.Value
677 wire *wireType
678 }
679
680
681
682
683
684
685
686 var typeInfoMap atomic.Value
687
688 func lookupTypeInfo(rt reflect.Type) *typeInfo {
689 m, _ := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
690 return m[rt]
691 }
692
693 func getTypeInfo(ut *userTypeInfo) (*typeInfo, error) {
694 rt := ut.base
695 if ut.externalEnc != 0 {
696
697 rt = ut.user
698 }
699 if info := lookupTypeInfo(rt); info != nil {
700 return info, nil
701 }
702 return buildTypeInfo(ut, rt)
703 }
704
705
706
707 func buildTypeInfo(ut *userTypeInfo, rt reflect.Type) (*typeInfo, error) {
708 typeLock.Lock()
709 defer typeLock.Unlock()
710
711 if info := lookupTypeInfo(rt); info != nil {
712 return info, nil
713 }
714
715 gt, err := getBaseType(rt.Name(), rt)
716 if err != nil {
717 return nil, err
718 }
719 info := &typeInfo{id: gt.id()}
720
721 if ut.externalEnc != 0 {
722 userType, err := getType(rt.Name(), ut, rt)
723 if err != nil {
724 return nil, err
725 }
726 gt := userType.id().gobType().(*gobEncoderType)
727 switch ut.externalEnc {
728 case xGob:
729 info.wire = &wireType{GobEncoderT: gt}
730 case xBinary:
731 info.wire = &wireType{BinaryMarshalerT: gt}
732 case xText:
733 info.wire = &wireType{TextMarshalerT: gt}
734 }
735 rt = ut.user
736 } else {
737 t := info.id.gobType()
738 switch typ := rt; typ.Kind() {
739 case reflect.Array:
740 info.wire = &wireType{ArrayT: t.(*arrayType)}
741 case reflect.Map:
742 info.wire = &wireType{MapT: t.(*mapType)}
743 case reflect.Slice:
744
745 if typ.Elem().Kind() != reflect.Uint8 {
746 info.wire = &wireType{SliceT: t.(*sliceType)}
747 }
748 case reflect.Struct:
749 info.wire = &wireType{StructT: t.(*structType)}
750 }
751 }
752
753
754 newm := make(map[reflect.Type]*typeInfo)
755 m, _ := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
756 for k, v := range m {
757 newm[k] = v
758 }
759 newm[rt] = info
760 typeInfoMap.Store(newm)
761 return info, nil
762 }
763
764
765 func mustGetTypeInfo(rt reflect.Type) *typeInfo {
766 t, err := getTypeInfo(userType(rt))
767 if err != nil {
768 panic("getTypeInfo: " + err.Error())
769 }
770 return t
771 }
772
773
774
775
776
777
778
779
780
781
782
783
784 type GobEncoder interface {
785
786
787
788 GobEncode() ([]byte, error)
789 }
790
791
792
793 type GobDecoder interface {
794
795
796
797 GobDecode([]byte) error
798 }
799
800 var (
801 nameToConcreteType sync.Map
802 concreteTypeToName sync.Map
803 )
804
805
806
807 func RegisterName(name string, value interface{}) {
808 if name == "" {
809
810 panic("attempt to register empty name")
811 }
812
813 ut := userType(reflect.TypeOf(value))
814
815
816
817
818
819 if t, dup := nameToConcreteType.LoadOrStore(name, reflect.TypeOf(value)); dup && t != ut.user {
820 panic(fmt.Sprintf("gob: registering duplicate types for %q: %s != %s", name, t, ut.user))
821 }
822
823
824 if n, dup := concreteTypeToName.LoadOrStore(ut.base, name); dup && n != name {
825 nameToConcreteType.Delete(name)
826 panic(fmt.Sprintf("gob: registering duplicate names for %s: %q != %q", ut.user, n, name))
827 }
828 }
829
830
831
832
833
834
835
836 func Register(value interface{}) {
837
838 rt := reflect.TypeOf(value)
839 name := rt.String()
840
841
842
843 star := ""
844 if rt.Name() == "" {
845 if pt := rt; pt.Kind() == reflect.Ptr {
846 star = "*"
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863 rt = pt
864 }
865 }
866 if rt.Name() != "" {
867 if rt.PkgPath() == "" {
868 name = star + rt.Name()
869 } else {
870 name = star + rt.PkgPath() + "." + rt.Name()
871 }
872 }
873
874 RegisterName(name, value)
875 }
876
877 func registerBasics() {
878 Register(int(0))
879 Register(int8(0))
880 Register(int16(0))
881 Register(int32(0))
882 Register(int64(0))
883 Register(uint(0))
884 Register(uint8(0))
885 Register(uint16(0))
886 Register(uint32(0))
887 Register(uint64(0))
888 Register(float32(0))
889 Register(float64(0))
890 Register(complex64(0i))
891 Register(complex128(0i))
892 Register(uintptr(0))
893 Register(false)
894 Register("")
895 Register([]byte(nil))
896 Register([]int(nil))
897 Register([]int8(nil))
898 Register([]int16(nil))
899 Register([]int32(nil))
900 Register([]int64(nil))
901 Register([]uint(nil))
902 Register([]uint8(nil))
903 Register([]uint16(nil))
904 Register([]uint32(nil))
905 Register([]uint64(nil))
906 Register([]float32(nil))
907 Register([]float64(nil))
908 Register([]complex64(nil))
909 Register([]complex128(nil))
910 Register([]uintptr(nil))
911 Register([]bool(nil))
912 Register([]string(nil))
913 }
914
View as plain text