mirror of
https://github.com/golang/go
synced 2024-11-24 10:30:10 -07:00
gob: add DecodeValue and EncodeValue
R=rsc CC=golang-dev https://golang.org/cl/1698045
This commit is contained in:
parent
6d61da6350
commit
12a4d84371
@ -1028,7 +1028,7 @@ func TestInvalidField(t *testing.T) {
|
|||||||
var bad0 Bad0
|
var bad0 Bad0
|
||||||
bad0.inter = 17
|
bad0.inter = 17
|
||||||
b := new(bytes.Buffer)
|
b := new(bytes.Buffer)
|
||||||
err := encode(b, &bad0)
|
err := encode(b, reflect.NewValue(&bad0))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("expected error; got none")
|
t.Error("expected error; got none")
|
||||||
} else if strings.Index(err.String(), "interface") < 0 {
|
} else if strings.Index(err.String(), "interface") < 0 {
|
||||||
|
@ -918,9 +918,9 @@ func (dec *Decoder) getIgnoreEnginePtr(wireId typeId) (enginePtr **decEngine, er
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *Decoder) decode(wireId typeId, e interface{}) os.Error {
|
func (dec *Decoder) decode(wireId typeId, val reflect.Value) os.Error {
|
||||||
// Dereference down to the underlying struct type.
|
// Dereference down to the underlying struct type.
|
||||||
rt, indir := indirect(reflect.Typeof(e))
|
rt, indir := indirect(val.Type())
|
||||||
enginePtr, err := dec.getDecEnginePtr(wireId, rt)
|
enginePtr, err := dec.getDecEnginePtr(wireId, rt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -931,9 +931,9 @@ func (dec *Decoder) decode(wireId typeId, e interface{}) os.Error {
|
|||||||
name := rt.Name()
|
name := rt.Name()
|
||||||
return os.ErrorString("gob: type mismatch: no fields matched compiling decoder for " + name)
|
return os.ErrorString("gob: type mismatch: no fields matched compiling decoder for " + name)
|
||||||
}
|
}
|
||||||
return decodeStruct(engine, st, dec.state.b, uintptr(reflect.NewValue(e).Addr()), indir)
|
return decodeStruct(engine, st, dec.state.b, uintptr(val.Addr()), indir)
|
||||||
}
|
}
|
||||||
return decodeSingle(engine, rt, dec.state.b, uintptr(reflect.NewValue(e).Addr()), indir)
|
return decodeSingle(engine, rt, dec.state.b, uintptr(val.Addr()), indir)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -47,7 +47,7 @@ func (dec *Decoder) recvType(id typeId) {
|
|||||||
|
|
||||||
// Type:
|
// Type:
|
||||||
wire := new(wireType)
|
wire := new(wireType)
|
||||||
dec.state.err = dec.decode(tWireType, wire)
|
dec.state.err = dec.decode(tWireType, reflect.NewValue(wire))
|
||||||
// Remember we've seen this type.
|
// Remember we've seen this type.
|
||||||
dec.wireType[id] = wire
|
dec.wireType[id] = wire
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ func (dec *Decoder) recvType(id typeId) {
|
|||||||
// Decode reads the next value from the connection and stores
|
// Decode reads the next value from the connection and stores
|
||||||
// it in the data represented by the empty interface value.
|
// it in the data represented by the empty interface value.
|
||||||
// The value underlying e must be the correct type for the next
|
// The value underlying e must be the correct type for the next
|
||||||
// data item received.
|
// data item received, which must be a pointer.
|
||||||
func (dec *Decoder) Decode(e interface{}) os.Error {
|
func (dec *Decoder) Decode(e interface{}) os.Error {
|
||||||
// If e represents a value, the answer won't get back to the
|
// If e represents a value, the answer won't get back to the
|
||||||
// caller. Make sure it's a pointer.
|
// caller. Make sure it's a pointer.
|
||||||
@ -63,7 +63,14 @@ func (dec *Decoder) Decode(e interface{}) os.Error {
|
|||||||
dec.state.err = os.ErrorString("gob: attempt to decode into a non-pointer")
|
dec.state.err = os.ErrorString("gob: attempt to decode into a non-pointer")
|
||||||
return dec.state.err
|
return dec.state.err
|
||||||
}
|
}
|
||||||
|
return dec.DecodeValue(reflect.NewValue(e))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeValue reads the next value from the connection and stores
|
||||||
|
// it in the data represented by the reflection value.
|
||||||
|
// The value must be the correct type for the next
|
||||||
|
// data item received.
|
||||||
|
func (dec *Decoder) DecodeValue(value reflect.Value) os.Error {
|
||||||
// Make sure we're single-threaded through here.
|
// Make sure we're single-threaded through here.
|
||||||
dec.mutex.Lock()
|
dec.mutex.Lock()
|
||||||
defer dec.mutex.Unlock()
|
defer dec.mutex.Unlock()
|
||||||
@ -114,7 +121,7 @@ func (dec *Decoder) Decode(e interface{}) os.Error {
|
|||||||
dec.state.err = errBadType
|
dec.state.err = errBadType
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
dec.state.err = dec.decode(id, e)
|
dec.state.err = dec.decode(id, value)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return dec.state.err
|
return dec.state.err
|
||||||
|
@ -798,12 +798,11 @@ func getEncEngine(rt reflect.Type) (*encEngine, os.Error) {
|
|||||||
return info.encoder, err
|
return info.encoder, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func encode(b *bytes.Buffer, e interface{}) os.Error {
|
func encode(b *bytes.Buffer, value reflect.Value) os.Error {
|
||||||
// Dereference down to the underlying object.
|
// Dereference down to the underlying object.
|
||||||
rt, indir := indirect(reflect.Typeof(e))
|
rt, indir := indirect(value.Type())
|
||||||
v := reflect.NewValue(e)
|
|
||||||
for i := 0; i < indir; i++ {
|
for i := 0; i < indir; i++ {
|
||||||
v = reflect.Indirect(v)
|
value = reflect.Indirect(value)
|
||||||
}
|
}
|
||||||
typeLock.Lock()
|
typeLock.Lock()
|
||||||
engine, err := getEncEngine(rt)
|
engine, err := getEncEngine(rt)
|
||||||
@ -811,8 +810,8 @@ func encode(b *bytes.Buffer, e interface{}) os.Error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, ok := v.(*reflect.StructValue); ok {
|
if _, ok := value.(*reflect.StructValue); ok {
|
||||||
return encodeStruct(engine, b, v.Addr())
|
return encodeStruct(engine, b, value.Addr())
|
||||||
}
|
}
|
||||||
return encodeSingle(engine, b, v.Addr())
|
return encodeSingle(engine, b, value.Addr())
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ func (enc *Encoder) sendType(origt reflect.Type) (sent bool) {
|
|||||||
// Id:
|
// Id:
|
||||||
encodeInt(enc.state, -int64(info.id))
|
encodeInt(enc.state, -int64(info.id))
|
||||||
// Type:
|
// Type:
|
||||||
encode(enc.state.b, info.wire)
|
encode(enc.state.b, reflect.NewValue(info.wire))
|
||||||
enc.send()
|
enc.send()
|
||||||
if enc.state.err != nil {
|
if enc.state.err != nil {
|
||||||
return
|
return
|
||||||
@ -140,13 +140,19 @@ func (enc *Encoder) sendType(origt reflect.Type) (sent bool) {
|
|||||||
// Encode transmits the data item represented by the empty interface value,
|
// Encode transmits the data item represented by the empty interface value,
|
||||||
// guaranteeing that all necessary type information has been transmitted first.
|
// guaranteeing that all necessary type information has been transmitted first.
|
||||||
func (enc *Encoder) Encode(e interface{}) os.Error {
|
func (enc *Encoder) Encode(e interface{}) os.Error {
|
||||||
|
return enc.EncodeValue(reflect.NewValue(e))
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeValue transmits the data item represented by the reflection value,
|
||||||
|
// guaranteeing that all necessary type information has been transmitted first.
|
||||||
|
func (enc *Encoder) EncodeValue(value reflect.Value) os.Error {
|
||||||
// Make sure we're single-threaded through here, so multiple
|
// Make sure we're single-threaded through here, so multiple
|
||||||
// goroutines can share an encoder.
|
// goroutines can share an encoder.
|
||||||
enc.mutex.Lock()
|
enc.mutex.Lock()
|
||||||
defer enc.mutex.Unlock()
|
defer enc.mutex.Unlock()
|
||||||
|
|
||||||
enc.state.err = nil
|
enc.state.err = nil
|
||||||
rt, _ := indirect(reflect.Typeof(e))
|
rt, _ := indirect(value.Type())
|
||||||
|
|
||||||
// Sanity check only: encoder should never come in with data present.
|
// Sanity check only: encoder should never come in with data present.
|
||||||
if enc.state.b.Len() > 0 || enc.countState.b.Len() > 0 {
|
if enc.state.b.Len() > 0 || enc.countState.b.Len() > 0 {
|
||||||
@ -181,7 +187,7 @@ func (enc *Encoder) Encode(e interface{}) os.Error {
|
|||||||
encodeInt(enc.state, int64(enc.sent[rt]))
|
encodeInt(enc.state, int64(enc.sent[rt]))
|
||||||
|
|
||||||
// Encode the object.
|
// Encode the object.
|
||||||
err := encode(enc.state.b, e)
|
err := encode(enc.state.b, value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
enc.setError(err)
|
enc.setError(err)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user