}
func (enc *Encoder) badType(rt reflect.Type) {
- enc.state.err = os.ErrorString("gob: can't encode type " + rt.String())
+ enc.setError(os.ErrorString("gob: can't encode type " + rt.String()))
+}
+
+func (enc *Encoder) setError(err os.Error) {
+ if enc.state.err == nil { // remember the first.
+ enc.state.err = err
+ }
+ enc.state.b.Reset();
}
// Send the data item preceded by a unsigned count of its length.
// Now the data.
enc.state.b.Read(enc.buf[countLen:total]);
// Write the data.
- enc.w.Write(enc.buf[0:total]);
+ _, err := enc.w.Write(enc.buf[0:total]);
+ if err != nil {
+ enc.setError(err)
+ }
}
func (enc *Encoder) sendType(origt reflect.Type) {
info, err := getTypeInfo(rt);
typeLock.Unlock();
if err != nil {
- enc.state.err = err;
+ enc.setError(err);
return;
}
// Send the pair (-id, type)
// Type:
encode(enc.state.b, info.wire);
enc.send();
+ if enc.state.err != nil {
+ return
+ }
// Remember we've sent this type.
enc.sent[rt] = info.id;
// Encode transmits the data item represented by the empty interface value,
// guaranteeing that all necessary type information has been transmitted first.
func (enc *Encoder) Encode(e interface{}) os.Error {
- if enc.state.b.Len() > 0 || enc.countState.b.Len() > 0 {
- panicln("Encoder: buffer not empty")
- }
+ // Make sure we're single-threaded through here, so multiple
+ // goroutines can share an encoder.
+ enc.mutex.Lock();
+ defer enc.mutex.Unlock();
+
+ enc.state.err = nil;
rt, _ := indirect(reflect.Typeof(e));
// Must be a struct
if _, ok := rt.(*reflect.StructType); !ok {
return enc.state.err;
}
-
- // Make sure we're single-threaded through here.
- enc.mutex.Lock();
- defer enc.mutex.Unlock();
+ // Sanity check only: encoder should never come in with data present.
+ if enc.state.b.Len() > 0 || enc.countState.b.Len() > 0 {
+ enc.state.err = os.ErrorString("encoder: buffer not empty");
+ return enc.state.err;
+ }
// Make sure the type is known to the other side.
// First, have we already sent this type?
// No, so send it.
enc.sendType(rt);
if enc.state.err != nil {
- enc.state.b.Reset();
enc.countState.b.Reset();
return enc.state.err;
}