From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- libgo/go/gob/decoder.go | 164 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 libgo/go/gob/decoder.go (limited to 'libgo/go/gob/decoder.go') diff --git a/libgo/go/gob/decoder.go b/libgo/go/gob/decoder.go new file mode 100644 index 000000000..664001a4b --- /dev/null +++ b/libgo/go/gob/decoder.go @@ -0,0 +1,164 @@ +// 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 ( + "bytes" + "io" + "os" + "reflect" + "sync" +) + +// 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 + 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 + state *decodeState // reads data from in-memory buffer + countState *decodeState // reads counts from wire + buf []byte + countBuf [9]byte // counts may be uint64s (unlikely!), require 9 bytes + byteBuffer *bytes.Buffer + err os.Error +} + +// NewDecoder returns a new decoder that reads from the io.Reader. +func NewDecoder(r io.Reader) *Decoder { + dec := new(Decoder) + dec.r = r + dec.wireType = make(map[typeId]*wireType) + dec.state = newDecodeState(dec, &dec.byteBuffer) // buffer set in Decode() + dec.decoderCache = make(map[reflect.Type]map[typeId]**decEngine) + dec.ignorerCache = make(map[typeId]**decEngine) + + return dec +} + +// recvType loads the definition of a type and reloads the Decoder's buffer. +func (dec *Decoder) recvType(id typeId) { + // Have we already seen this type? That's an error + if dec.wireType[id] != nil { + dec.err = os.ErrorString("gob: duplicate type received") + return + } + + // Type: + wire := new(wireType) + dec.err = dec.decode(tWireType, reflect.NewValue(wire)) + if dec.err != nil { + return + } + // Remember we've seen this type. + dec.wireType[id] = wire + + // Load the next parcel. + dec.recv() +} + +// Decode reads the next value from the connection and stores +// it in the data represented by the empty interface value. +// The value underlying e must be the correct type for the next +// data item received, and must be a pointer. +func (dec *Decoder) Decode(e interface{}) os.Error { + 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) +} + +// recv reads the next count-delimited item from the input. It is the converse +// of Encoder.send. +func (dec *Decoder) recv() { + // Read a count. + var nbytes uint64 + nbytes, dec.err = decodeUintReader(dec.r, dec.countBuf[0:]) + if dec.err != nil { + return + } + // Allocate the buffer. + if nbytes > uint64(len(dec.buf)) { + dec.buf = make([]byte, nbytes+1000) + } + dec.byteBuffer = bytes.NewBuffer(dec.buf[0:nbytes]) + + // Read the data + _, dec.err = io.ReadFull(dec.r, dec.buf[0:nbytes]) + if dec.err != nil { + if dec.err == os.EOF { + dec.err = io.ErrUnexpectedEOF + } + return + } +} + +// decodeValueFromBuffer grabs the next value from the input. The Decoder's +// buffer already contains data. If the next item in the buffer is a type +// descriptor, it may be necessary to reload the buffer, but recvType does that. +func (dec *Decoder) decodeValueFromBuffer(value reflect.Value, ignoreInterfaceValue, countPresent bool) { + for dec.state.b.Len() > 0 { + // Receive a type id. + id := typeId(dec.state.decodeInt()) + + // Is it a new type? + if id < 0 { // 0 is the error state, handled above + // If the id is negative, we have a type. + dec.recvType(-id) + if dec.err != nil { + break + } + continue + } + + // Make sure the type has been defined already or is a builtin type (for + // top-level singleton values). + if dec.wireType[id] == nil && builtinIdToType[id] == nil { + dec.err = errBadType + break + } + // An interface value is preceded by a byte count. + if countPresent { + count := int(dec.state.decodeUint()) + if ignoreInterfaceValue { + // An interface value is preceded by a byte count. Just skip that many bytes. + dec.state.b.Next(int(count)) + break + } + // Otherwise fall through and decode it. + } + dec.err = dec.decode(id, value) + break + } +} + +// 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. + dec.mutex.Lock() + defer dec.mutex.Unlock() + + dec.err = nil + dec.recv() + if dec.err != nil { + return dec.err + } + dec.decodeValueFromBuffer(value, false, false) + 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) -- cgit v1.2.3