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 keys := v.MapKeys()
798 sv := make([]reflectWithString, len(keys))
799 for i, v := range keys {
800 sv[i].v = v
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].s < sv[j].s })
806
807 for i, kv := range sv {
808 if i > 0 {
809 e.WriteByte(',')
810 }
811 e.string(kv.s, opts.escapeHTML)
812 e.WriteByte(':')
813 me.elemEnc(e, v.MapIndex(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 uintptr
880 len int
881 }{v.Pointer(), 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.PtrTo(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.Ptr {
992 t = t.Elem()
993 }
994 t = t.Field(i).Type
995 }
996 return t
997 }
998
999 type reflectWithString struct {
1000 v reflect.Value
1001 s string
1002 }
1003
1004 func (w *reflectWithString) resolve() error {
1005 if w.v.Kind() == reflect.String {
1006 w.s = w.v.String()
1007 return nil
1008 }
1009 if tm, ok := w.v.Interface().(encoding.TextMarshaler); ok {
1010 if w.v.Kind() == reflect.Ptr && w.v.IsNil() {
1011 return nil
1012 }
1013 buf, err := tm.MarshalText()
1014 w.s = string(buf)
1015 return err
1016 }
1017 switch w.v.Kind() {
1018 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1019 w.s = strconv.FormatInt(w.v.Int(), 10)
1020 return nil
1021 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
1022 w.s = strconv.FormatUint(w.v.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 isUnexported := sf.PkgPath != ""
1243 if sf.Anonymous {
1244 t := sf.Type
1245 if t.Kind() == reflect.Ptr {
1246 t = t.Elem()
1247 }
1248 if isUnexported && t.Kind() != reflect.Struct {
1249
1250 continue
1251 }
1252
1253
1254 } else if isUnexported {
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.Ptr {
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