2009-07-11 15:45:54 -07:00
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package gob
|
|
|
|
|
|
|
|
|
|
import (
|
2009-12-15 15:35:38 -08:00
|
|
|
"bytes"
|
|
|
|
|
"io"
|
|
|
|
|
"os"
|
|
|
|
|
"reflect"
|
|
|
|
|
"sync"
|
2009-07-11 15:45:54 -07:00
|
|
|
)
|
|
|
|
|
|
2009-07-27 11:02:06 -07:00
|
|
|
// A Decoder manages the receipt of type and data information read from the
|
|
|
|
|
// remote side of a connection.
|
2009-07-11 15:45:54 -07:00
|
|
|
type Decoder struct {
|
2009-12-15 15:35:38 -08:00
|
|
|
mutex sync.Mutex // each item must be received atomically
|
|
|
|
|
r io.Reader // source of the data
|
2011-01-28 10:53:42 -08:00
|
|
|
buf bytes.Buffer // buffer for more efficient i/o from r
|
2009-12-15 15:35:38 -08:00
|
|
|
wireType map[typeId]*wireType // map from remote ID to local description
|
|
|
|
|
decoderCache map[reflect.Type]map[typeId]**decEngine // cache of compiled engines
|
|
|
|
|
ignorerCache map[typeId]**decEngine // ditto for ignored objects
|
gob: beginning of support for GobEncoder/GobDecoder interfaces.
This allows a data item that can marshal itself to be transmitted by its
own encoding, enabling some types to be handled that cannot be
normally, plus providing a way to use gobs on data with unexported
fields.
In this CL, the necessary methods are protected by leading _, so only
package gob can use the facilities (in its tests, of course); this
code is not ready for real use yet. I could be talked into enabling
it for experimentation, though. The main drawback is that the
methods must be implemented by the actual type passed through,
not by an indirection from it. For instance, if *T implements
GobEncoder, you must send a *T, not a T. This will be addressed
in due course.
Also there is improved commentary and a couple of unrelated
minor bug fixes.
R=rsc
CC=golang-dev
https://golang.org/cl/4243056
2011-03-04 12:25:18 -08:00
|
|
|
countState *decoderState // reads counts from wire
|
2011-01-28 10:53:42 -08:00
|
|
|
countBuf []byte // used for decoding integers while parsing messages
|
|
|
|
|
tmp []byte // temporary storage for i/o; saves reallocating
|
2010-10-22 15:16:34 -07:00
|
|
|
err os.Error
|
2009-07-11 15:45:54 -07:00
|
|
|
}
|
|
|
|
|
|
2009-07-27 11:02:06 -07:00
|
|
|
// NewDecoder returns a new decoder that reads from the io.Reader.
|
2009-07-11 15:45:54 -07:00
|
|
|
func NewDecoder(r io.Reader) *Decoder {
|
2009-12-15 15:35:38 -08:00
|
|
|
dec := new(Decoder)
|
|
|
|
|
dec.r = r
|
|
|
|
|
dec.wireType = make(map[typeId]*wireType)
|
|
|
|
|
dec.decoderCache = make(map[reflect.Type]map[typeId]**decEngine)
|
|
|
|
|
dec.ignorerCache = make(map[typeId]**decEngine)
|
2011-01-28 10:53:42 -08:00
|
|
|
dec.countBuf = make([]byte, 9) // counts may be uint64s (unlikely!), require 9 bytes
|
2009-07-11 15:45:54 -07:00
|
|
|
|
2009-12-15 15:35:38 -08:00
|
|
|
return dec
|
2009-07-11 15:45:54 -07:00
|
|
|
}
|
|
|
|
|
|
2011-01-28 10:53:42 -08:00
|
|
|
// recvType loads the definition of a type.
|
2009-07-27 11:02:06 -07:00
|
|
|
func (dec *Decoder) recvType(id typeId) {
|
2009-07-11 15:45:54 -07:00
|
|
|
// Have we already seen this type? That's an error
|
2011-01-28 10:53:42 -08:00
|
|
|
if id < firstUserId || dec.wireType[id] != nil {
|
2010-10-22 15:16:34 -07:00
|
|
|
dec.err = os.ErrorString("gob: duplicate type received")
|
2009-12-15 15:35:38 -08:00
|
|
|
return
|
2009-07-11 15:45:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Type:
|
2009-12-15 15:35:38 -08:00
|
|
|
wire := new(wireType)
|
2011-01-28 10:53:42 -08:00
|
|
|
dec.err = dec.decodeValue(tWireType, reflect.NewValue(wire))
|
2010-10-22 15:16:34 -07:00
|
|
|
if dec.err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
2009-07-11 15:45:54 -07:00
|
|
|
// Remember we've seen this type.
|
2009-12-15 15:35:38 -08:00
|
|
|
dec.wireType[id] = wire
|
2010-06-28 17:11:54 -07:00
|
|
|
}
|
2009-12-01 21:47:00 -08:00
|
|
|
|
2011-01-21 11:28:53 -08:00
|
|
|
// recvMessage reads the next count-delimited item from the input. It is the converse
|
2011-01-28 10:53:42 -08:00
|
|
|
// of Encoder.writeMessage. It returns false on EOF or other error reading the message.
|
|
|
|
|
func (dec *Decoder) recvMessage() bool {
|
2010-10-22 11:17:40 -07:00
|
|
|
// Read a count.
|
2011-01-28 10:53:42 -08:00
|
|
|
nbytes, _, err := decodeUintReader(dec.r, dec.countBuf)
|
|
|
|
|
if err != nil {
|
|
|
|
|
dec.err = err
|
|
|
|
|
return false
|
2010-10-22 11:17:40 -07:00
|
|
|
}
|
2011-01-28 10:53:42 -08:00
|
|
|
dec.readMessage(int(nbytes))
|
|
|
|
|
return dec.err == nil
|
2011-01-21 11:28:53 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// readMessage reads the next nbytes bytes from the input.
|
2011-01-28 10:53:42 -08:00
|
|
|
func (dec *Decoder) readMessage(nbytes int) {
|
2010-10-22 11:17:40 -07:00
|
|
|
// Allocate the buffer.
|
2011-01-28 10:53:42 -08:00
|
|
|
if cap(dec.tmp) < nbytes {
|
|
|
|
|
dec.tmp = make([]byte, nbytes+100) // room to grow
|
2010-10-22 11:17:40 -07:00
|
|
|
}
|
2011-01-28 10:53:42 -08:00
|
|
|
dec.tmp = dec.tmp[:nbytes]
|
2009-07-16 13:05:46 -07:00
|
|
|
|
2010-10-22 11:17:40 -07:00
|
|
|
// Read the data
|
2011-01-28 10:53:42 -08:00
|
|
|
_, dec.err = io.ReadFull(dec.r, dec.tmp)
|
2010-10-22 15:16:34 -07:00
|
|
|
if dec.err != nil {
|
|
|
|
|
if dec.err == os.EOF {
|
|
|
|
|
dec.err = io.ErrUnexpectedEOF
|
2009-07-15 16:10:17 -07:00
|
|
|
}
|
2010-10-22 11:17:40 -07:00
|
|
|
return
|
|
|
|
|
}
|
2011-01-28 10:53:42 -08:00
|
|
|
dec.buf.Write(dec.tmp)
|
2010-10-22 11:17:40 -07:00
|
|
|
}
|
2009-07-15 16:10:17 -07:00
|
|
|
|
2011-01-28 10:53:42 -08:00
|
|
|
// toInt turns an encoded uint64 into an int, according to the marshaling rules.
|
|
|
|
|
func toInt(x uint64) int64 {
|
|
|
|
|
i := int64(x >> 1)
|
|
|
|
|
if x&1 != 0 {
|
|
|
|
|
i = ^i
|
|
|
|
|
}
|
|
|
|
|
return i
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (dec *Decoder) nextInt() int64 {
|
|
|
|
|
n, _, err := decodeUintReader(&dec.buf, dec.countBuf)
|
|
|
|
|
if err != nil {
|
|
|
|
|
dec.err = err
|
|
|
|
|
}
|
|
|
|
|
return toInt(n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (dec *Decoder) nextUint() uint64 {
|
|
|
|
|
n, _, err := decodeUintReader(&dec.buf, dec.countBuf)
|
|
|
|
|
if err != nil {
|
|
|
|
|
dec.err = err
|
|
|
|
|
}
|
|
|
|
|
return n
|
|
|
|
|
}
|
2009-07-11 15:45:54 -07:00
|
|
|
|
2011-01-28 10:53:42 -08:00
|
|
|
// decodeTypeSequence parses:
|
|
|
|
|
// TypeSequence
|
|
|
|
|
// (TypeDefinition DelimitedTypeDefinition*)?
|
|
|
|
|
// and returns the type id of the next value. It returns -1 at
|
|
|
|
|
// EOF. Upon return, the remainder of dec.buf is the value to be
|
|
|
|
|
// decoded. If this is an interface value, it can be ignored by
|
|
|
|
|
// simply resetting that buffer.
|
|
|
|
|
func (dec *Decoder) decodeTypeSequence(isInterface bool) typeId {
|
|
|
|
|
for dec.err == nil {
|
|
|
|
|
if dec.buf.Len() == 0 {
|
|
|
|
|
if !dec.recvMessage() {
|
2009-11-09 12:07:39 -08:00
|
|
|
break
|
2009-07-15 16:10:17 -07:00
|
|
|
}
|
2009-07-11 15:45:54 -07:00
|
|
|
}
|
2011-01-28 10:53:42 -08:00
|
|
|
// Receive a type id.
|
|
|
|
|
id := typeId(dec.nextInt())
|
|
|
|
|
if id >= 0 {
|
|
|
|
|
// Value follows.
|
|
|
|
|
return id
|
2009-11-16 23:32:30 -08:00
|
|
|
}
|
2011-01-28 10:53:42 -08:00
|
|
|
// Type definition for (-id) follows.
|
|
|
|
|
dec.recvType(-id)
|
|
|
|
|
// When decoding an interface, after a type there may be a
|
|
|
|
|
// DelimitedValue still in the buffer. Skip its count.
|
|
|
|
|
// (Alternatively, the buffer is empty and the byte count
|
|
|
|
|
// will be absorbed by recvMessage.)
|
|
|
|
|
if dec.buf.Len() > 0 {
|
|
|
|
|
if !isInterface {
|
|
|
|
|
dec.err = os.ErrorString("extra data in buffer")
|
2010-10-31 13:41:30 -07:00
|
|
|
break
|
|
|
|
|
}
|
2011-01-28 10:53:42 -08:00
|
|
|
dec.nextUint()
|
2010-10-31 13:41:30 -07:00
|
|
|
}
|
2009-07-11 15:45:54 -07:00
|
|
|
}
|
2011-01-28 10:53:42 -08:00
|
|
|
return -1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Decode reads the next value from the connection and stores
|
|
|
|
|
// it in the data represented by the empty interface value.
|
2011-02-12 18:03:54 -08:00
|
|
|
// If e is nil, the value will be discarded. Otherwise,
|
|
|
|
|
// the value underlying e must either be the correct type for the next
|
2011-01-28 10:53:42 -08:00
|
|
|
// data item received, and must be a pointer.
|
|
|
|
|
func (dec *Decoder) Decode(e interface{}) os.Error {
|
2011-02-12 18:03:54 -08:00
|
|
|
if e == nil {
|
|
|
|
|
return dec.DecodeValue(nil)
|
|
|
|
|
}
|
2011-01-28 10:53:42 -08:00
|
|
|
value := reflect.NewValue(e)
|
|
|
|
|
// If e represents a value as opposed to a pointer, the answer won't
|
|
|
|
|
// get back to the caller. Make sure it's a pointer.
|
|
|
|
|
if value.Type().Kind() != reflect.Ptr {
|
|
|
|
|
dec.err = os.ErrorString("gob: attempt to decode into a non-pointer")
|
|
|
|
|
return dec.err
|
|
|
|
|
}
|
|
|
|
|
return dec.DecodeValue(value)
|
2010-10-22 11:17:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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
|
2011-02-12 18:03:54 -08:00
|
|
|
// data item received, or it may be nil, which means the
|
|
|
|
|
// value will be discarded.
|
2010-10-22 11:17:40 -07:00
|
|
|
func (dec *Decoder) DecodeValue(value reflect.Value) os.Error {
|
|
|
|
|
// Make sure we're single-threaded through here.
|
|
|
|
|
dec.mutex.Lock()
|
|
|
|
|
defer dec.mutex.Unlock()
|
|
|
|
|
|
2011-01-28 10:53:42 -08:00
|
|
|
dec.buf.Reset() // In case data lingers from previous invocation.
|
2010-10-22 15:16:34 -07:00
|
|
|
dec.err = nil
|
2011-01-28 10:53:42 -08:00
|
|
|
id := dec.decodeTypeSequence(false)
|
2011-02-14 10:17:30 -08:00
|
|
|
if dec.err == nil {
|
|
|
|
|
dec.err = dec.decodeValue(id, value)
|
2010-10-22 11:17:40 -07:00
|
|
|
}
|
2010-10-22 15:16:34 -07:00
|
|
|
return dec.err
|
2009-07-11 15:45:54 -07:00
|
|
|
}
|
2010-10-29 15:07:56 -07:00
|
|
|
|
2010-10-29 15:52:25 -07:00
|
|
|
// If debug.go is compiled into the program , debugFunc prints a human-readable
|
|
|
|
|
// representation of the gob data read from r by calling that file's Debug function.
|
|
|
|
|
// Otherwise it is nil.
|
2010-10-29 15:07:56 -07:00
|
|
|
var debugFunc func(io.Reader)
|