f8d9fa9e80
This upgrades all of libgo other than the runtime package to the Go 1.4 release. In Go 1.4 much of the runtime was rewritten into Go. Merging that code will take more time and will not change the API, so I'm putting it off for now. There are a few runtime changes anyhow, to accomodate other packages that rely on minor modifications to the runtime support. The compiler changes slightly to add a one-bit flag to each type descriptor kind that is stored directly in an interface, which for gccgo is currently only pointer types. Another one-bit flag (gcprog) is reserved because it is used by the gc compiler, but gccgo does not currently use it. There is another error check in the compiler since I ran across it during testing. gotools/: * Makefile.am (go_cmd_go_files): Sort entries. Add generate.go. * Makefile.in: Rebuild. From-SVN: r219627
219 lines
6.5 KiB
Go
219 lines
6.5 KiB
Go
// 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 (
|
|
"bufio"
|
|
"errors"
|
|
"io"
|
|
"reflect"
|
|
"sync"
|
|
)
|
|
|
|
// tooBig provides a sanity check for sizes; used in several places.
|
|
// Upper limit of 1GB, allowing room to grow a little without overflow.
|
|
// TODO: make this adjustable?
|
|
const tooBig = 1 << 30
|
|
|
|
// A Decoder manages the receipt of type and data information read from the
|
|
// remote side of a connection.
|
|
type Decoder struct {
|
|
mutex sync.Mutex // each item must be received atomically
|
|
r io.Reader // source of the data
|
|
buf decBuffer // buffer for more efficient i/o from r
|
|
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
|
|
freeList *decoderState // list of free decoderStates; avoids reallocation
|
|
countBuf []byte // used for decoding integers while parsing messages
|
|
err error
|
|
}
|
|
|
|
// NewDecoder returns a new decoder that reads from the io.Reader.
|
|
// If r does not also implement io.ByteReader, it will be wrapped in a
|
|
// bufio.Reader.
|
|
func NewDecoder(r io.Reader) *Decoder {
|
|
dec := new(Decoder)
|
|
// We use the ability to read bytes as a plausible surrogate for buffering.
|
|
if _, ok := r.(io.ByteReader); !ok {
|
|
r = bufio.NewReader(r)
|
|
}
|
|
dec.r = r
|
|
dec.wireType = make(map[typeId]*wireType)
|
|
dec.decoderCache = make(map[reflect.Type]map[typeId]**decEngine)
|
|
dec.ignorerCache = make(map[typeId]**decEngine)
|
|
dec.countBuf = make([]byte, 9) // counts may be uint64s (unlikely!), require 9 bytes
|
|
|
|
return dec
|
|
}
|
|
|
|
// recvType loads the definition of a type.
|
|
func (dec *Decoder) recvType(id typeId) {
|
|
// Have we already seen this type? That's an error
|
|
if id < firstUserId || dec.wireType[id] != nil {
|
|
dec.err = errors.New("gob: duplicate type received")
|
|
return
|
|
}
|
|
|
|
// Type:
|
|
wire := new(wireType)
|
|
dec.decodeValue(tWireType, reflect.ValueOf(wire))
|
|
if dec.err != nil {
|
|
return
|
|
}
|
|
// Remember we've seen this type.
|
|
dec.wireType[id] = wire
|
|
}
|
|
|
|
var errBadCount = errors.New("invalid message length")
|
|
|
|
// recvMessage reads the next count-delimited item from the input. It is the converse
|
|
// of Encoder.writeMessage. It returns false on EOF or other error reading the message.
|
|
func (dec *Decoder) recvMessage() bool {
|
|
// Read a count.
|
|
nbytes, _, err := decodeUintReader(dec.r, dec.countBuf)
|
|
if err != nil {
|
|
dec.err = err
|
|
return false
|
|
}
|
|
if nbytes >= tooBig {
|
|
dec.err = errBadCount
|
|
return false
|
|
}
|
|
dec.readMessage(int(nbytes))
|
|
return dec.err == nil
|
|
}
|
|
|
|
// readMessage reads the next nbytes bytes from the input.
|
|
func (dec *Decoder) readMessage(nbytes int) {
|
|
if dec.buf.Len() != 0 {
|
|
// The buffer should always be empty now.
|
|
panic("non-empty decoder buffer")
|
|
}
|
|
// Read the data
|
|
dec.buf.Size(nbytes)
|
|
_, dec.err = io.ReadFull(dec.r, dec.buf.Bytes())
|
|
if dec.err != nil {
|
|
if dec.err == io.EOF {
|
|
dec.err = io.ErrUnexpectedEOF
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// 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
|
|
// resetting that buffer.
|
|
func (dec *Decoder) decodeTypeSequence(isInterface bool) typeId {
|
|
for dec.err == nil {
|
|
if dec.buf.Len() == 0 {
|
|
if !dec.recvMessage() {
|
|
break
|
|
}
|
|
}
|
|
// Receive a type id.
|
|
id := typeId(dec.nextInt())
|
|
if id >= 0 {
|
|
// Value follows.
|
|
return id
|
|
}
|
|
// 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 = errors.New("extra data in buffer")
|
|
break
|
|
}
|
|
dec.nextUint()
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
// Decode reads the next value from the input stream and stores
|
|
// it in the data represented by the empty interface value.
|
|
// If e is nil, the value will be discarded. Otherwise,
|
|
// the value underlying e must be a pointer to the
|
|
// correct type for the next data item received.
|
|
// If the input is at EOF, Decode returns io.EOF and
|
|
// does not modify e.
|
|
func (dec *Decoder) Decode(e interface{}) error {
|
|
if e == nil {
|
|
return dec.DecodeValue(reflect.Value{})
|
|
}
|
|
value := reflect.ValueOf(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 = errors.New("gob: attempt to decode into a non-pointer")
|
|
return dec.err
|
|
}
|
|
return dec.DecodeValue(value)
|
|
}
|
|
|
|
// DecodeValue reads the next value from the input stream.
|
|
// If v is the zero reflect.Value (v.Kind() == Invalid), DecodeValue discards the value.
|
|
// Otherwise, it stores the value into v. In that case, v must represent
|
|
// a non-nil pointer to data or be an assignable reflect.Value (v.CanSet())
|
|
// If the input is at EOF, DecodeValue returns io.EOF and
|
|
// does not modify v.
|
|
func (dec *Decoder) DecodeValue(v reflect.Value) error {
|
|
if v.IsValid() {
|
|
if v.Kind() == reflect.Ptr && !v.IsNil() {
|
|
// That's okay, we'll store through the pointer.
|
|
} else if !v.CanSet() {
|
|
return errors.New("gob: DecodeValue of unassignable value")
|
|
}
|
|
}
|
|
// Make sure we're single-threaded through here.
|
|
dec.mutex.Lock()
|
|
defer dec.mutex.Unlock()
|
|
|
|
dec.buf.Reset() // In case data lingers from previous invocation.
|
|
dec.err = nil
|
|
id := dec.decodeTypeSequence(false)
|
|
if dec.err == nil {
|
|
dec.decodeValue(id, v)
|
|
}
|
|
return dec.err
|
|
}
|
|
|
|
// 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.
|
|
var debugFunc func(io.Reader)
|