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

Delta Between Two Patch Sets: src/pkg/encoding/gob/decode.go

Issue 12681044: code review 12681044: encoding/gob: support new generic interfaces in package... (Closed)
Left Patch Set: diff -r b1c9e72c2ca3 https://code.google.com/p/go/ Created 10 years, 7 months ago
Right Patch Set: diff -r 00b5a40ae411 https://code.google.com/p/go/ Created 10 years, 7 months 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:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/encoding/gob/debug.go ('k') | src/pkg/encoding/gob/doc.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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 // TODO(rsc): When garbage collector changes, revisit 7 // TODO(rsc): When garbage collector changes, revisit
8 // the allocations in this file that use unsafe.Pointer. 8 // the allocations in this file that use unsafe.Pointer.
9 9
10 import ( 10 import (
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 // decodeGobDecoder decodes something implementing the GobDecoder interface. 769 // decodeGobDecoder decodes something implementing the GobDecoder interface.
770 // The data is encoded as a byte slice. 770 // The data is encoded as a byte slice.
771 func (dec *Decoder) decodeGobDecoder(ut *userTypeInfo, state *decoderState, v re flect.Value) { 771 func (dec *Decoder) decodeGobDecoder(ut *userTypeInfo, state *decoderState, v re flect.Value) {
772 // Read the bytes for the value. 772 // Read the bytes for the value.
773 b := make([]byte, state.decodeUint()) 773 b := make([]byte, state.decodeUint())
774 _, err := state.b.Read(b) 774 _, err := state.b.Read(b)
775 if err != nil { 775 if err != nil {
776 error_(err) 776 error_(err)
777 } 777 }
778 // We know it's one of these. 778 // We know it's one of these.
779 » switch { 779 » switch ut.externalDec {
780 » case ut.isGobDecoder: 780 » case xGob:
781 err = v.Interface().(GobDecoder).GobDecode(b) 781 err = v.Interface().(GobDecoder).GobDecode(b)
782 » case ut.isBinaryUnmarshaler: 782 » case xBinary:
783 err = v.Interface().(encoding.BinaryUnmarshaler).UnmarshalBinary (b) 783 err = v.Interface().(encoding.BinaryUnmarshaler).UnmarshalBinary (b)
784 » case ut.isTextUnmarshaler: 784 » case xText:
785 err = v.Interface().(encoding.TextUnmarshaler).UnmarshalText(b) 785 err = v.Interface().(encoding.TextUnmarshaler).UnmarshalText(b)
786 } 786 }
787 if err != nil { 787 if err != nil {
788 error_(err) 788 error_(err)
789 } 789 }
790 } 790 }
791 791
792 // ignoreGobDecoder discards the data for a GobDecoder value with no destination . 792 // ignoreGobDecoder discards the data for a GobDecoder value with no destination .
793 func (dec *Decoder) ignoreGobDecoder(state *decoderState) { 793 func (dec *Decoder) ignoreGobDecoder(state *decoderState) {
794 // Read the bytes for the value. 794 // Read the bytes for the value.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 tBytes: ignoreUint8Array, 826 tBytes: ignoreUint8Array,
827 tString: ignoreUint8Array, 827 tString: ignoreUint8Array,
828 tComplex: ignoreTwoUints, 828 tComplex: ignoreTwoUints,
829 } 829 }
830 830
831 // decOpFor returns the decoding op for the base type under rt and 831 // decOpFor returns the decoding op for the base type under rt and
832 // the indirection count to reach it. 832 // the indirection count to reach it.
833 func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string, inProg ress map[reflect.Type]*decOp) (*decOp, int) { 833 func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string, inProg ress map[reflect.Type]*decOp) (*decOp, int) {
834 ut := userType(rt) 834 ut := userType(rt)
835 // If the type implements GobEncoder, we handle it without further proce ssing. 835 // If the type implements GobEncoder, we handle it without further proce ssing.
836 » if ut.isGobDecoder || ut.isBinaryUnmarshaler || ut.isTextUnmarshaler { 836 » if ut.externalDec != 0 {
837 return dec.gobDecodeOpFor(ut) 837 return dec.gobDecodeOpFor(ut)
838 } 838 }
839 839
840 // If this type is already in progress, it's a recursive type (e.g. map[ string]*T). 840 // If this type is already in progress, it's a recursive type (e.g. map[ string]*T).
841 // Return the pointer to the op we're already building. 841 // Return the pointer to the op we're already building.
842 if opPtr := inProgress[rt]; opPtr != nil { 842 if opPtr := inProgress[rt]; opPtr != nil {
843 return opPtr, ut.indir 843 return opPtr, ut.indir
844 } 844 }
845 typ := ut.base 845 typ := ut.base
846 indir := ut.indir 846 indir := ut.indir
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 } 1018 }
1019 inProgress[fr] = fw 1019 inProgress[fr] = fw
1020 ut := userType(fr) 1020 ut := userType(fr)
1021 wire, ok := dec.wireType[fw] 1021 wire, ok := dec.wireType[fw]
1022 // If wire was encoded with an encoding method, fr must have that method . 1022 // If wire was encoded with an encoding method, fr must have that method .
1023 // And if not, it must not. 1023 // And if not, it must not.
1024 // At most one of the booleans in ut is set. 1024 // At most one of the booleans in ut is set.
1025 // We could possibly relax this constraint in the future in order to 1025 // We could possibly relax this constraint in the future in order to
1026 // choose the decoding method using the data in the wireType. 1026 // choose the decoding method using the data in the wireType.
1027 // The parentheses look odd but are correct. 1027 // The parentheses look odd but are correct.
1028 » if ut.isGobDecoder != (ok && wire.GobEncoderT != nil) || 1028 » if (ut.externalDec == xGob) != (ok && wire.GobEncoderT != nil) ||
1029 » » ut.isBinaryUnmarshaler != (ok && wire.BinaryMarshalerT != nil) | | 1029 » » (ut.externalDec == xBinary) != (ok && wire.BinaryMarshalerT != n il) ||
1030 » » ut.isTextUnmarshaler != (ok && wire.TextMarshalerT != nil) { 1030 » » (ut.externalDec == xText) != (ok && wire.TextMarshalerT != nil) {
1031 return false 1031 return false
1032 } 1032 }
1033 » if ut.isGobDecoder || ut.isBinaryUnmarshaler || ut.isTextUnmarshaler { / / This test trumps all others. 1033 » if ut.externalDec != 0 { // This test trumps all others.
1034 return true 1034 return true
1035 } 1035 }
1036 switch t := ut.base; t.Kind() { 1036 switch t := ut.base; t.Kind() {
1037 default: 1037 default:
1038 // chan, etc: cannot handle. 1038 // chan, etc: cannot handle.
1039 return false 1039 return false
1040 case reflect.Bool: 1040 case reflect.Bool:
1041 return fw == tBool 1041 return fw == tBool
1042 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.In t64: 1042 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.In t64:
1043 return fw == tInt 1043 return fw == tInt
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 engine.instr[0] = decInstr{op, 0, 0, 0, ovfl} 1122 engine.instr[0] = decInstr{op, 0, 0, 0, ovfl}
1123 engine.numInstr = 1 1123 engine.numInstr = 1
1124 return 1124 return
1125 } 1125 }
1126 1126
1127 // compileDec compiles the decoder engine for a value. If the value is not a st ruct, 1127 // compileDec compiles the decoder engine for a value. If the value is not a st ruct,
1128 // it calls out to compileSingle. 1128 // it calls out to compileSingle.
1129 func (dec *Decoder) compileDec(remoteId typeId, ut *userTypeInfo) (engine *decEn gine, err error) { 1129 func (dec *Decoder) compileDec(remoteId typeId, ut *userTypeInfo) (engine *decEn gine, err error) {
1130 rt := ut.base 1130 rt := ut.base
1131 srt := rt 1131 srt := rt
1132 » if srt.Kind() != reflect.Struct || 1132 » if srt.Kind() != reflect.Struct || ut.externalDec != 0 {
1133 » » ut.isGobDecoder ||
1134 » » ut.isBinaryUnmarshaler ||
1135 » » ut.isTextUnmarshaler {
1136 return dec.compileSingle(remoteId, ut) 1133 return dec.compileSingle(remoteId, ut)
1137 } 1134 }
1138 var wireStruct *structType 1135 var wireStruct *structType
1139 // Builtin types can come from global pool; the rest must be defined by the decoder. 1136 // Builtin types can come from global pool; the rest must be defined by the decoder.
1140 // Also we know we're decoding a struct now, so the client must have sen t one. 1137 // Also we know we're decoding a struct now, so the client must have sen t one.
1141 if t, ok := builtinIdToType[remoteId]; ok { 1138 if t, ok := builtinIdToType[remoteId]; ok {
1142 wireStruct, _ = t.(*structType) 1139 wireStruct, _ = t.(*structType)
1143 } else { 1140 } else {
1144 wire := dec.wireType[remoteId] 1141 wire := dec.wireType[remoteId]
1145 if wire == nil { 1142 if wire == nil {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 } 1230 }
1234 // Dereference down to the underlying type. 1231 // Dereference down to the underlying type.
1235 ut := userType(val.Type()) 1232 ut := userType(val.Type())
1236 base := ut.base 1233 base := ut.base
1237 var enginePtr **decEngine 1234 var enginePtr **decEngine
1238 enginePtr, dec.err = dec.getDecEnginePtr(wireId, ut) 1235 enginePtr, dec.err = dec.getDecEnginePtr(wireId, ut)
1239 if dec.err != nil { 1236 if dec.err != nil {
1240 return 1237 return
1241 } 1238 }
1242 engine := *enginePtr 1239 engine := *enginePtr
1243 » if st := base; st.Kind() == reflect.Struct && !ut.isGobDecoder { 1240 » if st := base; st.Kind() == reflect.Struct && ut.externalDec == 0 {
1244 if engine.numInstr == 0 && st.NumField() > 0 && len(dec.wireType [wireId].StructT.Field) > 0 { 1241 if engine.numInstr == 0 && st.NumField() > 0 && len(dec.wireType [wireId].StructT.Field) > 0 {
1245 name := base.Name() 1242 name := base.Name()
1246 errorf("type mismatch: no fields matched compiling decod er for %s", name) 1243 errorf("type mismatch: no fields matched compiling decod er for %s", name)
1247 } 1244 }
1248 dec.decodeStruct(engine, ut, unsafeAddr(val), ut.indir) 1245 dec.decodeStruct(engine, ut, unsafeAddr(val), ut.indir)
1249 } else { 1246 } else {
1250 dec.decodeSingle(engine, ut, unsafeAddr(val)) 1247 dec.decodeSingle(engine, ut, unsafeAddr(val))
1251 } 1248 }
1252 } 1249 }
1253 1250
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1308 return unsafe.Pointer(x.UnsafeAddr()) 1305 return unsafe.Pointer(x.UnsafeAddr())
1309 } 1306 }
1310 1307
1311 // Gob depends on being able to take the address 1308 // Gob depends on being able to take the address
1312 // of zeroed Values it creates, so use this wrapper instead 1309 // of zeroed Values it creates, so use this wrapper instead
1313 // of the standard reflect.Zero. 1310 // of the standard reflect.Zero.
1314 // Each call allocates once. 1311 // Each call allocates once.
1315 func allocValue(t reflect.Type) reflect.Value { 1312 func allocValue(t reflect.Type) reflect.Value {
1316 return reflect.New(t).Elem() 1313 return reflect.New(t).Elem()
1317 } 1314 }
LEFTRIGHT

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