Source file src/pkg/encoding/json/encode.go
1
2
3
4
5
6
7
8
9
10
11 package json
12
13 import (
14 "bytes"
15 "encoding/base64"
16 "math"
17 "reflect"
18 "runtime"
19 "sort"
20 "strconv"
21 "strings"
22 "sync"
23 "unicode"
24 "unicode/utf8"
25 )
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 func Marshal(v interface{}) ([]byte, error) {
130 e := &encodeState{}
131 err := e.marshal(v)
132 if err != nil {
133 return nil, err
134 }
135 return e.Bytes(), nil
136 }
137
138
139 func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
140 b, err := Marshal(v)
141 if err != nil {
142 return nil, err
143 }
144 var buf bytes.Buffer
145 err = Indent(&buf, b, prefix, indent)
146 if err != nil {
147 return nil, err
148 }
149 return buf.Bytes(), nil
150 }
151
152
153
154
155
156
157
158 func HTMLEscape(dst *bytes.Buffer, src []byte) {
159
160
161 start := 0
162 for i, c := range src {
163 if c == '<' || c == '>' || c == '&' {
164 if start < i {
165 dst.Write(src[start:i])
166 }
167 dst.WriteString(`\u00`)
168 dst.WriteByte(hex[c>>4])
169 dst.WriteByte(hex[c&0xF])
170 start = i + 1
171 }
172 }
173 if start < len(src) {
174 dst.Write(src[start:])
175 }
176 }
177
178
179
180 type Marshaler interface {
181 MarshalJSON() ([]byte, error)
182 }
183
184
185
186 type UnsupportedTypeError struct {
187 Type reflect.Type
188 }
189
190 func (e *UnsupportedTypeError) Error() string {
191 return "json: unsupported type: " + e.Type.String()
192 }
193
194 type UnsupportedValueError struct {
195 Value reflect.Value
196 Str string
197 }
198
199 func (e *UnsupportedValueError) Error() string {
200 return "json: unsupported value: " + e.Str
201 }
202
203
204
205 type InvalidUTF8Error struct {
206 S string
207 }
208
209 func (e *InvalidUTF8Error) Error() string {
210 return "json: invalid UTF-8 in string: " + strconv.Quote(e.S)
211 }
212
213 type MarshalerError struct {
214 Type reflect.Type
215 Err error
216 }
217
218 func (e *MarshalerError) Error() string {
219 return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error()
220 }
221
222 var hex = "0123456789abcdef"
223
224
225 type encodeState struct {
226 bytes.Buffer
227 scratch [64]byte
228 }
229
230 func (e *encodeState) marshal(v interface{}) (err error) {
231 defer func() {
232 if r := recover(); r != nil {
233 if _, ok := r.(runtime.Error); ok {
234 panic(r)
235 }
236 err = r.(error)
237 }
238 }()
239 e.reflectValue(reflect.ValueOf(v))
240 return nil
241 }
242
243 func (e *encodeState) error(err error) {
244 panic(err)
245 }
246
247 var byteSliceType = reflect.TypeOf([]byte(nil))
248
249 func isEmptyValue(v reflect.Value) bool {
250 switch v.Kind() {
251 case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
252 return v.Len() == 0
253 case reflect.Bool:
254 return !v.Bool()
255 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
256 return v.Int() == 0
257 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
258 return v.Uint() == 0
259 case reflect.Float32, reflect.Float64:
260 return v.Float() == 0
261 case reflect.Interface, reflect.Ptr:
262 return v.IsNil()
263 }
264 return false
265 }
266
267 func (e *encodeState) reflectValue(v reflect.Value) {
268 e.reflectValueQuoted(v, false)
269 }
270
271
272
273 func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
274 if !v.IsValid() {
275 e.WriteString("null")
276 return
277 }
278
279 m, ok := v.Interface().(Marshaler)
280 if !ok {
281
282 if v.Kind() != reflect.Ptr && v.CanAddr() {
283 m, ok = v.Addr().Interface().(Marshaler)
284 if ok {
285 v = v.Addr()
286 }
287 }
288 }
289 if ok && (v.Kind() != reflect.Ptr || !v.IsNil()) {
290 b, err := m.MarshalJSON()
291 if err == nil {
292
293 err = compact(&e.Buffer, b, true)
294 }
295 if err != nil {
296 e.error(&MarshalerError{v.Type(), err})
297 }
298 return
299 }
300
301 writeString := (*encodeState).WriteString
302 if quoted {
303 writeString = (*encodeState).string
304 }
305
306 switch v.Kind() {
307 case reflect.Bool:
308 x := v.Bool()
309 if x {
310 writeString(e, "true")
311 } else {
312 writeString(e, "false")
313 }
314
315 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
316 b := strconv.AppendInt(e.scratch[:0], v.Int(), 10)
317 if quoted {
318 writeString(e, string(b))
319 } else {
320 e.Write(b)
321 }
322 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
323 b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10)
324 if quoted {
325 writeString(e, string(b))
326 } else {
327 e.Write(b)
328 }
329 case reflect.Float32, reflect.Float64:
330 f := v.Float()
331 if math.IsInf(f, 0) || math.IsNaN(f) {
332 e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, v.Type().Bits())})
333 }
334 b := strconv.AppendFloat(e.scratch[:0], f, 'g', -1, v.Type().Bits())
335 if quoted {
336 writeString(e, string(b))
337 } else {
338 e.Write(b)
339 }
340 case reflect.String:
341 if v.Type() == numberType {
342 numStr := v.String()
343 if numStr == "" {
344 numStr = "0"
345 }
346 e.WriteString(numStr)
347 break
348 }
349 if quoted {
350 sb, err := Marshal(v.String())
351 if err != nil {
352 e.error(err)
353 }
354 e.string(string(sb))
355 } else {
356 e.string(v.String())
357 }
358
359 case reflect.Struct:
360 e.WriteByte('{')
361 first := true
362 for _, f := range cachedTypeFields(v.Type()) {
363 fv := fieldByIndex(v, f.index)
364 if !fv.IsValid() || f.omitEmpty && isEmptyValue(fv) {
365 continue
366 }
367 if first {
368 first = false
369 } else {
370 e.WriteByte(',')
371 }
372 e.string(f.name)
373 e.WriteByte(':')
374 e.reflectValueQuoted(fv, f.quoted)
375 }
376 e.WriteByte('}')
377
378 case reflect.Map:
379 if v.Type().Key().Kind() != reflect.String {
380 e.error(&UnsupportedTypeError{v.Type()})
381 }
382 if v.IsNil() {
383 e.WriteString("null")
384 break
385 }
386 e.WriteByte('{')
387 var sv stringValues = v.MapKeys()
388 sort.Sort(sv)
389 for i, k := range sv {
390 if i > 0 {
391 e.WriteByte(',')
392 }
393 e.string(k.String())
394 e.WriteByte(':')
395 e.reflectValue(v.MapIndex(k))
396 }
397 e.WriteByte('}')
398
399 case reflect.Slice:
400 if v.IsNil() {
401 e.WriteString("null")
402 break
403 }
404 if v.Type().Elem().Kind() == reflect.Uint8 {
405
406 s := v.Bytes()
407 e.WriteByte('"')
408 if len(s) < 1024 {
409
410 dst := make([]byte, base64.StdEncoding.EncodedLen(len(s)))
411 base64.StdEncoding.Encode(dst, s)
412 e.Write(dst)
413 } else {
414
415
416 enc := base64.NewEncoder(base64.StdEncoding, e)
417 enc.Write(s)
418 enc.Close()
419 }
420 e.WriteByte('"')
421 break
422 }
423
424
425 fallthrough
426 case reflect.Array:
427 e.WriteByte('[')
428 n := v.Len()
429 for i := 0; i < n; i++ {
430 if i > 0 {
431 e.WriteByte(',')
432 }
433 e.reflectValue(v.Index(i))
434 }
435 e.WriteByte(']')
436
437 case reflect.Interface, reflect.Ptr:
438 if v.IsNil() {
439 e.WriteString("null")
440 return
441 }
442 e.reflectValue(v.Elem())
443
444 default:
445 e.error(&UnsupportedTypeError{v.Type()})
446 }
447 return
448 }
449
450 func isValidTag(s string) bool {
451 if s == "" {
452 return false
453 }
454 for _, c := range s {
455 switch {
456 case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
457
458
459
460 default:
461 if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
462 return false
463 }
464 }
465 }
466 return true
467 }
468
469 func fieldByIndex(v reflect.Value, index []int) reflect.Value {
470 for _, i := range index {
471 if v.Kind() == reflect.Ptr {
472 if v.IsNil() {
473 return reflect.Value{}
474 }
475 v = v.Elem()
476 }
477 v = v.Field(i)
478 }
479 return v
480 }
481
482
483
484 type stringValues []reflect.Value
485
486 func (sv stringValues) Len() int { return len(sv) }
487 func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
488 func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
489 func (sv stringValues) get(i int) string { return sv[i].String() }
490
491 func (e *encodeState) string(s string) (int, error) {
492 len0 := e.Len()
493 e.WriteByte('"')
494 start := 0
495 for i := 0; i < len(s); {
496 if b := s[i]; b < utf8.RuneSelf {
497 if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' {
498 i++
499 continue
500 }
501 if start < i {
502 e.WriteString(s[start:i])
503 }
504 switch b {
505 case '\\', '"':
506 e.WriteByte('\\')
507 e.WriteByte(b)
508 case '\n':
509 e.WriteByte('\\')
510 e.WriteByte('n')
511 case '\r':
512 e.WriteByte('\\')
513 e.WriteByte('r')
514 default:
515
516
517
518
519 e.WriteString(`\u00`)
520 e.WriteByte(hex[b>>4])
521 e.WriteByte(hex[b&0xF])
522 }
523 i++
524 start = i
525 continue
526 }
527 c, size := utf8.DecodeRuneInString(s[i:])
528 if c == utf8.RuneError && size == 1 {
529 e.error(&InvalidUTF8Error{s})
530 }
531 i += size
532 }
533 if start < len(s) {
534 e.WriteString(s[start:])
535 }
536 e.WriteByte('"')
537 return e.Len() - len0, nil
538 }
539
540
541 type field struct {
542 name string
543 tag bool
544 index []int
545 typ reflect.Type
546 omitEmpty bool
547 quoted bool
548 }
549
550
551
552
553 type byName []field
554
555 func (x byName) Len() int { return len(x) }
556
557 func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
558
559 func (x byName) Less(i, j int) bool {
560 if x[i].name != x[j].name {
561 return x[i].name < x[j].name
562 }
563 if len(x[i].index) != len(x[j].index) {
564 return len(x[i].index) < len(x[j].index)
565 }
566 if x[i].tag != x[j].tag {
567 return x[i].tag
568 }
569 return byIndex(x).Less(i, j)
570 }
571
572
573 type byIndex []field
574
575 func (x byIndex) Len() int { return len(x) }
576
577 func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
578
579 func (x byIndex) Less(i, j int) bool {
580 for k, xik := range x[i].index {
581 if k >= len(x[j].index) {
582 return false
583 }
584 if xik != x[j].index[k] {
585 return xik < x[j].index[k]
586 }
587 }
588 return len(x[i].index) < len(x[j].index)
589 }
590
591
592
593
594 func typeFields(t reflect.Type) []field {
595
596 current := []field{}
597 next := []field{{typ: t}}
598
599
600 count := map[reflect.Type]int{}
601 nextCount := map[reflect.Type]int{}
602
603
604 visited := map[reflect.Type]bool{}
605
606
607 var fields []field
608
609 for len(next) > 0 {
610 current, next = next, current[:0]
611 count, nextCount = nextCount, map[reflect.Type]int{}
612
613 for _, f := range current {
614 if visited[f.typ] {
615 continue
616 }
617 visited[f.typ] = true
618
619
620 for i := 0; i < f.typ.NumField(); i++ {
621 sf := f.typ.Field(i)
622 if sf.PkgPath != "" {
623 continue
624 }
625 tag := sf.Tag.Get("json")
626 if tag == "-" {
627 continue
628 }
629 name, opts := parseTag(tag)
630 if !isValidTag(name) {
631 name = ""
632 }
633 index := make([]int, len(f.index)+1)
634 copy(index, f.index)
635 index[len(f.index)] = i
636
637 ft := sf.Type
638 if ft.Name() == "" && ft.Kind() == reflect.Ptr {
639
640 ft = ft.Elem()
641 }
642
643
644 if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
645 tagged := name != ""
646 if name == "" {
647 name = sf.Name
648 }
649 fields = append(fields, field{name, tagged, index, ft,
650 opts.Contains("omitempty"), opts.Contains("string")})
651 if count[f.typ] > 1 {
652
653
654
655
656 fields = append(fields, fields[len(fields)-1])
657 }
658 continue
659 }
660
661
662 nextCount[ft]++
663 if nextCount[ft] == 1 {
664 next = append(next, field{name: ft.Name(), index: index, typ: ft})
665 }
666 }
667 }
668 }
669
670 sort.Sort(byName(fields))
671
672
673
674
675
676
677
678 out := fields[:0]
679 for advance, i := 0, 0; i < len(fields); i += advance {
680
681
682 fi := fields[i]
683 name := fi.name
684 for advance = 1; i+advance < len(fields); advance++ {
685 fj := fields[i+advance]
686 if fj.name != name {
687 break
688 }
689 }
690 if advance == 1 {
691 out = append(out, fi)
692 continue
693 }
694 dominant, ok := dominantField(fields[i : i+advance])
695 if ok {
696 out = append(out, dominant)
697 }
698 }
699
700 fields = out
701 sort.Sort(byIndex(fields))
702
703 return fields
704 }
705
706
707
708
709
710
711
712 func dominantField(fields []field) (field, bool) {
713
714
715
716 length := len(fields[0].index)
717 tagged := -1
718 for i, f := range fields {
719 if len(f.index) > length {
720 fields = fields[:i]
721 break
722 }
723 if f.tag {
724 if tagged >= 0 {
725
726
727 return field{}, false
728 }
729 tagged = i
730 }
731 }
732 if tagged >= 0 {
733 return fields[tagged], true
734 }
735
736
737
738 if len(fields) > 1 {
739 return field{}, false
740 }
741 return fields[0], true
742 }
743
744 var fieldCache struct {
745 sync.RWMutex
746 m map[reflect.Type][]field
747 }
748
749
750 func cachedTypeFields(t reflect.Type) []field {
751 fieldCache.RLock()
752 f := fieldCache.m[t]
753 fieldCache.RUnlock()
754 if f != nil {
755 return f
756 }
757
758
759
760 f = typeFields(t)
761 if f == nil {
762 f = []field{}
763 }
764
765 fieldCache.Lock()
766 if fieldCache.m == nil {
767 fieldCache.m = map[reflect.Type][]field{}
768 }
769 fieldCache.m[t] = f
770 fieldCache.Unlock()
771 return f
772 }
View as plain text