diff options
Diffstat (limited to 'src/pkg/gob/encoder.go')
-rw-r--r-- | src/pkg/gob/encoder.go | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/src/pkg/gob/encoder.go b/src/pkg/gob/encoder.go index 4bfcf15c7..928f3b244 100644 --- a/src/pkg/gob/encoder.go +++ b/src/pkg/gob/encoder.go @@ -19,7 +19,9 @@ type Encoder struct { w []io.Writer // where to send the data sent map[reflect.Type]typeId // which types we've already sent countState *encoderState // stage for writing counts + freeList *encoderState // list of free encoderStates; avoids reallocation buf []byte // for collecting the output. + byteBuf bytes.Buffer // buffer for top-level encoderState err os.Error } @@ -28,7 +30,7 @@ func NewEncoder(w io.Writer) *Encoder { enc := new(Encoder) enc.w = []io.Writer{w} enc.sent = make(map[reflect.Type]typeId) - enc.countState = newEncoderState(enc, new(bytes.Buffer)) + enc.countState = enc.newEncoderState(new(bytes.Buffer)) return enc } @@ -107,12 +109,12 @@ func (enc *Encoder) sendActualType(w io.Writer, state *encoderState, ut *userTyp enc.sent[ut.user] = info.id } // Now send the inner types - switch st := actual.(type) { - case *reflect.StructType: + switch st := actual; st.Kind() { + case reflect.Struct: for i := 0; i < st.NumField(); i++ { enc.sendType(w, state, st.Field(i).Type) } - case reflect.ArrayOrSliceType: + case reflect.Array, reflect.Slice: enc.sendType(w, state, st.Elem()) } return true @@ -128,27 +130,27 @@ func (enc *Encoder) sendType(w io.Writer, state *encoderState, origt reflect.Typ } // It's a concrete value, so drill down to the base type. - switch rt := ut.base.(type) { + switch rt := ut.base; rt.Kind() { default: // Basic types and interfaces do not need to be described. return - case *reflect.SliceType: + case reflect.Slice: // If it's []uint8, don't send; it's considered basic. if rt.Elem().Kind() == reflect.Uint8 { return } // Otherwise we do send. break - case *reflect.ArrayType: + case reflect.Array: // arrays must be sent so we know their lengths and element types. break - case *reflect.MapType: + case reflect.Map: // maps must be sent so we know their lengths and key/value types. break - case *reflect.StructType: + case reflect.Struct: // structs must be sent so we know their fields. break - case *reflect.ChanType, *reflect.FuncType: + case reflect.Chan, reflect.Func: // Probably a bad field in a struct. enc.badType(rt) return @@ -172,9 +174,6 @@ func (enc *Encoder) sendTypeDescriptor(w io.Writer, state *encoderState, ut *use rt := ut.base if ut.isGobEncoder { rt = ut.user - if ut.encIndir != 0 { - panic("TODO: can't handle non-zero encIndir") - } } if _, alreadySent := enc.sent[rt]; !alreadySent { // No, so send it. @@ -221,7 +220,8 @@ func (enc *Encoder) EncodeValue(value reflect.Value) os.Error { } enc.err = nil - state := newEncoderState(enc, new(bytes.Buffer)) + enc.byteBuf.Reset() + state := enc.newEncoderState(&enc.byteBuf) enc.sendTypeDescriptor(enc.writer(), state, ut) enc.sendTypeId(state, ut) @@ -230,12 +230,11 @@ 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) } + enc.freeEncoderState(state) return enc.err } |