1
2
3
4
5
6
7
8
9
10
11 package json
12
13 import (
14 "bytes"
15 "encoding"
16 "encoding/base64"
17 "fmt"
18 "math"
19 "reflect"
20 "sort"
21 "strconv"
22 "strings"
23 "sync"
24 "unicode"
25 "unicode/utf8"
26 )
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 func Marshal(v any) ([]byte, error) {
158 e := newEncodeState()
159 defer encodeStatePool.Put(e)
160
161 err := e.marshal(v, encOpts{escapeHTML: true})
162 if err != nil {
163 return nil, err
164 }
165 buf := append([]byte(nil), e.Bytes()...)
166
167 return buf, nil
168 }
169
170 func MarshalEscaped(v any, escape bool) ([]byte, error) {
171 e := newEncodeState()
172 defer encodeStatePool.Put(e)
173
174 err := e.marshal(v, encOpts{escapeHTML: escape})
175 if err != nil {
176 return nil, err
177 }
178 buf := append([]byte(nil), e.Bytes()...)
179
180 return buf, nil
181 }
182
183
184
185
186 func MarshalIndent(v any, prefix, indent string) ([]byte, error) {
187 b, err := Marshal(v)
188 if err != nil {
189 return nil, err
190 }
191 var buf bytes.Buffer
192 err = Indent(&buf, b, prefix, indent)
193 if err != nil {
194 return nil, err
195 }
196 return buf.Bytes(), nil
197 }
198
199
200
201
202
203
204
205 func HTMLEscape(dst *bytes.Buffer, src []byte) {
206
207
208 start := 0
209 for i, c := range src {
210 if c == '<' || c == '>' || c == '&' {
211 if start < i {
212 dst.Write(src[start:i])
213 }
214 dst.WriteString(`\u00`)
215 dst.WriteByte(hex[c>>4])
216 dst.WriteByte(hex[c&0xF])
217 start = i + 1
218 }
219
220 if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
221 if start < i {
222 dst.Write(src[start:i])
223 }
224 dst.WriteString(`\u202`)
225 dst.WriteByte(hex[src[i+2]&0xF])
226 start = i + 3
227 }
228 }
229 if start < len(src) {
230 dst.Write(src[start:])
231 }
232 }
233
234
235
236 type Marshaler interface {
237 MarshalJSON() ([]byte, error)
238 }
239
240 type RedirectMarshaler interface {
241 RedirectMarshalJSON() (any, error)
242 }
243
244 type TrustMarshaler interface {
245 TrustMarshalJSON(b *bytes.Buffer) error
246 }
247
248
249
250 type UnsupportedTypeError struct {
251 Type reflect.Type
252 }
253
254 func (e *UnsupportedTypeError) Error() string {
255 return "json: unsupported type: " + e.Type.String()
256 }
257
258
259
260 type UnsupportedValueError struct {
261 Value reflect.Value
262 Str string
263 }
264
265 func (e *UnsupportedValueError) Error() string {
266 return "json: unsupported value: " + e.Str
267 }
268
269
270
271
272
273
274
275 type InvalidUTF8Error struct {
276 S string
277 }
278
279 func (e *InvalidUTF8Error) Error() string {
280 return "json: invalid UTF-8 in string: " + strconv.Quote(e.S)
281 }
282
283
284 type MarshalerError struct {
285 Type reflect.Type
286 Err error
287 sourceFunc string
288 }
289
290 func (e *MarshalerError) Error() string {
291 srcFunc := e.sourceFunc
292 if srcFunc == "" {
293 srcFunc = "MarshalJSON"
294 }
295 return "json: error calling " + srcFunc +
296 " for type " + e.Type.String() +
297 ": " + e.Err.Error()
298 }
299
300
301 func (e *MarshalerError) Unwrap() error { return e.Err }
302
303 var hex = "0123456789abcdef"
304
305
306 type encodeState struct {
307 bytes.Buffer
308 scratch [64]byte
309
310
311
312
313
314
315 ptrLevel uint
316 ptrSeen map[any]struct{}
317 }
318
319 const startDetectingCyclesAfter = 1000
320
321 var encodeStatePool sync.Pool
322
323 func newEncodeState() *encodeState {
324 if v := encodeStatePool.Get(); v != nil {
325 e := v.(*encodeState)
326 e.Reset()
327 if len(e.ptrSeen) > 0 {
328 panic("ptrEncoder.encode should have emptied ptrSeen via defers")
329 }
330 e.ptrLevel = 0
331 return e
332 }
333 return &encodeState{ptrSeen: make(map[any]struct{})}
334 }
335
336
337
338
339 type jsonError struct{ error }
340
341 func (e *encodeState) marshal(v any, opts encOpts) (err error) {
342 defer func() {
343 if r := recover(); r != nil {
344 if je, ok := r.(jsonError); ok {
345 err = je.error
346 } else {
347 panic(r)
348 }
349 }
350 }()
351 e.reflectValue(reflect.ValueOf(v), opts)
352 return nil
353 }
354
355
356 func (e *encodeState) error(err error) {
357 panic(jsonError{err})
358 }
359
360 func isEmptyValue(v reflect.Value) bool {
361 switch v.Kind() {
362 case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
363 return v.Len() == 0
364 case reflect.Bool:
365 return !v.Bool()
366 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
367 return v.Int() == 0
368 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
369 return v.Uint() == 0
370 case reflect.Float32, reflect.Float64:
371 return v.Float() == 0
372 case reflect.Interface, reflect.Pointer:
373 return v.IsNil()
374 }
375 return false
376 }
377
378 func (e *encodeState) reflectValue(v reflect.Value, opts encOpts) {
379 valueEncoder(v)(e, v, opts)
380 }
381
382 type encOpts struct {
383
384 quoted bool
385
386 escapeHTML bool
387 }
388
389 type encoderFunc func(e *encodeState, v reflect.Value, opts encOpts)
390
391 var encoderCache sync.Map
392
393 func valueEncoder(v reflect.Value) encoderFunc {
394 if !v.IsValid() {
395 return invalidValueEncoder
396 }
397 return typeEncoder(v.Type())
398 }
399
400 func typeEncoder(t reflect.Type) encoderFunc {
401 if fi, ok := encoderCache.Load(t); ok {
402 return fi.(encoderFunc)
403 }
404
405
406
407
408
409 var (
410 wg sync.WaitGroup
411 f encoderFunc
412 )
413 wg.Add(1)
414 fi, loaded := encoderCache.LoadOrStore(t, encoderFunc(func(e *encodeState, v reflect.Value, opts encOpts) {
415 wg.Wait()
416 f(e, v, opts)
417 }))
418 if loaded {
419 return fi.(encoderFunc)
420 }
421
422
423 f = newTypeEncoder(t, true)
424 wg.Done()
425 encoderCache.Store(t, f)
426 return f
427 }
428
429 var (
430 marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
431 redirMarshalerType = reflect.TypeOf((*RedirectMarshaler)(nil)).Elem()
432 trustMarshalerType = reflect.TypeOf((*TrustMarshaler)(nil)).Elem()
433 textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
434 )
435
436
437
438 func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc {
439 if t.Implements(redirMarshalerType) {
440 return redirMarshalerEncoder
441 }
442 if t.Implements(trustMarshalerType) {
443 return marshalerTrustEncoder
444 }
445
446
447
448
449 if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(marshalerType) {
450 return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false))
451 }
452 if t.Implements(marshalerType) {
453 return marshalerEncoder
454 }
455 if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(textMarshalerType) {
456 return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false))
457 }
458 if t.Implements(textMarshalerType) {
459 return textMarshalerEncoder
460 }
461
462 switch t.Kind() {
463 case reflect.Bool:
464 return boolEncoder
465 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
466 return intEncoder
467 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
468 return uintEncoder
469 case reflect.Float32:
470 return float32Encoder
471 case reflect.Float64:
472 return float64Encoder
473 case reflect.String:
474 return stringEncoder
475 case reflect.Interface:
476 return interfaceEncoder
477 case reflect.Struct:
478 return newStructEncoder(t)
479 case reflect.Map:
480 return newMapEncoder(t)
481 case reflect.Slice:
482 return newSliceEncoder(t)
483 case reflect.Array:
484 return newArrayEncoder(t)
485 case reflect.Pointer:
486 return newPtrEncoder(t)
487 default:
488 return unsupportedTypeEncoder
489 }
490 }
491
492 func invalidValueEncoder(e *encodeState, v reflect.Value, _ encOpts) {
493 e.WriteString("null")
494 }
495
496 func redirMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
497 if v.Kind() == reflect.Pointer && v.IsNil() {
498 e.WriteString("null")
499 return
500 }
501 m, ok := v.Interface().(RedirectMarshaler)
502 if !ok {
503 e.WriteString("null")
504 return
505 }
506
507 iv, err := m.RedirectMarshalJSON()
508 if err != nil {
509 e.error(&MarshalerError{v.Type(), err, "RedirectMarshalJSON"})
510 return
511 }
512
513 e.marshal(iv, opts)
514 }
515
516 func marshalerTrustEncoder(e *encodeState, v reflect.Value, opts encOpts) {
517 if v.Kind() == reflect.Pointer && v.IsNil() {
518 e.WriteString("null")
519 return
520 }
521 m, ok := v.Interface().(TrustMarshaler)
522 if !ok {
523 e.WriteString("null")
524 return
525 }
526 err := m.TrustMarshalJSON(&e.Buffer)
527 if err == nil {
528
529
530
531 }
532 if err != nil {
533 e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
534 }
535 }
536 func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
537 if v.Kind() == reflect.Pointer && v.IsNil() {
538 e.WriteString("null")
539 return
540 }
541 m, ok := v.Interface().(Marshaler)
542 if !ok {
543 e.WriteString("null")
544 return
545 }
546 b, err := m.MarshalJSON()
547 if err == nil {
548
549 err = compact(&e.Buffer, b, opts.escapeHTML)
550 }
551 if err != nil {
552 e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
553 }
554 }
555
556 func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
557 va := v.Addr()
558 if va.IsNil() {
559 e.WriteString("null")
560 return
561 }
562 m := va.Interface().(Marshaler)
563 b, err := m.MarshalJSON()
564 if err == nil {
565
566 err = compact(&e.Buffer, b, opts.escapeHTML)
567 }
568 if err != nil {
569 e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
570 }
571 }
572
573 func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
574 if v.Kind() == reflect.Pointer && v.IsNil() {
575 e.WriteString("null")
576 return
577 }
578 m, ok := v.Interface().(encoding.TextMarshaler)
579 if !ok {
580 e.WriteString("null")
581 return
582 }
583 b, err := m.MarshalText()
584 if err != nil {
585 e.error(&MarshalerError{v.Type(), err, "MarshalText"})
586 }
587 e.stringBytes(b, opts.escapeHTML)
588 }
589
590 func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
591 va := v.Addr()
592 if va.IsNil() {
593 e.WriteString("null")
594 return
595 }
596 m := va.Interface().(encoding.TextMarshaler)
597 b, err := m.MarshalText()
598 if err != nil {
599 e.error(&MarshalerError{v.Type(), err, "MarshalText"})
600 }
601 e.stringBytes(b, opts.escapeHTML)
602 }
603
604 func boolEncoder(e *encodeState, v reflect.Value, opts encOpts) {
605 if opts.quoted {
606 e.WriteByte('"')
607 }
608 if v.Bool() {
609 e.WriteString("true")
610 } else {
611 e.WriteString("false")
612 }
613 if opts.quoted {
614 e.WriteByte('"')
615 }
616 }
617
618 func intEncoder(e *encodeState, v reflect.Value, opts encOpts) {
619 b := strconv.AppendInt(e.scratch[:0], v.Int(), 10)
620 if opts.quoted {
621 e.WriteByte('"')
622 }
623 e.Write(b)
624 if opts.quoted {
625 e.WriteByte('"')
626 }
627 }
628
629 func uintEncoder(e *encodeState, v reflect.Value, opts encOpts) {
630 b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10)
631 if opts.quoted {
632 e.WriteByte('"')
633 }
634 e.Write(b)
635 if opts.quoted {
636 e.WriteByte('"')
637 }
638 }
639
640 type floatEncoder int
641
642 func (bits floatEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
643 f := v.Float()
644 if math.IsInf(f, 0) || math.IsNaN(f) {
645 e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))})
646 }
647
648
649
650
651
652
653 b := e.scratch[:0]
654 abs := math.Abs(f)
655 fmt := byte('f')
656
657 if abs != 0 {
658 if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
659 fmt = 'e'
660 }
661 }
662 b = strconv.AppendFloat(b, f, fmt, -1, int(bits))
663 if fmt == 'e' {
664
665 n := len(b)
666 if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' {
667 b[n-2] = b[n-1]
668 b = b[:n-1]
669 }
670 }
671
672 if opts.quoted {
673 e.WriteByte('"')
674 }
675 e.Write(b)
676 if opts.quoted {
677 e.WriteByte('"')
678 }
679 }
680
681 var (
682 float32Encoder = (floatEncoder(32)).encode
683 float64Encoder = (floatEncoder(64)).encode
684 )
685
686 func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) {
687 if v.Type() == numberType {
688 numStr := v.String()
689
690
691 if numStr == "" {
692 numStr = "0"
693 }
694 if !isValidNumber(numStr) {
695 e.error(fmt.Errorf("json: invalid number literal %q", numStr))
696 }
697 if opts.quoted {
698 e.WriteByte('"')
699 }
700 e.WriteString(numStr)
701 if opts.quoted {
702 e.WriteByte('"')
703 }
704 return
705 }
706 if opts.quoted {
707 e2 := newEncodeState()
708
709
710 e2.string(v.String(), opts.escapeHTML)
711 e.stringBytes(e2.Bytes(), false)
712 encodeStatePool.Put(e2)
713 } else {
714 e.string(v.String(), opts.escapeHTML)
715 }
716 }
717
718
719 func isValidNumber(s string) bool {
720
721
722
723
724 if s == "" {
725 return false
726 }
727
728
729 if s[0] == '-' {
730 s = s[1:]
731 if s == "" {
732 return false
733 }
734 }
735
736
737 switch {
738 default:
739 return false
740
741 case s[0] == '0':
742 s = s[1:]
743
744 case '1' <= s[0] && s[0] <= '9':
745 s = s[1:]
746 for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
747 s = s[1:]
748 }
749 }
750
751
752 if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' {
753 s = s[2:]
754 for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
755 s = s[1:]
756 }
757 }
758
759
760
761 if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
762 s = s[1:]
763 if s[0] == '+' || s[0] == '-' {
764 s = s[1:]
765 if s == "" {
766 return false
767 }
768 }
769 for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
770 s = s[1:]
771 }
772 }
773
774
775 return s == ""
776 }
777
778 func interfaceEncoder(e *encodeState, v reflect.Value, opts encOpts) {
779 if v.IsNil() {
780 e.WriteString("null")
781 return
782 }
783 e.reflectValue(v.Elem(), opts)
784 }
785
786 func unsupportedTypeEncoder(e *encodeState, v reflect.Value, _ encOpts) {
787 e.error(&UnsupportedTypeError{v.Type()})
788 }
789
790 type structEncoder struct {
791 fields structFields
792 }
793
794 type structFields struct {
795 list []field
796 nameIndex map[string]int
797 }
798
799 func (se structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
800 next := byte('{')
801 FieldLoop:
802 for i := range se.fields.list {
803 f := &se.fields.list[i]
804
805
806 fv := v
807 for _, i := range f.index {
808 if fv.Kind() == reflect.Pointer {
809 if fv.IsNil() {
810 continue FieldLoop
811 }
812 fv = fv.Elem()
813 }
814 fv = fv.Field(i)
815 }
816
817 if f.omitEmpty && isEmptyValue(fv) {
818 continue
819 }
820 e.WriteByte(next)
821 next = ','
822 if opts.escapeHTML {
823 e.WriteString(f.nameEscHTML)
824 } else {
825 e.WriteString(f.nameNonEsc)
826 }
827 opts.quoted = f.quoted
828 f.encoder(e, fv, opts)
829 }
830 if next == '{' {
831 e.WriteString("{}")
832 } else {
833 e.WriteByte('}')
834 }
835 }
836
837 func newStructEncoder(t reflect.Type) encoderFunc {
838 se := structEncoder{fields: cachedTypeFields(t)}
839 return se.encode
840 }
841
842 type mapEncoder struct {
843 elemEnc encoderFunc
844 }
845
846 func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
847 if v.IsNil() {
848 e.WriteString("null")
849 return
850 }
851 if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
852
853
854 ptr := v.UnsafePointer()
855 if _, ok := e.ptrSeen[ptr]; ok {
856 e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
857 }
858 e.ptrSeen[ptr] = struct{}{}
859 defer delete(e.ptrSeen, ptr)
860 }
861 e.WriteByte('{')
862
863
864 sv := make([]reflectWithString, v.Len())
865 mi := v.MapRange()
866 for i := 0; mi.Next(); i++ {
867 sv[i].k = mi.Key()
868 sv[i].v = mi.Value()
869 if err := sv[i].resolve(); err != nil {
870 e.error(fmt.Errorf("json: encoding error for type %q: %q", v.Type().String(), err.Error()))
871 }
872 }
873 sort.Slice(sv, func(i, j int) bool { return sv[i].ks < sv[j].ks })
874
875 for i, kv := range sv {
876 if i > 0 {
877 e.WriteByte(',')
878 }
879 e.string(kv.ks, opts.escapeHTML)
880 e.WriteByte(':')
881 me.elemEnc(e, kv.v, opts)
882 }
883 e.WriteByte('}')
884 e.ptrLevel--
885 }
886
887 func newMapEncoder(t reflect.Type) encoderFunc {
888 switch t.Key().Kind() {
889 case reflect.String,
890 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
891 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
892 default:
893 if !t.Key().Implements(textMarshalerType) {
894 return unsupportedTypeEncoder
895 }
896 }
897 me := mapEncoder{typeEncoder(t.Elem())}
898 return me.encode
899 }
900
901 func encodeByteSlice(e *encodeState, v reflect.Value, _ encOpts) {
902 if v.IsNil() {
903 e.WriteString("null")
904 return
905 }
906 s := v.Bytes()
907 e.WriteByte('"')
908 encodedLen := base64.StdEncoding.EncodedLen(len(s))
909 if encodedLen <= len(e.scratch) {
910
911
912 dst := e.scratch[:encodedLen]
913 base64.StdEncoding.Encode(dst, s)
914 e.Write(dst)
915 } else if encodedLen <= 1024 {
916
917
918 dst := make([]byte, encodedLen)
919 base64.StdEncoding.Encode(dst, s)
920 e.Write(dst)
921 } else {
922
923
924 enc := base64.NewEncoder(base64.StdEncoding, e)
925 enc.Write(s)
926 enc.Close()
927 }
928 e.WriteByte('"')
929 }
930
931
932 type sliceEncoder struct {
933 arrayEnc encoderFunc
934 }
935
936 func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
937 if v.IsNil() {
938 e.WriteString("null")
939 return
940 }
941 if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
942
943
944
945
946 ptr := struct {
947 ptr interface{}
948 len int
949 }{v.UnsafePointer(), v.Len()}
950 if _, ok := e.ptrSeen[ptr]; ok {
951 e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
952 }
953 e.ptrSeen[ptr] = struct{}{}
954 defer delete(e.ptrSeen, ptr)
955 }
956 se.arrayEnc(e, v, opts)
957 e.ptrLevel--
958 }
959
960 func newSliceEncoder(t reflect.Type) encoderFunc {
961
962 if t.Elem().Kind() == reflect.Uint8 {
963 p := reflect.PointerTo(t.Elem())
964 if !p.Implements(marshalerType) && !p.Implements(textMarshalerType) {
965 return encodeByteSlice
966 }
967 }
968 enc := sliceEncoder{newArrayEncoder(t)}
969 return enc.encode
970 }
971
972 type arrayEncoder struct {
973 elemEnc encoderFunc
974 }
975
976 func (ae arrayEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
977 e.WriteByte('[')
978 n := v.Len()
979 for i := 0; i < n; i++ {
980 if i > 0 {
981 e.WriteByte(',')
982 }
983 ae.elemEnc(e, v.Index(i), opts)
984 }
985 e.WriteByte(']')
986 }
987
988 func newArrayEncoder(t reflect.Type) encoderFunc {
989 enc := arrayEncoder{typeEncoder(t.Elem())}
990 return enc.encode
991 }
992
993 type ptrEncoder struct {
994 elemEnc encoderFunc
995 }
996
997 func (pe ptrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
998 if v.IsNil() {
999 e.WriteString("null")
1000 return
1001 }
1002 if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
1003
1004
1005 ptr := v.Interface()
1006 if _, ok := e.ptrSeen[ptr]; ok {
1007 e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
1008 }
1009 e.ptrSeen[ptr] = struct{}{}
1010 defer delete(e.ptrSeen, ptr)
1011 }
1012 pe.elemEnc(e, v.Elem(), opts)
1013 e.ptrLevel--
1014 }
1015
1016 func newPtrEncoder(t reflect.Type) encoderFunc {
1017 enc := ptrEncoder{typeEncoder(t.Elem())}
1018 return enc.encode
1019 }
1020
1021 type condAddrEncoder struct {
1022 canAddrEnc, elseEnc encoderFunc
1023 }
1024
1025 func (ce condAddrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
1026 if v.CanAddr() {
1027 ce.canAddrEnc(e, v, opts)
1028 } else {
1029 ce.elseEnc(e, v, opts)
1030 }
1031 }
1032
1033
1034
1035 func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc {
1036 enc := condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc}
1037 return enc.encode
1038 }
1039
1040 func isValidTag(s string) bool {
1041 if s == "" {
1042 return false
1043 }
1044 for _, c := range s {
1045 switch {
1046 case strings.ContainsRune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c):
1047
1048
1049
1050 case !unicode.IsLetter(c) && !unicode.IsDigit(c):
1051 return false
1052 }
1053 }
1054 return true
1055 }
1056
1057 func typeByIndex(t reflect.Type, index []int) reflect.Type {
1058 for _, i := range index {
1059 if t.Kind() == reflect.Pointer {
1060 t = t.Elem()
1061 }
1062 t = t.Field(i).Type
1063 }
1064 return t
1065 }
1066
1067 type reflectWithString struct {
1068 k reflect.Value
1069 v reflect.Value
1070 ks string
1071 }
1072
1073 func (w *reflectWithString) resolve() error {
1074 if w.k.Kind() == reflect.String {
1075 w.ks = w.k.String()
1076 return nil
1077 }
1078 if tm, ok := w.k.Interface().(encoding.TextMarshaler); ok {
1079 if w.k.Kind() == reflect.Pointer && w.k.IsNil() {
1080 return nil
1081 }
1082 buf, err := tm.MarshalText()
1083 w.ks = string(buf)
1084 return err
1085 }
1086 switch w.k.Kind() {
1087 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1088 w.ks = strconv.FormatInt(w.k.Int(), 10)
1089 return nil
1090 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
1091 w.ks = strconv.FormatUint(w.k.Uint(), 10)
1092 return nil
1093 }
1094 panic("unexpected map key type")
1095 }
1096
1097
1098 func (e *encodeState) string(s string, escapeHTML bool) {
1099 e.WriteByte('"')
1100 start := 0
1101 for i := 0; i < len(s); {
1102 if b := s[i]; b < utf8.RuneSelf {
1103 if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) {
1104 i++
1105 continue
1106 }
1107 if start < i {
1108 e.WriteString(s[start:i])
1109 }
1110 e.WriteByte('\\')
1111 switch b {
1112 case '\\', '"':
1113 e.WriteByte(b)
1114 case '\n':
1115 e.WriteByte('n')
1116 case '\r':
1117 e.WriteByte('r')
1118 case '\t':
1119 e.WriteByte('t')
1120 default:
1121
1122
1123
1124
1125
1126 e.WriteString(`u00`)
1127 e.WriteByte(hex[b>>4])
1128 e.WriteByte(hex[b&0xF])
1129 }
1130 i++
1131 start = i
1132 continue
1133 }
1134 c, size := utf8.DecodeRuneInString(s[i:])
1135 if c == utf8.RuneError && size == 1 {
1136 if start < i {
1137 e.WriteString(s[start:i])
1138 }
1139 e.WriteString(`\ufffd`)
1140 i += size
1141 start = i
1142 continue
1143 }
1144
1145
1146
1147
1148
1149
1150
1151 if c == '\u2028' || c == '\u2029' {
1152 if start < i {
1153 e.WriteString(s[start:i])
1154 }
1155 e.WriteString(`\u202`)
1156 e.WriteByte(hex[c&0xF])
1157 i += size
1158 start = i
1159 continue
1160 }
1161 i += size
1162 }
1163 if start < len(s) {
1164 e.WriteString(s[start:])
1165 }
1166 e.WriteByte('"')
1167 }
1168
1169
1170 func (e *encodeState) stringBytes(s []byte, escapeHTML bool) {
1171 e.WriteByte('"')
1172 start := 0
1173 for i := 0; i < len(s); {
1174 if b := s[i]; b < utf8.RuneSelf {
1175 if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) {
1176 i++
1177 continue
1178 }
1179 if start < i {
1180 e.Write(s[start:i])
1181 }
1182 e.WriteByte('\\')
1183 switch b {
1184 case '\\', '"':
1185 e.WriteByte(b)
1186 case '\n':
1187 e.WriteByte('n')
1188 case '\r':
1189 e.WriteByte('r')
1190 case '\t':
1191 e.WriteByte('t')
1192 default:
1193
1194
1195
1196
1197
1198 e.WriteString(`u00`)
1199 e.WriteByte(hex[b>>4])
1200 e.WriteByte(hex[b&0xF])
1201 }
1202 i++
1203 start = i
1204 continue
1205 }
1206 c, size := utf8.DecodeRune(s[i:])
1207 if c == utf8.RuneError && size == 1 {
1208 if start < i {
1209 e.Write(s[start:i])
1210 }
1211 e.WriteString(`\ufffd`)
1212 i += size
1213 start = i
1214 continue
1215 }
1216
1217
1218
1219
1220
1221
1222
1223 if c == '\u2028' || c == '\u2029' {
1224 if start < i {
1225 e.Write(s[start:i])
1226 }
1227 e.WriteString(`\u202`)
1228 e.WriteByte(hex[c&0xF])
1229 i += size
1230 start = i
1231 continue
1232 }
1233 i += size
1234 }
1235 if start < len(s) {
1236 e.Write(s[start:])
1237 }
1238 e.WriteByte('"')
1239 }
1240
1241
1242 type field struct {
1243 name string
1244 nameBytes []byte
1245 equalFold func(s, t []byte) bool
1246
1247 nameNonEsc string
1248 nameEscHTML string
1249
1250 tag bool
1251 index []int
1252 typ reflect.Type
1253 omitEmpty bool
1254 quoted bool
1255
1256 encoder encoderFunc
1257 }
1258
1259
1260 type byIndex []field
1261
1262 func (x byIndex) Len() int { return len(x) }
1263
1264 func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
1265
1266 func (x byIndex) Less(i, j int) bool {
1267 for k, xik := range x[i].index {
1268 if k >= len(x[j].index) {
1269 return false
1270 }
1271 if xik != x[j].index[k] {
1272 return xik < x[j].index[k]
1273 }
1274 }
1275 return len(x[i].index) < len(x[j].index)
1276 }
1277
1278
1279
1280
1281 func typeFields(t reflect.Type) structFields {
1282
1283 current := []field{}
1284 next := []field{{typ: t}}
1285
1286
1287 var count, nextCount map[reflect.Type]int
1288
1289
1290 visited := map[reflect.Type]bool{}
1291
1292
1293 var fields []field
1294
1295
1296 var nameEscBuf bytes.Buffer
1297
1298 for len(next) > 0 {
1299 current, next = next, current[:0]
1300 count, nextCount = nextCount, map[reflect.Type]int{}
1301
1302 for _, f := range current {
1303 if visited[f.typ] {
1304 continue
1305 }
1306 visited[f.typ] = true
1307
1308
1309 for i := 0; i < f.typ.NumField(); i++ {
1310 sf := f.typ.Field(i)
1311 if sf.Anonymous {
1312 t := sf.Type
1313 if t.Kind() == reflect.Pointer {
1314 t = t.Elem()
1315 }
1316 if !sf.IsExported() && t.Kind() != reflect.Struct {
1317
1318 continue
1319 }
1320
1321
1322 } else if !sf.IsExported() {
1323
1324 continue
1325 }
1326 tag := sf.Tag.Get("json")
1327 if tag == "-" {
1328 continue
1329 }
1330 name, opts := parseTag(tag)
1331 if !isValidTag(name) {
1332 name = ""
1333 }
1334 index := make([]int, len(f.index)+1)
1335 copy(index, f.index)
1336 index[len(f.index)] = i
1337
1338 ft := sf.Type
1339 if ft.Name() == "" && ft.Kind() == reflect.Pointer {
1340
1341 ft = ft.Elem()
1342 }
1343
1344
1345 quoted := false
1346 if opts.Contains("string") {
1347 switch ft.Kind() {
1348 case reflect.Bool,
1349 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
1350 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
1351 reflect.Float32, reflect.Float64,
1352 reflect.String:
1353 quoted = true
1354 }
1355 }
1356
1357
1358 if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
1359 tagged := name != ""
1360 if name == "" {
1361 name = sf.Name
1362 }
1363 field := field{
1364 name: name,
1365 tag: tagged,
1366 index: index,
1367 typ: ft,
1368 omitEmpty: opts.Contains("omitempty"),
1369 quoted: quoted,
1370 }
1371 field.nameBytes = []byte(field.name)
1372 field.equalFold = foldFunc(field.nameBytes)
1373
1374
1375 nameEscBuf.Reset()
1376 nameEscBuf.WriteString(`"`)
1377 HTMLEscape(&nameEscBuf, field.nameBytes)
1378 nameEscBuf.WriteString(`":`)
1379 field.nameEscHTML = nameEscBuf.String()
1380 field.nameNonEsc = `"` + field.name + `":`
1381
1382 fields = append(fields, field)
1383 if count[f.typ] > 1 {
1384
1385
1386
1387
1388 fields = append(fields, fields[len(fields)-1])
1389 }
1390 continue
1391 }
1392
1393
1394 nextCount[ft]++
1395 if nextCount[ft] == 1 {
1396 next = append(next, field{name: ft.Name(), index: index, typ: ft})
1397 }
1398 }
1399 }
1400 }
1401
1402 sort.Slice(fields, func(i, j int) bool {
1403 x := fields
1404
1405
1406
1407 if x[i].name != x[j].name {
1408 return x[i].name < x[j].name
1409 }
1410 if len(x[i].index) != len(x[j].index) {
1411 return len(x[i].index) < len(x[j].index)
1412 }
1413 if x[i].tag != x[j].tag {
1414 return x[i].tag
1415 }
1416 return byIndex(x).Less(i, j)
1417 })
1418
1419
1420
1421
1422
1423
1424
1425 out := fields[:0]
1426 for advance, i := 0, 0; i < len(fields); i += advance {
1427
1428
1429 fi := fields[i]
1430 name := fi.name
1431 for advance = 1; i+advance < len(fields); advance++ {
1432 fj := fields[i+advance]
1433 if fj.name != name {
1434 break
1435 }
1436 }
1437 if advance == 1 {
1438 out = append(out, fi)
1439 continue
1440 }
1441 dominant, ok := dominantField(fields[i : i+advance])
1442 if ok {
1443 out = append(out, dominant)
1444 }
1445 }
1446
1447 fields = out
1448 sort.Sort(byIndex(fields))
1449
1450 for i := range fields {
1451 f := &fields[i]
1452 f.encoder = typeEncoder(typeByIndex(t, f.index))
1453 }
1454 nameIndex := make(map[string]int, len(fields))
1455 for i, field := range fields {
1456 nameIndex[field.name] = i
1457 }
1458 return structFields{fields, nameIndex}
1459 }
1460
1461
1462
1463
1464
1465
1466
1467 func dominantField(fields []field) (field, bool) {
1468
1469
1470
1471 if len(fields) > 1 && len(fields[0].index) == len(fields[1].index) && fields[0].tag == fields[1].tag {
1472 return field{}, false
1473 }
1474 return fields[0], true
1475 }
1476
1477 var fieldCache sync.Map
1478
1479
1480 func cachedTypeFields(t reflect.Type) structFields {
1481 if f, ok := fieldCache.Load(t); ok {
1482 return f.(structFields)
1483 }
1484 f, _ := fieldCache.LoadOrStore(t, typeFields(t))
1485 return f.(structFields)
1486 }
1487
View as plain text