github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/encoding/json/encode.go (about) 1 // Copyright 2010 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package json implements encoding and decoding of JSON objects as defined in 6 // RFC 4627. The mapping between JSON objects and Go values is described 7 // in the documentation for the Marshal and Unmarshal functions. 8 // 9 // See "JSON and Go" for an introduction to this package: 10 // http://golang.org/doc/articles/json_and_go.html 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 // Marshal returns the JSON encoding of v. 28 // 29 // Marshal traverses the value v recursively. 30 // If an encountered value implements the Marshaler interface 31 // and is not a nil pointer, Marshal calls its MarshalJSON method 32 // to produce JSON. The nil pointer exception is not strictly necessary 33 // but mimics a similar, necessary exception in the behavior of 34 // UnmarshalJSON. 35 // 36 // Otherwise, Marshal uses the following type-dependent default encodings: 37 // 38 // Boolean values encode as JSON booleans. 39 // 40 // Floating point, integer, and Number values encode as JSON numbers. 41 // 42 // String values encode as JSON strings. InvalidUTF8Error will be returned 43 // if an invalid UTF-8 sequence is encountered. 44 // The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e" 45 // to keep some browsers from misinterpreting JSON output as HTML. 46 // 47 // Array and slice values encode as JSON arrays, except that 48 // []byte encodes as a base64-encoded string, and a nil slice 49 // encodes as the null JSON object. 50 // 51 // Struct values encode as JSON objects. Each exported struct field 52 // becomes a member of the object unless 53 // - the field's tag is "-", or 54 // - the field is empty and its tag specifies the "omitempty" option. 55 // The empty values are false, 0, any 56 // nil pointer or interface value, and any array, slice, map, or string of 57 // length zero. The object's default key string is the struct field name 58 // but can be specified in the struct field's tag value. The "json" key in 59 // the struct field's tag value is the key name, followed by an optional comma 60 // and options. Examples: 61 // 62 // // Field is ignored by this package. 63 // Field int `json:"-"` 64 // 65 // // Field appears in JSON as key "myName". 66 // Field int `json:"myName"` 67 // 68 // // Field appears in JSON as key "myName" and 69 // // the field is omitted from the object if its value is empty, 70 // // as defined above. 71 // Field int `json:"myName,omitempty"` 72 // 73 // // Field appears in JSON as key "Field" (the default), but 74 // // the field is skipped if empty. 75 // // Note the leading comma. 76 // Field int `json:",omitempty"` 77 // 78 // The "string" option signals that a field is stored as JSON inside a 79 // JSON-encoded string. It applies only to fields of string, floating point, 80 // or integer types. This extra level of encoding is sometimes used when 81 // communicating with JavaScript programs: 82 // 83 // Int64String int64 `json:",string"` 84 // 85 // The key name will be used if it's a non-empty string consisting of 86 // only Unicode letters, digits, dollar signs, percent signs, hyphens, 87 // underscores and slashes. 88 // 89 // Anonymous struct fields are usually marshaled as if their inner exported fields 90 // were fields in the outer struct, subject to the usual Go visibility rules amended 91 // as described in the next paragraph. 92 // An anonymous struct field with a name given in its JSON tag is treated as 93 // having that name, rather than being anonymous. 94 // 95 // The Go visibility rules for struct fields are amended for JSON when 96 // deciding which field to marshal or unmarshal. If there are 97 // multiple fields at the same level, and that level is the least 98 // nested (and would therefore be the nesting level selected by the 99 // usual Go rules), the following extra rules apply: 100 // 101 // 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, 102 // even if there are multiple untagged fields that would otherwise conflict. 103 // 2) If there is exactly one field (tagged or not according to the first rule), that is selected. 104 // 3) Otherwise there are multiple fields, and all are ignored; no error occurs. 105 // 106 // Handling of anonymous struct fields is new in Go 1.1. 107 // Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of 108 // an anonymous struct field in both current and earlier versions, give the field 109 // a JSON tag of "-". 110 // 111 // Map values encode as JSON objects. 112 // The map's key type must be string; the object keys are used directly 113 // as map keys. 114 // 115 // Pointer values encode as the value pointed to. 116 // A nil pointer encodes as the null JSON object. 117 // 118 // Interface values encode as the value contained in the interface. 119 // A nil interface value encodes as the null JSON object. 120 // 121 // Channel, complex, and function values cannot be encoded in JSON. 122 // Attempting to encode such a value causes Marshal to return 123 // an UnsupportedTypeError. 124 // 125 // JSON cannot represent cyclic data structures and Marshal does not 126 // handle them. Passing cyclic structures to Marshal will result in 127 // an infinite recursion. 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 // MarshalIndent is like Marshal but applies Indent to format the output. 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 // HTMLEscape appends to dst the JSON-encoded src with <, >, and & 153 // characters inside string literals changed to \u003c, \u003e, \u0026 154 // so that the JSON will be safe to embed inside HTML <script> tags. 155 // For historical reasons, web browsers don't honor standard HTML 156 // escaping within <script> tags, so an alternative JSON encoding must 157 // be used. 158 func HTMLEscape(dst *bytes.Buffer, src []byte) { 159 // < > & can only appear in string literals, 160 // so just scan the string one byte at a time. 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 // Marshaler is the interface implemented by objects that 179 // can marshal themselves into valid JSON. 180 type Marshaler interface { 181 MarshalJSON() ([]byte, error) 182 } 183 184 // An UnsupportedTypeError is returned by Marshal when attempting 185 // to encode an unsupported value type. 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 // An InvalidUTF8Error is returned by Marshal when attempting 204 // to encode a string value with invalid UTF-8 sequences. 205 type InvalidUTF8Error struct { 206 S string // the whole string value that caused the error 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 // An encodeState encodes JSON into a bytes.Buffer. 225 type encodeState struct { 226 bytes.Buffer // accumulated output 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 // reflectValueQuoted writes the value in v to the output. 272 // If quoted is true, the serialization is wrapped in a JSON string. 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 // T doesn't match the interface. Check against *T too. 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 // copy JSON into buffer, checking validity. 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" // Number's zero-val 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 // Byte slices get special treatment; arrays don't. 406 s := v.Bytes() 407 e.WriteByte('"') 408 if len(s) < 1024 { 409 // for small buffers, using Encode directly is much faster. 410 dst := make([]byte, base64.StdEncoding.EncodedLen(len(s))) 411 base64.StdEncoding.Encode(dst, s) 412 e.Write(dst) 413 } else { 414 // for large buffers, avoid unnecessary extra temporary 415 // buffer space. 416 enc := base64.NewEncoder(base64.StdEncoding, e) 417 enc.Write(s) 418 enc.Close() 419 } 420 e.WriteByte('"') 421 break 422 } 423 // Slices can be marshalled as nil, but otherwise are handled 424 // as arrays. 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 // Backslash and quote chars are reserved, but 458 // otherwise any punctuation chars are allowed 459 // in a tag name. 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 // stringValues is a slice of reflect.Value holding *reflect.StringValue. 483 // It implements the methods to sort by string. 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 // This encodes bytes < 0x20 except for \n and \r, 516 // as well as < and >. The latter are escaped because they 517 // can lead to security holes when user-controlled strings 518 // are rendered into JSON and served to some browsers. 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 // A field represents a single field found in a struct. 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 // byName sorts field by name, breaking ties with depth, 551 // then breaking ties with "name came from json tag", then 552 // breaking ties with index sequence. 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 // byIndex sorts field by index sequence. 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 // typeFields returns a list of fields that JSON should recognize for the given type. 592 // The algorithm is breadth-first search over the set of structs to include - the top struct 593 // and then any reachable anonymous structs. 594 func typeFields(t reflect.Type) []field { 595 // Anonymous fields to explore at the current level and the next. 596 current := []field{} 597 next := []field{{typ: t}} 598 599 // Count of queued names for current level and the next. 600 count := map[reflect.Type]int{} 601 nextCount := map[reflect.Type]int{} 602 603 // Types already visited at an earlier level. 604 visited := map[reflect.Type]bool{} 605 606 // Fields found. 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 // Scan f.typ for fields to include. 620 for i := 0; i < f.typ.NumField(); i++ { 621 sf := f.typ.Field(i) 622 if sf.PkgPath != "" { // unexported 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 // Follow pointer. 640 ft = ft.Elem() 641 } 642 643 // Record found field and index sequence. 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 // If there were multiple instances, add a second, 653 // so that the annihilation code will see a duplicate. 654 // It only cares about the distinction between 1 or 2, 655 // so don't bother generating any more copies. 656 fields = append(fields, fields[len(fields)-1]) 657 } 658 continue 659 } 660 661 // Record new anonymous struct to explore in next round. 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 // Delete all fields that are hidden by the Go rules for embedded fields, 673 // except that fields with JSON tags are promoted. 674 675 // The fields are sorted in primary order of name, secondary order 676 // of field index length. Loop over names; for each name, delete 677 // hidden fields by choosing the one dominant field that survives. 678 out := fields[:0] 679 for advance, i := 0, 0; i < len(fields); i += advance { 680 // One iteration per name. 681 // Find the sequence of fields with the name of this first field. 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 { // Only one field with this name 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 // dominantField looks through the fields, all of which are known to 707 // have the same name, to find the single field that dominates the 708 // others using Go's embedding rules, modified by the presence of 709 // JSON tags. If there are multiple top-level fields, the boolean 710 // will be false: This condition is an error in Go and we skip all 711 // the fields. 712 func dominantField(fields []field) (field, bool) { 713 // The fields are sorted in increasing index-length order. The winner 714 // must therefore be one with the shortest index length. Drop all 715 // longer entries, which is easy: just truncate the slice. 716 length := len(fields[0].index) 717 tagged := -1 // Index of first tagged field. 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 // Multiple tagged fields at the same level: conflict. 726 // Return no field. 727 return field{}, false 728 } 729 tagged = i 730 } 731 } 732 if tagged >= 0 { 733 return fields[tagged], true 734 } 735 // All remaining fields have the same length. If there's more than one, 736 // we have a conflict (two fields named "X" at the same level) and we 737 // return no field. 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 // cachedTypeFields is like typeFields but uses a cache to avoid repeated work. 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 // Compute fields without lock. 759 // Might duplicate effort but won't hold other computations back. 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 }