OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [encoding/] [gob/] [type.go] - Blame information for rev 747

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.