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 gobEncoder, _ := reflect.TypeAssert[GobEncoder](v)
444 data, err = gobEncoder.GobEncode()
445 case xBinary:
446 binaryMarshaler, _ := reflect.TypeAssert[encoding.BinaryMarshaler](v)
447 data, err = binaryMarshaler.MarshalBinary()
448 case xText:
449 textMarshaler, _ := reflect.TypeAssert[encoding.TextMarshaler](v)
450 data, err = textMarshaler.MarshalText()
451 }
452 if err != nil {
453 error_(err)
454 }
455 state := enc.newEncoderState(b)
456 state.fieldnum = -1
457 state.encodeUint(uint64(len(data)))
458 state.b.Write(data)
459 enc.freeEncoderState(state)
460 }
461
462 var encOpTable = [...]encOp{
463 reflect.Bool: encBool,
464 reflect.Int: encInt,
465 reflect.Int8: encInt,
466 reflect.Int16: encInt,
467 reflect.Int32: encInt,
468 reflect.Int64: encInt,
469 reflect.Uint: encUint,
470 reflect.Uint8: encUint,
471 reflect.Uint16: encUint,
472 reflect.Uint32: encUint,
473 reflect.Uint64: encUint,
474 reflect.Uintptr: encUint,
475 reflect.Float32: encFloat,
476 reflect.Float64: encFloat,
477 reflect.Complex64: encComplex,
478 reflect.Complex128: encComplex,
479 reflect.String: encString,
480 }
481
482
483
484 func encOpFor(rt reflect.Type, inProgress map[reflect.Type]*encOp, building map[*typeInfo]bool) (*encOp, int) {
485 ut := userType(rt)
486
487 if ut.externalEnc != 0 {
488 return gobEncodeOpFor(ut)
489 }
490
491
492 if opPtr := inProgress[rt]; opPtr != nil {
493 return opPtr, ut.indir
494 }
495 typ := ut.base
496 indir := ut.indir
497 k := typ.Kind()
498 var op encOp
499 if int(k) < len(encOpTable) {
500 op = encOpTable[k]
501 }
502 if op == nil {
503 inProgress[rt] = &op
504
505 switch t := typ; t.Kind() {
506 case reflect.Slice:
507 if t.Elem().Kind() == reflect.Uint8 {
508 op = encUint8Array
509 break
510 }
511
512 elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
513 helper := encSliceHelper[t.Elem().Kind()]
514 op = func(i *encInstr, state *encoderState, slice reflect.Value) {
515 if !state.sendZero && slice.Len() == 0 {
516 return
517 }
518 state.update(i)
519 state.enc.encodeArray(state.b, slice, *elemOp, elemIndir, slice.Len(), helper)
520 }
521 case reflect.Array:
522
523 elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
524 helper := encArrayHelper[t.Elem().Kind()]
525 op = func(i *encInstr, state *encoderState, array reflect.Value) {
526 state.update(i)
527 state.enc.encodeArray(state.b, array, *elemOp, elemIndir, array.Len(), helper)
528 }
529 case reflect.Map:
530 keyOp, keyIndir := encOpFor(t.Key(), inProgress, building)
531 elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
532 op = func(i *encInstr, state *encoderState, mv reflect.Value) {
533
534
535 if !state.sendZero && mv.IsNil() {
536 return
537 }
538 state.update(i)
539 state.enc.encodeMap(state.b, mv, *keyOp, *elemOp, keyIndir, elemIndir)
540 }
541 case reflect.Struct:
542
543 getEncEngine(userType(typ), building)
544 info := mustGetTypeInfo(typ)
545 op = func(i *encInstr, state *encoderState, sv reflect.Value) {
546 state.update(i)
547
548 enc := info.encoder.Load()
549 state.enc.encodeStruct(state.b, enc, sv)
550 }
551 case reflect.Interface:
552 op = func(i *encInstr, state *encoderState, iv reflect.Value) {
553 if !state.sendZero && (!iv.IsValid() || iv.IsNil()) {
554 return
555 }
556 state.update(i)
557 state.enc.encodeInterface(state.b, iv)
558 }
559 }
560 }
561 if op == nil {
562 errorf("can't happen: encode type %s", rt)
563 }
564 return &op, indir
565 }
566
567
568 func gobEncodeOpFor(ut *userTypeInfo) (*encOp, int) {
569 rt := ut.user
570 if ut.encIndir == -1 {
571 rt = reflect.PointerTo(rt)
572 } else if ut.encIndir > 0 {
573 for i := int8(0); i < ut.encIndir; i++ {
574 rt = rt.Elem()
575 }
576 }
577 var op encOp
578 op = func(i *encInstr, state *encoderState, v reflect.Value) {
579 if ut.encIndir == -1 {
580
581 if !v.CanAddr() {
582 errorf("unaddressable value of type %s", rt)
583 }
584 v = v.Addr()
585 }
586 if !state.sendZero && v.IsZero() {
587 return
588 }
589 state.update(i)
590 state.enc.encodeGobEncoder(state.b, ut, v)
591 }
592 return &op, int(ut.encIndir)
593 }
594
595
596 func compileEnc(ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
597 srt := ut.base
598 engine := new(encEngine)
599 seen := make(map[reflect.Type]*encOp)
600 rt := ut.base
601 if ut.externalEnc != 0 {
602 rt = ut.user
603 }
604 if ut.externalEnc == 0 && srt.Kind() == reflect.Struct {
605 for fieldNum, wireFieldNum := 0, 0; fieldNum < srt.NumField(); fieldNum++ {
606 f := srt.Field(fieldNum)
607 if !isSent(&f) {
608 continue
609 }
610 op, indir := encOpFor(f.Type, seen, building)
611 engine.instr = append(engine.instr, encInstr{*op, wireFieldNum, f.Index, indir})
612 wireFieldNum++
613 }
614 if srt.NumField() > 0 && len(engine.instr) == 0 {
615 errorf("type %s has no exported fields", rt)
616 }
617 engine.instr = append(engine.instr, encInstr{encStructTerminator, 0, nil, 0})
618 } else {
619 engine.instr = make([]encInstr, 1)
620 op, indir := encOpFor(rt, seen, building)
621 engine.instr[0] = encInstr{*op, singletonField, nil, indir}
622 }
623 return engine
624 }
625
626
627 func getEncEngine(ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
628 info, err := getTypeInfo(ut)
629 if err != nil {
630 error_(err)
631 }
632 enc := info.encoder.Load()
633 if enc == nil {
634 enc = buildEncEngine(info, ut, building)
635 }
636 return enc
637 }
638
639 func buildEncEngine(info *typeInfo, ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
640
641 if building != nil && building[info] {
642 return nil
643 }
644 info.encInit.Lock()
645 defer info.encInit.Unlock()
646 enc := info.encoder.Load()
647 if enc == nil {
648 if building == nil {
649 building = make(map[*typeInfo]bool)
650 }
651 building[info] = true
652 enc = compileEnc(ut, building)
653 info.encoder.Store(enc)
654 }
655 return enc
656 }
657
658 func (enc *Encoder) encode(b *encBuffer, value reflect.Value, ut *userTypeInfo) {
659 defer catchError(&enc.err)
660 engine := getEncEngine(ut, nil)
661 indir := ut.indir
662 if ut.externalEnc != 0 {
663 indir = int(ut.encIndir)
664 }
665 for i := 0; i < indir; i++ {
666 value = reflect.Indirect(value)
667 }
668 if ut.externalEnc == 0 && value.Kind() == reflect.Struct {
669 enc.encodeStruct(b, engine, value)
670 } else {
671 enc.encodeSingle(b, engine, value)
672 }
673 }
674
View as plain text