github.com/aergoio/aergo@v1.3.1/cmd/aergocli/util/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 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 json 12 13 import ( 14 "bytes" 15 "encoding" 16 "fmt" 17 "math" 18 "reflect" 19 "sort" 20 "strconv" 21 "strings" 22 "sync" 23 "unicode" 24 "unicode/utf8" 25 26 "github.com/mr-tron/base58/base58" 27 ) 28 29 // Marshal returns the JSON encoding of v. 30 // 31 // Marshal traverses the value v recursively. 32 // If an encountered value implements the Marshaler interface 33 // and is not a nil pointer, Marshal calls its MarshalJSON method 34 // to produce JSON. If no MarshalJSON method is present but the 35 // value implements encoding.TextMarshaler instead, Marshal calls 36 // its MarshalText method and encodes the result as a JSON string. 37 // The nil pointer exception is not strictly necessary 38 // but mimics a similar, necessary exception in the behavior of 39 // UnmarshalJSON. 40 // 41 // Otherwise, Marshal uses the following type-dependent default encodings: 42 // 43 // Boolean values encode as JSON booleans. 44 // 45 // Floating point, integer, and Number values encode as JSON numbers. 46 // 47 // String values encode as JSON strings coerced to valid UTF-8, 48 // replacing invalid bytes with the Unicode replacement rune. 49 // The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e" 50 // to keep some browsers from misinterpreting JSON output as HTML. 51 // Ampersand "&" is also escaped to "\u0026" for the same reason. 52 // This escaping can be disabled using an Encoder that had SetEscapeHTML(false) 53 // called on it. 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 // - string keys 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 type MarshalerError struct { 264 Type reflect.Type 265 Err error 266 } 267 268 func (e *MarshalerError) Error() string { 269 return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error() 270 } 271 272 var hex = "0123456789abcdef" 273 274 // An encodeState encodes JSON into a bytes.Buffer. 275 type encodeState struct { 276 bytes.Buffer // accumulated output 277 scratch [64]byte 278 } 279 280 var encodeStatePool sync.Pool 281 282 func newEncodeState() *encodeState { 283 if v := encodeStatePool.Get(); v != nil { 284 e := v.(*encodeState) 285 e.Reset() 286 return e 287 } 288 return new(encodeState) 289 } 290 291 // jsonError is an error wrapper type for internal use only. 292 // Panics with errors are wrapped in jsonError so that the top-level recover 293 // can distinguish intentional panics from this package. 294 type jsonError struct{ error } 295 296 func (e *encodeState) marshal(v interface{}, opts encOpts) (err error) { 297 defer func() { 298 if r := recover(); r != nil { 299 if je, ok := r.(jsonError); ok { 300 err = je.error 301 } else { 302 panic(r) 303 } 304 } 305 }() 306 e.reflectValue(reflect.ValueOf(v), opts) 307 return nil 308 } 309 310 // error aborts the encoding by panicking with err wrapped in jsonError. 311 func (e *encodeState) error(err error) { 312 panic(jsonError{err}) 313 } 314 315 func isEmptyValue(v reflect.Value) bool { 316 switch v.Kind() { 317 case reflect.Array, reflect.Map, reflect.Slice, reflect.String: 318 return v.Len() == 0 319 case reflect.Bool: 320 return !v.Bool() 321 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 322 return v.Int() == 0 323 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 324 return v.Uint() == 0 325 case reflect.Float32, reflect.Float64: 326 return v.Float() == 0 327 case reflect.Interface, reflect.Ptr: 328 return v.IsNil() 329 } 330 return false 331 } 332 333 func (e *encodeState) reflectValue(v reflect.Value, opts encOpts) { 334 valueEncoder(v)(e, v, opts) 335 } 336 337 type encOpts struct { 338 // quoted causes primitive fields to be encoded inside JSON strings. 339 quoted bool 340 // escapeHTML causes '<', '>', and '&' to be escaped in JSON strings. 341 escapeHTML bool 342 } 343 344 type encoderFunc func(e *encodeState, v reflect.Value, opts encOpts) 345 346 var encoderCache sync.Map // map[reflect.Type]encoderFunc 347 348 func valueEncoder(v reflect.Value) encoderFunc { 349 if !v.IsValid() { 350 return invalidValueEncoder 351 } 352 return typeEncoder(v.Type()) 353 } 354 355 func typeEncoder(t reflect.Type) encoderFunc { 356 if fi, ok := encoderCache.Load(t); ok { 357 return fi.(encoderFunc) 358 } 359 360 // To deal with recursive types, populate the map with an 361 // indirect func before we build it. This type waits on the 362 // real func (f) to be ready and then calls it. This indirect 363 // func is only used for recursive types. 364 var ( 365 wg sync.WaitGroup 366 f encoderFunc 367 ) 368 wg.Add(1) 369 fi, loaded := encoderCache.LoadOrStore(t, encoderFunc(func(e *encodeState, v reflect.Value, opts encOpts) { 370 wg.Wait() 371 f(e, v, opts) 372 })) 373 if loaded { 374 return fi.(encoderFunc) 375 } 376 377 // Compute the real encoder and replace the indirect func with it. 378 f = newTypeEncoder(t, true) 379 wg.Done() 380 encoderCache.Store(t, f) 381 return f 382 } 383 384 var ( 385 marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() 386 textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() 387 ) 388 389 // newTypeEncoder constructs an encoderFunc for a type. 390 // The returned encoder only checks CanAddr when allowAddr is true. 391 func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc { 392 if t.Implements(marshalerType) { 393 return marshalerEncoder 394 } 395 if t.Kind() != reflect.Ptr && allowAddr { 396 if reflect.PtrTo(t).Implements(marshalerType) { 397 return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false)) 398 } 399 } 400 401 if t.Implements(textMarshalerType) { 402 return textMarshalerEncoder 403 } 404 if t.Kind() != reflect.Ptr && allowAddr { 405 if reflect.PtrTo(t).Implements(textMarshalerType) { 406 return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false)) 407 } 408 } 409 410 switch t.Kind() { 411 case reflect.Bool: 412 return boolEncoder 413 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 414 return intEncoder 415 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 416 return uintEncoder 417 case reflect.Float32: 418 return float32Encoder 419 case reflect.Float64: 420 return float64Encoder 421 case reflect.String: 422 return stringEncoder 423 case reflect.Interface: 424 return interfaceEncoder 425 case reflect.Struct: 426 return newStructEncoder(t) 427 case reflect.Map: 428 return newMapEncoder(t) 429 case reflect.Slice: 430 return newSliceEncoder(t) 431 case reflect.Array: 432 return newArrayEncoder(t) 433 case reflect.Ptr: 434 return newPtrEncoder(t) 435 default: 436 return unsupportedTypeEncoder 437 } 438 } 439 440 func invalidValueEncoder(e *encodeState, v reflect.Value, _ encOpts) { 441 e.WriteString("null") 442 } 443 444 func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 445 if v.Kind() == reflect.Ptr && v.IsNil() { 446 e.WriteString("null") 447 return 448 } 449 m, ok := v.Interface().(Marshaler) 450 if !ok { 451 e.WriteString("null") 452 return 453 } 454 b, err := m.MarshalJSON() 455 if err == nil { 456 // copy JSON into buffer, checking validity. 457 err = compact(&e.Buffer, b, opts.escapeHTML) 458 } 459 if err != nil { 460 e.error(&MarshalerError{v.Type(), err}) 461 } 462 } 463 464 func addrMarshalerEncoder(e *encodeState, v reflect.Value, _ encOpts) { 465 va := v.Addr() 466 if va.IsNil() { 467 e.WriteString("null") 468 return 469 } 470 m := va.Interface().(Marshaler) 471 b, err := m.MarshalJSON() 472 if err == nil { 473 // copy JSON into buffer, checking validity. 474 err = compact(&e.Buffer, b, true) 475 } 476 if err != nil { 477 e.error(&MarshalerError{v.Type(), err}) 478 } 479 } 480 481 func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 482 if v.Kind() == reflect.Ptr && v.IsNil() { 483 e.WriteString("null") 484 return 485 } 486 m := v.Interface().(encoding.TextMarshaler) 487 b, err := m.MarshalText() 488 if err != nil { 489 e.error(&MarshalerError{v.Type(), err}) 490 } 491 e.stringBytes(b, opts.escapeHTML) 492 } 493 494 func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 495 va := v.Addr() 496 if va.IsNil() { 497 e.WriteString("null") 498 return 499 } 500 m := va.Interface().(encoding.TextMarshaler) 501 b, err := m.MarshalText() 502 if err != nil { 503 e.error(&MarshalerError{v.Type(), err}) 504 } 505 e.stringBytes(b, opts.escapeHTML) 506 } 507 508 func boolEncoder(e *encodeState, v reflect.Value, opts encOpts) { 509 if opts.quoted { 510 e.WriteByte('"') 511 } 512 if v.Bool() { 513 e.WriteString("true") 514 } else { 515 e.WriteString("false") 516 } 517 if opts.quoted { 518 e.WriteByte('"') 519 } 520 } 521 522 func intEncoder(e *encodeState, v reflect.Value, opts encOpts) { 523 b := strconv.AppendInt(e.scratch[:0], v.Int(), 10) 524 if opts.quoted { 525 e.WriteByte('"') 526 } 527 e.Write(b) 528 if opts.quoted { 529 e.WriteByte('"') 530 } 531 } 532 533 func uintEncoder(e *encodeState, v reflect.Value, opts encOpts) { 534 b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10) 535 if opts.quoted { 536 e.WriteByte('"') 537 } 538 e.Write(b) 539 if opts.quoted { 540 e.WriteByte('"') 541 } 542 } 543 544 type floatEncoder int // number of bits 545 546 func (bits floatEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 547 f := v.Float() 548 if math.IsInf(f, 0) || math.IsNaN(f) { 549 e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))}) 550 } 551 552 // Convert as if by ES6 number to string conversion. 553 // This matches most other JSON generators. 554 // See golang.org/issue/6384 and golang.org/issue/14135. 555 // Like fmt %g, but the exponent cutoffs are different 556 // and exponents themselves are not padded to two digits. 557 b := e.scratch[:0] 558 abs := math.Abs(f) 559 fmt := byte('f') 560 // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. 561 if abs != 0 { 562 if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) { 563 fmt = 'e' 564 } 565 } 566 b = strconv.AppendFloat(b, f, fmt, -1, int(bits)) 567 if fmt == 'e' { 568 // clean up e-09 to e-9 569 n := len(b) 570 if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' { 571 b[n-2] = b[n-1] 572 b = b[:n-1] 573 } 574 } 575 576 if opts.quoted { 577 e.WriteByte('"') 578 } 579 e.Write(b) 580 if opts.quoted { 581 e.WriteByte('"') 582 } 583 } 584 585 var ( 586 float32Encoder = (floatEncoder(32)).encode 587 float64Encoder = (floatEncoder(64)).encode 588 ) 589 590 func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) { 591 if v.Type() == numberType { 592 numStr := v.String() 593 // In Go1.5 the empty string encodes to "0", while this is not a valid number literal 594 // we keep compatibility so check validity after this. 595 if numStr == "" { 596 numStr = "0" // Number's zero-val 597 } 598 if !isValidNumber(numStr) { 599 e.error(fmt.Errorf("json: invalid number literal %q", numStr)) 600 } 601 e.WriteString(numStr) 602 return 603 } 604 if opts.quoted { 605 sb, err := Marshal(v.String()) 606 if err != nil { 607 e.error(err) 608 } 609 e.string(string(sb), opts.escapeHTML) 610 } else { 611 e.string(v.String(), opts.escapeHTML) 612 } 613 } 614 615 func interfaceEncoder(e *encodeState, v reflect.Value, opts encOpts) { 616 if v.IsNil() { 617 e.WriteString("null") 618 return 619 } 620 e.reflectValue(v.Elem(), opts) 621 } 622 623 func unsupportedTypeEncoder(e *encodeState, v reflect.Value, _ encOpts) { 624 e.error(&UnsupportedTypeError{v.Type()}) 625 } 626 627 type structEncoder struct { 628 fields []field 629 } 630 631 func (se structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 632 next := byte('{') 633 FieldLoop: 634 for i := range se.fields { 635 f := &se.fields[i] 636 637 // Find the nested struct field by following f.index. 638 fv := v 639 for _, i := range f.index { 640 if fv.Kind() == reflect.Ptr { 641 if fv.IsNil() { 642 continue FieldLoop 643 } 644 fv = fv.Elem() 645 } 646 fv = fv.Field(i) 647 } 648 649 if f.omitEmpty && isEmptyValue(fv) { 650 continue 651 } 652 e.WriteByte(next) 653 next = ',' 654 if opts.escapeHTML { 655 e.WriteString(f.nameEscHTML) 656 } else { 657 e.WriteString(f.nameNonEsc) 658 } 659 opts.quoted = f.quoted 660 f.encoder(e, fv, opts) 661 } 662 if next == '{' { 663 e.WriteString("{}") 664 } else { 665 e.WriteByte('}') 666 } 667 } 668 669 func newStructEncoder(t reflect.Type) encoderFunc { 670 se := structEncoder{fields: cachedTypeFields(t)} 671 return se.encode 672 } 673 674 type mapEncoder struct { 675 elemEnc encoderFunc 676 } 677 678 func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 679 if v.IsNil() { 680 e.WriteString("null") 681 return 682 } 683 e.WriteByte('{') 684 685 // Extract and sort the keys. 686 keys := v.MapKeys() 687 sv := make([]reflectWithString, len(keys)) 688 for i, v := range keys { 689 sv[i].v = v 690 if err := sv[i].resolve(); err != nil { 691 e.error(&MarshalerError{v.Type(), err}) 692 } 693 } 694 sort.Slice(sv, func(i, j int) bool { return sv[i].s < sv[j].s }) 695 696 for i, kv := range sv { 697 if i > 0 { 698 e.WriteByte(',') 699 } 700 e.string(kv.s, opts.escapeHTML) 701 e.WriteByte(':') 702 me.elemEnc(e, v.MapIndex(kv.v), opts) 703 } 704 e.WriteByte('}') 705 } 706 707 func newMapEncoder(t reflect.Type) encoderFunc { 708 switch t.Key().Kind() { 709 case reflect.String, 710 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 711 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 712 default: 713 if !t.Key().Implements(textMarshalerType) { 714 return unsupportedTypeEncoder 715 } 716 } 717 me := mapEncoder{typeEncoder(t.Elem())} 718 return me.encode 719 } 720 721 func encodeByteSlice(e *encodeState, v reflect.Value, _ encOpts) { 722 if v.IsNil() { 723 e.WriteString("null") 724 return 725 } 726 s := v.Bytes() 727 e.WriteByte('"') 728 e.WriteString(base58.Encode(s)) 729 e.WriteByte('"') 730 } 731 732 // sliceEncoder just wraps an arrayEncoder, checking to make sure the value isn't nil. 733 type sliceEncoder struct { 734 arrayEnc encoderFunc 735 } 736 737 func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 738 if v.IsNil() { 739 e.WriteString("null") 740 return 741 } 742 se.arrayEnc(e, v, opts) 743 } 744 745 func newSliceEncoder(t reflect.Type) encoderFunc { 746 // Byte slices get special treatment; arrays don't. 747 if t.Elem().Kind() == reflect.Uint8 { 748 p := reflect.PtrTo(t.Elem()) 749 if !p.Implements(marshalerType) && !p.Implements(textMarshalerType) { 750 return encodeByteSlice 751 } 752 } 753 enc := sliceEncoder{newArrayEncoder(t)} 754 return enc.encode 755 } 756 757 type arrayEncoder struct { 758 elemEnc encoderFunc 759 } 760 761 func (ae arrayEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 762 e.WriteByte('[') 763 n := v.Len() 764 for i := 0; i < n; i++ { 765 if i > 0 { 766 e.WriteByte(',') 767 } 768 ae.elemEnc(e, v.Index(i), opts) 769 } 770 e.WriteByte(']') 771 } 772 773 func newArrayEncoder(t reflect.Type) encoderFunc { 774 enc := arrayEncoder{typeEncoder(t.Elem())} 775 return enc.encode 776 } 777 778 type ptrEncoder struct { 779 elemEnc encoderFunc 780 } 781 782 func (pe ptrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 783 if v.IsNil() { 784 e.WriteString("null") 785 return 786 } 787 pe.elemEnc(e, v.Elem(), opts) 788 } 789 790 func newPtrEncoder(t reflect.Type) encoderFunc { 791 enc := ptrEncoder{typeEncoder(t.Elem())} 792 return enc.encode 793 } 794 795 type condAddrEncoder struct { 796 canAddrEnc, elseEnc encoderFunc 797 } 798 799 func (ce condAddrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 800 if v.CanAddr() { 801 ce.canAddrEnc(e, v, opts) 802 } else { 803 ce.elseEnc(e, v, opts) 804 } 805 } 806 807 // newCondAddrEncoder returns an encoder that checks whether its value 808 // CanAddr and delegates to canAddrEnc if so, else to elseEnc. 809 func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc { 810 enc := condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc} 811 return enc.encode 812 } 813 814 func isValidTag(s string) bool { 815 if s == "" { 816 return false 817 } 818 for _, c := range s { 819 switch { 820 case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): 821 // Backslash and quote chars are reserved, but 822 // otherwise any punctuation chars are allowed 823 // in a tag name. 824 case !unicode.IsLetter(c) && !unicode.IsDigit(c): 825 return false 826 } 827 } 828 return true 829 } 830 831 func typeByIndex(t reflect.Type, index []int) reflect.Type { 832 for _, i := range index { 833 if t.Kind() == reflect.Ptr { 834 t = t.Elem() 835 } 836 t = t.Field(i).Type 837 } 838 return t 839 } 840 841 type reflectWithString struct { 842 v reflect.Value 843 s string 844 } 845 846 func (w *reflectWithString) resolve() error { 847 if w.v.Kind() == reflect.String { 848 w.s = w.v.String() 849 return nil 850 } 851 if tm, ok := w.v.Interface().(encoding.TextMarshaler); ok { 852 buf, err := tm.MarshalText() 853 w.s = string(buf) 854 return err 855 } 856 switch w.v.Kind() { 857 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 858 w.s = strconv.FormatInt(w.v.Int(), 10) 859 return nil 860 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 861 w.s = strconv.FormatUint(w.v.Uint(), 10) 862 return nil 863 } 864 panic("unexpected map key type") 865 } 866 867 // NOTE: keep in sync with stringBytes below. 868 func (e *encodeState) string(s string, escapeHTML bool) { 869 e.WriteByte('"') 870 start := 0 871 for i := 0; i < len(s); { 872 if b := s[i]; b < utf8.RuneSelf { 873 if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) { 874 i++ 875 continue 876 } 877 if start < i { 878 e.WriteString(s[start:i]) 879 } 880 e.WriteByte('\\') 881 switch b { 882 case '\\', '"': 883 e.WriteByte(b) 884 case '\n': 885 e.WriteByte('n') 886 case '\r': 887 e.WriteByte('r') 888 case '\t': 889 e.WriteByte('t') 890 default: 891 // This encodes bytes < 0x20 except for \t, \n and \r. 892 // If escapeHTML is set, it also escapes <, >, and & 893 // because they can lead to security holes when 894 // user-controlled strings are rendered into JSON 895 // and served to some browsers. 896 e.WriteString(`u00`) 897 e.WriteByte(hex[b>>4]) 898 e.WriteByte(hex[b&0xF]) 899 } 900 i++ 901 start = i 902 continue 903 } 904 c, size := utf8.DecodeRuneInString(s[i:]) 905 if c == utf8.RuneError && size == 1 { 906 if start < i { 907 e.WriteString(s[start:i]) 908 } 909 e.WriteString(`\ufffd`) 910 i += size 911 start = i 912 continue 913 } 914 // U+2028 is LINE SEPARATOR. 915 // U+2029 is PARAGRAPH SEPARATOR. 916 // They are both technically valid characters in JSON strings, 917 // but don't work in JSONP, which has to be evaluated as JavaScript, 918 // and can lead to security holes there. It is valid JSON to 919 // escape them, so we do so unconditionally. 920 // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. 921 if c == '\u2028' || c == '\u2029' { 922 if start < i { 923 e.WriteString(s[start:i]) 924 } 925 e.WriteString(`\u202`) 926 e.WriteByte(hex[c&0xF]) 927 i += size 928 start = i 929 continue 930 } 931 i += size 932 } 933 if start < len(s) { 934 e.WriteString(s[start:]) 935 } 936 e.WriteByte('"') 937 } 938 939 // NOTE: keep in sync with string above. 940 func (e *encodeState) stringBytes(s []byte, escapeHTML bool) { 941 e.WriteByte('"') 942 start := 0 943 for i := 0; i < len(s); { 944 if b := s[i]; b < utf8.RuneSelf { 945 if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) { 946 i++ 947 continue 948 } 949 if start < i { 950 e.Write(s[start:i]) 951 } 952 e.WriteByte('\\') 953 switch b { 954 case '\\', '"': 955 e.WriteByte(b) 956 case '\n': 957 e.WriteByte('n') 958 case '\r': 959 e.WriteByte('r') 960 case '\t': 961 e.WriteByte('t') 962 default: 963 // This encodes bytes < 0x20 except for \t, \n and \r. 964 // If escapeHTML is set, it also escapes <, >, and & 965 // because they can lead to security holes when 966 // user-controlled strings are rendered into JSON 967 // and served to some browsers. 968 e.WriteString(`u00`) 969 e.WriteByte(hex[b>>4]) 970 e.WriteByte(hex[b&0xF]) 971 } 972 i++ 973 start = i 974 continue 975 } 976 c, size := utf8.DecodeRune(s[i:]) 977 if c == utf8.RuneError && size == 1 { 978 if start < i { 979 e.Write(s[start:i]) 980 } 981 e.WriteString(`\ufffd`) 982 i += size 983 start = i 984 continue 985 } 986 // U+2028 is LINE SEPARATOR. 987 // U+2029 is PARAGRAPH SEPARATOR. 988 // They are both technically valid characters in JSON strings, 989 // but don't work in JSONP, which has to be evaluated as JavaScript, 990 // and can lead to security holes there. It is valid JSON to 991 // escape them, so we do so unconditionally. 992 // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. 993 if c == '\u2028' || c == '\u2029' { 994 if start < i { 995 e.Write(s[start:i]) 996 } 997 e.WriteString(`\u202`) 998 e.WriteByte(hex[c&0xF]) 999 i += size 1000 start = i 1001 continue 1002 } 1003 i += size 1004 } 1005 if start < len(s) { 1006 e.Write(s[start:]) 1007 } 1008 e.WriteByte('"') 1009 } 1010 1011 // A field represents a single field found in a struct. 1012 type field struct { 1013 name string 1014 nameBytes []byte // []byte(name) 1015 equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent 1016 1017 nameNonEsc string // `"` + name + `":` 1018 nameEscHTML string // `"` + HTMLEscape(name) + `":` 1019 1020 tag bool 1021 index []int 1022 typ reflect.Type 1023 omitEmpty bool 1024 quoted bool 1025 1026 encoder encoderFunc 1027 } 1028 1029 // byIndex sorts field by index sequence. 1030 type byIndex []field 1031 1032 func (x byIndex) Len() int { return len(x) } 1033 1034 func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 1035 1036 func (x byIndex) Less(i, j int) bool { 1037 for k, xik := range x[i].index { 1038 if k >= len(x[j].index) { 1039 return false 1040 } 1041 if xik != x[j].index[k] { 1042 return xik < x[j].index[k] 1043 } 1044 } 1045 return len(x[i].index) < len(x[j].index) 1046 } 1047 1048 // typeFields returns a list of fields that JSON should recognize for the given type. 1049 // The algorithm is breadth-first search over the set of structs to include - the top struct 1050 // and then any reachable anonymous structs. 1051 func typeFields(t reflect.Type) []field { 1052 // Anonymous fields to explore at the current level and the next. 1053 current := []field{} 1054 next := []field{{typ: t}} 1055 1056 // Count of queued names for current level and the next. 1057 count := map[reflect.Type]int{} 1058 nextCount := map[reflect.Type]int{} 1059 1060 // Types already visited at an earlier level. 1061 visited := map[reflect.Type]bool{} 1062 1063 // Fields found. 1064 var fields []field 1065 1066 // Buffer to run HTMLEscape on field names. 1067 var nameEscBuf bytes.Buffer 1068 1069 for len(next) > 0 { 1070 current, next = next, current[:0] 1071 count, nextCount = nextCount, map[reflect.Type]int{} 1072 1073 for _, f := range current { 1074 if visited[f.typ] { 1075 continue 1076 } 1077 visited[f.typ] = true 1078 1079 // Scan f.typ for fields to include. 1080 for i := 0; i < f.typ.NumField(); i++ { 1081 sf := f.typ.Field(i) 1082 isUnexported := sf.PkgPath != "" 1083 if sf.Anonymous { 1084 t := sf.Type 1085 if t.Kind() == reflect.Ptr { 1086 t = t.Elem() 1087 } 1088 if isUnexported && t.Kind() != reflect.Struct { 1089 // Ignore embedded fields of unexported non-struct types. 1090 continue 1091 } 1092 // Do not ignore embedded fields of unexported struct types 1093 // since they may have exported fields. 1094 } else if isUnexported { 1095 // Ignore unexported non-embedded fields. 1096 continue 1097 } 1098 tag := sf.Tag.Get("json") 1099 if tag == "-" { 1100 continue 1101 } 1102 name, opts := parseTag(tag) 1103 if !isValidTag(name) { 1104 name = "" 1105 } 1106 index := make([]int, len(f.index)+1) 1107 copy(index, f.index) 1108 index[len(f.index)] = i 1109 1110 ft := sf.Type 1111 if ft.Name() == "" && ft.Kind() == reflect.Ptr { 1112 // Follow pointer. 1113 ft = ft.Elem() 1114 } 1115 1116 // Only strings, floats, integers, and booleans can be quoted. 1117 quoted := false 1118 if opts.Contains("string") { 1119 switch ft.Kind() { 1120 case reflect.Bool, 1121 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 1122 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, 1123 reflect.Float32, reflect.Float64, 1124 reflect.String: 1125 quoted = true 1126 } 1127 } 1128 1129 // Record found field and index sequence. 1130 if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { 1131 tagged := name != "" 1132 if name == "" { 1133 name = sf.Name 1134 } 1135 field := field{ 1136 name: name, 1137 tag: tagged, 1138 index: index, 1139 typ: ft, 1140 omitEmpty: opts.Contains("omitempty"), 1141 quoted: quoted, 1142 } 1143 field.nameBytes = []byte(field.name) 1144 field.equalFold = foldFunc(field.nameBytes) 1145 1146 // Build nameEscHTML and nameNonEsc ahead of time. 1147 nameEscBuf.Reset() 1148 nameEscBuf.WriteString(`"`) 1149 HTMLEscape(&nameEscBuf, field.nameBytes) 1150 nameEscBuf.WriteString(`":`) 1151 field.nameEscHTML = nameEscBuf.String() 1152 field.nameNonEsc = `"` + field.name + `":` 1153 1154 fields = append(fields, field) 1155 if count[f.typ] > 1 { 1156 // If there were multiple instances, add a second, 1157 // so that the annihilation code will see a duplicate. 1158 // It only cares about the distinction between 1 or 2, 1159 // so don't bother generating any more copies. 1160 fields = append(fields, fields[len(fields)-1]) 1161 } 1162 continue 1163 } 1164 1165 // Record new anonymous struct to explore in next round. 1166 nextCount[ft]++ 1167 if nextCount[ft] == 1 { 1168 next = append(next, field{name: ft.Name(), index: index, typ: ft}) 1169 } 1170 } 1171 } 1172 } 1173 1174 sort.Slice(fields, func(i, j int) bool { 1175 x := fields 1176 // sort field by name, breaking ties with depth, then 1177 // breaking ties with "name came from json tag", then 1178 // breaking ties with index sequence. 1179 if x[i].name != x[j].name { 1180 return x[i].name < x[j].name 1181 } 1182 if len(x[i].index) != len(x[j].index) { 1183 return len(x[i].index) < len(x[j].index) 1184 } 1185 if x[i].tag != x[j].tag { 1186 return x[i].tag 1187 } 1188 return byIndex(x).Less(i, j) 1189 }) 1190 1191 // Delete all fields that are hidden by the Go rules for embedded fields, 1192 // except that fields with JSON tags are promoted. 1193 1194 // The fields are sorted in primary order of name, secondary order 1195 // of field index length. Loop over names; for each name, delete 1196 // hidden fields by choosing the one dominant field that survives. 1197 out := fields[:0] 1198 for advance, i := 0, 0; i < len(fields); i += advance { 1199 // One iteration per name. 1200 // Find the sequence of fields with the name of this first field. 1201 fi := fields[i] 1202 name := fi.name 1203 for advance = 1; i+advance < len(fields); advance++ { 1204 fj := fields[i+advance] 1205 if fj.name != name { 1206 break 1207 } 1208 } 1209 if advance == 1 { // Only one field with this name 1210 out = append(out, fi) 1211 continue 1212 } 1213 dominant, ok := dominantField(fields[i : i+advance]) 1214 if ok { 1215 out = append(out, dominant) 1216 } 1217 } 1218 1219 fields = out 1220 sort.Sort(byIndex(fields)) 1221 1222 for i := range fields { 1223 f := &fields[i] 1224 f.encoder = typeEncoder(typeByIndex(t, f.index)) 1225 } 1226 return fields 1227 } 1228 1229 // dominantField looks through the fields, all of which are known to 1230 // have the same name, to find the single field that dominates the 1231 // others using Go's embedding rules, modified by the presence of 1232 // JSON tags. If there are multiple top-level fields, the boolean 1233 // will be false: This condition is an error in Go and we skip all 1234 // the fields. 1235 func dominantField(fields []field) (field, bool) { 1236 // The fields are sorted in increasing index-length order, then by presence of tag. 1237 // That means that the first field is the dominant one. We need only check 1238 // for error cases: two fields at top level, either both tagged or neither tagged. 1239 if len(fields) > 1 && len(fields[0].index) == len(fields[1].index) && fields[0].tag == fields[1].tag { 1240 return field{}, false 1241 } 1242 return fields[0], true 1243 } 1244 1245 var fieldCache sync.Map // map[reflect.Type][]field 1246 1247 // cachedTypeFields is like typeFields but uses a cache to avoid repeated work. 1248 func cachedTypeFields(t reflect.Type) []field { 1249 if f, ok := fieldCache.Load(t); ok { 1250 return f.([]field) 1251 } 1252 f, _ := fieldCache.LoadOrStore(t, typeFields(t)) 1253 return f.([]field) 1254 }