1
2
3
4
5
6
7 package gob
8
9 import (
10 "encoding"
11 "encoding/binary"
12 "math"
13 "math/bits"
14 "reflect"
15 "sync"
16 )
17
18 const uint64Size = 8
19
20 type encHelper func(state *encoderState, v reflect.Value) bool
21
22
23
24
25
26 type encoderState struct {
27 enc *Encoder
28 b *encBuffer
29 sendZero bool
30 fieldnum int
31 buf [1 + uint64Size]byte
32 next *encoderState
33 }
34
35
36
37 type encBuffer struct {
38 data []byte
39 scratch [64]byte
40 }
41
42 var encBufferPool = sync.Pool{
43 New: func() any {
44 e := new(encBuffer)
45 e.data = e.scratch[0:0]
46 return e
47 },
48 }
49
50 func (e *encBuffer) writeByte(c byte) {
51 e.data = append(e.data, c)
52 }
53
54 func (e *encBuffer) Write(p []byte) (int, error) {
55 e.data = append(e.data, p...)
56 return len(p), nil
57 }
58
59 func (e *encBuffer) WriteString(s string) {
60 e.data = append(e.data, s...)
61 }
62
63 func (e *encBuffer) Len() int {
64 return len(e.data)
65 }
66
67 func (e *encBuffer) Bytes() []byte {
68 return e.data
69 }
70
71 func (e *encBuffer) Reset() {
72 if len(e.data) >= tooBig {
73 e.data = e.scratch[0:0]
74 } else {
75 e.data = e.data[0:0]
76 }
77 }
78
79 func (enc *Encoder) newEncoderState(b *encBuffer) *encoderState {
80 e := enc.freeList
81 if e == nil {
82 e = new(encoderState)
83 e.enc = enc
84 } else {
85 enc.freeList = e.next
86 }
87 e.sendZero = false
88 e.fieldnum = 0
89 e.b = b
90 if len(b.data) == 0 {
91 b.data = b.scratch[0:0]
92 }
93 return e
94 }
95
96 func (enc *Encoder) freeEncoderState(e *encoderState) {
97 e.next = enc.freeList
98 enc.freeList = e
99 }
100
101
102
103
104
105
106
107 func (state *encoderState) encodeUint(x uint64) {
108 if x <= 0x7F {
109 state.b.writeByte(uint8(x))
110 return
111 }
112
113 binary.BigEndian.PutUint64(state.buf[1:], x)
114 bc := bits.LeadingZeros64(x) >> 3
115 state.buf[bc] = uint8(bc - uint64Size)
116
117 state.b.Write(state.buf[bc : uint64Size+1])
118 }
119
120
121
122
123 func (state *encoderState) encodeInt(i int64) {
124 var x uint64
125 if i < 0 {
126 x = uint64(^i<<1) | 1
127 } else {
128 x = uint64(i << 1)
129 }
130 state.encodeUint(x)
131 }
132
133
134 type encOp func(i *encInstr, state *encoderState, v reflect.Value)
135
136
137 type encInstr struct {
138 op encOp
139 field int
140 index []int
141 indir int
142 }
143
144
145
146 func (state *encoderState) update(instr *encInstr) {
147 if instr != nil {
148 state.encodeUint(uint64(instr.field - state.fieldnum))
149 state.fieldnum = instr.field
150 }
151 }
152
153
154
155
156
157
158
159
160
161
162
163 func encIndirect(pv reflect.Value, indir int) reflect.Value {
164 for ; indir > 0; indir-- {
165 if pv.IsNil() {
166 break
167 }
168 pv = pv.Elem()
169 }
170 return pv
171 }
172
173
174 func encBool(i *encInstr, state *encoderState, v reflect.Value) {
175 b := v.Bool()
176 if b || state.sendZero {
177 state.update(i)
178 if b {
179 state.encodeUint(1)
180 } else {
181 state.encodeUint(0)
182 }
183 }
184 }
185
186
187 func encInt(i *encInstr, state *encoderState, v reflect.Value) {
188 value := v.Int()
189 if value != 0 || state.sendZero {
190 state.update(i)
191 state.encodeInt(value)
192 }
193 }
194
195
196 func encUint(i *encInstr, state *encoderState, v reflect.Value) {
197 value := v.Uint()
198 if value != 0 || state.sendZero {
199 state.update(i)
200 state.encodeUint(value)
201 }
202 }
203
204
205
206
207
208
209
210 func floatBits(f float64) uint64 {
211 u := math.Float64bits(f)
212 return bits.ReverseBytes64(u)
213 }
214
215
216 func encFloat(i *encInstr, state *encoderState, v reflect.Value) {
217 f := v.Float()
218 if f != 0 || state.sendZero {
219 bits := floatBits(f)
220 state.update(i)
221 state.encodeUint(bits)
222 }
223 }
224
225
226
227 func encComplex(i *encInstr, state *encoderState, v reflect.Value) {
228 c := v.Complex()
229 if c != 0+0i || state.sendZero {
230 rpart := floatBits(real(c))
231 ipart := floatBits(imag(c))
232 state.update(i)
233 state.encodeUint(rpart)
234 state.encodeUint(ipart)
235 }
236 }
237
238
239
240 func encUint8Array(i *encInstr, state *encoderState, v reflect.Value) {
241 b := v.Bytes()
242 if len(b) > 0 || state.sendZero {
243 state.update(i)
244 state.encodeUint(uint64(len(b)))
245 state.b.Write(b)
246 }
247 }
248
249
250
251 func encString(i *encInstr, state *encoderState, v reflect.Value) {
252 s := v.String()
253 if len(s) > 0 || state.sendZero {
254 state.update(i)
255 state.encodeUint(uint64(len(s)))
256 state.b.WriteString(s)
257 }
258 }
259
260
261
262 func encStructTerminator(i *encInstr, state *encoderState, v reflect.Value) {
263 state.encodeUint(0)
264 }
265
266
267
268
269
270 type encEngine struct {
271 instr []encInstr
272 }
273
274 const singletonField = 0
275
276
277
278 func valid(v reflect.Value) bool {
279 switch v.Kind() {
280 case reflect.Invalid:
281 return false
282 case reflect.Pointer:
283 return !v.IsNil()
284 }
285 return true
286 }
287
288
289 func (enc *Encoder) encodeSingle(b *encBuffer, engine *encEngine, value reflect.Value) {
290 state := enc.newEncoderState(b)
291 defer enc.freeEncoderState(state)
292 state.fieldnum = singletonField
293
294
295 state.sendZero = true
296 instr := &engine.instr[singletonField]
297 if instr.indir > 0 {
298 value = encIndirect(value, instr.indir)
299 }
300 if valid(value) {
301 instr.op(instr, state, value)
302 }
303 }
304
305
306 func (enc *Encoder) encodeStruct(b *encBuffer, engine *encEngine, value reflect.Value) {
307 if !valid(value) {
308 return
309 }
310 state := enc.newEncoderState(b)
311 defer enc.freeEncoderState(state)
312 state.fieldnum = -1
313 for i := 0; i < len(engine.instr); i++ {
314 instr := &engine.instr[i]
315 if i >= value.NumField() {
316
317 instr.op(instr, state, reflect.Value{})
318 break
319 }
320 field := value.FieldByIndex(instr.index)
321 if instr.indir > 0 {
322 field = encIndirect(field, instr.indir)
323
324 if !valid(field) {
325 continue
326 }
327 }
328 instr.op(instr, state, field)
329 }
330 }
331
332
333 func (enc *Encoder) encodeArray(b *encBuffer, value reflect.Value, op encOp, elemIndir int, length int, helper encHelper) {
334 state := enc.newEncoderState(b)
335 defer enc.freeEncoderState(state)
336 state.fieldnum = -1
337 state.sendZero = true
338 state.encodeUint(uint64(length))
339 if helper != nil && helper(state, value) {
340 return
341 }
342 for i := 0; i < length; i++ {
343 elem := value.Index(i)
344 if elemIndir > 0 {
345 elem = encIndirect(elem, elemIndir)
346
347 if !valid(elem) {
348 errorf("encodeArray: nil element")
349 }
350 }
351 op(nil, state, elem)
352 }
353 }
354
355
356 func encodeReflectValue(state *encoderState, v reflect.Value, op encOp, indir int) {
357 for i := 0; i < indir && v.IsValid(); i++ {
358 v = reflect.Indirect(v)
359 }
360 if !v.IsValid() {
361 errorf("encodeReflectValue: nil element")
362 }
363 op(nil, state, v)
364 }
365
366
367 func (enc *Encoder) encodeMap(b *encBuffer, mv reflect.Value, keyOp, elemOp encOp, keyIndir, elemIndir int) {
368 state := enc.newEncoderState(b)
369 state.fieldnum = -1
370 state.sendZero = true
371 state.encodeUint(uint64(mv.Len()))
372 mi := mv.MapRange()
373 for mi.Next() {
374 encodeReflectValue(state, mi.Key(), keyOp, keyIndir)
375 encodeReflectValue(state, mi.Value(), elemOp, elemIndir)
376 }
377 enc.freeEncoderState(state)
378 }
379
380
381
382
383
384
385 func (enc *Encoder) encodeInterface(b *encBuffer, iv reflect.Value) {
386
387
388 elem := iv.Elem()
389 if elem.Kind() == reflect.Pointer && elem.IsNil() {
390 errorf("gob: cannot encode nil pointer of type %s inside interface", iv.Elem().Type())
391 }
392 state := enc.newEncoderState(b)
393 state.fieldnum = -1
394 state.sendZero = true
395 if iv.IsNil() {
396 state.encodeUint(0)
397 return
398 }
399
400 ut := userType(iv.Elem().Type())
401 namei, ok := concreteTypeToName.Load(ut.base)
402 if !ok {
403 errorf("type not registered for interface: %s", ut.base)
404 }
405 name := namei.(string)
406
407
408 state.encodeUint(uint64(len(name)))
409 state.b.WriteString(name)
410
411 enc.sendTypeDescriptor(enc.writer(), state, ut)
412
413 enc.sendTypeId(state, ut)
414
415
416 enc.pushWriter(b)
417 data := encBufferPool.Get().(*encBuffer)
418 data.Write(spaceForLength)
419 enc.encode(data, elem, ut)
420 if enc.err != nil {
421 error_(enc.err)
422 }
423 enc.popWriter()
424 enc.writeMessage(b, data)
425 data.Reset()
426 encBufferPool.Put(data)
427 if enc.err != nil {
428 error_(enc.err)
429 }
430 enc.freeEncoderState(state)
431 }
432
433
434
435 func (enc *Encoder) encodeGobEncoder(b *encBuffer, ut *userTypeInfo, v reflect.Value) {
436
437
438 var data []byte
439 var err error
440
441 switch ut.externalEnc {
442 case xGob:
443 data, err = v.Interface().(GobEncoder).GobEncode()
444 case xBinary:
445 data, err = v.Interface().(encoding.BinaryMarshaler).MarshalBinary()
446 case xText:
447 data, err = v.Interface().(encoding.TextMarshaler).MarshalText()
448 }
449 if err != nil {
450 error_(err)
451 }
452 state := enc.newEncoderState(b)
453 state.fieldnum = -1
454 state.encodeUint(uint64(len(data)))
455 state.b.Write(data)
456 enc.freeEncoderState(state)
457 }
458
459 var encOpTable = [...]encOp{
460 reflect.Bool: encBool,
461 reflect.Int: encInt,
462 reflect.Int8: encInt,
463 reflect.Int16: encInt,
464 reflect.Int32: encInt,
465 reflect.Int64: encInt,
466 reflect.Uint: encUint,
467 reflect.Uint8: encUint,
468 reflect.Uint16: encUint,
469 reflect.Uint32: encUint,
470 reflect.Uint64: encUint,
471 reflect.Uintptr: encUint,
472 reflect.Float32: encFloat,
473 reflect.Float64: encFloat,
474 reflect.Complex64: encComplex,
475 reflect.Complex128: encComplex,
476 reflect.String: encString,
477 }
478
479
480
481 func encOpFor(rt reflect.Type, inProgress map[reflect.Type]*encOp, building map[*typeInfo]bool) (*encOp, int) {
482 ut := userType(rt)
483
484 if ut.externalEnc != 0 {
485 return gobEncodeOpFor(ut)
486 }
487
488
489 if opPtr := inProgress[rt]; opPtr != nil {
490 return opPtr, ut.indir
491 }
492 typ := ut.base
493 indir := ut.indir
494 k := typ.Kind()
495 var op encOp
496 if int(k) < len(encOpTable) {
497 op = encOpTable[k]
498 }
499 if op == nil {
500 inProgress[rt] = &op
501
502 switch t := typ; t.Kind() {
503 case reflect.Slice:
504 if t.Elem().Kind() == reflect.Uint8 {
505 op = encUint8Array
506 break
507 }
508
509 elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
510 helper := encSliceHelper[t.Elem().Kind()]
511 op = func(i *encInstr, state *encoderState, slice reflect.Value) {
512 if !state.sendZero && slice.Len() == 0 {
513 return
514 }
515 state.update(i)
516 state.enc.encodeArray(state.b, slice, *elemOp, elemIndir, slice.Len(), helper)
517 }
518 case reflect.Array:
519
520 elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
521 helper := encArrayHelper[t.Elem().Kind()]
522 op = func(i *encInstr, state *encoderState, array reflect.Value) {
523 state.update(i)
524 state.enc.encodeArray(state.b, array, *elemOp, elemIndir, array.Len(), helper)
525 }
526 case reflect.Map:
527 keyOp, keyIndir := encOpFor(t.Key(), inProgress, building)
528 elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
529 op = func(i *encInstr, state *encoderState, mv reflect.Value) {
530
531
532 if !state.sendZero && mv.IsNil() {
533 return
534 }
535 state.update(i)
536 state.enc.encodeMap(state.b, mv, *keyOp, *elemOp, keyIndir, elemIndir)
537 }
538 case reflect.Struct:
539
540 getEncEngine(userType(typ), building)
541 info := mustGetTypeInfo(typ)
542 op = func(i *encInstr, state *encoderState, sv reflect.Value) {
543 state.update(i)
544
545 enc := info.encoder.Load()
546 state.enc.encodeStruct(state.b, enc, sv)
547 }
548 case reflect.Interface:
549 op = func(i *encInstr, state *encoderState, iv reflect.Value) {
550 if !state.sendZero && (!iv.IsValid() || iv.IsNil()) {
551 return
552 }
553 state.update(i)
554 state.enc.encodeInterface(state.b, iv)
555 }
556 }
557 }
558 if op == nil {
559 errorf("can't happen: encode type %s", rt)
560 }
561 return &op, indir
562 }
563
564
565 func gobEncodeOpFor(ut *userTypeInfo) (*encOp, int) {
566 rt := ut.user
567 if ut.encIndir == -1 {
568 rt = reflect.PointerTo(rt)
569 } else if ut.encIndir > 0 {
570 for i := int8(0); i < ut.encIndir; i++ {
571 rt = rt.Elem()
572 }
573 }
574 var op encOp
575 op = func(i *encInstr, state *encoderState, v reflect.Value) {
576 if ut.encIndir == -1 {
577
578 if !v.CanAddr() {
579 errorf("unaddressable value of type %s", rt)
580 }
581 v = v.Addr()
582 }
583 if !state.sendZero && v.IsZero() {
584 return
585 }
586 state.update(i)
587 state.enc.encodeGobEncoder(state.b, ut, v)
588 }
589 return &op, int(ut.encIndir)
590 }
591
592
593 func compileEnc(ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
594 srt := ut.base
595 engine := new(encEngine)
596 seen := make(map[reflect.Type]*encOp)
597 rt := ut.base
598 if ut.externalEnc != 0 {
599 rt = ut.user
600 }
601 if ut.externalEnc == 0 && srt.Kind() == reflect.Struct {
602 for fieldNum, wireFieldNum := 0, 0; fieldNum < srt.NumField(); fieldNum++ {
603 f := srt.Field(fieldNum)
604 if !isSent(&f) {
605 continue
606 }
607 op, indir := encOpFor(f.Type, seen, building)
608 engine.instr = append(engine.instr, encInstr{*op, wireFieldNum, f.Index, indir})
609 wireFieldNum++
610 }
611 if srt.NumField() > 0 && len(engine.instr) == 0 {
612 errorf("type %s has no exported fields", rt)
613 }
614 engine.instr = append(engine.instr, encInstr{encStructTerminator, 0, nil, 0})
615 } else {
616 engine.instr = make([]encInstr, 1)
617 op, indir := encOpFor(rt, seen, building)
618 engine.instr[0] = encInstr{*op, singletonField, nil, indir}
619 }
620 return engine
621 }
622
623
624 func getEncEngine(ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
625 info, err := getTypeInfo(ut)
626 if err != nil {
627 error_(err)
628 }
629 enc := info.encoder.Load()
630 if enc == nil {
631 enc = buildEncEngine(info, ut, building)
632 }
633 return enc
634 }
635
636 func buildEncEngine(info *typeInfo, ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
637
638 if building != nil && building[info] {
639 return nil
640 }
641 info.encInit.Lock()
642 defer info.encInit.Unlock()
643 enc := info.encoder.Load()
644 if enc == nil {
645 if building == nil {
646 building = make(map[*typeInfo]bool)
647 }
648 building[info] = true
649 enc = compileEnc(ut, building)
650 info.encoder.Store(enc)
651 }
652 return enc
653 }
654
655 func (enc *Encoder) encode(b *encBuffer, value reflect.Value, ut *userTypeInfo) {
656 defer catchError(&enc.err)
657 engine := getEncEngine(ut, nil)
658 indir := ut.indir
659 if ut.externalEnc != 0 {
660 indir = int(ut.encIndir)
661 }
662 for i := 0; i < indir; i++ {
663 value = reflect.Indirect(value)
664 }
665 if ut.externalEnc == 0 && value.Type().Kind() == reflect.Struct {
666 enc.encodeStruct(b, engine, value)
667 } else {
668 enc.encodeSingle(b, engine, value)
669 }
670 }
671
View as plain text