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