]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgo/go/encoding/gob/decoder.go
libgo: Update to current sources.
[thirdparty/gcc.git] / libgo / go / encoding / gob / decoder.go
CommitLineData
7a938933
ILT
1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package gob
6
7import (
8039ca76 8 "bufio"
7a938933 9 "bytes"
2fd401c8 10 "errors"
7a938933 11 "io"
7a938933
ILT
12 "reflect"
13 "sync"
14)
15
16// A Decoder manages the receipt of type and data information read from the
17// remote side of a connection.
18type Decoder struct {
19 mutex sync.Mutex // each item must be received atomically
20 r io.Reader // source of the data
5133f00e 21 buf bytes.Buffer // buffer for more efficient i/o from r
7a938933
ILT
22 wireType map[typeId]*wireType // map from remote ID to local description
23 decoderCache map[reflect.Type]map[typeId]**decEngine // cache of compiled engines
24 ignorerCache map[typeId]**decEngine // ditto for ignored objects
8039ca76 25 freeList *decoderState // list of free decoderStates; avoids reallocation
5133f00e
ILT
26 countBuf []byte // used for decoding integers while parsing messages
27 tmp []byte // temporary storage for i/o; saves reallocating
2fd401c8 28 err error
7a938933
ILT
29}
30
31// NewDecoder returns a new decoder that reads from the io.Reader.
d8f41257
ILT
32// If r does not also implement io.ByteReader, it will be wrapped in a
33// bufio.Reader.
7a938933
ILT
34func NewDecoder(r io.Reader) *Decoder {
35 dec := new(Decoder)
d8f41257
ILT
36 // We use the ability to read bytes as a plausible surrogate for buffering.
37 if _, ok := r.(io.ByteReader); !ok {
38 r = bufio.NewReader(r)
39 }
40 dec.r = r
7a938933 41 dec.wireType = make(map[typeId]*wireType)
7a938933
ILT
42 dec.decoderCache = make(map[reflect.Type]map[typeId]**decEngine)
43 dec.ignorerCache = make(map[typeId]**decEngine)
5133f00e 44 dec.countBuf = make([]byte, 9) // counts may be uint64s (unlikely!), require 9 bytes
7a938933
ILT
45
46 return dec
47}
48
5133f00e 49// recvType loads the definition of a type.
7a938933
ILT
50func (dec *Decoder) recvType(id typeId) {
51 // Have we already seen this type? That's an error
5133f00e 52 if id < firstUserId || dec.wireType[id] != nil {
2fd401c8 53 dec.err = errors.New("gob: duplicate type received")
7a938933
ILT
54 return
55 }
56
57 // Type:
58 wire := new(wireType)
9ff56c95 59 dec.decodeValue(tWireType, reflect.ValueOf(wire))
7a938933
ILT
60 if dec.err != nil {
61 return
62 }
63 // Remember we've seen this type.
64 dec.wireType[id] = wire
7a938933
ILT
65}
66
2fd401c8 67var errBadCount = errors.New("invalid message length")
d8f41257 68
5133f00e
ILT
69// recvMessage reads the next count-delimited item from the input. It is the converse
70// of Encoder.writeMessage. It returns false on EOF or other error reading the message.
71func (dec *Decoder) recvMessage() bool {
72 // Read a count.
73 nbytes, _, err := decodeUintReader(dec.r, dec.countBuf)
74 if err != nil {
75 dec.err = err
76 return false
7a938933 77 }
9af4cb95
ILT
78 // Upper limit of 1GB, allowing room to grow a little without overflow.
79 // TODO: We might want more control over this limit.
80 if nbytes >= 1<<30 {
d8f41257
ILT
81 dec.err = errBadCount
82 return false
83 }
5133f00e
ILT
84 dec.readMessage(int(nbytes))
85 return dec.err == nil
7a938933
ILT
86}
87
5133f00e
ILT
88// readMessage reads the next nbytes bytes from the input.
89func (dec *Decoder) readMessage(nbytes int) {
4ccad563
ILT
90 // Allocate the dec.tmp buffer, up to 10KB.
91 const maxBuf = 10 * 1024
92 nTmp := nbytes
93 if nTmp > maxBuf {
94 nTmp = maxBuf
7a938933 95 }
4ccad563
ILT
96 if cap(dec.tmp) < nTmp {
97 nAlloc := nTmp + 100 // A little extra for growth.
98 if nAlloc > maxBuf {
99 nAlloc = maxBuf
100 }
101 dec.tmp = make([]byte, nAlloc)
102 }
103 dec.tmp = dec.tmp[:nTmp]
7a938933
ILT
104
105 // Read the data
4ccad563
ILT
106 dec.buf.Grow(nbytes)
107 for nbytes > 0 {
108 if nbytes < nTmp {
109 dec.tmp = dec.tmp[:nbytes]
7a938933 110 }
4ccad563
ILT
111 var nRead int
112 nRead, dec.err = io.ReadFull(dec.r, dec.tmp)
113 if dec.err != nil {
114 if dec.err == io.EOF {
115 dec.err = io.ErrUnexpectedEOF
116 }
117 return
118 }
119 dec.buf.Write(dec.tmp)
120 nbytes -= nRead
7a938933
ILT
121 }
122}
123
5133f00e
ILT
124// toInt turns an encoded uint64 into an int, according to the marshaling rules.
125func toInt(x uint64) int64 {
126 i := int64(x >> 1)
127 if x&1 != 0 {
128 i = ^i
129 }
130 return i
131}
132
133func (dec *Decoder) nextInt() int64 {
134 n, _, err := decodeUintReader(&dec.buf, dec.countBuf)
135 if err != nil {
136 dec.err = err
137 }
138 return toInt(n)
139}
7a938933 140
5133f00e
ILT
141func (dec *Decoder) nextUint() uint64 {
142 n, _, err := decodeUintReader(&dec.buf, dec.countBuf)
143 if err != nil {
144 dec.err = err
145 }
146 return n
147}
148
149// decodeTypeSequence parses:
150// TypeSequence
151// (TypeDefinition DelimitedTypeDefinition*)?
152// and returns the type id of the next value. It returns -1 at
153// EOF. Upon return, the remainder of dec.buf is the value to be
154// decoded. If this is an interface value, it can be ignored by
94252f4b 155// resetting that buffer.
5133f00e
ILT
156func (dec *Decoder) decodeTypeSequence(isInterface bool) typeId {
157 for dec.err == nil {
158 if dec.buf.Len() == 0 {
159 if !dec.recvMessage() {
7a938933
ILT
160 break
161 }
7a938933 162 }
5133f00e
ILT
163 // Receive a type id.
164 id := typeId(dec.nextInt())
165 if id >= 0 {
166 // Value follows.
167 return id
7a938933 168 }
5133f00e
ILT
169 // Type definition for (-id) follows.
170 dec.recvType(-id)
171 // When decoding an interface, after a type there may be a
172 // DelimitedValue still in the buffer. Skip its count.
173 // (Alternatively, the buffer is empty and the byte count
174 // will be absorbed by recvMessage.)
175 if dec.buf.Len() > 0 {
176 if !isInterface {
2fd401c8 177 dec.err = errors.New("extra data in buffer")
7a938933
ILT
178 break
179 }
5133f00e 180 dec.nextUint()
7a938933 181 }
7a938933 182 }
5133f00e
ILT
183 return -1
184}
185
186// Decode reads the next value from the connection and stores
187// it in the data represented by the empty interface value.
188// If e is nil, the value will be discarded. Otherwise,
adb0401d
ILT
189// the value underlying e must be a pointer to the
190// correct type for the next data item received.
2fd401c8 191func (dec *Decoder) Decode(e interface{}) error {
5133f00e 192 if e == nil {
9ff56c95 193 return dec.DecodeValue(reflect.Value{})
5133f00e 194 }
9ff56c95 195 value := reflect.ValueOf(e)
5133f00e
ILT
196 // If e represents a value as opposed to a pointer, the answer won't
197 // get back to the caller. Make sure it's a pointer.
198 if value.Type().Kind() != reflect.Ptr {
2fd401c8 199 dec.err = errors.New("gob: attempt to decode into a non-pointer")
5133f00e
ILT
200 return dec.err
201 }
202 return dec.DecodeValue(value)
7a938933
ILT
203}
204
9ff56c95
ILT
205// DecodeValue reads the next value from the connection.
206// If v is the zero reflect.Value (v.Kind() == Invalid), DecodeValue discards the value.
207// Otherwise, it stores the value into v. In that case, v must represent
208// a non-nil pointer to data or be an assignable reflect.Value (v.CanSet())
2fd401c8 209func (dec *Decoder) DecodeValue(v reflect.Value) error {
9ff56c95
ILT
210 if v.IsValid() {
211 if v.Kind() == reflect.Ptr && !v.IsNil() {
212 // That's okay, we'll store through the pointer.
213 } else if !v.CanSet() {
2fd401c8 214 return errors.New("gob: DecodeValue of unassignable value")
9ff56c95
ILT
215 }
216 }
7a938933
ILT
217 // Make sure we're single-threaded through here.
218 dec.mutex.Lock()
219 defer dec.mutex.Unlock()
220
5133f00e 221 dec.buf.Reset() // In case data lingers from previous invocation.
7a938933 222 dec.err = nil
5133f00e
ILT
223 id := dec.decodeTypeSequence(false)
224 if dec.err == nil {
9ff56c95 225 dec.decodeValue(id, v)
7a938933 226 }
7a938933
ILT
227 return dec.err
228}
229
230// If debug.go is compiled into the program , debugFunc prints a human-readable
231// representation of the gob data read from r by calling that file's Debug function.
232// Otherwise it is nil.
233var debugFunc func(io.Reader)