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 "runtime"
21 "sort"
22 "strconv"
23 "strings"
24 "sync"
25 "sync/atomic"
26 "unicode"
27 "unicode/utf8"
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
158
159 func Marshal(v interface{}) ([]byte, error) {
160 e := &encodeState{}
161 err := e.marshal(v, encOpts{escapeHTML: true})
162 if err != nil {
163 return nil, err
164 }
165 return e.Bytes(), nil
166 }
167
168
169
170
171 func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
172 b, err := Marshal(v)
173 if err != nil {
174 return nil, err
175 }
176 var buf bytes.Buffer
177 err = Indent(&buf, b, prefix, indent)
178 if err != nil {
179 return nil, err
180 }
181 return buf.Bytes(), nil
182 }
183
184
185
186
187
188
189
190 func HTMLEscape(dst *bytes.Buffer, src []byte) {
191
192
193 start := 0
194 for i, c := range src {
195 if c == '<' || c == '>' || c == '&' {
196 if start < i {
197 dst.Write(src[start:i])
198 }
199 dst.WriteString(`\u00`)
200 dst.WriteByte(hex[c>>4])
201 dst.WriteByte(hex[c&0xF])
202 start = i + 1
203 }
204
205 if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
206 if start < i {
207 dst.Write(src[start:i])
208 }
209 dst.WriteString(`\u202`)
210 dst.WriteByte(hex[src[i+2]&0xF])
211 start = i + 3
212 }
213 }
214 if start < len(src) {
215 dst.Write(src[start:])
216 }
217 }
218
219
220
221 type Marshaler interface {
222 MarshalJSON() ([]byte, error)
223 }
224
225
226
227 type UnsupportedTypeError struct {
228 Type reflect.Type
229 }
230
231 func (e *UnsupportedTypeError) Error() string {
232 return "json: unsupported type: " + e.Type.String()
233 }
234
235 type UnsupportedValueError struct {
236 Value reflect.Value
237 Str string
238 }
239
240 func (e *UnsupportedValueError) Error() string {
241 return "json: unsupported value: " + e.Str
242 }
243
244
245
246
247
248
249
250 type InvalidUTF8Error struct {
251 S string
252 }
253
254 func (e *InvalidUTF8Error) Error() string {
255 return "json: invalid UTF-8 in string: " + strconv.Quote(e.S)
256 }
257
258 type MarshalerError struct {
259 Type reflect.Type
260 Err error
261 }
262
263 func (e *MarshalerError) Error() string {
264 return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error()
265 }
266
267 var hex = "0123456789abcdef"
268
269
270 type encodeState struct {
271 bytes.Buffer
272 scratch [64]byte
273 }
274
275 var encodeStatePool sync.Pool
276
277 func newEncodeState() *encodeState {
278 if v := encodeStatePool.Get(); v != nil {
279 e := v.(*encodeState)
280 e.Reset()
281 return e
282 }
283 return new(encodeState)
284 }
285
286 func (e *encodeState) marshal(v interface{}, opts encOpts) (err error) {
287 defer func() {
288 if r := recover(); r != nil {
289 if _, ok := r.(runtime.Error); ok {
290 panic(r)
291 }
292 if s, ok := r.(string); ok {
293 panic(s)
294 }
295 err = r.(error)
296 }
297 }()
298 e.reflectValue(reflect.ValueOf(v), opts)
299 return nil
300 }
301
302 func (e *encodeState) error(err error) {
303 panic(err)
304 }
305
306 func isEmptyValue(v reflect.Value) bool {
307 switch v.Kind() {
308 case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
309 return v.Len() == 0
310 case reflect.Bool:
311 return !v.Bool()
312 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
313 return v.Int() == 0
314 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
315 return v.Uint() == 0
316 case reflect.Float32, reflect.Float64:
317 return v.Float() == 0
318 case reflect.Interface, reflect.Ptr:
319 return v.IsNil()
320 }
321 return false
322 }
323
324 func (e *encodeState) reflectValue(v reflect.Value, opts encOpts) {
325 valueEncoder(v)(e, v, opts)
326 }
327
328 type encOpts struct {
329
330 quoted bool
331
332 escapeHTML bool
333 }
334
335 type encoderFunc func(e *encodeState, v reflect.Value, opts encOpts)
336
337 var encoderCache sync.Map
338
339 func valueEncoder(v reflect.Value) encoderFunc {
340 if !v.IsValid() {
341 return invalidValueEncoder
342 }
343 return typeEncoder(v.Type())
344 }
345
346 func typeEncoder(t reflect.Type) encoderFunc {
347 if fi, ok := encoderCache.Load(t); ok {
348 return fi.(encoderFunc)
349 }
350
351
352
353
354
355 var (
356 wg sync.WaitGroup
357 f encoderFunc
358 )
359 wg.Add(1)
360 fi, loaded := encoderCache.LoadOrStore(t, encoderFunc(func(e *encodeState, v reflect.Value, opts encOpts) {
361 wg.Wait()
362 f(e, v, opts)
363 }))
364 if loaded {
365 return fi.(encoderFunc)
366 }
367
368
369 f = newTypeEncoder(t, true)
370 wg.Done()
371 encoderCache.Store(t, f)
372 return f
373 }
374
375 var (
376 marshalerType = reflect.TypeOf(new(Marshaler)).Elem()
377 textMarshalerType = reflect.TypeOf(new(encoding.TextMarshaler)).Elem()
378 )
379
380
381
382 func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc {
383 if t.Implements(marshalerType) {
384 return marshalerEncoder
385 }
386 if t.Kind() != reflect.Ptr && allowAddr {
387 if reflect.PtrTo(t).Implements(marshalerType) {
388 return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false))
389 }
390 }
391
392 if t.Implements(textMarshalerType) {
393 return textMarshalerEncoder
394 }
395 if t.Kind() != reflect.Ptr && allowAddr {
396 if reflect.PtrTo(t).Implements(textMarshalerType) {
397 return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false))
398 }
399 }
400
401 switch t.Kind() {
402 case reflect.Bool:
403 return boolEncoder
404 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
405 return intEncoder
406 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
407 return uintEncoder
408 case reflect.Float32:
409 return float32Encoder
410 case reflect.Float64:
411 return float64Encoder
412 case reflect.String:
413 return stringEncoder
414 case reflect.Interface:
415 return interfaceEncoder
416 case reflect.Struct:
417 return newStructEncoder(t)
418 case reflect.Map:
419 return newMapEncoder(t)
420 case reflect.Slice:
421 return newSliceEncoder(t)
422 case reflect.Array:
423 return newArrayEncoder(t)
424 case reflect.Ptr:
425 return newPtrEncoder(t)
426 default:
427 return unsupportedTypeEncoder
428 }
429 }
430
431 func invalidValueEncoder(e *encodeState, v reflect.Value, _ encOpts) {
432 e.WriteString("null")
433 }
434
435 func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
436 if v.Kind() == reflect.Ptr && v.IsNil() {
437 e.WriteString("null")
438 return
439 }
440 m, ok := v.Interface().(Marshaler)
441 if !ok {
442 e.WriteString("null")
443 return
444 }
445 b, err := m.MarshalJSON()
446 if err == nil {
447
448 err = compact(&e.Buffer, b, opts.escapeHTML)
449 }
450 if err != nil {
451 e.error(&MarshalerError{v.Type(), err})
452 }
453 }
454
455 func addrMarshalerEncoder(e *encodeState, v reflect.Value, _ encOpts) {
456 va := v.Addr()
457 if va.IsNil() {
458 e.WriteString("null")
459 return
460 }
461 m := va.Interface().(Marshaler)
462 b, err := m.MarshalJSON()
463 if err == nil {
464
465 err = compact(&e.Buffer, b, true)
466 }
467 if err != nil {
468 e.error(&MarshalerError{v.Type(), err})
469 }
470 }
471
472 func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
473 if v.Kind() == reflect.Ptr && v.IsNil() {
474 e.WriteString("null")
475 return
476 }
477 m := v.Interface().(encoding.TextMarshaler)
478 b, err := m.MarshalText()
479 if err != nil {
480 e.error(&MarshalerError{v.Type(), err})
481 }
482 e.stringBytes(b, opts.escapeHTML)
483 }
484
485 func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
486 va := v.Addr()
487 if va.IsNil() {
488 e.WriteString("null")
489 return
490 }
491 m := va.Interface().(encoding.TextMarshaler)
492 b, err := m.MarshalText()
493 if err != nil {
494 e.error(&MarshalerError{v.Type(), err})
495 }
496 e.stringBytes(b, opts.escapeHTML)
497 }
498
499 func boolEncoder(e *encodeState, v reflect.Value, opts encOpts) {
500 if opts.quoted {
501 e.WriteByte('"')
502 }
503 if v.Bool() {
504 e.WriteString("true")
505 } else {
506 e.WriteString("false")
507 }
508 if opts.quoted {
509 e.WriteByte('"')
510 }
511 }
512
513 func intEncoder(e *encodeState, v reflect.Value, opts encOpts) {
514 b := strconv.AppendInt(e.scratch[:0], v.Int(), 10)
515 if opts.quoted {
516 e.WriteByte('"')
517 }
518 e.Write(b)
519 if opts.quoted {
520 e.WriteByte('"')
521 }
522 }
523
524 func uintEncoder(e *encodeState, v reflect.Value, opts encOpts) {
525 b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10)
526 if opts.quoted {
527 e.WriteByte('"')
528 }
529 e.Write(b)
530 if opts.quoted {
531 e.WriteByte('"')
532 }
533 }
534
535 type floatEncoder int
536
537 func (bits floatEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
538 f := v.Float()
539 if math.IsInf(f, 0) || math.IsNaN(f) {
540 e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))})
541 }
542
543
544
545
546
547
548 b := e.scratch[:0]
549 abs := math.Abs(f)
550 fmt := byte('f')
551
552 if abs != 0 {
553 if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
554 fmt = 'e'
555 }
556 }
557 b = strconv.AppendFloat(b, f, fmt, -1, int(bits))
558 if fmt == 'e' {
559
560 n := len(b)
561 if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' {
562 b[n-2] = b[n-1]
563 b = b[:n-1]
564 }
565 }
566
567 if opts.quoted {
568 e.WriteByte('"')
569 }
570 e.Write(b)
571 if opts.quoted {
572 e.WriteByte('"')
573 }
574 }
575
576 var (
577 float32Encoder = (floatEncoder(32)).encode
578 float64Encoder = (floatEncoder(64)).encode
579 )
580
581 func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) {
582 if v.Type() == numberType {
583 numStr := v.String()
584
585
586 if numStr == "" {
587 numStr = "0"
588 }
589 if !isValidNumber(numStr) {
590 e.error(fmt.Errorf("json: invalid number literal %q", numStr))
591 }
592 e.WriteString(numStr)
593 return
594 }
595 if opts.quoted {
596 sb, err := Marshal(v.String())
597 if err != nil {
598 e.error(err)
599 }
600 e.string(string(sb), opts.escapeHTML)
601 } else {
602 e.string(v.String(), opts.escapeHTML)
603 }
604 }
605
606 func interfaceEncoder(e *encodeState, v reflect.Value, opts encOpts) {
607 if v.IsNil() {
608 e.WriteString("null")
609 return
610 }
611 e.reflectValue(v.Elem(), opts)
612 }
613
614 func unsupportedTypeEncoder(e *encodeState, v reflect.Value, _ encOpts) {
615 e.error(&UnsupportedTypeError{v.Type()})
616 }
617
618 type structEncoder struct {
619 fields []field
620 fieldEncs []encoderFunc
621 }
622
623 func (se *structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
624 e.WriteByte('{')
625 first := true
626 for i, f := range se.fields {
627 fv := fieldByIndex(v, f.index)
628 if !fv.IsValid() || f.omitEmpty && isEmptyValue(fv) {
629 continue
630 }
631 if first {
632 first = false
633 } else {
634 e.WriteByte(',')
635 }
636 e.string(f.name, opts.escapeHTML)
637 e.WriteByte(':')
638 opts.quoted = f.quoted
639 se.fieldEncs[i](e, fv, opts)
640 }
641 e.WriteByte('}')
642 }
643
644 func newStructEncoder(t reflect.Type) encoderFunc {
645 fields := cachedTypeFields(t)
646 se := &structEncoder{
647 fields: fields,
648 fieldEncs: make([]encoderFunc, len(fields)),
649 }
650 for i, f := range fields {
651 se.fieldEncs[i] = typeEncoder(typeByIndex(t, f.index))
652 }
653 return se.encode
654 }
655
656 type mapEncoder struct {
657 elemEnc encoderFunc
658 }
659
660 func (me *mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
661 if v.IsNil() {
662 e.WriteString("null")
663 return
664 }
665 e.WriteByte('{')
666
667
668 keys := v.MapKeys()
669 sv := make([]reflectWithString, len(keys))
670 for i, v := range keys {
671 sv[i].v = v
672 if err := sv[i].resolve(); err != nil {
673 e.error(&MarshalerError{v.Type(), err})
674 }
675 }
676 sort.Slice(sv, func(i, j int) bool { return sv[i].s < sv[j].s })
677
678 for i, kv := range sv {
679 if i > 0 {
680 e.WriteByte(',')
681 }
682 e.string(kv.s, opts.escapeHTML)
683 e.WriteByte(':')
684 me.elemEnc(e, v.MapIndex(kv.v), opts)
685 }
686 e.WriteByte('}')
687 }
688
689 func newMapEncoder(t reflect.Type) encoderFunc {
690 switch t.Key().Kind() {
691 case reflect.String,
692 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
693 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
694 default:
695 if !t.Key().Implements(textMarshalerType) {
696 return unsupportedTypeEncoder
697 }
698 }
699 me := &mapEncoder{typeEncoder(t.Elem())}
700 return me.encode
701 }
702
703 func encodeByteSlice(e *encodeState, v reflect.Value, _ encOpts) {
704 if v.IsNil() {
705 e.WriteString("null")
706 return
707 }
708 s := v.Bytes()
709 e.WriteByte('"')
710 if len(s) < 1024 {
711
712 dst := make([]byte, base64.StdEncoding.EncodedLen(len(s)))
713 base64.StdEncoding.Encode(dst, s)
714 e.Write(dst)
715 } else {
716
717
718 enc := base64.NewEncoder(base64.StdEncoding, e)
719 enc.Write(s)
720 enc.Close()
721 }
722 e.WriteByte('"')
723 }
724
725
726 type sliceEncoder struct {
727 arrayEnc encoderFunc
728 }
729
730 func (se *sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
731 if v.IsNil() {
732 e.WriteString("null")
733 return
734 }
735 se.arrayEnc(e, v, opts)
736 }
737
738 func newSliceEncoder(t reflect.Type) encoderFunc {
739
740 if t.Elem().Kind() == reflect.Uint8 {
741 p := reflect.PtrTo(t.Elem())
742 if !p.Implements(marshalerType) && !p.Implements(textMarshalerType) {
743 return encodeByteSlice
744 }
745 }
746 enc := &sliceEncoder{newArrayEncoder(t)}
747 return enc.encode
748 }
749
750 type arrayEncoder struct {
751 elemEnc encoderFunc
752 }
753
754 func (ae *arrayEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
755 e.WriteByte('[')
756 n := v.Len()
757 for i := 0; i < n; i++ {
758 if i > 0 {
759 e.WriteByte(',')
760 }
761 ae.elemEnc(e, v.Index(i), opts)
762 }
763 e.WriteByte(']')
764 }
765
766 func newArrayEncoder(t reflect.Type) encoderFunc {
767 enc := &arrayEncoder{typeEncoder(t.Elem())}
768 return enc.encode
769 }
770
771 type ptrEncoder struct {
772 elemEnc encoderFunc
773 }
774
775 func (pe *ptrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
776 if v.IsNil() {
777 e.WriteString("null")
778 return
779 }
780 pe.elemEnc(e, v.Elem(), opts)
781 }
782
783 func newPtrEncoder(t reflect.Type) encoderFunc {
784 enc := &ptrEncoder{typeEncoder(t.Elem())}
785 return enc.encode
786 }
787
788 type condAddrEncoder struct {
789 canAddrEnc, elseEnc encoderFunc
790 }
791
792 func (ce *condAddrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
793 if v.CanAddr() {
794 ce.canAddrEnc(e, v, opts)
795 } else {
796 ce.elseEnc(e, v, opts)
797 }
798 }
799
800
801
802 func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc {
803 enc := &condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc}
804 return enc.encode
805 }
806
807 func isValidTag(s string) bool {
808 if s == "" {
809 return false
810 }
811 for _, c := range s {
812 switch {
813 case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
814
815
816
817 default:
818 if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
819 return false
820 }
821 }
822 }
823 return true
824 }
825
826 func fieldByIndex(v reflect.Value, index []int) reflect.Value {
827 for _, i := range index {
828 if v.Kind() == reflect.Ptr {
829 if v.IsNil() {
830 return reflect.Value{}
831 }
832 v = v.Elem()
833 }
834 v = v.Field(i)
835 }
836 return v
837 }
838
839 func typeByIndex(t reflect.Type, index []int) reflect.Type {
840 for _, i := range index {
841 if t.Kind() == reflect.Ptr {
842 t = t.Elem()
843 }
844 t = t.Field(i).Type
845 }
846 return t
847 }
848
849 type reflectWithString struct {
850 v reflect.Value
851 s string
852 }
853
854 func (w *reflectWithString) resolve() error {
855 if w.v.Kind() == reflect.String {
856 w.s = w.v.String()
857 return nil
858 }
859 if tm, ok := w.v.Interface().(encoding.TextMarshaler); ok {
860 buf, err := tm.MarshalText()
861 w.s = string(buf)
862 return err
863 }
864 switch w.v.Kind() {
865 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
866 w.s = strconv.FormatInt(w.v.Int(), 10)
867 return nil
868 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
869 w.s = strconv.FormatUint(w.v.Uint(), 10)
870 return nil
871 }
872 panic("unexpected map key type")
873 }
874
875
876 func (e *encodeState) string(s string, escapeHTML bool) {
877 e.WriteByte('"')
878 start := 0
879 for i := 0; i < len(s); {
880 if b := s[i]; b < utf8.RuneSelf {
881 if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) {
882 i++
883 continue
884 }
885 if start < i {
886 e.WriteString(s[start:i])
887 }
888 switch b {
889 case '\\', '"':
890 e.WriteByte('\\')
891 e.WriteByte(b)
892 case '\n':
893 e.WriteByte('\\')
894 e.WriteByte('n')
895 case '\r':
896 e.WriteByte('\\')
897 e.WriteByte('r')
898 case '\t':
899 e.WriteByte('\\')
900 e.WriteByte('t')
901 default:
902
903
904
905
906
907 e.WriteString(`\u00`)
908 e.WriteByte(hex[b>>4])
909 e.WriteByte(hex[b&0xF])
910 }
911 i++
912 start = i
913 continue
914 }
915 c, size := utf8.DecodeRuneInString(s[i:])
916 if c == utf8.RuneError && size == 1 {
917 if start < i {
918 e.WriteString(s[start:i])
919 }
920 e.WriteString(`\ufffd`)
921 i += size
922 start = i
923 continue
924 }
925
926
927
928
929
930
931
932 if c == '\u2028' || c == '\u2029' {
933 if start < i {
934 e.WriteString(s[start:i])
935 }
936 e.WriteString(`\u202`)
937 e.WriteByte(hex[c&0xF])
938 i += size
939 start = i
940 continue
941 }
942 i += size
943 }
944 if start < len(s) {
945 e.WriteString(s[start:])
946 }
947 e.WriteByte('"')
948 }
949
950
951 func (e *encodeState) stringBytes(s []byte, escapeHTML bool) {
952 e.WriteByte('"')
953 start := 0
954 for i := 0; i < len(s); {
955 if b := s[i]; b < utf8.RuneSelf {
956 if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) {
957 i++
958 continue
959 }
960 if start < i {
961 e.Write(s[start:i])
962 }
963 switch b {
964 case '\\', '"':
965 e.WriteByte('\\')
966 e.WriteByte(b)
967 case '\n':
968 e.WriteByte('\\')
969 e.WriteByte('n')
970 case '\r':
971 e.WriteByte('\\')
972 e.WriteByte('r')
973 case '\t':
974 e.WriteByte('\\')
975 e.WriteByte('t')
976 default:
977
978
979
980
981
982 e.WriteString(`\u00`)
983 e.WriteByte(hex[b>>4])
984 e.WriteByte(hex[b&0xF])
985 }
986 i++
987 start = i
988 continue
989 }
990 c, size := utf8.DecodeRune(s[i:])
991 if c == utf8.RuneError && size == 1 {
992 if start < i {
993 e.Write(s[start:i])
994 }
995 e.WriteString(`\ufffd`)
996 i += size
997 start = i
998 continue
999 }
1000
1001
1002
1003
1004
1005
1006
1007 if c == '\u2028' || c == '\u2029' {
1008 if start < i {
1009 e.Write(s[start:i])
1010 }
1011 e.WriteString(`\u202`)
1012 e.WriteByte(hex[c&0xF])
1013 i += size
1014 start = i
1015 continue
1016 }
1017 i += size
1018 }
1019 if start < len(s) {
1020 e.Write(s[start:])
1021 }
1022 e.WriteByte('"')
1023 }
1024
1025
1026 type field struct {
1027 name string
1028 nameBytes []byte
1029 equalFold func(s, t []byte) bool
1030
1031 tag bool
1032 index []int
1033 typ reflect.Type
1034 omitEmpty bool
1035 quoted bool
1036 }
1037
1038 func fillField(f field) field {
1039 f.nameBytes = []byte(f.name)
1040 f.equalFold = foldFunc(f.nameBytes)
1041 return f
1042 }
1043
1044
1045 type byIndex []field
1046
1047 func (x byIndex) Len() int { return len(x) }
1048
1049 func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
1050
1051 func (x byIndex) Less(i, j int) bool {
1052 for k, xik := range x[i].index {
1053 if k >= len(x[j].index) {
1054 return false
1055 }
1056 if xik != x[j].index[k] {
1057 return xik < x[j].index[k]
1058 }
1059 }
1060 return len(x[i].index) < len(x[j].index)
1061 }
1062
1063
1064
1065
1066 func typeFields(t reflect.Type) []field {
1067
1068 current := []field{}
1069 next := []field{{typ: t}}
1070
1071
1072 count := map[reflect.Type]int{}
1073 nextCount := map[reflect.Type]int{}
1074
1075
1076 visited := map[reflect.Type]bool{}
1077
1078
1079 var fields []field
1080
1081 for len(next) > 0 {
1082 current, next = next, current[:0]
1083 count, nextCount = nextCount, map[reflect.Type]int{}
1084
1085 for _, f := range current {
1086 if visited[f.typ] {
1087 continue
1088 }
1089 visited[f.typ] = true
1090
1091
1092 for i := 0; i < f.typ.NumField(); i++ {
1093 sf := f.typ.Field(i)
1094 isUnexported := sf.PkgPath != ""
1095 if sf.Anonymous {
1096 t := sf.Type
1097 if t.Kind() == reflect.Ptr {
1098 t = t.Elem()
1099 }
1100 if isUnexported && t.Kind() != reflect.Struct {
1101
1102 continue
1103 }
1104
1105
1106 } else if isUnexported {
1107
1108 continue
1109 }
1110 tag := sf.Tag.Get("json")
1111 if tag == "-" {
1112 continue
1113 }
1114 name, opts := parseTag(tag)
1115 if !isValidTag(name) {
1116 name = ""
1117 }
1118 index := make([]int, len(f.index)+1)
1119 copy(index, f.index)
1120 index[len(f.index)] = i
1121
1122 ft := sf.Type
1123 if ft.Name() == "" && ft.Kind() == reflect.Ptr {
1124
1125 ft = ft.Elem()
1126 }
1127
1128
1129 quoted := false
1130 if opts.Contains("string") {
1131 switch ft.Kind() {
1132 case reflect.Bool,
1133 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
1134 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
1135 reflect.Float32, reflect.Float64,
1136 reflect.String:
1137 quoted = true
1138 }
1139 }
1140
1141
1142 if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
1143 tagged := name != ""
1144 if name == "" {
1145 name = sf.Name
1146 }
1147 fields = append(fields, fillField(field{
1148 name: name,
1149 tag: tagged,
1150 index: index,
1151 typ: ft,
1152 omitEmpty: opts.Contains("omitempty"),
1153 quoted: quoted,
1154 }))
1155 if count[f.typ] > 1 {
1156
1157
1158
1159
1160 fields = append(fields, fields[len(fields)-1])
1161 }
1162 continue
1163 }
1164
1165
1166 nextCount[ft]++
1167 if nextCount[ft] == 1 {
1168 next = append(next, fillField(field{name: ft.Name(), index: index, typ: ft}))
1169 }
1170 }
1171 }
1172 }
1173
1174 sort.Slice(fields, func(i, j int) bool {
1175 x := fields
1176
1177
1178
1179 if x[i].name != x[j].name {
1180 return x[i].name < x[j].name
1181 }
1182 if len(x[i].index) != len(x[j].index) {
1183 return len(x[i].index) < len(x[j].index)
1184 }
1185 if x[i].tag != x[j].tag {
1186 return x[i].tag
1187 }
1188 return byIndex(x).Less(i, j)
1189 })
1190
1191
1192
1193
1194
1195
1196
1197 out := fields[:0]
1198 for advance, i := 0, 0; i < len(fields); i += advance {
1199
1200
1201 fi := fields[i]
1202 name := fi.name
1203 for advance = 1; i+advance < len(fields); advance++ {
1204 fj := fields[i+advance]
1205 if fj.name != name {
1206 break
1207 }
1208 }
1209 if advance == 1 {
1210 out = append(out, fi)
1211 continue
1212 }
1213 dominant, ok := dominantField(fields[i : i+advance])
1214 if ok {
1215 out = append(out, dominant)
1216 }
1217 }
1218
1219 fields = out
1220 sort.Sort(byIndex(fields))
1221
1222 return fields
1223 }
1224
1225
1226
1227
1228
1229
1230
1231 func dominantField(fields []field) (field, bool) {
1232
1233
1234
1235 length := len(fields[0].index)
1236 tagged := -1
1237 for i, f := range fields {
1238 if len(f.index) > length {
1239 fields = fields[:i]
1240 break
1241 }
1242 if f.tag {
1243 if tagged >= 0 {
1244
1245
1246 return field{}, false
1247 }
1248 tagged = i
1249 }
1250 }
1251 if tagged >= 0 {
1252 return fields[tagged], true
1253 }
1254
1255
1256
1257 if len(fields) > 1 {
1258 return field{}, false
1259 }
1260 return fields[0], true
1261 }
1262
1263 var fieldCache struct {
1264 value atomic.Value
1265 mu sync.Mutex
1266 }
1267
1268
1269 func cachedTypeFields(t reflect.Type) []field {
1270 m, _ := fieldCache.value.Load().(map[reflect.Type][]field)
1271 f := m[t]
1272 if f != nil {
1273 return f
1274 }
1275
1276
1277
1278 f = typeFields(t)
1279 if f == nil {
1280 f = []field{}
1281 }
1282
1283 fieldCache.mu.Lock()
1284 m, _ = fieldCache.value.Load().(map[reflect.Type][]field)
1285 newM := make(map[reflect.Type][]field, len(m)+1)
1286 for k, v := range m {
1287 newM[k] = v
1288 }
1289 newM[t] = f
1290 fieldCache.value.Store(newM)
1291 fieldCache.mu.Unlock()
1292 return f
1293 }
1294
View as plain text