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