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