LEFT | RIGHT |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
LEFT | RIGHT |