summaryrefslogtreecommitdiff
path: root/src/pkg/gob/encoder.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/gob/encoder.go')
-rw-r--r--src/pkg/gob/encoder.go35
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
}