diff --git a/src/pkg/gob/codec_test.go b/src/pkg/gob/codec_test.go index e4364e6fd7a..28042ccaa3a 100644 --- a/src/pkg/gob/codec_test.go +++ b/src/pkg/gob/codec_test.go @@ -1004,9 +1004,9 @@ func TestInvalidField(t *testing.T) { var bad0 Bad0 bad0.CH = make(chan int) b := new(bytes.Buffer) - var nilEncoder *Encoder - err := nilEncoder.encode(b, reflect.NewValue(&bad0), userType(reflect.Typeof(&bad0))) - if err == nil { + dummyEncoder := new(Encoder) // sufficient for this purpose. + dummyEncoder.encode(b, reflect.NewValue(&bad0), userType(reflect.Typeof(&bad0))) + if err := dummyEncoder.err; err == nil { t.Error("expected error; got none") } else if strings.Index(err.String(), "type") < 0 { t.Error("expected type error; got", err) diff --git a/src/pkg/gob/decode.go b/src/pkg/gob/decode.go index d00ef7cd657..f77504d871d 100644 --- a/src/pkg/gob/decode.go +++ b/src/pkg/gob/decode.go @@ -478,7 +478,7 @@ func (dec *Decoder) decodeSingle(engine *decEngine, ut *userTypeInfo, p uintptr) // differ from ut.indir, which was computed when the engine was built. // This state cannot arise for decodeSingle, which is called directly // from the user's value, not from the innards of an engine. -func (dec *Decoder) decodeStruct(engine *decEngine, ut *userTypeInfo, p uintptr, indir int) (err os.Error) { +func (dec *Decoder) decodeStruct(engine *decEngine, ut *userTypeInfo, p uintptr, indir int) { p = allocate(ut.base.(*reflect.StructType), p, indir) state := dec.newDecoderState(&dec.buf) state.fieldnum = -1 @@ -505,11 +505,10 @@ func (dec *Decoder) decodeStruct(engine *decEngine, ut *userTypeInfo, p uintptr, state.fieldnum = fieldnum } dec.freeDecoderState(state) - return nil } // ignoreStruct discards the data for a struct with no destination. -func (dec *Decoder) ignoreStruct(engine *decEngine) (err os.Error) { +func (dec *Decoder) ignoreStruct(engine *decEngine) { state := dec.newDecoderState(&dec.buf) state.fieldnum = -1 for state.b.Len() > 0 { @@ -529,12 +528,11 @@ func (dec *Decoder) ignoreStruct(engine *decEngine) (err os.Error) { state.fieldnum = fieldnum } dec.freeDecoderState(state) - return nil } // ignoreSingle discards the data for a top-level non-struct value with no // destination. It's used when calling Decode with a nil value. -func (dec *Decoder) ignoreSingle(engine *decEngine) (err os.Error) { +func (dec *Decoder) ignoreSingle(engine *decEngine) { state := dec.newDecoderState(&dec.buf) state.fieldnum = singletonField delta := int(state.decodeUint()) @@ -544,7 +542,6 @@ func (dec *Decoder) ignoreSingle(engine *decEngine) (err os.Error) { instr := &engine.instr[singletonField] instr.op(instr, state, unsafe.Pointer(nil)) dec.freeDecoderState(state) - return nil } // decodeArrayHelper does the work for decoding arrays and slices. @@ -867,10 +864,7 @@ func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string, inProg } op = func(i *decInstr, state *decoderState, p unsafe.Pointer) { // indirect through enginePtr to delay evaluation for recursive structs. - err = dec.decodeStruct(*enginePtr, userType(typ), uintptr(p), i.indir) - if err != nil { - error(err) - } + dec.decodeStruct(*enginePtr, userType(typ), uintptr(p), i.indir) } case *reflect.InterfaceType: op = func(i *decInstr, state *decoderState, p unsafe.Pointer) { @@ -1185,11 +1179,12 @@ func (dec *Decoder) getIgnoreEnginePtr(wireId typeId) (enginePtr **decEngine, er } // decodeValue decodes the data stream representing a value and stores it in val. -func (dec *Decoder) decodeValue(wireId typeId, val reflect.Value) (err os.Error) { - defer catchError(&err) +func (dec *Decoder) decodeValue(wireId typeId, val reflect.Value) { + defer catchError(&dec.err) // If the value is nil, it means we should just ignore this item. if val == nil { - return dec.decodeIgnoredValue(wireId) + dec.decodeIgnoredValue(wireId) + return } // Dereference down to the underlying struct type. ut := userType(val.Type()) @@ -1198,32 +1193,36 @@ func (dec *Decoder) decodeValue(wireId typeId, val reflect.Value) (err os.Error) if ut.isGobDecoder { indir = int(ut.decIndir) } - enginePtr, err := dec.getDecEnginePtr(wireId, ut) - if err != nil { - return err + var enginePtr **decEngine + enginePtr, dec.err = dec.getDecEnginePtr(wireId, ut) + if dec.err != nil { + return } engine := *enginePtr if st, ok := base.(*reflect.StructType); ok && !ut.isGobDecoder { if engine.numInstr == 0 && st.NumField() > 0 && len(dec.wireType[wireId].StructT.Field) > 0 { name := base.Name() - return os.ErrorString("gob: type mismatch: no fields matched compiling decoder for " + name) + errorf("gob: type mismatch: no fields matched compiling decoder for %s", name) } - return dec.decodeStruct(engine, ut, uintptr(val.UnsafeAddr()), indir) + dec.decodeStruct(engine, ut, uintptr(val.UnsafeAddr()), indir) + } else { + dec.decodeSingle(engine, ut, uintptr(val.UnsafeAddr())) } - return dec.decodeSingle(engine, ut, uintptr(val.UnsafeAddr())) } // decodeIgnoredValue decodes the data stream representing a value of the specified type and discards it. -func (dec *Decoder) decodeIgnoredValue(wireId typeId) os.Error { - enginePtr, err := dec.getIgnoreEnginePtr(wireId) - if err != nil { - return err +func (dec *Decoder) decodeIgnoredValue(wireId typeId) { + var enginePtr **decEngine + enginePtr, dec.err = dec.getIgnoreEnginePtr(wireId) + if dec.err != nil { + return } wire := dec.wireType[wireId] if wire != nil && wire.StructT != nil { - return dec.ignoreStruct(*enginePtr) + dec.ignoreStruct(*enginePtr) + } else { + dec.ignoreSingle(*enginePtr) } - return dec.ignoreSingle(*enginePtr) } func init() { diff --git a/src/pkg/gob/decoder.go b/src/pkg/gob/decoder.go index 5e5afb37b4b..34364161aa3 100644 --- a/src/pkg/gob/decoder.go +++ b/src/pkg/gob/decoder.go @@ -50,7 +50,7 @@ func (dec *Decoder) recvType(id typeId) { // Type: wire := new(wireType) - dec.err = dec.decodeValue(tWireType, reflect.NewValue(wire)) + dec.decodeValue(tWireType, reflect.NewValue(wire)) if dec.err != nil { return } @@ -185,7 +185,7 @@ func (dec *Decoder) DecodeValue(value reflect.Value) os.Error { dec.err = nil id := dec.decodeTypeSequence(false) if dec.err == nil { - dec.err = dec.decodeValue(id, value) + dec.decodeValue(id, value) } return dec.err } diff --git a/src/pkg/gob/encode.go b/src/pkg/gob/encode.go index 4dbafdddeb7..5cfdb583a18 100644 --- a/src/pkg/gob/encode.go +++ b/src/pkg/gob/encode.go @@ -6,9 +6,7 @@ package gob import ( "bytes" - "io" "math" - "os" "reflect" "unsafe" ) @@ -320,7 +318,7 @@ func encString(i *encInstr, state *encoderState, p unsafe.Pointer) { if len(s) > 0 || state.sendZero { state.update(i) state.encodeUint(uint64(len(s))) - io.WriteString(state.b, s) + state.b.WriteString(s) } } @@ -444,7 +442,7 @@ func (enc *Encoder) encodeInterface(b *bytes.Buffer, iv *reflect.InterfaceValue) } // Send the name. state.encodeUint(uint64(len(name))) - _, err := io.WriteString(state.b, name) + _, err := state.b.WriteString(name) if err != nil { error(err) } @@ -456,9 +454,9 @@ func (enc *Encoder) encodeInterface(b *bytes.Buffer, iv *reflect.InterfaceValue) // should be written to b, before the encoded value. enc.pushWriter(b) data := new(bytes.Buffer) - err = enc.encode(data, iv.Elem(), ut) - if err != nil { - error(err) + enc.encode(data, iv.Elem(), ut) + if enc.err != nil { + error(enc.err) } enc.popWriter() enc.writeMessage(b, data) @@ -685,8 +683,8 @@ func (enc *Encoder) lockAndGetEncEngine(ut *userTypeInfo) *encEngine { return enc.getEncEngine(ut) } -func (enc *Encoder) encode(b *bytes.Buffer, value reflect.Value, ut *userTypeInfo) (err os.Error) { - defer catchError(&err) +func (enc *Encoder) encode(b *bytes.Buffer, value reflect.Value, ut *userTypeInfo) { + defer catchError(&enc.err) engine := enc.lockAndGetEncEngine(ut) indir := ut.indir if ut.isGobEncoder { @@ -700,5 +698,4 @@ func (enc *Encoder) encode(b *bytes.Buffer, value reflect.Value, ut *userTypeInf } else { enc.encodeSingle(b, engine, value.UnsafeAddr()) } - return nil } diff --git a/src/pkg/gob/encoder.go b/src/pkg/gob/encoder.go index 7045e8e892b..55481a98854 100644 --- a/src/pkg/gob/encoder.go +++ b/src/pkg/gob/encoder.go @@ -228,10 +228,8 @@ func (enc *Encoder) EncodeValue(value reflect.Value) os.Error { } // Encode the object. - err = enc.encode(state.b, value, ut) - if err != nil { - enc.setError(err) - } else { + enc.encode(state.b, value, ut) + if enc.err == nil { enc.writeMessage(enc.writer(), state.b) }