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