OLD | NEW |
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 "bytes" | 8 "bytes" |
9 "io" | 9 "io" |
10 "math" | 10 "math" |
(...skipping 19 matching lines...) Expand all Loading... |
30 func newEncoderState(enc *Encoder, b *bytes.Buffer) *encoderState { | 30 func newEncoderState(enc *Encoder, b *bytes.Buffer) *encoderState { |
31 return &encoderState{enc: enc, b: b} | 31 return &encoderState{enc: enc, b: b} |
32 } | 32 } |
33 | 33 |
34 // Unsigned integers have a two-state encoding. If the number is less | 34 // Unsigned integers have a two-state encoding. If the number is less |
35 // than 128 (0 through 0x7F), its value is written directly. | 35 // than 128 (0 through 0x7F), its value is written directly. |
36 // Otherwise the value is written in big-endian byte order preceded | 36 // Otherwise the value is written in big-endian byte order preceded |
37 // by the byte length, negated. | 37 // by the byte length, negated. |
38 | 38 |
39 // encodeUint writes an encoded unsigned integer to state.b. | 39 // encodeUint writes an encoded unsigned integer to state.b. |
40 func encodeUint(state *encoderState, x uint64) { | 40 func (state *encoderState) encodeUint(x uint64) { |
41 if x <= 0x7F { | 41 if x <= 0x7F { |
42 err := state.b.WriteByte(uint8(x)) | 42 err := state.b.WriteByte(uint8(x)) |
43 if err != nil { | 43 if err != nil { |
44 error(err) | 44 error(err) |
45 } | 45 } |
46 return | 46 return |
47 } | 47 } |
48 var n, m int | 48 var n, m int |
49 m = uint64Size | 49 m = uint64Size |
50 for n = 1; x > 0; n++ { | 50 for n = 1; x > 0; n++ { |
51 state.buf[m] = uint8(x & 0xFF) | 51 state.buf[m] = uint8(x & 0xFF) |
52 x >>= 8 | 52 x >>= 8 |
53 m-- | 53 m-- |
54 } | 54 } |
55 state.buf[m] = uint8(-(n - 1)) | 55 state.buf[m] = uint8(-(n - 1)) |
56 n, err := state.b.Write(state.buf[m : uint64Size+1]) | 56 n, err := state.b.Write(state.buf[m : uint64Size+1]) |
57 if err != nil { | 57 if err != nil { |
58 error(err) | 58 error(err) |
59 } | 59 } |
60 } | 60 } |
61 | 61 |
62 // encodeInt writes an encoded signed integer to state.w. | 62 // encodeInt writes an encoded signed integer to state.w. |
63 // The low bit of the encoding says whether to bit complement the (other bits of
the) | 63 // The low bit of the encoding says whether to bit complement the (other bits of
the) |
64 // uint to recover the int. | 64 // uint to recover the int. |
65 func encodeInt(state *encoderState, i int64) { | 65 func (state *encoderState) encodeInt(i int64) { |
66 var x uint64 | 66 var x uint64 |
67 if i < 0 { | 67 if i < 0 { |
68 x = uint64(^i<<1) | 1 | 68 x = uint64(^i<<1) | 1 |
69 } else { | 69 } else { |
70 x = uint64(i << 1) | 70 x = uint64(i << 1) |
71 } | 71 } |
72 » encodeUint(state, uint64(x)) | 72 » state.encodeUint(uint64(x)) |
73 } | 73 } |
74 | 74 |
75 type encOp func(i *encInstr, state *encoderState, p unsafe.Pointer) | 75 type encOp func(i *encInstr, state *encoderState, p unsafe.Pointer) |
76 | 76 |
77 // The 'instructions' of the encoding machine | 77 // The 'instructions' of the encoding machine |
78 type encInstr struct { | 78 type encInstr struct { |
79 op encOp | 79 op encOp |
80 field int // field number | 80 field int // field number |
81 indir int // how many pointer indirections to reach the value in th
e struct | 81 indir int // how many pointer indirections to reach the value in th
e struct |
82 offset uintptr // offset in the structure of the field to encode | 82 offset uintptr // offset in the structure of the field to encode |
83 } | 83 } |
84 | 84 |
85 // Emit a field number and update the state to record its value for delta encodi
ng. | 85 // Emit a field number and update the state to record its value for delta encodi
ng. |
86 // If the instruction pointer is nil, do nothing | 86 // If the instruction pointer is nil, do nothing |
87 func (state *encoderState) update(instr *encInstr) { | 87 func (state *encoderState) update(instr *encInstr) { |
88 if instr != nil { | 88 if instr != nil { |
89 » » encodeUint(state, uint64(instr.field-state.fieldnum)) | 89 » » state.encodeUint(uint64(instr.field - state.fieldnum)) |
90 state.fieldnum = instr.field | 90 state.fieldnum = instr.field |
91 } | 91 } |
92 } | 92 } |
93 | 93 |
94 // Each encoder is responsible for handling any indirections associated | 94 // Each encoder is responsible for handling any indirections associated |
95 // with the data structure. If any pointer so reached is nil, no bytes are writ
ten. | 95 // with the data structure. If any pointer so reached is nil, no bytes are writ
ten. |
96 // If the data item is zero, no bytes are written. | 96 // If the data item is zero, no bytes are written. |
97 // Otherwise, the output (for a scalar) is the field number, as an encoded integ
er, | 97 // Otherwise, the output (for a scalar) is the field number, as an encoded integ
er, |
98 // followed by the field data in its appropriate format. | 98 // followed by the field data in its appropriate format. |
99 | 99 |
100 func encIndirect(p unsafe.Pointer, indir int) unsafe.Pointer { | 100 func encIndirect(p unsafe.Pointer, indir int) unsafe.Pointer { |
101 for ; indir > 0; indir-- { | 101 for ; indir > 0; indir-- { |
102 p = *(*unsafe.Pointer)(p) | 102 p = *(*unsafe.Pointer)(p) |
103 if p == nil { | 103 if p == nil { |
104 return unsafe.Pointer(nil) | 104 return unsafe.Pointer(nil) |
105 } | 105 } |
106 } | 106 } |
107 return p | 107 return p |
108 } | 108 } |
109 | 109 |
110 func encBool(i *encInstr, state *encoderState, p unsafe.Pointer) { | 110 func encBool(i *encInstr, state *encoderState, p unsafe.Pointer) { |
111 b := *(*bool)(p) | 111 b := *(*bool)(p) |
112 if b || state.sendZero { | 112 if b || state.sendZero { |
113 state.update(i) | 113 state.update(i) |
114 if b { | 114 if b { |
115 » » » encodeUint(state, 1) | 115 » » » state.encodeUint(1) |
116 } else { | 116 } else { |
117 » » » encodeUint(state, 0) | 117 » » » state.encodeUint(0) |
118 } | 118 } |
119 } | 119 } |
120 } | 120 } |
121 | 121 |
122 func encInt(i *encInstr, state *encoderState, p unsafe.Pointer) { | 122 func encInt(i *encInstr, state *encoderState, p unsafe.Pointer) { |
123 v := int64(*(*int)(p)) | 123 v := int64(*(*int)(p)) |
124 if v != 0 || state.sendZero { | 124 if v != 0 || state.sendZero { |
125 state.update(i) | 125 state.update(i) |
126 » » encodeInt(state, v) | 126 » » state.encodeInt(v) |
127 } | 127 } |
128 } | 128 } |
129 | 129 |
130 func encUint(i *encInstr, state *encoderState, p unsafe.Pointer) { | 130 func encUint(i *encInstr, state *encoderState, p unsafe.Pointer) { |
131 v := uint64(*(*uint)(p)) | 131 v := uint64(*(*uint)(p)) |
132 if v != 0 || state.sendZero { | 132 if v != 0 || state.sendZero { |
133 state.update(i) | 133 state.update(i) |
134 » » encodeUint(state, v) | 134 » » state.encodeUint(v) |
135 } | 135 } |
136 } | 136 } |
137 | 137 |
138 func encInt8(i *encInstr, state *encoderState, p unsafe.Pointer) { | 138 func encInt8(i *encInstr, state *encoderState, p unsafe.Pointer) { |
139 v := int64(*(*int8)(p)) | 139 v := int64(*(*int8)(p)) |
140 if v != 0 || state.sendZero { | 140 if v != 0 || state.sendZero { |
141 state.update(i) | 141 state.update(i) |
142 » » encodeInt(state, v) | 142 » » state.encodeInt(v) |
143 } | 143 } |
144 } | 144 } |
145 | 145 |
146 func encUint8(i *encInstr, state *encoderState, p unsafe.Pointer) { | 146 func encUint8(i *encInstr, state *encoderState, p unsafe.Pointer) { |
147 v := uint64(*(*uint8)(p)) | 147 v := uint64(*(*uint8)(p)) |
148 if v != 0 || state.sendZero { | 148 if v != 0 || state.sendZero { |
149 state.update(i) | 149 state.update(i) |
150 » » encodeUint(state, v) | 150 » » state.encodeUint(v) |
151 } | 151 } |
152 } | 152 } |
153 | 153 |
154 func encInt16(i *encInstr, state *encoderState, p unsafe.Pointer) { | 154 func encInt16(i *encInstr, state *encoderState, p unsafe.Pointer) { |
155 v := int64(*(*int16)(p)) | 155 v := int64(*(*int16)(p)) |
156 if v != 0 || state.sendZero { | 156 if v != 0 || state.sendZero { |
157 state.update(i) | 157 state.update(i) |
158 » » encodeInt(state, v) | 158 » » state.encodeInt(v) |
159 } | 159 } |
160 } | 160 } |
161 | 161 |
162 func encUint16(i *encInstr, state *encoderState, p unsafe.Pointer) { | 162 func encUint16(i *encInstr, state *encoderState, p unsafe.Pointer) { |
163 v := uint64(*(*uint16)(p)) | 163 v := uint64(*(*uint16)(p)) |
164 if v != 0 || state.sendZero { | 164 if v != 0 || state.sendZero { |
165 state.update(i) | 165 state.update(i) |
166 » » encodeUint(state, v) | 166 » » state.encodeUint(v) |
167 } | 167 } |
168 } | 168 } |
169 | 169 |
170 func encInt32(i *encInstr, state *encoderState, p unsafe.Pointer) { | 170 func encInt32(i *encInstr, state *encoderState, p unsafe.Pointer) { |
171 v := int64(*(*int32)(p)) | 171 v := int64(*(*int32)(p)) |
172 if v != 0 || state.sendZero { | 172 if v != 0 || state.sendZero { |
173 state.update(i) | 173 state.update(i) |
174 » » encodeInt(state, v) | 174 » » state.encodeInt(v) |
175 } | 175 } |
176 } | 176 } |
177 | 177 |
178 func encUint32(i *encInstr, state *encoderState, p unsafe.Pointer) { | 178 func encUint32(i *encInstr, state *encoderState, p unsafe.Pointer) { |
179 v := uint64(*(*uint32)(p)) | 179 v := uint64(*(*uint32)(p)) |
180 if v != 0 || state.sendZero { | 180 if v != 0 || state.sendZero { |
181 state.update(i) | 181 state.update(i) |
182 » » encodeUint(state, v) | 182 » » state.encodeUint(v) |
183 } | 183 } |
184 } | 184 } |
185 | 185 |
186 func encInt64(i *encInstr, state *encoderState, p unsafe.Pointer) { | 186 func encInt64(i *encInstr, state *encoderState, p unsafe.Pointer) { |
187 v := *(*int64)(p) | 187 v := *(*int64)(p) |
188 if v != 0 || state.sendZero { | 188 if v != 0 || state.sendZero { |
189 state.update(i) | 189 state.update(i) |
190 » » encodeInt(state, v) | 190 » » state.encodeInt(v) |
191 } | 191 } |
192 } | 192 } |
193 | 193 |
194 func encUint64(i *encInstr, state *encoderState, p unsafe.Pointer) { | 194 func encUint64(i *encInstr, state *encoderState, p unsafe.Pointer) { |
195 v := *(*uint64)(p) | 195 v := *(*uint64)(p) |
196 if v != 0 || state.sendZero { | 196 if v != 0 || state.sendZero { |
197 state.update(i) | 197 state.update(i) |
198 » » encodeUint(state, v) | 198 » » state.encodeUint(v) |
199 } | 199 } |
200 } | 200 } |
201 | 201 |
202 func encUintptr(i *encInstr, state *encoderState, p unsafe.Pointer) { | 202 func encUintptr(i *encInstr, state *encoderState, p unsafe.Pointer) { |
203 v := uint64(*(*uintptr)(p)) | 203 v := uint64(*(*uintptr)(p)) |
204 if v != 0 || state.sendZero { | 204 if v != 0 || state.sendZero { |
205 state.update(i) | 205 state.update(i) |
206 » » encodeUint(state, v) | 206 » » state.encodeUint(v) |
207 } | 207 } |
208 } | 208 } |
209 | 209 |
210 // Floating-point numbers are transmitted as uint64s holding the bits | 210 // Floating-point numbers are transmitted as uint64s holding the bits |
211 // of the underlying representation. They are sent byte-reversed, with | 211 // of the underlying representation. They are sent byte-reversed, with |
212 // the exponent end coming out first, so integer floating point numbers | 212 // the exponent end coming out first, so integer floating point numbers |
213 // (for example) transmit more compactly. This routine does the | 213 // (for example) transmit more compactly. This routine does the |
214 // swizzling. | 214 // swizzling. |
215 func floatBits(f float64) uint64 { | 215 func floatBits(f float64) uint64 { |
216 u := math.Float64bits(f) | 216 u := math.Float64bits(f) |
217 var v uint64 | 217 var v uint64 |
218 for i := 0; i < 8; i++ { | 218 for i := 0; i < 8; i++ { |
219 v <<= 8 | 219 v <<= 8 |
220 v |= u & 0xFF | 220 v |= u & 0xFF |
221 u >>= 8 | 221 u >>= 8 |
222 } | 222 } |
223 return v | 223 return v |
224 } | 224 } |
225 | 225 |
226 func encFloat(i *encInstr, state *encoderState, p unsafe.Pointer) { | 226 func encFloat(i *encInstr, state *encoderState, p unsafe.Pointer) { |
227 f := *(*float)(p) | 227 f := *(*float)(p) |
228 if f != 0 || state.sendZero { | 228 if f != 0 || state.sendZero { |
229 v := floatBits(float64(f)) | 229 v := floatBits(float64(f)) |
230 state.update(i) | 230 state.update(i) |
231 » » encodeUint(state, v) | 231 » » state.encodeUint(v) |
232 } | 232 } |
233 } | 233 } |
234 | 234 |
235 func encFloat32(i *encInstr, state *encoderState, p unsafe.Pointer) { | 235 func encFloat32(i *encInstr, state *encoderState, p unsafe.Pointer) { |
236 f := *(*float32)(p) | 236 f := *(*float32)(p) |
237 if f != 0 || state.sendZero { | 237 if f != 0 || state.sendZero { |
238 v := floatBits(float64(f)) | 238 v := floatBits(float64(f)) |
239 state.update(i) | 239 state.update(i) |
240 » » encodeUint(state, v) | 240 » » state.encodeUint(v) |
241 } | 241 } |
242 } | 242 } |
243 | 243 |
244 func encFloat64(i *encInstr, state *encoderState, p unsafe.Pointer) { | 244 func encFloat64(i *encInstr, state *encoderState, p unsafe.Pointer) { |
245 f := *(*float64)(p) | 245 f := *(*float64)(p) |
246 if f != 0 || state.sendZero { | 246 if f != 0 || state.sendZero { |
247 state.update(i) | 247 state.update(i) |
248 v := floatBits(f) | 248 v := floatBits(f) |
249 » » encodeUint(state, v) | 249 » » state.encodeUint(v) |
250 } | 250 } |
251 } | 251 } |
252 | 252 |
253 // Complex numbers are just a pair of floating-point numbers, real part first. | 253 // Complex numbers are just a pair of floating-point numbers, real part first. |
254 func encComplex(i *encInstr, state *encoderState, p unsafe.Pointer) { | 254 func encComplex(i *encInstr, state *encoderState, p unsafe.Pointer) { |
255 c := *(*complex)(p) | 255 c := *(*complex)(p) |
256 if c != 0+0i || state.sendZero { | 256 if c != 0+0i || state.sendZero { |
257 rpart := floatBits(float64(real(c))) | 257 rpart := floatBits(float64(real(c))) |
258 ipart := floatBits(float64(imag(c))) | 258 ipart := floatBits(float64(imag(c))) |
259 state.update(i) | 259 state.update(i) |
260 » » encodeUint(state, rpart) | 260 » » state.encodeUint(rpart) |
261 » » encodeUint(state, ipart) | 261 » » state.encodeUint(ipart) |
262 } | 262 } |
263 } | 263 } |
264 | 264 |
265 func encComplex64(i *encInstr, state *encoderState, p unsafe.Pointer) { | 265 func encComplex64(i *encInstr, state *encoderState, p unsafe.Pointer) { |
266 c := *(*complex64)(p) | 266 c := *(*complex64)(p) |
267 if c != 0+0i || state.sendZero { | 267 if c != 0+0i || state.sendZero { |
268 rpart := floatBits(float64(real(c))) | 268 rpart := floatBits(float64(real(c))) |
269 ipart := floatBits(float64(imag(c))) | 269 ipart := floatBits(float64(imag(c))) |
270 state.update(i) | 270 state.update(i) |
271 » » encodeUint(state, rpart) | 271 » » state.encodeUint(rpart) |
272 » » encodeUint(state, ipart) | 272 » » state.encodeUint(ipart) |
273 } | 273 } |
274 } | 274 } |
275 | 275 |
276 func encComplex128(i *encInstr, state *encoderState, p unsafe.Pointer) { | 276 func encComplex128(i *encInstr, state *encoderState, p unsafe.Pointer) { |
277 c := *(*complex128)(p) | 277 c := *(*complex128)(p) |
278 if c != 0+0i || state.sendZero { | 278 if c != 0+0i || state.sendZero { |
279 rpart := floatBits(real(c)) | 279 rpart := floatBits(real(c)) |
280 ipart := floatBits(imag(c)) | 280 ipart := floatBits(imag(c)) |
281 state.update(i) | 281 state.update(i) |
282 » » encodeUint(state, rpart) | 282 » » state.encodeUint(rpart) |
283 » » encodeUint(state, ipart) | 283 » » state.encodeUint(ipart) |
284 } | 284 } |
285 } | 285 } |
286 | 286 |
287 func encNoOp(i *encInstr, state *encoderState, p unsafe.Pointer) { | 287 func encNoOp(i *encInstr, state *encoderState, p unsafe.Pointer) { |
288 } | 288 } |
289 | 289 |
290 // Byte arrays are encoded as an unsigned count followed by the raw bytes. | 290 // Byte arrays are encoded as an unsigned count followed by the raw bytes. |
291 func encUint8Array(i *encInstr, state *encoderState, p unsafe.Pointer) { | 291 func encUint8Array(i *encInstr, state *encoderState, p unsafe.Pointer) { |
292 b := *(*[]byte)(p) | 292 b := *(*[]byte)(p) |
293 if len(b) > 0 || state.sendZero { | 293 if len(b) > 0 || state.sendZero { |
294 state.update(i) | 294 state.update(i) |
295 » » encodeUint(state, uint64(len(b))) | 295 » » state.encodeUint(uint64(len(b))) |
296 state.b.Write(b) | 296 state.b.Write(b) |
297 } | 297 } |
298 } | 298 } |
299 | 299 |
300 // Strings are encoded as an unsigned count followed by the raw bytes. | 300 // Strings are encoded as an unsigned count followed by the raw bytes. |
301 func encString(i *encInstr, state *encoderState, p unsafe.Pointer) { | 301 func encString(i *encInstr, state *encoderState, p unsafe.Pointer) { |
302 s := *(*string)(p) | 302 s := *(*string)(p) |
303 if len(s) > 0 || state.sendZero { | 303 if len(s) > 0 || state.sendZero { |
304 state.update(i) | 304 state.update(i) |
305 » » encodeUint(state, uint64(len(s))) | 305 » » state.encodeUint(uint64(len(s))) |
306 io.WriteString(state.b, s) | 306 io.WriteString(state.b, s) |
307 } | 307 } |
308 } | 308 } |
309 | 309 |
310 // The end of a struct is marked by a delta field number of 0. | 310 // The end of a struct is marked by a delta field number of 0. |
311 func encStructTerminator(i *encInstr, state *encoderState, p unsafe.Pointer) { | 311 func encStructTerminator(i *encInstr, state *encoderState, p unsafe.Pointer) { |
312 » encodeUint(state, 0) | 312 » state.encodeUint(0) |
313 } | 313 } |
314 | 314 |
315 // Execution engine | 315 // Execution engine |
316 | 316 |
317 // The encoder engine is an array of instructions indexed by field number of the
encoding | 317 // The encoder engine is an array of instructions indexed by field number of the
encoding |
318 // data, typically a struct. It is executed top to bottom, walking the struct. | 318 // data, typically a struct. It is executed top to bottom, walking the struct. |
319 type encEngine struct { | 319 type encEngine struct { |
320 instr []encInstr | 320 instr []encInstr |
321 } | 321 } |
322 | 322 |
(...skipping 27 matching lines...) Expand all Loading... |
350 } | 350 } |
351 } | 351 } |
352 instr.op(instr, state, p) | 352 instr.op(instr, state, p) |
353 } | 353 } |
354 } | 354 } |
355 | 355 |
356 func (enc *Encoder) encodeArray(b *bytes.Buffer, p uintptr, op encOp, elemWid ui
ntptr, elemIndir int, length int) { | 356 func (enc *Encoder) encodeArray(b *bytes.Buffer, p uintptr, op encOp, elemWid ui
ntptr, elemIndir int, length int) { |
357 state := newEncoderState(enc, b) | 357 state := newEncoderState(enc, b) |
358 state.fieldnum = -1 | 358 state.fieldnum = -1 |
359 state.sendZero = true | 359 state.sendZero = true |
360 » encodeUint(state, uint64(length)) | 360 » state.encodeUint(uint64(length)) |
361 for i := 0; i < length; i++ { | 361 for i := 0; i < length; i++ { |
362 elemp := p | 362 elemp := p |
363 up := unsafe.Pointer(elemp) | 363 up := unsafe.Pointer(elemp) |
364 if elemIndir > 0 { | 364 if elemIndir > 0 { |
365 if up = encIndirect(up, elemIndir); up == nil { | 365 if up = encIndirect(up, elemIndir); up == nil { |
366 errorf("gob: encodeArray: nil element") | 366 errorf("gob: encodeArray: nil element") |
367 } | 367 } |
368 elemp = uintptr(up) | 368 elemp = uintptr(up) |
369 } | 369 } |
370 op(nil, state, unsafe.Pointer(elemp)) | 370 op(nil, state, unsafe.Pointer(elemp)) |
371 p += uintptr(elemWid) | 371 p += uintptr(elemWid) |
372 } | 372 } |
373 } | 373 } |
374 | 374 |
375 func encodeReflectValue(state *encoderState, v reflect.Value, op encOp, indir in
t) { | 375 func encodeReflectValue(state *encoderState, v reflect.Value, op encOp, indir in
t) { |
376 for i := 0; i < indir && v != nil; i++ { | 376 for i := 0; i < indir && v != nil; i++ { |
377 v = reflect.Indirect(v) | 377 v = reflect.Indirect(v) |
378 } | 378 } |
379 if v == nil { | 379 if v == nil { |
380 errorf("gob: encodeReflectValue: nil element") | 380 errorf("gob: encodeReflectValue: nil element") |
381 } | 381 } |
382 op(nil, state, unsafe.Pointer(v.Addr())) | 382 op(nil, state, unsafe.Pointer(v.Addr())) |
383 } | 383 } |
384 | 384 |
385 func (enc *Encoder) encodeMap(b *bytes.Buffer, mv *reflect.MapValue, keyOp, elem
Op encOp, keyIndir, elemIndir int) { | 385 func (enc *Encoder) encodeMap(b *bytes.Buffer, mv *reflect.MapValue, keyOp, elem
Op encOp, keyIndir, elemIndir int) { |
386 state := newEncoderState(enc, b) | 386 state := newEncoderState(enc, b) |
387 state.fieldnum = -1 | 387 state.fieldnum = -1 |
388 state.sendZero = true | 388 state.sendZero = true |
389 keys := mv.Keys() | 389 keys := mv.Keys() |
390 » encodeUint(state, uint64(len(keys))) | 390 » state.encodeUint(uint64(len(keys))) |
391 for _, key := range keys { | 391 for _, key := range keys { |
392 encodeReflectValue(state, key, keyOp, keyIndir) | 392 encodeReflectValue(state, key, keyOp, keyIndir) |
393 encodeReflectValue(state, mv.Elem(key), elemOp, elemIndir) | 393 encodeReflectValue(state, mv.Elem(key), elemOp, elemIndir) |
394 } | 394 } |
395 } | 395 } |
396 | 396 |
397 // To send an interface, we send a string identifying the concrete type, followe
d | 397 // To send an interface, we send a string identifying the concrete type, followe
d |
398 // by the type identifier (which might require defining that type right now), fo
llowed | 398 // by the type identifier (which might require defining that type right now), fo
llowed |
399 // by the concrete value. A nil value gets sent as the empty string for the nam
e, | 399 // by the concrete value. A nil value gets sent as the empty string for the nam
e, |
400 // followed by no value. | 400 // followed by no value. |
401 func (enc *Encoder) encodeInterface(b *bytes.Buffer, iv *reflect.InterfaceValue)
{ | 401 func (enc *Encoder) encodeInterface(b *bytes.Buffer, iv *reflect.InterfaceValue)
{ |
402 state := newEncoderState(enc, b) | 402 state := newEncoderState(enc, b) |
403 state.fieldnum = -1 | 403 state.fieldnum = -1 |
404 state.sendZero = true | 404 state.sendZero = true |
405 if iv.IsNil() { | 405 if iv.IsNil() { |
406 » » encodeUint(state, 0) | 406 » » state.encodeUint(0) |
407 return | 407 return |
408 } | 408 } |
409 | 409 |
410 typ, _ := indirect(iv.Elem().Type()) | 410 typ, _ := indirect(iv.Elem().Type()) |
411 name, ok := concreteTypeToName[typ] | 411 name, ok := concreteTypeToName[typ] |
412 if !ok { | 412 if !ok { |
413 errorf("gob: type not registered for interface: %s", typ) | 413 errorf("gob: type not registered for interface: %s", typ) |
414 } | 414 } |
415 // Send the name. | 415 // Send the name. |
416 » encodeUint(state, uint64(len(name))) | 416 » state.encodeUint(uint64(len(name))) |
417 _, err := io.WriteString(state.b, name) | 417 _, err := io.WriteString(state.b, name) |
418 if err != nil { | 418 if err != nil { |
419 error(err) | 419 error(err) |
420 } | 420 } |
421 // Send (and maybe first define) the type id. | 421 // Send (and maybe first define) the type id. |
422 enc.sendTypeDescriptor(typ) | 422 enc.sendTypeDescriptor(typ) |
423 // Encode the value into a new buffer. | 423 // Encode the value into a new buffer. |
424 data := new(bytes.Buffer) | 424 data := new(bytes.Buffer) |
425 err = enc.encode(data, iv.Elem()) | 425 err = enc.encode(data, iv.Elem()) |
426 if err != nil { | 426 if err != nil { |
427 error(err) | 427 error(err) |
428 } | 428 } |
429 » encodeUint(state, uint64(data.Len())) | 429 » state.encodeUint(uint64(data.Len())) |
430 _, err = state.b.Write(data.Bytes()) | 430 _, err = state.b.Write(data.Bytes()) |
431 if err != nil { | 431 if err != nil { |
432 error(err) | 432 error(err) |
433 } | 433 } |
434 } | 434 } |
435 | 435 |
436 var encOpMap = []encOp{ | 436 var encOpMap = []encOp{ |
437 reflect.Bool: encBool, | 437 reflect.Bool: encBool, |
438 reflect.Int: encInt, | 438 reflect.Int: encInt, |
439 reflect.Int8: encInt8, | 439 reflect.Int8: encInt8, |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 value = reflect.Indirect(value) | 586 value = reflect.Indirect(value) |
587 } | 587 } |
588 engine := enc.lockAndGetEncEngine(rt) | 588 engine := enc.lockAndGetEncEngine(rt) |
589 if value.Type().Kind() == reflect.Struct { | 589 if value.Type().Kind() == reflect.Struct { |
590 enc.encodeStruct(b, engine, value.Addr()) | 590 enc.encodeStruct(b, engine, value.Addr()) |
591 } else { | 591 } else { |
592 enc.encodeSingle(b, engine, value.Addr()) | 592 enc.encodeSingle(b, engine, value.Addr()) |
593 } | 593 } |
594 return nil | 594 return nil |
595 } | 595 } |
OLD | NEW |