Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1191)

Side by Side Diff: src/pkg/gob/encode.go

Issue 4301043: update tree for reflect changes (Closed)
Patch Set: diff -r f692a5e90f6f https://go.googlecode.com/hg/ Created 13 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pkg/gob/decode.go ('k') | src/pkg/gob/encoder.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 package gob 5 package gob
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "math" 9 "math"
10 "reflect" 10 "reflect"
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 typ := ut.base 518 typ := ut.base
519 indir := ut.indir 519 indir := ut.indir
520 k := typ.Kind() 520 k := typ.Kind()
521 var op encOp 521 var op encOp
522 if int(k) < len(encOpTable) { 522 if int(k) < len(encOpTable) {
523 op = encOpTable[k] 523 op = encOpTable[k]
524 } 524 }
525 if op == nil { 525 if op == nil {
526 inProgress[rt] = &op 526 inProgress[rt] = &op
527 // Special cases 527 // Special cases
528 » » switch t := typ.(type) { 528 » » switch t := typ; t.Kind() {
529 » » case *reflect.SliceType: 529 » » case reflect.Slice:
530 if t.Elem().Kind() == reflect.Uint8 { 530 if t.Elem().Kind() == reflect.Uint8 {
531 op = encUint8Array 531 op = encUint8Array
532 break 532 break
533 } 533 }
534 // Slices have a header; we decode it to find the underl ying array. 534 // Slices have a header; we decode it to find the underl ying array.
535 elemOp, indir := enc.encOpFor(t.Elem(), inProgress) 535 elemOp, indir := enc.encOpFor(t.Elem(), inProgress)
536 op = func(i *encInstr, state *encoderState, p unsafe.Poi nter) { 536 op = func(i *encInstr, state *encoderState, p unsafe.Poi nter) {
537 slice := (*reflect.SliceHeader)(p) 537 slice := (*reflect.SliceHeader)(p)
538 if !state.sendZero && slice.Len == 0 { 538 if !state.sendZero && slice.Len == 0 {
539 return 539 return
540 } 540 }
541 state.update(i) 541 state.update(i)
542 state.enc.encodeArray(state.b, slice.Data, *elem Op, t.Elem().Size(), indir, int(slice.Len)) 542 state.enc.encodeArray(state.b, slice.Data, *elem Op, t.Elem().Size(), indir, int(slice.Len))
543 } 543 }
544 » » case *reflect.ArrayType: 544 » » case reflect.Array:
545 // True arrays have size in the type. 545 // True arrays have size in the type.
546 elemOp, indir := enc.encOpFor(t.Elem(), inProgress) 546 elemOp, indir := enc.encOpFor(t.Elem(), inProgress)
547 op = func(i *encInstr, state *encoderState, p unsafe.Poi nter) { 547 op = func(i *encInstr, state *encoderState, p unsafe.Poi nter) {
548 state.update(i) 548 state.update(i)
549 state.enc.encodeArray(state.b, uintptr(p), *elem Op, t.Elem().Size(), indir, t.Len()) 549 state.enc.encodeArray(state.b, uintptr(p), *elem Op, t.Elem().Size(), indir, t.Len())
550 } 550 }
551 » » case *reflect.MapType: 551 » » case reflect.Map:
552 keyOp, keyIndir := enc.encOpFor(t.Key(), inProgress) 552 keyOp, keyIndir := enc.encOpFor(t.Key(), inProgress)
553 elemOp, elemIndir := enc.encOpFor(t.Elem(), inProgress) 553 elemOp, elemIndir := enc.encOpFor(t.Elem(), inProgress)
554 op = func(i *encInstr, state *encoderState, p unsafe.Poi nter) { 554 op = func(i *encInstr, state *encoderState, p unsafe.Poi nter) {
555 // Maps cannot be accessed by moving addresses a round the way 555 // Maps cannot be accessed by moving addresses a round the way
556 // that slices etc. can. We must recover a full reflection value for 556 // that slices etc. can. We must recover a full reflection value for
557 // the iteration. 557 // the iteration.
558 v := reflect.NewValue(unsafe.Unreflect(t, unsafe .Pointer(p))) 558 v := reflect.NewValue(unsafe.Unreflect(t, unsafe .Pointer(p)))
559 mv := reflect.Indirect(v).(*reflect.MapValue) 559 mv := reflect.Indirect(v).(*reflect.MapValue)
560 if !state.sendZero && mv.Len() == 0 { 560 if !state.sendZero && mv.Len() == 0 {
561 return 561 return
562 } 562 }
563 state.update(i) 563 state.update(i)
564 state.enc.encodeMap(state.b, mv, *keyOp, *elemOp , keyIndir, elemIndir) 564 state.enc.encodeMap(state.b, mv, *keyOp, *elemOp , keyIndir, elemIndir)
565 } 565 }
566 » » case *reflect.StructType: 566 » » case reflect.Struct:
567 // Generate a closure that calls out to the engine for t he nested type. 567 // Generate a closure that calls out to the engine for t he nested type.
568 enc.getEncEngine(userType(typ)) 568 enc.getEncEngine(userType(typ))
569 info := mustGetTypeInfo(typ) 569 info := mustGetTypeInfo(typ)
570 op = func(i *encInstr, state *encoderState, p unsafe.Poi nter) { 570 op = func(i *encInstr, state *encoderState, p unsafe.Poi nter) {
571 state.update(i) 571 state.update(i)
572 // indirect through info to delay evaluation for recursive structs 572 // indirect through info to delay evaluation for recursive structs
573 state.enc.encodeStruct(state.b, info.encoder, ui ntptr(p)) 573 state.enc.encodeStruct(state.b, info.encoder, ui ntptr(p))
574 } 574 }
575 » » case *reflect.InterfaceType: 575 » » case reflect.Interface:
576 op = func(i *encInstr, state *encoderState, p unsafe.Poi nter) { 576 op = func(i *encInstr, state *encoderState, p unsafe.Poi nter) {
577 // Interfaces transmit the name and contents of the concrete 577 // Interfaces transmit the name and contents of the concrete
578 // value they contain. 578 // value they contain.
579 v := reflect.NewValue(unsafe.Unreflect(t, unsafe .Pointer(p))) 579 v := reflect.NewValue(unsafe.Unreflect(t, unsafe .Pointer(p)))
580 iv := reflect.Indirect(v).(*reflect.InterfaceVal ue) 580 iv := reflect.Indirect(v).(*reflect.InterfaceVal ue)
581 if !state.sendZero && (iv == nil || iv.IsNil()) { 581 if !state.sendZero && (iv == nil || iv.IsNil()) {
582 return 582 return
583 } 583 }
584 state.update(i) 584 state.update(i)
585 state.enc.encodeInterface(state.b, iv) 585 state.enc.encodeInterface(state.b, iv)
(...skipping 18 matching lines...) Expand all
604 } 604 }
605 605
606 // gobEncodeOpFor returns the op for a type that is known to implement 606 // gobEncodeOpFor returns the op for a type that is known to implement
607 // GobEncoder. 607 // GobEncoder.
608 func (enc *Encoder) gobEncodeOpFor(ut *userTypeInfo) (*encOp, int) { 608 func (enc *Encoder) gobEncodeOpFor(ut *userTypeInfo) (*encOp, int) {
609 rt := ut.user 609 rt := ut.user
610 if ut.encIndir == -1 { 610 if ut.encIndir == -1 {
611 rt = reflect.PtrTo(rt) 611 rt = reflect.PtrTo(rt)
612 } else if ut.encIndir > 0 { 612 } else if ut.encIndir > 0 {
613 for i := int8(0); i < ut.encIndir; i++ { 613 for i := int8(0); i < ut.encIndir; i++ {
614 » » » rt = rt.(*reflect.PtrType).Elem() 614 » » » rt = rt.Elem()
615 } 615 }
616 } 616 }
617 var op encOp 617 var op encOp
618 op = func(i *encInstr, state *encoderState, p unsafe.Pointer) { 618 op = func(i *encInstr, state *encoderState, p unsafe.Pointer) {
619 var v reflect.Value 619 var v reflect.Value
620 if ut.encIndir == -1 { 620 if ut.encIndir == -1 {
621 // Need to climb up one level to turn value into pointer . 621 // Need to climb up one level to turn value into pointer .
622 v = reflect.NewValue(unsafe.Unreflect(rt, unsafe.Pointer (&p))) 622 v = reflect.NewValue(unsafe.Unreflect(rt, unsafe.Pointer (&p)))
623 } else { 623 } else {
624 v = reflect.NewValue(unsafe.Unreflect(rt, p)) 624 v = reflect.NewValue(unsafe.Unreflect(rt, p))
625 } 625 }
626 state.update(i) 626 state.update(i)
627 state.enc.encodeGobEncoder(state.b, v, methodIndex(rt, gobEncode MethodName)) 627 state.enc.encodeGobEncoder(state.b, v, methodIndex(rt, gobEncode MethodName))
628 } 628 }
629 return &op, int(ut.encIndir) // encIndir: op will get called with p == a ddress of receiver. 629 return &op, int(ut.encIndir) // encIndir: op will get called with p == a ddress of receiver.
630 } 630 }
631 631
632 // compileEnc returns the engine to compile the type. 632 // compileEnc returns the engine to compile the type.
633 func (enc *Encoder) compileEnc(ut *userTypeInfo) *encEngine { 633 func (enc *Encoder) compileEnc(ut *userTypeInfo) *encEngine {
634 » srt, isStruct := ut.base.(*reflect.StructType) 634 » srt := ut.base
635 engine := new(encEngine) 635 engine := new(encEngine)
636 seen := make(map[reflect.Type]*encOp) 636 seen := make(map[reflect.Type]*encOp)
637 rt := ut.base 637 rt := ut.base
638 if ut.isGobEncoder { 638 if ut.isGobEncoder {
639 rt = ut.user 639 rt = ut.user
640 } 640 }
641 » if !ut.isGobEncoder && isStruct { 641 » if !ut.isGobEncoder &&
642 » » srt.Kind() == reflect.Struct {
642 for fieldNum, wireFieldNum := 0, 0; fieldNum < srt.NumField(); f ieldNum++ { 643 for fieldNum, wireFieldNum := 0, 0; fieldNum < srt.NumField(); f ieldNum++ {
643 f := srt.Field(fieldNum) 644 f := srt.Field(fieldNum)
644 if !isExported(f.Name) { 645 if !isExported(f.Name) {
645 continue 646 continue
646 } 647 }
647 op, indir := enc.encOpFor(f.Type, seen) 648 op, indir := enc.encOpFor(f.Type, seen)
648 engine.instr = append(engine.instr, encInstr{*op, wireFi eldNum, indir, uintptr(f.Offset)}) 649 engine.instr = append(engine.instr, encInstr{*op, wireFi eldNum, indir, uintptr(f.Offset)})
649 wireFieldNum++ 650 wireFieldNum++
650 } 651 }
651 if srt.NumField() > 0 && len(engine.instr) == 0 { 652 if srt.NumField() > 0 && len(engine.instr) == 0 {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 } 693 }
693 for i := 0; i < indir; i++ { 694 for i := 0; i < indir; i++ {
694 value = reflect.Indirect(value) 695 value = reflect.Indirect(value)
695 } 696 }
696 if !ut.isGobEncoder && value.Type().Kind() == reflect.Struct { 697 if !ut.isGobEncoder && value.Type().Kind() == reflect.Struct {
697 enc.encodeStruct(b, engine, value.UnsafeAddr()) 698 enc.encodeStruct(b, engine, value.UnsafeAddr())
698 } else { 699 } else {
699 enc.encodeSingle(b, engine, value.UnsafeAddr()) 700 enc.encodeSingle(b, engine, value.UnsafeAddr())
700 } 701 }
701 } 702 }
OLDNEW
« no previous file with comments | « src/pkg/gob/decode.go ('k') | src/pkg/gob/encoder.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b