github.com/yaegashi/msgraph.go@v0.1.4/jsonx/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 as defined in 6 // RFC 7159. The mapping between JSON 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 // https://golang.org/doc/articles/json_and_go.html 11 package jsonx 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 // Marshal returns the JSON encoding of v. 29 // 30 // Marshal traverses the value v recursively. 31 // If an encountered value implements the Marshaler interface 32 // and is not a nil pointer, Marshal calls its MarshalJSON method 33 // to produce JSON. If no MarshalJSON method is present but the 34 // value implements encoding.TextMarshaler instead, Marshal calls 35 // its MarshalText method and encodes the result as a JSON string. 36 // The nil pointer exception is not strictly necessary 37 // but mimics a similar, necessary exception in the behavior of 38 // UnmarshalJSON. 39 // 40 // Otherwise, Marshal uses the following type-dependent default encodings: 41 // 42 // Boolean values encode as JSON booleans. 43 // 44 // Floating point, integer, and Number values encode as JSON numbers. 45 // 46 // String values encode as JSON strings coerced to valid UTF-8, 47 // replacing invalid bytes with the Unicode replacement rune. 48 // So that the JSON will be safe to embed inside HTML <script> tags, 49 // the string is encoded using HTMLEscape, 50 // which replaces "<", ">", "&", U+2028, and U+2029 are escaped 51 // to "\u003c","\u003e", "\u0026", "\u2028", and "\u2029". 52 // This replacement can be disabled when using an Encoder, 53 // by calling SetEscapeHTML(false). 54 // 55 // Array and slice values encode as JSON arrays, except that 56 // []byte encodes as a base64-encoded string, and a nil slice 57 // encodes as the null JSON value. 58 // 59 // Struct values encode as JSON objects. 60 // Each exported struct field becomes a member of the object, using the 61 // field name as the object key, unless the field is omitted for one of the 62 // reasons given below. 63 // 64 // The encoding of each struct field can be customized by the format string 65 // stored under the "json" key in the struct field's tag. 66 // The format string gives the name of the field, possibly followed by a 67 // comma-separated list of options. The name may be empty in order to 68 // specify options without overriding the default field name. 69 // 70 // The "omitempty" option specifies that the field should be omitted 71 // from the encoding if the field has an empty value, defined as 72 // false, 0, a nil pointer, a nil interface value, and any empty array, 73 // slice, map, or string. 74 // 75 // As a special case, if the field tag is "-", the field is always omitted. 76 // Note that a field with name "-" can still be generated using the tag "-,". 77 // 78 // Examples of struct field tags and their meanings: 79 // 80 // // Field appears in JSON as key "myName". 81 // Field int `json:"myName"` 82 // 83 // // Field appears in JSON as key "myName" and 84 // // the field is omitted from the object if its value is empty, 85 // // as defined above. 86 // Field int `json:"myName,omitempty"` 87 // 88 // // Field appears in JSON as key "Field" (the default), but 89 // // the field is skipped if empty. 90 // // Note the leading comma. 91 // Field int `json:",omitempty"` 92 // 93 // // Field is ignored by this package. 94 // Field int `json:"-"` 95 // 96 // // Field appears in JSON as key "-". 97 // Field int `json:"-,"` 98 // 99 // The "string" option signals that a field is stored as JSON inside a 100 // JSON-encoded string. It applies only to fields of string, floating point, 101 // integer, or boolean types. This extra level of encoding is sometimes used 102 // when communicating with JavaScript programs: 103 // 104 // Int64String int64 `json:",string"` 105 // 106 // The key name will be used if it's a non-empty string consisting of 107 // only Unicode letters, digits, and ASCII punctuation except quotation 108 // marks, backslash, and comma. 109 // 110 // Anonymous struct fields are usually marshaled as if their inner exported fields 111 // were fields in the outer struct, subject to the usual Go visibility rules amended 112 // as described in the next paragraph. 113 // An anonymous struct field with a name given in its JSON tag is treated as 114 // having that name, rather than being anonymous. 115 // An anonymous struct field of interface type is treated the same as having 116 // that type as its name, rather than being anonymous. 117 // 118 // The Go visibility rules for struct fields are amended for JSON when 119 // deciding which field to marshal or unmarshal. If there are 120 // multiple fields at the same level, and that level is the least 121 // nested (and would therefore be the nesting level selected by the 122 // usual Go rules), the following extra rules apply: 123 // 124 // 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, 125 // even if there are multiple untagged fields that would otherwise conflict. 126 // 127 // 2) If there is exactly one field (tagged or not according to the first rule), that is selected. 128 // 129 // 3) Otherwise there are multiple fields, and all are ignored; no error occurs. 130 // 131 // Handling of anonymous struct fields is new in Go 1.1. 132 // Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of 133 // an anonymous struct field in both current and earlier versions, give the field 134 // a JSON tag of "-". 135 // 136 // Map values encode as JSON objects. The map's key type must either be a 137 // string, an integer type, or implement encoding.TextMarshaler. The map keys 138 // are sorted and used as JSON object keys by applying the following rules, 139 // subject to the UTF-8 coercion described for string values above: 140 // - keys of any string type are used directly 141 // - encoding.TextMarshalers are marshaled 142 // - integer keys are converted to strings 143 // 144 // Pointer values encode as the value pointed to. 145 // A nil pointer encodes as the null JSON value. 146 // 147 // Interface values encode as the value contained in the interface. 148 // A nil interface value encodes as the null JSON value. 149 // 150 // Channel, complex, and function values cannot be encoded in JSON. 151 // Attempting to encode such a value causes Marshal to return 152 // an UnsupportedTypeError. 153 // 154 // JSON cannot represent cyclic data structures and Marshal does not 155 // handle them. Passing cyclic structures to Marshal will result in 156 // an infinite recursion. 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 e.Reset() 168 encodeStatePool.Put(e) 169 170 return buf, nil 171 } 172 173 // MarshalIndent is like Marshal but applies Indent to format the output. 174 // Each JSON element in the output will begin on a new line beginning with prefix 175 // followed by one or more copies of indent according to the indentation nesting. 176 func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { 177 b, err := Marshal(v) 178 if err != nil { 179 return nil, err 180 } 181 var buf bytes.Buffer 182 err = Indent(&buf, b, prefix, indent) 183 if err != nil { 184 return nil, err 185 } 186 return buf.Bytes(), nil 187 } 188 189 // HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029 190 // characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029 191 // so that the JSON will be safe to embed inside HTML <script> tags. 192 // For historical reasons, web browsers don't honor standard HTML 193 // escaping within <script> tags, so an alternative JSON encoding must 194 // be used. 195 func HTMLEscape(dst *bytes.Buffer, src []byte) { 196 // The characters can only appear in string literals, 197 // so just scan the string one byte at a time. 198 start := 0 199 for i, c := range src { 200 if c == '<' || c == '>' || c == '&' { 201 if start < i { 202 dst.Write(src[start:i]) 203 } 204 dst.WriteString(`\u00`) 205 dst.WriteByte(hex[c>>4]) 206 dst.WriteByte(hex[c&0xF]) 207 start = i + 1 208 } 209 // Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9). 210 if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 { 211 if start < i { 212 dst.Write(src[start:i]) 213 } 214 dst.WriteString(`\u202`) 215 dst.WriteByte(hex[src[i+2]&0xF]) 216 start = i + 3 217 } 218 } 219 if start < len(src) { 220 dst.Write(src[start:]) 221 } 222 } 223 224 // Marshaler is the interface implemented by types that 225 // can marshal themselves into valid JSON. 226 type Marshaler interface { 227 MarshalJSON() ([]byte, error) 228 } 229 230 // An UnsupportedTypeError is returned by Marshal when attempting 231 // to encode an unsupported value type. 232 type UnsupportedTypeError struct { 233 Type reflect.Type 234 } 235 236 func (e *UnsupportedTypeError) Error() string { 237 return "json: unsupported type: " + e.Type.String() 238 } 239 240 type UnsupportedValueError struct { 241 Value reflect.Value 242 Str string 243 } 244 245 func (e *UnsupportedValueError) Error() string { 246 return "json: unsupported value: " + e.Str 247 } 248 249 // Before Go 1.2, an InvalidUTF8Error was returned by Marshal when 250 // attempting to encode a string value with invalid UTF-8 sequences. 251 // As of Go 1.2, Marshal instead coerces the string to valid UTF-8 by 252 // replacing invalid bytes with the Unicode replacement rune U+FFFD. 253 // 254 // Deprecated: No longer used; kept for compatibility. 255 type InvalidUTF8Error struct { 256 S string // the whole string value that caused the error 257 } 258 259 func (e *InvalidUTF8Error) Error() string { 260 return "json: invalid UTF-8 in string: " + strconv.Quote(e.S) 261 } 262 263 // A MarshalerError represents an error from calling a MarshalJSON or MarshalText method. 264 type MarshalerError struct { 265 Type reflect.Type 266 Err error 267 } 268 269 func (e *MarshalerError) Error() string { 270 return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error() 271 } 272 273 func (e *MarshalerError) Unwrap() error { return e.Err } 274 275 var hex = "0123456789abcdef" 276 277 // An encodeState encodes JSON into a bytes.Buffer. 278 type encodeState struct { 279 bytes.Buffer // accumulated output 280 scratch [64]byte 281 } 282 283 var encodeStatePool sync.Pool 284 285 func newEncodeState() *encodeState { 286 if v := encodeStatePool.Get(); v != nil { 287 e := v.(*encodeState) 288 e.Reset() 289 return e 290 } 291 return new(encodeState) 292 } 293 294 // jsonError is an error wrapper type for internal use only. 295 // Panics with errors are wrapped in jsonError so that the top-level recover 296 // can distinguish intentional panics from this package. 297 type jsonError struct{ error } 298 299 func (e *encodeState) marshal(v interface{}, opts encOpts) (err error) { 300 defer func() { 301 if r := recover(); r != nil { 302 if je, ok := r.(jsonError); ok { 303 err = je.error 304 } else { 305 panic(r) 306 } 307 } 308 }() 309 e.reflectValue(reflect.ValueOf(v), opts) 310 return nil 311 } 312 313 // error aborts the encoding by panicking with err wrapped in jsonError. 314 func (e *encodeState) error(err error) { 315 panic(jsonError{err}) 316 } 317 318 func isEmptyValue(v reflect.Value) bool { 319 switch v.Kind() { 320 case reflect.Array, reflect.Map, reflect.Slice, reflect.String: 321 return v.Len() == 0 322 case reflect.Bool: 323 return !v.Bool() 324 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 325 return v.Int() == 0 326 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 327 return v.Uint() == 0 328 case reflect.Float32, reflect.Float64: 329 return v.Float() == 0 330 case reflect.Interface, reflect.Ptr: 331 return v.IsNil() 332 } 333 return false 334 } 335 336 func (e *encodeState) reflectValue(v reflect.Value, opts encOpts) { 337 valueEncoder(v)(e, v, opts) 338 } 339 340 type encOpts struct { 341 // quoted causes primitive fields to be encoded inside JSON strings. 342 quoted bool 343 // escapeHTML causes '<', '>', and '&' to be escaped in JSON strings. 344 escapeHTML bool 345 } 346 347 type encoderFunc func(e *encodeState, v reflect.Value, opts encOpts) 348 349 var encoderCache sync.Map // map[reflect.Type]encoderFunc 350 351 func valueEncoder(v reflect.Value) encoderFunc { 352 if !v.IsValid() { 353 return invalidValueEncoder 354 } 355 return typeEncoder(v.Type()) 356 } 357 358 func typeEncoder(t reflect.Type) encoderFunc { 359 if fi, ok := encoderCache.Load(t); ok { 360 return fi.(encoderFunc) 361 } 362 363 // To deal with recursive types, populate the map with an 364 // indirect func before we build it. This type waits on the 365 // real func (f) to be ready and then calls it. This indirect 366 // func is only used for recursive types. 367 var ( 368 wg sync.WaitGroup 369 f encoderFunc 370 ) 371 wg.Add(1) 372 fi, loaded := encoderCache.LoadOrStore(t, encoderFunc(func(e *encodeState, v reflect.Value, opts encOpts) { 373 wg.Wait() 374 f(e, v, opts) 375 })) 376 if loaded { 377 return fi.(encoderFunc) 378 } 379 380 // Compute the real encoder and replace the indirect func with it. 381 f = newTypeEncoder(t, true) 382 wg.Done() 383 encoderCache.Store(t, f) 384 return f 385 } 386 387 var ( 388 marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() 389 textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() 390 ) 391 392 // newTypeEncoder constructs an encoderFunc for a type. 393 // The returned encoder only checks CanAddr when allowAddr is true. 394 func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc { 395 if t.Implements(marshalerType) { 396 return marshalerEncoder 397 } 398 if t.Kind() != reflect.Ptr && allowAddr && reflect.PtrTo(t).Implements(marshalerType) { 399 return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false)) 400 } 401 402 if t.Implements(textMarshalerType) { 403 return textMarshalerEncoder 404 } 405 if t.Kind() != reflect.Ptr && allowAddr && reflect.PtrTo(t).Implements(textMarshalerType) { 406 return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false)) 407 } 408 409 switch t.Kind() { 410 case reflect.Bool: 411 return boolEncoder 412 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 413 return intEncoder 414 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 415 return uintEncoder 416 case reflect.Float32: 417 return float32Encoder 418 case reflect.Float64: 419 return float64Encoder 420 case reflect.String: 421 return stringEncoder 422 case reflect.Interface: 423 return interfaceEncoder 424 case reflect.Struct: 425 return newStructEncoder(t) 426 case reflect.Map: 427 return newMapEncoder(t) 428 case reflect.Slice: 429 return newSliceEncoder(t) 430 case reflect.Array: 431 return newArrayEncoder(t) 432 case reflect.Ptr: 433 return newPtrEncoder(t) 434 default: 435 return unsupportedTypeEncoder 436 } 437 } 438 439 func invalidValueEncoder(e *encodeState, v reflect.Value, _ encOpts) { 440 e.WriteString("null") 441 } 442 443 func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 444 if v.Kind() == reflect.Ptr && v.IsNil() { 445 e.WriteString("null") 446 return 447 } 448 m, ok := v.Interface().(Marshaler) 449 if !ok { 450 e.WriteString("null") 451 return 452 } 453 b, err := m.MarshalJSON() 454 if err == nil { 455 // copy JSON into buffer, checking validity. 456 err = compact(&e.Buffer, b, opts.escapeHTML) 457 } 458 if err != nil { 459 e.error(&MarshalerError{v.Type(), err}) 460 } 461 } 462 463 func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 464 va := v.Addr() 465 if va.IsNil() { 466 e.WriteString("null") 467 return 468 } 469 m := va.Interface().(Marshaler) 470 b, err := m.MarshalJSON() 471 if err == nil { 472 // copy JSON into buffer, checking validity. 473 err = compact(&e.Buffer, b, opts.escapeHTML) 474 } 475 if err != nil { 476 e.error(&MarshalerError{v.Type(), err}) 477 } 478 } 479 480 func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 481 if v.Kind() == reflect.Ptr && v.IsNil() { 482 e.WriteString("null") 483 return 484 } 485 m := v.Interface().(encoding.TextMarshaler) 486 b, err := m.MarshalText() 487 if err != nil { 488 e.error(&MarshalerError{v.Type(), err}) 489 } 490 e.stringBytes(b, opts.escapeHTML) 491 } 492 493 func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 494 va := v.Addr() 495 if va.IsNil() { 496 e.WriteString("null") 497 return 498 } 499 m := va.Interface().(encoding.TextMarshaler) 500 b, err := m.MarshalText() 501 if err != nil { 502 e.error(&MarshalerError{v.Type(), err}) 503 } 504 e.stringBytes(b, opts.escapeHTML) 505 } 506 507 func boolEncoder(e *encodeState, v reflect.Value, opts encOpts) { 508 if opts.quoted { 509 e.WriteByte('"') 510 } 511 if v.Bool() { 512 e.WriteString("true") 513 } else { 514 e.WriteString("false") 515 } 516 if opts.quoted { 517 e.WriteByte('"') 518 } 519 } 520 521 func intEncoder(e *encodeState, v reflect.Value, opts encOpts) { 522 b := strconv.AppendInt(e.scratch[:0], v.Int(), 10) 523 if opts.quoted { 524 e.WriteByte('"') 525 } 526 e.Write(b) 527 if opts.quoted { 528 e.WriteByte('"') 529 } 530 } 531 532 func uintEncoder(e *encodeState, v reflect.Value, opts encOpts) { 533 b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10) 534 if opts.quoted { 535 e.WriteByte('"') 536 } 537 e.Write(b) 538 if opts.quoted { 539 e.WriteByte('"') 540 } 541 } 542 543 type floatEncoder int // number of bits 544 545 func (bits floatEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 546 f := v.Float() 547 if math.IsInf(f, 0) || math.IsNaN(f) { 548 e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))}) 549 } 550 551 // Convert as if by ES6 number to string conversion. 552 // This matches most other JSON generators. 553 // See golang.org/issue/6384 and golang.org/issue/14135. 554 // Like fmt %g, but the exponent cutoffs are different 555 // and exponents themselves are not padded to two digits. 556 b := e.scratch[:0] 557 abs := math.Abs(f) 558 fmt := byte('f') 559 // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. 560 if abs != 0 { 561 if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) { 562 fmt = 'e' 563 } 564 } 565 b = strconv.AppendFloat(b, f, fmt, -1, int(bits)) 566 if fmt == 'e' { 567 // clean up e-09 to e-9 568 n := len(b) 569 if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' { 570 b[n-2] = b[n-1] 571 b = b[:n-1] 572 } 573 } 574 575 if opts.quoted { 576 e.WriteByte('"') 577 } 578 e.Write(b) 579 if opts.quoted { 580 e.WriteByte('"') 581 } 582 } 583 584 var ( 585 float32Encoder = (floatEncoder(32)).encode 586 float64Encoder = (floatEncoder(64)).encode 587 ) 588 589 func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) { 590 if v.Type() == numberType { 591 numStr := v.String() 592 // In Go1.5 the empty string encodes to "0", while this is not a valid number literal 593 // we keep compatibility so check validity after this. 594 if numStr == "" { 595 numStr = "0" // Number's zero-val 596 } 597 if !isValidNumber(numStr) { 598 e.error(fmt.Errorf("json: invalid number literal %q", numStr)) 599 } 600 e.WriteString(numStr) 601 return 602 } 603 if opts.quoted { 604 sb, err := Marshal(v.String()) 605 if err != nil { 606 e.error(err) 607 } 608 e.string(string(sb), opts.escapeHTML) 609 } else { 610 e.string(v.String(), opts.escapeHTML) 611 } 612 } 613 614 func interfaceEncoder(e *encodeState, v reflect.Value, opts encOpts) { 615 if v.IsNil() { 616 e.WriteString("null") 617 return 618 } 619 e.reflectValue(v.Elem(), opts) 620 } 621 622 func unsupportedTypeEncoder(e *encodeState, v reflect.Value, _ encOpts) { 623 e.error(&UnsupportedTypeError{v.Type()}) 624 } 625 626 type structEncoder struct { 627 fields structFields 628 } 629 630 type structFields struct { 631 list []field 632 nameIndex map[string]int 633 } 634 635 func (se structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 636 next := byte('{') 637 FieldLoop: 638 for i := range se.fields.list { 639 f := &se.fields.list[i] 640 641 // Find the nested struct field by following f.index. 642 fv := v 643 for _, i := range f.index { 644 if fv.Kind() == reflect.Ptr { 645 if fv.IsNil() { 646 continue FieldLoop 647 } 648 fv = fv.Elem() 649 } 650 fv = fv.Field(i) 651 } 652 653 if f.omitEmpty && isEmptyValue(fv) { 654 continue 655 } 656 if f.extra { 657 keys := fv.MapKeys() 658 sv := make([]reflectWithString, len(keys)) 659 for i, v := range keys { 660 sv[i].v = v 661 if err := sv[i].resolve(); err != nil { 662 e.error(&MarshalerError{v.Type(), err}) 663 } 664 } 665 sort.Slice(sv, func(i, j int) bool { return sv[i].s < sv[j].s }) 666 elemEnc := typeEncoder(fv.Type().Elem()) 667 for _, kv := range sv { 668 e.WriteByte(next) 669 next = ',' 670 e.string(kv.s, opts.escapeHTML) 671 e.WriteByte(':') 672 elemEnc(e, fv.MapIndex(kv.v), opts) 673 } 674 continue 675 } 676 e.WriteByte(next) 677 next = ',' 678 if opts.escapeHTML { 679 e.WriteString(f.nameEscHTML) 680 } else { 681 e.WriteString(f.nameNonEsc) 682 } 683 opts.quoted = f.quoted 684 f.encoder(e, fv, opts) 685 } 686 if next == '{' { 687 e.WriteString("{}") 688 } else { 689 e.WriteByte('}') 690 } 691 } 692 693 func newStructEncoder(t reflect.Type) encoderFunc { 694 se := structEncoder{fields: cachedTypeFields(t)} 695 return se.encode 696 } 697 698 type mapEncoder struct { 699 elemEnc encoderFunc 700 } 701 702 func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 703 if v.IsNil() { 704 e.WriteString("null") 705 return 706 } 707 e.WriteByte('{') 708 709 // Extract and sort the keys. 710 keys := v.MapKeys() 711 sv := make([]reflectWithString, len(keys)) 712 for i, v := range keys { 713 sv[i].v = v 714 if err := sv[i].resolve(); err != nil { 715 e.error(&MarshalerError{v.Type(), err}) 716 } 717 } 718 sort.Slice(sv, func(i, j int) bool { return sv[i].s < sv[j].s }) 719 720 for i, kv := range sv { 721 if i > 0 { 722 e.WriteByte(',') 723 } 724 e.string(kv.s, opts.escapeHTML) 725 e.WriteByte(':') 726 me.elemEnc(e, v.MapIndex(kv.v), opts) 727 } 728 e.WriteByte('}') 729 } 730 731 func newMapEncoder(t reflect.Type) encoderFunc { 732 switch t.Key().Kind() { 733 case reflect.String, 734 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 735 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 736 default: 737 if !t.Key().Implements(textMarshalerType) { 738 return unsupportedTypeEncoder 739 } 740 } 741 me := mapEncoder{typeEncoder(t.Elem())} 742 return me.encode 743 } 744 745 func encodeByteSlice(e *encodeState, v reflect.Value, _ encOpts) { 746 if v.IsNil() { 747 e.WriteString("null") 748 return 749 } 750 s := v.Bytes() 751 e.WriteByte('"') 752 encodedLen := base64.StdEncoding.EncodedLen(len(s)) 753 if encodedLen <= len(e.scratch) { 754 // If the encoded bytes fit in e.scratch, avoid an extra 755 // allocation and use the cheaper Encoding.Encode. 756 dst := e.scratch[:encodedLen] 757 base64.StdEncoding.Encode(dst, s) 758 e.Write(dst) 759 } else if encodedLen <= 1024 { 760 // The encoded bytes are short enough to allocate for, and 761 // Encoding.Encode is still cheaper. 762 dst := make([]byte, encodedLen) 763 base64.StdEncoding.Encode(dst, s) 764 e.Write(dst) 765 } else { 766 // The encoded bytes are too long to cheaply allocate, and 767 // Encoding.Encode is no longer noticeably cheaper. 768 enc := base64.NewEncoder(base64.StdEncoding, e) 769 enc.Write(s) 770 enc.Close() 771 } 772 e.WriteByte('"') 773 } 774 775 // sliceEncoder just wraps an arrayEncoder, checking to make sure the value isn't nil. 776 type sliceEncoder struct { 777 arrayEnc encoderFunc 778 } 779 780 func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 781 if v.IsNil() { 782 e.WriteString("null") 783 return 784 } 785 se.arrayEnc(e, v, opts) 786 } 787 788 func newSliceEncoder(t reflect.Type) encoderFunc { 789 // Byte slices get special treatment; arrays don't. 790 if t.Elem().Kind() == reflect.Uint8 { 791 p := reflect.PtrTo(t.Elem()) 792 if !p.Implements(marshalerType) && !p.Implements(textMarshalerType) { 793 return encodeByteSlice 794 } 795 } 796 enc := sliceEncoder{newArrayEncoder(t)} 797 return enc.encode 798 } 799 800 type arrayEncoder struct { 801 elemEnc encoderFunc 802 } 803 804 func (ae arrayEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 805 e.WriteByte('[') 806 n := v.Len() 807 for i := 0; i < n; i++ { 808 if i > 0 { 809 e.WriteByte(',') 810 } 811 ae.elemEnc(e, v.Index(i), opts) 812 } 813 e.WriteByte(']') 814 } 815 816 func newArrayEncoder(t reflect.Type) encoderFunc { 817 enc := arrayEncoder{typeEncoder(t.Elem())} 818 return enc.encode 819 } 820 821 type ptrEncoder struct { 822 elemEnc encoderFunc 823 } 824 825 func (pe ptrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 826 if v.IsNil() { 827 e.WriteString("null") 828 return 829 } 830 pe.elemEnc(e, v.Elem(), opts) 831 } 832 833 func newPtrEncoder(t reflect.Type) encoderFunc { 834 enc := ptrEncoder{typeEncoder(t.Elem())} 835 return enc.encode 836 } 837 838 type condAddrEncoder struct { 839 canAddrEnc, elseEnc encoderFunc 840 } 841 842 func (ce condAddrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 843 if v.CanAddr() { 844 ce.canAddrEnc(e, v, opts) 845 } else { 846 ce.elseEnc(e, v, opts) 847 } 848 } 849 850 // newCondAddrEncoder returns an encoder that checks whether its value 851 // CanAddr and delegates to canAddrEnc if so, else to elseEnc. 852 func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc { 853 enc := condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc} 854 return enc.encode 855 } 856 857 func isValidTag(s string) bool { 858 if s == "" { 859 return false 860 } 861 for _, c := range s { 862 switch { 863 case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): 864 // Backslash and quote chars are reserved, but 865 // otherwise any punctuation chars are allowed 866 // in a tag name. 867 case !unicode.IsLetter(c) && !unicode.IsDigit(c): 868 return false 869 } 870 } 871 return true 872 } 873 874 func typeByIndex(t reflect.Type, index []int) reflect.Type { 875 for _, i := range index { 876 if t.Kind() == reflect.Ptr { 877 t = t.Elem() 878 } 879 t = t.Field(i).Type 880 } 881 return t 882 } 883 884 type reflectWithString struct { 885 v reflect.Value 886 s string 887 } 888 889 func (w *reflectWithString) resolve() error { 890 if w.v.Kind() == reflect.String { 891 w.s = w.v.String() 892 return nil 893 } 894 if tm, ok := w.v.Interface().(encoding.TextMarshaler); ok { 895 buf, err := tm.MarshalText() 896 w.s = string(buf) 897 return err 898 } 899 switch w.v.Kind() { 900 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 901 w.s = strconv.FormatInt(w.v.Int(), 10) 902 return nil 903 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 904 w.s = strconv.FormatUint(w.v.Uint(), 10) 905 return nil 906 } 907 panic("unexpected map key type") 908 } 909 910 // NOTE: keep in sync with stringBytes below. 911 func (e *encodeState) string(s string, escapeHTML bool) { 912 e.WriteByte('"') 913 start := 0 914 for i := 0; i < len(s); { 915 if b := s[i]; b < utf8.RuneSelf { 916 if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) { 917 i++ 918 continue 919 } 920 if start < i { 921 e.WriteString(s[start:i]) 922 } 923 e.WriteByte('\\') 924 switch b { 925 case '\\', '"': 926 e.WriteByte(b) 927 case '\n': 928 e.WriteByte('n') 929 case '\r': 930 e.WriteByte('r') 931 case '\t': 932 e.WriteByte('t') 933 default: 934 // This encodes bytes < 0x20 except for \t, \n and \r. 935 // If escapeHTML is set, it also escapes <, >, and & 936 // because they can lead to security holes when 937 // user-controlled strings are rendered into JSON 938 // and served to some browsers. 939 e.WriteString(`u00`) 940 e.WriteByte(hex[b>>4]) 941 e.WriteByte(hex[b&0xF]) 942 } 943 i++ 944 start = i 945 continue 946 } 947 c, size := utf8.DecodeRuneInString(s[i:]) 948 if c == utf8.RuneError && size == 1 { 949 if start < i { 950 e.WriteString(s[start:i]) 951 } 952 e.WriteString(`\ufffd`) 953 i += size 954 start = i 955 continue 956 } 957 // U+2028 is LINE SEPARATOR. 958 // U+2029 is PARAGRAPH SEPARATOR. 959 // They are both technically valid characters in JSON strings, 960 // but don't work in JSONP, which has to be evaluated as JavaScript, 961 // and can lead to security holes there. It is valid JSON to 962 // escape them, so we do so unconditionally. 963 // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. 964 if c == '\u2028' || c == '\u2029' { 965 if start < i { 966 e.WriteString(s[start:i]) 967 } 968 e.WriteString(`\u202`) 969 e.WriteByte(hex[c&0xF]) 970 i += size 971 start = i 972 continue 973 } 974 i += size 975 } 976 if start < len(s) { 977 e.WriteString(s[start:]) 978 } 979 e.WriteByte('"') 980 } 981 982 // NOTE: keep in sync with string above. 983 func (e *encodeState) stringBytes(s []byte, escapeHTML bool) { 984 e.WriteByte('"') 985 start := 0 986 for i := 0; i < len(s); { 987 if b := s[i]; b < utf8.RuneSelf { 988 if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) { 989 i++ 990 continue 991 } 992 if start < i { 993 e.Write(s[start:i]) 994 } 995 e.WriteByte('\\') 996 switch b { 997 case '\\', '"': 998 e.WriteByte(b) 999 case '\n': 1000 e.WriteByte('n') 1001 case '\r': 1002 e.WriteByte('r') 1003 case '\t': 1004 e.WriteByte('t') 1005 default: 1006 // This encodes bytes < 0x20 except for \t, \n and \r. 1007 // If escapeHTML is set, it also escapes <, >, and & 1008 // because they can lead to security holes when 1009 // user-controlled strings are rendered into JSON 1010 // and served to some browsers. 1011 e.WriteString(`u00`) 1012 e.WriteByte(hex[b>>4]) 1013 e.WriteByte(hex[b&0xF]) 1014 } 1015 i++ 1016 start = i 1017 continue 1018 } 1019 c, size := utf8.DecodeRune(s[i:]) 1020 if c == utf8.RuneError && size == 1 { 1021 if start < i { 1022 e.Write(s[start:i]) 1023 } 1024 e.WriteString(`\ufffd`) 1025 i += size 1026 start = i 1027 continue 1028 } 1029 // U+2028 is LINE SEPARATOR. 1030 // U+2029 is PARAGRAPH SEPARATOR. 1031 // They are both technically valid characters in JSON strings, 1032 // but don't work in JSONP, which has to be evaluated as JavaScript, 1033 // and can lead to security holes there. It is valid JSON to 1034 // escape them, so we do so unconditionally. 1035 // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. 1036 if c == '\u2028' || c == '\u2029' { 1037 if start < i { 1038 e.Write(s[start:i]) 1039 } 1040 e.WriteString(`\u202`) 1041 e.WriteByte(hex[c&0xF]) 1042 i += size 1043 start = i 1044 continue 1045 } 1046 i += size 1047 } 1048 if start < len(s) { 1049 e.Write(s[start:]) 1050 } 1051 e.WriteByte('"') 1052 } 1053 1054 // A field represents a single field found in a struct. 1055 type field struct { 1056 name string 1057 nameBytes []byte // []byte(name) 1058 equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent 1059 1060 nameNonEsc string // `"` + name + `":` 1061 nameEscHTML string // `"` + HTMLEscape(name) + `":` 1062 1063 tag bool 1064 index []int 1065 typ reflect.Type 1066 omitEmpty bool 1067 extra bool 1068 quoted bool 1069 1070 encoder encoderFunc 1071 } 1072 1073 // byIndex sorts field by index sequence. 1074 type byIndex []field 1075 1076 func (x byIndex) Len() int { return len(x) } 1077 1078 func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 1079 1080 func (x byIndex) Less(i, j int) bool { 1081 for k, xik := range x[i].index { 1082 if k >= len(x[j].index) { 1083 return false 1084 } 1085 if xik != x[j].index[k] { 1086 return xik < x[j].index[k] 1087 } 1088 } 1089 return len(x[i].index) < len(x[j].index) 1090 } 1091 1092 // typeFields returns a list of fields that JSON should recognize for the given type. 1093 // The algorithm is breadth-first search over the set of structs to include - the top struct 1094 // and then any reachable anonymous structs. 1095 func typeFields(t reflect.Type) structFields { 1096 // Anonymous fields to explore at the current level and the next. 1097 current := []field{} 1098 next := []field{{typ: t}} 1099 1100 // Count of queued names for current level and the next. 1101 var count, nextCount map[reflect.Type]int 1102 1103 // Types already visited at an earlier level. 1104 visited := map[reflect.Type]bool{} 1105 1106 // Fields found. 1107 var fields []field 1108 1109 // Buffer to run HTMLEscape on field names. 1110 var nameEscBuf bytes.Buffer 1111 1112 for len(next) > 0 { 1113 current, next = next, current[:0] 1114 count, nextCount = nextCount, map[reflect.Type]int{} 1115 1116 for _, f := range current { 1117 if visited[f.typ] { 1118 continue 1119 } 1120 visited[f.typ] = true 1121 1122 // Scan f.typ for fields to include. 1123 for i := 0; i < f.typ.NumField(); i++ { 1124 sf := f.typ.Field(i) 1125 isUnexported := sf.PkgPath != "" 1126 if sf.Anonymous { 1127 t := sf.Type 1128 if t.Kind() == reflect.Ptr { 1129 t = t.Elem() 1130 } 1131 if isUnexported && t.Kind() != reflect.Struct { 1132 // Ignore embedded fields of unexported non-struct types. 1133 continue 1134 } 1135 // Do not ignore embedded fields of unexported struct types 1136 // since they may have exported fields. 1137 } else if isUnexported { 1138 // Ignore unexported non-embedded fields. 1139 continue 1140 } 1141 tag := sf.Tag.Get("json") 1142 tagx := sf.Tag.Get("jsonx") 1143 if tag == "-" && tagx == "" { 1144 continue 1145 } 1146 if tagx != "" { 1147 tag = "" 1148 } 1149 name, opts := parseTag(tag) 1150 if !isValidTag(name) { 1151 name = "" 1152 } 1153 index := make([]int, len(f.index)+1) 1154 copy(index, f.index) 1155 index[len(f.index)] = i 1156 1157 ft := sf.Type 1158 if ft.Name() == "" && ft.Kind() == reflect.Ptr { 1159 // Follow pointer. 1160 ft = ft.Elem() 1161 } 1162 1163 // Only maps can be extra. 1164 extra := false 1165 if tagx != "" { 1166 switch ft.Kind() { 1167 case reflect.Map: 1168 extra = true 1169 default: 1170 continue 1171 } 1172 } 1173 1174 // Only strings, floats, integers, and booleans can be quoted. 1175 quoted := false 1176 if opts.Contains("string") { 1177 switch ft.Kind() { 1178 case reflect.Bool, 1179 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 1180 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, 1181 reflect.Float32, reflect.Float64, 1182 reflect.String: 1183 quoted = true 1184 } 1185 } 1186 1187 // Record found field and index sequence. 1188 if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { 1189 tagged := name != "" 1190 if name == "" { 1191 name = sf.Name 1192 } 1193 field := field{ 1194 name: name, 1195 tag: tagged, 1196 index: index, 1197 typ: ft, 1198 omitEmpty: opts.Contains("omitempty"), 1199 extra: extra, 1200 quoted: quoted, 1201 } 1202 field.nameBytes = []byte(field.name) 1203 field.equalFold = foldFunc(field.nameBytes) 1204 1205 // Build nameEscHTML and nameNonEsc ahead of time. 1206 nameEscBuf.Reset() 1207 nameEscBuf.WriteString(`"`) 1208 HTMLEscape(&nameEscBuf, field.nameBytes) 1209 nameEscBuf.WriteString(`":`) 1210 field.nameEscHTML = nameEscBuf.String() 1211 field.nameNonEsc = `"` + field.name + `":` 1212 1213 fields = append(fields, field) 1214 if count[f.typ] > 1 { 1215 // If there were multiple instances, add a second, 1216 // so that the annihilation code will see a duplicate. 1217 // It only cares about the distinction between 1 or 2, 1218 // so don't bother generating any more copies. 1219 fields = append(fields, fields[len(fields)-1]) 1220 } 1221 continue 1222 } 1223 1224 // Record new anonymous struct to explore in next round. 1225 nextCount[ft]++ 1226 if nextCount[ft] == 1 { 1227 next = append(next, field{name: ft.Name(), index: index, typ: ft}) 1228 } 1229 } 1230 } 1231 } 1232 1233 sort.Slice(fields, func(i, j int) bool { 1234 x := fields 1235 // sort field by name, breaking ties with depth, then 1236 // breaking ties with "name came from json tag", then 1237 // breaking ties with index sequence. 1238 if x[i].name != x[j].name { 1239 return x[i].name < x[j].name 1240 } 1241 if len(x[i].index) != len(x[j].index) { 1242 return len(x[i].index) < len(x[j].index) 1243 } 1244 if x[i].tag != x[j].tag { 1245 return x[i].tag 1246 } 1247 return byIndex(x).Less(i, j) 1248 }) 1249 1250 // Delete all fields that are hidden by the Go rules for embedded fields, 1251 // except that fields with JSON tags are promoted. 1252 1253 // The fields are sorted in primary order of name, secondary order 1254 // of field index length. Loop over names; for each name, delete 1255 // hidden fields by choosing the one dominant field that survives. 1256 out := fields[:0] 1257 for advance, i := 0, 0; i < len(fields); i += advance { 1258 // One iteration per name. 1259 // Find the sequence of fields with the name of this first field. 1260 fi := fields[i] 1261 name := fi.name 1262 for advance = 1; i+advance < len(fields); advance++ { 1263 fj := fields[i+advance] 1264 if fj.name != name { 1265 break 1266 } 1267 } 1268 if advance == 1 { // Only one field with this name 1269 out = append(out, fi) 1270 continue 1271 } 1272 dominant, ok := dominantField(fields[i : i+advance]) 1273 if ok { 1274 out = append(out, dominant) 1275 } 1276 } 1277 1278 fields = out 1279 sort.Sort(byIndex(fields)) 1280 1281 for i := range fields { 1282 f := &fields[i] 1283 f.encoder = typeEncoder(typeByIndex(t, f.index)) 1284 } 1285 nameIndex := make(map[string]int, len(fields)) 1286 for i, field := range fields { 1287 nameIndex[field.name] = i 1288 } 1289 return structFields{fields, nameIndex} 1290 } 1291 1292 // dominantField looks through the fields, all of which are known to 1293 // have the same name, to find the single field that dominates the 1294 // others using Go's embedding rules, modified by the presence of 1295 // JSON tags. If there are multiple top-level fields, the boolean 1296 // will be false: This condition is an error in Go and we skip all 1297 // the fields. 1298 func dominantField(fields []field) (field, bool) { 1299 // The fields are sorted in increasing index-length order, then by presence of tag. 1300 // That means that the first field is the dominant one. We need only check 1301 // for error cases: two fields at top level, either both tagged or neither tagged. 1302 if len(fields) > 1 && len(fields[0].index) == len(fields[1].index) && fields[0].tag == fields[1].tag { 1303 return field{}, false 1304 } 1305 return fields[0], true 1306 } 1307 1308 var fieldCache sync.Map // map[reflect.Type]structFields 1309 1310 // cachedTypeFields is like typeFields but uses a cache to avoid repeated work. 1311 func cachedTypeFields(t reflect.Type) structFields { 1312 if f, ok := fieldCache.Load(t); ok { 1313 return f.(structFields) 1314 } 1315 f, _ := fieldCache.LoadOrStore(t, typeFields(t)) 1316 return f.(structFields) 1317 }