1package json 2 3import ( 4 "encoding" 5 "encoding/base64" 6 "math" 7 "reflect" 8 "sort" 9 "strconv" 10 "sync" 11 "time" 12 "unicode/utf8" 13 "unsafe" 14) 15 16const hex = "0123456789abcdef" 17 18func (e encoder) encodeNull(b []byte, p unsafe.Pointer) ([]byte, error) { 19 return append(b, "null"...), nil 20} 21 22func (e encoder) encodeBool(b []byte, p unsafe.Pointer) ([]byte, error) { 23 if *(*bool)(p) { 24 return append(b, "true"...), nil 25 } 26 return append(b, "false"...), nil 27} 28 29func (e encoder) encodeInt(b []byte, p unsafe.Pointer) ([]byte, error) { 30 return appendInt(b, int64(*(*int)(p))), nil 31} 32 33func (e encoder) encodeInt8(b []byte, p unsafe.Pointer) ([]byte, error) { 34 return appendInt(b, int64(*(*int8)(p))), nil 35} 36 37func (e encoder) encodeInt16(b []byte, p unsafe.Pointer) ([]byte, error) { 38 return appendInt(b, int64(*(*int16)(p))), nil 39} 40 41func (e encoder) encodeInt32(b []byte, p unsafe.Pointer) ([]byte, error) { 42 return appendInt(b, int64(*(*int32)(p))), nil 43} 44 45func (e encoder) encodeInt64(b []byte, p unsafe.Pointer) ([]byte, error) { 46 return appendInt(b, *(*int64)(p)), nil 47} 48 49func (e encoder) encodeUint(b []byte, p unsafe.Pointer) ([]byte, error) { 50 return appendUint(b, uint64(*(*uint)(p))), nil 51} 52 53func (e encoder) encodeUintptr(b []byte, p unsafe.Pointer) ([]byte, error) { 54 return appendUint(b, uint64(*(*uintptr)(p))), nil 55} 56 57func (e encoder) encodeUint8(b []byte, p unsafe.Pointer) ([]byte, error) { 58 return appendUint(b, uint64(*(*uint8)(p))), nil 59} 60 61func (e encoder) encodeUint16(b []byte, p unsafe.Pointer) ([]byte, error) { 62 return appendUint(b, uint64(*(*uint16)(p))), nil 63} 64 65func (e encoder) encodeUint32(b []byte, p unsafe.Pointer) ([]byte, error) { 66 return appendUint(b, uint64(*(*uint32)(p))), nil 67} 68 69func (e encoder) encodeUint64(b []byte, p unsafe.Pointer) ([]byte, error) { 70 return appendUint(b, *(*uint64)(p)), nil 71} 72 73func (e encoder) encodeFloat32(b []byte, p unsafe.Pointer) ([]byte, error) { 74 return e.encodeFloat(b, float64(*(*float32)(p)), 32) 75} 76 77func (e encoder) encodeFloat64(b []byte, p unsafe.Pointer) ([]byte, error) { 78 return e.encodeFloat(b, *(*float64)(p), 64) 79} 80 81func (e encoder) encodeFloat(b []byte, f float64, bits int) ([]byte, error) { 82 switch { 83 case math.IsNaN(f): 84 return b, &UnsupportedValueError{Value: reflect.ValueOf(f), Str: "NaN"} 85 case math.IsInf(f, 0): 86 return b, &UnsupportedValueError{Value: reflect.ValueOf(f), Str: "inf"} 87 } 88 89 // Convert as if by ES6 number to string conversion. 90 // This matches most other JSON generators. 91 // See golang.org/issue/6384 and golang.org/issue/14135. 92 // Like fmt %g, but the exponent cutoffs are different 93 // and exponents themselves are not padded to two digits. 94 abs := math.Abs(f) 95 fmt := byte('f') 96 // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. 97 if abs != 0 { 98 if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) { 99 fmt = 'e' 100 } 101 } 102 103 b = strconv.AppendFloat(b, f, fmt, -1, int(bits)) 104 105 if fmt == 'e' { 106 // clean up e-09 to e-9 107 n := len(b) 108 if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' { 109 b[n-2] = b[n-1] 110 b = b[:n-1] 111 } 112 } 113 114 return b, nil 115} 116 117func (e encoder) encodeNumber(b []byte, p unsafe.Pointer) ([]byte, error) { 118 n := *(*Number)(p) 119 if n == "" { 120 n = "0" 121 } 122 123 d := decoder{} 124 _, _, _, err := d.parseNumber(stringToBytes(string(n))) 125 if err != nil { 126 return b, err 127 } 128 129 return append(b, n...), nil 130} 131 132func (e encoder) encodeString(b []byte, p unsafe.Pointer) ([]byte, error) { 133 s := *(*string)(p) 134 if len(s) == 0 { 135 return append(b, `""`...), nil 136 } 137 i := 0 138 j := 0 139 escapeHTML := (e.flags & EscapeHTML) != 0 140 141 b = append(b, '"') 142 143 if len(s) >= 8 { 144 if j = escapeIndex(s, escapeHTML); j < 0 { 145 return append(append(b, s...), '"'), nil 146 } 147 } 148 149 for j < len(s) { 150 c := s[j] 151 152 if c >= 0x20 && c <= 0x7f && c != '\\' && c != '"' && (!escapeHTML || (c != '<' && c != '>' && c != '&')) { 153 // fast path: most of the time, printable ascii characters are used 154 j++ 155 continue 156 } 157 158 switch c { 159 case '\\', '"': 160 b = append(b, s[i:j]...) 161 b = append(b, '\\', c) 162 i = j + 1 163 j = j + 1 164 continue 165 166 case '\n': 167 b = append(b, s[i:j]...) 168 b = append(b, '\\', 'n') 169 i = j + 1 170 j = j + 1 171 continue 172 173 case '\r': 174 b = append(b, s[i:j]...) 175 b = append(b, '\\', 'r') 176 i = j + 1 177 j = j + 1 178 continue 179 180 case '\t': 181 b = append(b, s[i:j]...) 182 b = append(b, '\\', 't') 183 i = j + 1 184 j = j + 1 185 continue 186 187 case '<', '>', '&': 188 b = append(b, s[i:j]...) 189 b = append(b, `\u00`...) 190 b = append(b, hex[c>>4], hex[c&0xF]) 191 i = j + 1 192 j = j + 1 193 continue 194 } 195 196 // This encodes bytes < 0x20 except for \t, \n and \r. 197 if c < 0x20 { 198 b = append(b, s[i:j]...) 199 b = append(b, `\u00`...) 200 b = append(b, hex[c>>4], hex[c&0xF]) 201 i = j + 1 202 j = j + 1 203 continue 204 } 205 206 r, size := utf8.DecodeRuneInString(s[j:]) 207 208 if r == utf8.RuneError && size == 1 { 209 b = append(b, s[i:j]...) 210 b = append(b, `\ufffd`...) 211 i = j + size 212 j = j + size 213 continue 214 } 215 216 switch r { 217 case '\u2028', '\u2029': 218 // U+2028 is LINE SEPARATOR. 219 // U+2029 is PARAGRAPH SEPARATOR. 220 // They are both technically valid characters in JSON strings, 221 // but don't work in JSONP, which has to be evaluated as JavaScript, 222 // and can lead to security holes there. It is valid JSON to 223 // escape them, so we do so unconditionally. 224 // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. 225 b = append(b, s[i:j]...) 226 b = append(b, `\u202`...) 227 b = append(b, hex[r&0xF]) 228 i = j + size 229 j = j + size 230 continue 231 } 232 233 j += size 234 } 235 236 b = append(b, s[i:]...) 237 b = append(b, '"') 238 return b, nil 239} 240 241func (e encoder) encodeToString(b []byte, p unsafe.Pointer, encode encodeFunc) ([]byte, error) { 242 i := len(b) 243 244 b, err := encode(e, b, p) 245 if err != nil { 246 return b, err 247 } 248 249 j := len(b) 250 s := b[i:] 251 252 if b, err = e.encodeString(b, unsafe.Pointer(&s)); err != nil { 253 return b, err 254 } 255 256 n := copy(b[i:], b[j:]) 257 return b[:i+n], nil 258} 259 260func (e encoder) encodeBytes(b []byte, p unsafe.Pointer) ([]byte, error) { 261 v := *(*[]byte)(p) 262 if v == nil { 263 return append(b, "null"...), nil 264 } 265 266 n := base64.StdEncoding.EncodedLen(len(v)) + 2 267 268 if avail := cap(b) - len(b); avail < n { 269 newB := make([]byte, cap(b)+(n-avail)) 270 copy(newB, b) 271 b = newB[:len(b)] 272 } 273 274 i := len(b) 275 j := len(b) + n 276 277 b = b[:j] 278 b[i] = '"' 279 base64.StdEncoding.Encode(b[i+1:j-1], v) 280 b[j-1] = '"' 281 return b, nil 282} 283 284func (e encoder) encodeDuration(b []byte, p unsafe.Pointer) ([]byte, error) { 285 b = append(b, '"') 286 b = appendDuration(b, *(*time.Duration)(p)) 287 b = append(b, '"') 288 return b, nil 289} 290 291func (e encoder) encodeTime(b []byte, p unsafe.Pointer) ([]byte, error) { 292 t := *(*time.Time)(p) 293 b = append(b, '"') 294 b = t.AppendFormat(b, time.RFC3339Nano) 295 b = append(b, '"') 296 return b, nil 297} 298 299func (e encoder) encodeArray(b []byte, p unsafe.Pointer, n int, size uintptr, t reflect.Type, encode encodeFunc) ([]byte, error) { 300 var start = len(b) 301 var err error 302 b = append(b, '[') 303 304 for i := 0; i < n; i++ { 305 if i != 0 { 306 b = append(b, ',') 307 } 308 if b, err = encode(e, b, unsafe.Pointer(uintptr(p)+(uintptr(i)*size))); err != nil { 309 return b[:start], err 310 } 311 } 312 313 b = append(b, ']') 314 return b, nil 315} 316 317func (e encoder) encodeSlice(b []byte, p unsafe.Pointer, size uintptr, t reflect.Type, encode encodeFunc) ([]byte, error) { 318 s := (*slice)(p) 319 320 if s.data == nil && s.len == 0 && s.cap == 0 { 321 return append(b, "null"...), nil 322 } 323 324 return e.encodeArray(b, s.data, s.len, size, t, encode) 325} 326 327func (e encoder) encodeMap(b []byte, p unsafe.Pointer, t reflect.Type, encodeKey, encodeValue encodeFunc, sortKeys sortFunc) ([]byte, error) { 328 m := reflect.NewAt(t, p).Elem() 329 if m.IsNil() { 330 return append(b, "null"...), nil 331 } 332 333 keys := m.MapKeys() 334 if sortKeys != nil && (e.flags&SortMapKeys) != 0 { 335 sortKeys(keys) 336 } 337 338 var start = len(b) 339 var err error 340 b = append(b, '{') 341 342 for i, k := range keys { 343 v := m.MapIndex(k) 344 345 if i != 0 { 346 b = append(b, ',') 347 } 348 349 if b, err = encodeKey(e, b, (*iface)(unsafe.Pointer(&k)).ptr); err != nil { 350 return b[:start], err 351 } 352 353 b = append(b, ':') 354 355 if b, err = encodeValue(e, b, (*iface)(unsafe.Pointer(&v)).ptr); err != nil { 356 return b[:start], err 357 } 358 } 359 360 b = append(b, '}') 361 return b, nil 362} 363 364type element struct { 365 key string 366 val interface{} 367 raw RawMessage 368} 369 370type mapslice struct { 371 elements []element 372} 373 374func (m *mapslice) Len() int { return len(m.elements) } 375func (m *mapslice) Less(i, j int) bool { return m.elements[i].key < m.elements[j].key } 376func (m *mapslice) Swap(i, j int) { m.elements[i], m.elements[j] = m.elements[j], m.elements[i] } 377 378var mapslicePool = sync.Pool{ 379 New: func() interface{} { return new(mapslice) }, 380} 381 382func (e encoder) encodeMapStringInterface(b []byte, p unsafe.Pointer) ([]byte, error) { 383 m := *(*map[string]interface{})(p) 384 if m == nil { 385 return append(b, "null"...), nil 386 } 387 388 if (e.flags & SortMapKeys) == 0 { 389 // Optimized code path when the program does not need the map keys to be 390 // sorted. 391 b = append(b, '{') 392 393 if len(m) != 0 { 394 var err error 395 var i = 0 396 397 for k, v := range m { 398 if i != 0 { 399 b = append(b, ',') 400 } 401 402 b, _ = e.encodeString(b, unsafe.Pointer(&k)) 403 b = append(b, ':') 404 405 b, err = Append(b, v, e.flags) 406 if err != nil { 407 return b, err 408 } 409 410 i++ 411 } 412 } 413 414 b = append(b, '}') 415 return b, nil 416 } 417 418 s := mapslicePool.Get().(*mapslice) 419 if cap(s.elements) < len(m) { 420 s.elements = make([]element, 0, align(10, uintptr(len(m)))) 421 } 422 for key, val := range m { 423 s.elements = append(s.elements, element{key: key, val: val}) 424 } 425 sort.Sort(s) 426 427 var start = len(b) 428 var err error 429 b = append(b, '{') 430 431 for i, elem := range s.elements { 432 if i != 0 { 433 b = append(b, ',') 434 } 435 436 b, _ = e.encodeString(b, unsafe.Pointer(&elem.key)) 437 b = append(b, ':') 438 439 b, err = Append(b, elem.val, e.flags) 440 if err != nil { 441 break 442 } 443 } 444 445 for i := range s.elements { 446 s.elements[i] = element{} 447 } 448 449 s.elements = s.elements[:0] 450 mapslicePool.Put(s) 451 452 if err != nil { 453 return b[:start], err 454 } 455 456 b = append(b, '}') 457 return b, nil 458} 459 460func (e encoder) encodeMapStringRawMessage(b []byte, p unsafe.Pointer) ([]byte, error) { 461 m := *(*map[string]RawMessage)(p) 462 if m == nil { 463 return append(b, "null"...), nil 464 } 465 466 if (e.flags & SortMapKeys) == 0 { 467 // Optimized code path when the program does not need the map keys to be 468 // sorted. 469 b = append(b, '{') 470 471 if len(m) != 0 { 472 var err error 473 var i = 0 474 475 for k, v := range m { 476 if i != 0 { 477 b = append(b, ',') 478 } 479 480 // encodeString doesn't return errors so we ignore it here 481 b, _ = e.encodeString(b, unsafe.Pointer(&k)) 482 b = append(b, ':') 483 484 b, err = e.encodeRawMessage(b, unsafe.Pointer(&v)) 485 if err != nil { 486 break 487 } 488 489 i++ 490 } 491 } 492 493 b = append(b, '}') 494 return b, nil 495 } 496 497 s := mapslicePool.Get().(*mapslice) 498 if cap(s.elements) < len(m) { 499 s.elements = make([]element, 0, align(10, uintptr(len(m)))) 500 } 501 for key, raw := range m { 502 s.elements = append(s.elements, element{key: key, raw: raw}) 503 } 504 sort.Sort(s) 505 506 var start = len(b) 507 var err error 508 b = append(b, '{') 509 510 for i, elem := range s.elements { 511 if i != 0 { 512 b = append(b, ',') 513 } 514 515 b, _ = e.encodeString(b, unsafe.Pointer(&elem.key)) 516 b = append(b, ':') 517 518 b, err = e.encodeRawMessage(b, unsafe.Pointer(&elem.raw)) 519 if err != nil { 520 break 521 } 522 } 523 524 for i := range s.elements { 525 s.elements[i] = element{} 526 } 527 528 s.elements = s.elements[:0] 529 mapslicePool.Put(s) 530 531 if err != nil { 532 return b[:start], err 533 } 534 535 b = append(b, '}') 536 return b, nil 537} 538 539func (e encoder) encodeMapStringString(b []byte, p unsafe.Pointer) ([]byte, error) { 540 m := *(*map[string]string)(p) 541 if m == nil { 542 return append(b, "null"...), nil 543 } 544 545 if (e.flags & SortMapKeys) == 0 { 546 // Optimized code path when the program does not need the map keys to be 547 // sorted. 548 b = append(b, '{') 549 550 if len(m) != 0 { 551 var i = 0 552 553 for k, v := range m { 554 if i != 0 { 555 b = append(b, ',') 556 } 557 558 // encodeString never returns an error so we ignore it here 559 b, _ = e.encodeString(b, unsafe.Pointer(&k)) 560 b = append(b, ':') 561 b, _ = e.encodeString(b, unsafe.Pointer(&v)) 562 563 i++ 564 } 565 } 566 567 b = append(b, '}') 568 return b, nil 569 } 570 571 s := mapslicePool.Get().(*mapslice) 572 if cap(s.elements) < len(m) { 573 s.elements = make([]element, 0, align(10, uintptr(len(m)))) 574 } 575 for key, val := range m { 576 v := val 577 s.elements = append(s.elements, element{key: key, val: &v}) 578 } 579 sort.Sort(s) 580 581 b = append(b, '{') 582 583 for i, elem := range s.elements { 584 if i != 0 { 585 b = append(b, ',') 586 } 587 588 // encodeString never returns an error so we ignore it here 589 b, _ = e.encodeString(b, unsafe.Pointer(&elem.key)) 590 b = append(b, ':') 591 b, _ = e.encodeString(b, unsafe.Pointer(elem.val.(*string))) 592 } 593 594 for i := range s.elements { 595 s.elements[i] = element{} 596 } 597 598 s.elements = s.elements[:0] 599 mapslicePool.Put(s) 600 601 b = append(b, '}') 602 return b, nil 603} 604 605func (e encoder) encodeMapStringStringSlice(b []byte, p unsafe.Pointer) ([]byte, error) { 606 m := *(*map[string][]string)(p) 607 if m == nil { 608 return append(b, "null"...), nil 609 } 610 611 var stringSize = unsafe.Sizeof("") 612 613 if (e.flags & SortMapKeys) == 0 { 614 // Optimized code path when the program does not need the map keys to be 615 // sorted. 616 b = append(b, '{') 617 618 if len(m) != 0 { 619 var err error 620 var i = 0 621 622 for k, v := range m { 623 if i != 0 { 624 b = append(b, ',') 625 } 626 627 b, _ = e.encodeString(b, unsafe.Pointer(&k)) 628 b = append(b, ':') 629 630 b, err = e.encodeSlice(b, unsafe.Pointer(&v), stringSize, sliceStringType, encoder.encodeString) 631 if err != nil { 632 return b, err 633 } 634 635 i++ 636 } 637 } 638 639 b = append(b, '}') 640 return b, nil 641 } 642 643 s := mapslicePool.Get().(*mapslice) 644 if cap(s.elements) < len(m) { 645 s.elements = make([]element, 0, align(10, uintptr(len(m)))) 646 } 647 for key, val := range m { 648 v := val 649 s.elements = append(s.elements, element{key: key, val: &v}) 650 } 651 sort.Sort(s) 652 653 var start = len(b) 654 var err error 655 b = append(b, '{') 656 657 for i, elem := range s.elements { 658 if i != 0 { 659 b = append(b, ',') 660 } 661 662 b, _ = e.encodeString(b, unsafe.Pointer(&elem.key)) 663 b = append(b, ':') 664 665 b, err = e.encodeSlice(b, unsafe.Pointer(elem.val.(*[]string)), stringSize, sliceStringType, encoder.encodeString) 666 if err != nil { 667 break 668 } 669 } 670 671 for i := range s.elements { 672 s.elements[i] = element{} 673 } 674 675 s.elements = s.elements[:0] 676 mapslicePool.Put(s) 677 678 if err != nil { 679 return b[:start], err 680 } 681 682 b = append(b, '}') 683 return b, nil 684} 685 686func (e encoder) encodeMapStringBool(b []byte, p unsafe.Pointer) ([]byte, error) { 687 m := *(*map[string]bool)(p) 688 if m == nil { 689 return append(b, "null"...), nil 690 } 691 692 if (e.flags & SortMapKeys) == 0 { 693 // Optimized code path when the program does not need the map keys to be 694 // sorted. 695 b = append(b, '{') 696 697 if len(m) != 0 { 698 var i = 0 699 700 for k, v := range m { 701 if i != 0 { 702 b = append(b, ',') 703 } 704 705 // encodeString never returns an error so we ignore it here 706 b, _ = e.encodeString(b, unsafe.Pointer(&k)) 707 if v { 708 b = append(b, ":true"...) 709 } else { 710 b = append(b, ":false"...) 711 } 712 713 i++ 714 } 715 } 716 717 b = append(b, '}') 718 return b, nil 719 } 720 721 s := mapslicePool.Get().(*mapslice) 722 if cap(s.elements) < len(m) { 723 s.elements = make([]element, 0, align(10, uintptr(len(m)))) 724 } 725 for key, val := range m { 726 s.elements = append(s.elements, element{key: key, val: val}) 727 } 728 sort.Sort(s) 729 730 b = append(b, '{') 731 732 for i, elem := range s.elements { 733 if i != 0 { 734 b = append(b, ',') 735 } 736 737 // encodeString never returns an error so we ignore it here 738 b, _ = e.encodeString(b, unsafe.Pointer(&elem.key)) 739 if elem.val.(bool) { 740 b = append(b, ":true"...) 741 } else { 742 b = append(b, ":false"...) 743 } 744 } 745 746 for i := range s.elements { 747 s.elements[i] = element{} 748 } 749 750 s.elements = s.elements[:0] 751 mapslicePool.Put(s) 752 753 b = append(b, '}') 754 return b, nil 755} 756 757func (e encoder) encodeStruct(b []byte, p unsafe.Pointer, st *structType) ([]byte, error) { 758 var start = len(b) 759 var err error 760 var k string 761 var n int 762 b = append(b, '{') 763 764 escapeHTML := (e.flags & EscapeHTML) != 0 765 766 for i := range st.fields { 767 f := &st.fields[i] 768 v := unsafe.Pointer(uintptr(p) + f.offset) 769 770 if f.omitempty && f.empty(v) { 771 continue 772 } 773 774 if escapeHTML { 775 k = f.html 776 } else { 777 k = f.json 778 } 779 780 lengthBeforeKey := len(b) 781 782 if n != 0 { 783 b = append(b, k...) 784 } else { 785 b = append(b, k[1:]...) 786 } 787 788 if b, err = f.codec.encode(e, b, v); err != nil { 789 if err == (rollback{}) { 790 b = b[:lengthBeforeKey] 791 continue 792 } 793 return b[:start], err 794 } 795 796 n++ 797 } 798 799 b = append(b, '}') 800 return b, nil 801} 802 803type rollback struct{} 804 805func (rollback) Error() string { return "rollback" } 806 807func (e encoder) encodeEmbeddedStructPointer(b []byte, p unsafe.Pointer, t reflect.Type, unexported bool, offset uintptr, encode encodeFunc) ([]byte, error) { 808 p = *(*unsafe.Pointer)(p) 809 if p == nil { 810 return b, rollback{} 811 } 812 return encode(e, b, unsafe.Pointer(uintptr(p)+offset)) 813} 814 815func (e encoder) encodePointer(b []byte, p unsafe.Pointer, t reflect.Type, encode encodeFunc) ([]byte, error) { 816 if p = *(*unsafe.Pointer)(p); p != nil { 817 return encode(e, b, p) 818 } 819 return e.encodeNull(b, nil) 820} 821 822func (e encoder) encodeInterface(b []byte, p unsafe.Pointer) ([]byte, error) { 823 return Append(b, *(*interface{})(p), e.flags) 824} 825 826func (e encoder) encodeMaybeEmptyInterface(b []byte, p unsafe.Pointer, t reflect.Type) ([]byte, error) { 827 return Append(b, reflect.NewAt(t, p).Elem().Interface(), e.flags) 828} 829 830func (e encoder) encodeUnsupportedTypeError(b []byte, p unsafe.Pointer, t reflect.Type) ([]byte, error) { 831 return b, &UnsupportedTypeError{Type: t} 832} 833 834func (e encoder) encodeRawMessage(b []byte, p unsafe.Pointer) ([]byte, error) { 835 v := *(*RawMessage)(p) 836 837 if v == nil { 838 return append(b, "null"...), nil 839 } 840 841 var s []byte 842 843 if (e.flags & TrustRawMessage) != 0 { 844 s = v 845 } else { 846 var err error 847 d := decoder{} 848 s, _, _, err = d.parseValue(v) 849 if err != nil { 850 return b, &UnsupportedValueError{Value: reflect.ValueOf(v), Str: err.Error()} 851 } 852 } 853 854 if (e.flags & EscapeHTML) != 0 { 855 return appendCompactEscapeHTML(b, s), nil 856 } 857 858 return append(b, s...), nil 859} 860 861func (e encoder) encodeJSONMarshaler(b []byte, p unsafe.Pointer, t reflect.Type, pointer bool) ([]byte, error) { 862 v := reflect.NewAt(t, p) 863 864 if !pointer { 865 v = v.Elem() 866 } 867 868 switch v.Kind() { 869 case reflect.Ptr, reflect.Interface: 870 if v.IsNil() { 871 return append(b, "null"...), nil 872 } 873 } 874 875 j, err := v.Interface().(Marshaler).MarshalJSON() 876 if err != nil { 877 return b, err 878 } 879 880 d := decoder{} 881 s, _, _, err := d.parseValue(j) 882 if err != nil { 883 return b, &MarshalerError{Type: t, Err: err} 884 } 885 886 if (e.flags & EscapeHTML) != 0 { 887 return appendCompactEscapeHTML(b, s), nil 888 } 889 890 return append(b, s...), nil 891} 892 893func (e encoder) encodeTextMarshaler(b []byte, p unsafe.Pointer, t reflect.Type, pointer bool) ([]byte, error) { 894 v := reflect.NewAt(t, p) 895 896 if !pointer { 897 v = v.Elem() 898 } 899 900 switch v.Kind() { 901 case reflect.Ptr, reflect.Interface: 902 if v.IsNil() { 903 return append(b, `null`...), nil 904 } 905 } 906 907 s, err := v.Interface().(encoding.TextMarshaler).MarshalText() 908 if err != nil { 909 return b, err 910 } 911 912 return e.encodeString(b, unsafe.Pointer(&s)) 913} 914 915func appendCompactEscapeHTML(dst []byte, src []byte) []byte { 916 start := 0 917 escape := false 918 inString := false 919 920 for i, c := range src { 921 if !inString { 922 switch c { 923 case '"': // enter string 924 inString = true 925 case ' ', '\n', '\r', '\t': // skip space 926 if start < i { 927 dst = append(dst, src[start:i]...) 928 } 929 start = i + 1 930 } 931 continue 932 } 933 934 if escape { 935 escape = false 936 continue 937 } 938 939 if c == '\\' { 940 escape = true 941 continue 942 } 943 944 if c == '"' { 945 inString = false 946 continue 947 } 948 949 if c == '<' || c == '>' || c == '&' { 950 if start < i { 951 dst = append(dst, src[start:i]...) 952 } 953 dst = append(dst, `\u00`...) 954 dst = append(dst, hex[c>>4], hex[c&0xF]) 955 start = i + 1 956 continue 957 } 958 959 // Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9). 960 if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 { 961 if start < i { 962 dst = append(dst, src[start:i]...) 963 } 964 dst = append(dst, `\u202`...) 965 dst = append(dst, hex[src[i+2]&0xF]) 966 start = i + 3 967 continue 968 } 969 } 970 971 if start < len(src) { 972 dst = append(dst, src[start:]...) 973 } 974 975 return dst 976} 977