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