LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package gob | 5 package gob |
6 | 6 |
7 import ( | 7 import ( |
8 "bufio" | 8 "bufio" |
9 "bytes" | |
10 "errors" | 9 "errors" |
11 "io" | 10 "io" |
12 "reflect" | 11 "reflect" |
13 "sync" | 12 "sync" |
14 ) | 13 ) |
15 | 14 |
| 15 // tooBig provides a sanity check for sizes; used in several places. |
| 16 // Upper limit of 1GB, allowing room to grow a little without overflow. |
| 17 // TODO: make this adjustable? |
| 18 const tooBig = 1 << 30 |
| 19 |
16 // A Decoder manages the receipt of type and data information read from the | 20 // A Decoder manages the receipt of type and data information read from the |
17 // remote side of a connection. | 21 // remote side of a connection. |
18 type Decoder struct { | 22 type Decoder struct { |
19 mutex sync.Mutex // each item must b
e received atomically | 23 mutex sync.Mutex // each item must b
e received atomically |
20 r io.Reader // source of the da
ta | 24 r io.Reader // source of the da
ta |
21 » buf bytes.Buffer // buffer for more
efficient i/o from r | 25 » buf decBuffer // buffer for more
efficient i/o from r |
22 wireType map[typeId]*wireType // map from remote
ID to local description | 26 wireType map[typeId]*wireType // map from remote
ID to local description |
23 decoderCache map[reflect.Type]map[typeId]**decEngine // cache of compile
d engines | 27 decoderCache map[reflect.Type]map[typeId]**decEngine // cache of compile
d engines |
24 ignorerCache map[typeId]**decEngine // ditto for ignore
d objects | 28 ignorerCache map[typeId]**decEngine // ditto for ignore
d objects |
25 freeList *decoderState // list of free dec
oderStates; avoids reallocation | 29 freeList *decoderState // list of free dec
oderStates; avoids reallocation |
26 countBuf []byte // used for decodin
g integers while parsing messages | 30 countBuf []byte // used for decodin
g integers while parsing messages |
27 tmp []byte // temporary storag
e for i/o; saves reallocating | |
28 err error | 31 err error |
29 } | 32 } |
30 | 33 |
31 // NewDecoder returns a new decoder that reads from the io.Reader. | 34 // NewDecoder returns a new decoder that reads from the io.Reader. |
32 // If r does not also implement io.ByteReader, it will be wrapped in a | 35 // If r does not also implement io.ByteReader, it will be wrapped in a |
33 // bufio.Reader. | 36 // bufio.Reader. |
34 func NewDecoder(r io.Reader) *Decoder { | 37 func NewDecoder(r io.Reader) *Decoder { |
35 dec := new(Decoder) | 38 dec := new(Decoder) |
36 // We use the ability to read bytes as a plausible surrogate for bufferi
ng. | 39 // We use the ability to read bytes as a plausible surrogate for bufferi
ng. |
37 if _, ok := r.(io.ByteReader); !ok { | 40 if _, ok := r.(io.ByteReader); !ok { |
(...skipping 30 matching lines...) Expand all Loading... |
68 | 71 |
69 // recvMessage reads the next count-delimited item from the input. It is the con
verse | 72 // recvMessage reads the next count-delimited item from the input. It is the con
verse |
70 // of Encoder.writeMessage. It returns false on EOF or other error reading the m
essage. | 73 // of Encoder.writeMessage. It returns false on EOF or other error reading the m
essage. |
71 func (dec *Decoder) recvMessage() bool { | 74 func (dec *Decoder) recvMessage() bool { |
72 // Read a count. | 75 // Read a count. |
73 nbytes, _, err := decodeUintReader(dec.r, dec.countBuf) | 76 nbytes, _, err := decodeUintReader(dec.r, dec.countBuf) |
74 if err != nil { | 77 if err != nil { |
75 dec.err = err | 78 dec.err = err |
76 return false | 79 return false |
77 } | 80 } |
78 » // Upper limit of 1GB, allowing room to grow a little without overflow. | 81 » if nbytes >= tooBig { |
79 » // TODO: We might want more control over this limit. | |
80 » if nbytes >= 1<<30 { | |
81 dec.err = errBadCount | 82 dec.err = errBadCount |
82 return false | 83 return false |
83 } | 84 } |
84 dec.readMessage(int(nbytes)) | 85 dec.readMessage(int(nbytes)) |
85 return dec.err == nil | 86 return dec.err == nil |
86 } | 87 } |
87 | 88 |
88 // readMessage reads the next nbytes bytes from the input. | 89 // readMessage reads the next nbytes bytes from the input. |
89 func (dec *Decoder) readMessage(nbytes int) { | 90 func (dec *Decoder) readMessage(nbytes int) { |
90 » // Allocate the dec.tmp buffer, up to 10KB. | 91 » if dec.buf.Len() != 0 { |
91 » const maxBuf = 10 * 1024 | 92 » » // The buffer should always be empty now. |
92 » nTmp := nbytes | 93 » » panic("non-empty decoder buffer") |
93 » if nTmp > maxBuf { | 94 » } |
94 » » nTmp = maxBuf | |
95 » } | |
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] | |
104 | |
105 // Read the data | 95 // Read the data |
106 » dec.buf.Grow(nbytes) | 96 » dec.buf.Size(nbytes) |
107 » for nbytes > 0 { | 97 » _, dec.err = io.ReadFull(dec.r, dec.buf.Bytes()) |
108 » » if nbytes < nTmp { | 98 » if dec.err != nil { |
109 » » » dec.tmp = dec.tmp[:nbytes] | 99 » » if dec.err == io.EOF { |
110 » » } | 100 » » » dec.err = io.ErrUnexpectedEOF |
111 » » var nRead int | 101 » » } |
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 | |
121 } | 102 } |
122 } | 103 } |
123 | 104 |
124 // toInt turns an encoded uint64 into an int, according to the marshaling rules. | 105 // toInt turns an encoded uint64 into an int, according to the marshaling rules. |
125 func toInt(x uint64) int64 { | 106 func toInt(x uint64) int64 { |
126 i := int64(x >> 1) | 107 i := int64(x >> 1) |
127 if x&1 != 0 { | 108 if x&1 != 0 { |
128 i = ^i | 109 i = ^i |
129 } | 110 } |
130 return i | 111 return i |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 return dec.err | 183 return dec.err |
203 } | 184 } |
204 return dec.DecodeValue(value) | 185 return dec.DecodeValue(value) |
205 } | 186 } |
206 | 187 |
207 // DecodeValue reads the next value from the input stream. | 188 // DecodeValue reads the next value from the input stream. |
208 // If v is the zero reflect.Value (v.Kind() == Invalid), DecodeValue discards th
e value. | 189 // If v is the zero reflect.Value (v.Kind() == Invalid), DecodeValue discards th
e value. |
209 // Otherwise, it stores the value into v. In that case, v must represent | 190 // Otherwise, it stores the value into v. In that case, v must represent |
210 // a non-nil pointer to data or be an assignable reflect.Value (v.CanSet()) | 191 // a non-nil pointer to data or be an assignable reflect.Value (v.CanSet()) |
211 // If the input is at EOF, DecodeValue returns io.EOF and | 192 // If the input is at EOF, DecodeValue returns io.EOF and |
212 // does not modify e. | 193 // does not modify v. |
213 func (dec *Decoder) DecodeValue(v reflect.Value) error { | 194 func (dec *Decoder) DecodeValue(v reflect.Value) error { |
214 if v.IsValid() { | 195 if v.IsValid() { |
215 if v.Kind() == reflect.Ptr && !v.IsNil() { | 196 if v.Kind() == reflect.Ptr && !v.IsNil() { |
216 // That's okay, we'll store through the pointer. | 197 // That's okay, we'll store through the pointer. |
217 } else if !v.CanSet() { | 198 } else if !v.CanSet() { |
218 return errors.New("gob: DecodeValue of unassignable valu
e") | 199 return errors.New("gob: DecodeValue of unassignable valu
e") |
219 } | 200 } |
220 } | 201 } |
221 // Make sure we're single-threaded through here. | 202 // Make sure we're single-threaded through here. |
222 dec.mutex.Lock() | 203 dec.mutex.Lock() |
223 defer dec.mutex.Unlock() | 204 defer dec.mutex.Unlock() |
224 | 205 |
225 dec.buf.Reset() // In case data lingers from previous invocation. | 206 dec.buf.Reset() // In case data lingers from previous invocation. |
226 dec.err = nil | 207 dec.err = nil |
227 id := dec.decodeTypeSequence(false) | 208 id := dec.decodeTypeSequence(false) |
228 if dec.err == nil { | 209 if dec.err == nil { |
229 dec.decodeValue(id, v) | 210 dec.decodeValue(id, v) |
230 } | 211 } |
231 return dec.err | 212 return dec.err |
232 } | 213 } |
233 | 214 |
234 // If debug.go is compiled into the program , debugFunc prints a human-readable | 215 // If debug.go is compiled into the program , debugFunc prints a human-readable |
235 // representation of the gob data read from r by calling that file's Debug funct
ion. | 216 // representation of the gob data read from r by calling that file's Debug funct
ion. |
236 // Otherwise it is nil. | 217 // Otherwise it is nil. |
237 var debugFunc func(io.Reader) | 218 var debugFunc func(io.Reader) |
LEFT | RIGHT |