github.com/neilotoole/jsoncolor@v0.6.0/codec.go (about) 1 package jsoncolor 2 3 import ( 4 "encoding" 5 "encoding/json" 6 "fmt" 7 "reflect" 8 "sort" 9 "strconv" 10 "strings" 11 "sync/atomic" 12 "time" 13 "unicode" 14 "unsafe" 15 ) 16 17 type codec struct { 18 encode encodeFunc 19 decode decodeFunc 20 } 21 22 type encoder struct { 23 flags AppendFlags 24 clrs *Colors 25 indentr *indenter 26 } 27 type decoder struct{ flags ParseFlags } 28 29 type encodeFunc func(encoder, []byte, unsafe.Pointer) ([]byte, error) 30 type decodeFunc func(decoder, []byte, unsafe.Pointer) ([]byte, error) 31 32 type emptyFunc func(unsafe.Pointer) bool 33 type sortFunc func([]reflect.Value) 34 35 var ( 36 // Eventually consistent cache mapping go types to dynamically generated 37 // codecs. 38 // 39 // Note: using a uintptr as key instead of reflect.Type shaved ~15ns off of 40 // the ~30ns Marhsal/Unmarshal functions which were dominated by the map 41 // lookup time for simple types like bool, int, etc.. 42 cache unsafe.Pointer // map[unsafe.Pointer]codec 43 ) 44 45 func cacheLoad() map[unsafe.Pointer]codec { 46 p := atomic.LoadPointer(&cache) 47 return *(*map[unsafe.Pointer]codec)(unsafe.Pointer(&p)) 48 } 49 50 func cacheStore(typ reflect.Type, cod codec, oldCodecs map[unsafe.Pointer]codec) { 51 newCodecs := make(map[unsafe.Pointer]codec, len(oldCodecs)+1) 52 newCodecs[typeid(typ)] = cod 53 54 for t, c := range oldCodecs { 55 newCodecs[t] = c 56 } 57 58 atomic.StorePointer(&cache, *(*unsafe.Pointer)(unsafe.Pointer(&newCodecs))) 59 } 60 61 func typeid(t reflect.Type) unsafe.Pointer { 62 return (*iface)(unsafe.Pointer(&t)).ptr 63 } 64 65 func constructCachedCodec(t reflect.Type, cache map[unsafe.Pointer]codec) codec { 66 c := constructCodec(t, map[reflect.Type]*structType{}, t.Kind() == reflect.Ptr) 67 68 if inlined(t) { 69 c.encode = constructInlineValueEncodeFunc(c.encode) 70 } 71 72 cacheStore(t, c, cache) 73 return c 74 } 75 76 func constructCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) (c codec) { 77 switch t { 78 case nullType, nil: 79 c = codec{encode: encoder.encodeNull, decode: decoder.decodeNull} 80 81 case numberType: 82 c = codec{encode: encoder.encodeNumber, decode: decoder.decodeNumber} 83 84 case bytesType: 85 c = codec{encode: encoder.encodeBytes, decode: decoder.decodeBytes} 86 87 case durationType: 88 c = codec{encode: encoder.encodeDuration, decode: decoder.decodeDuration} 89 90 case timeType: 91 c = codec{encode: encoder.encodeTime, decode: decoder.decodeTime} 92 93 case interfaceType: 94 c = codec{encode: encoder.encodeInterface, decode: decoder.decodeInterface} 95 96 case rawMessageType: 97 c = codec{encode: encoder.encodeRawMessage, decode: decoder.decodeRawMessage} 98 99 case numberPtrType: 100 c = constructPointerCodec(numberPtrType, nil) 101 102 case durationPtrType: 103 c = constructPointerCodec(durationPtrType, nil) 104 105 case timePtrType: 106 c = constructPointerCodec(timePtrType, nil) 107 108 case rawMessagePtrType: 109 c = constructPointerCodec(rawMessagePtrType, nil) 110 } 111 112 if c.encode != nil { 113 return 114 } 115 116 switch t.Kind() { 117 case reflect.Bool: 118 c = codec{encode: encoder.encodeBool, decode: decoder.decodeBool} 119 120 case reflect.Int: 121 c = codec{encode: encoder.encodeInt, decode: decoder.decodeInt} 122 123 case reflect.Int8: 124 c = codec{encode: encoder.encodeInt8, decode: decoder.decodeInt8} 125 126 case reflect.Int16: 127 c = codec{encode: encoder.encodeInt16, decode: decoder.decodeInt16} 128 129 case reflect.Int32: 130 c = codec{encode: encoder.encodeInt32, decode: decoder.decodeInt32} 131 132 case reflect.Int64: 133 c = codec{encode: encoder.encodeInt64, decode: decoder.decodeInt64} 134 135 case reflect.Uint: 136 c = codec{encode: encoder.encodeUint, decode: decoder.decodeUint} 137 138 case reflect.Uintptr: 139 c = codec{encode: encoder.encodeUintptr, decode: decoder.decodeUintptr} 140 141 case reflect.Uint8: 142 c = codec{encode: encoder.encodeUint8, decode: decoder.decodeUint8} 143 144 case reflect.Uint16: 145 c = codec{encode: encoder.encodeUint16, decode: decoder.decodeUint16} 146 147 case reflect.Uint32: 148 c = codec{encode: encoder.encodeUint32, decode: decoder.decodeUint32} 149 150 case reflect.Uint64: 151 c = codec{encode: encoder.encodeUint64, decode: decoder.decodeUint64} 152 153 case reflect.Float32: 154 c = codec{encode: encoder.encodeFloat32, decode: decoder.decodeFloat32} 155 156 case reflect.Float64: 157 c = codec{encode: encoder.encodeFloat64, decode: decoder.decodeFloat64} 158 159 case reflect.String: 160 c = codec{encode: encoder.encodeString, decode: decoder.decodeString} 161 162 case reflect.Interface: 163 c = constructInterfaceCodec(t) 164 165 case reflect.Array: 166 c = constructArrayCodec(t, seen, canAddr) 167 168 case reflect.Slice: 169 c = constructSliceCodec(t, seen) 170 171 case reflect.Map: 172 c = constructMapCodec(t, seen) 173 174 case reflect.Struct: 175 c = constructStructCodec(t, seen, canAddr) 176 177 case reflect.Ptr: 178 c = constructPointerCodec(t, seen) 179 180 default: 181 c = constructUnsupportedTypeCodec(t) 182 } 183 184 p := reflect.PtrTo(t) 185 186 if canAddr { 187 switch { 188 case p.Implements(jsonMarshalerType): 189 c.encode = constructJSONMarshalerEncodeFunc(t, true) 190 case p.Implements(textMarshalerType): 191 c.encode = constructTextMarshalerEncodeFunc(t, true) 192 } 193 } 194 195 switch { 196 case t.Implements(jsonMarshalerType): 197 c.encode = constructJSONMarshalerEncodeFunc(t, false) 198 case t.Implements(textMarshalerType): 199 c.encode = constructTextMarshalerEncodeFunc(t, false) 200 } 201 202 switch { 203 case p.Implements(jsonUnmarshalerType): 204 c.decode = constructJSONUnmarshalerDecodeFunc(t, true) 205 case p.Implements(textUnmarshalerType): 206 c.decode = constructTextUnmarshalerDecodeFunc(t, true) 207 } 208 209 return 210 } 211 212 func constructStringCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) codec { 213 c := constructCodec(t, seen, canAddr) 214 return codec{ 215 encode: constructStringEncodeFunc(c.encode), 216 decode: constructStringDecodeFunc(c.decode), 217 } 218 } 219 220 func constructStringEncodeFunc(encode encodeFunc) encodeFunc { 221 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 222 return e.encodeToString(b, p, encode) 223 } 224 } 225 226 func constructStringDecodeFunc(decode decodeFunc) decodeFunc { 227 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 228 return d.decodeFromString(b, p, decode) 229 } 230 } 231 232 func constructStringToIntDecodeFunc(t reflect.Type, decode decodeFunc) decodeFunc { 233 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 234 return d.decodeFromStringToInt(b, p, t, decode) 235 } 236 } 237 238 func constructArrayCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) codec { 239 e := t.Elem() 240 c := constructCodec(e, seen, canAddr) 241 s := alignedSize(e) 242 return codec{ 243 encode: constructArrayEncodeFunc(s, t, c.encode), 244 decode: constructArrayDecodeFunc(s, t, c.decode), 245 } 246 } 247 248 func constructArrayEncodeFunc(size uintptr, t reflect.Type, encode encodeFunc) encodeFunc { 249 n := t.Len() 250 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 251 return e.encodeArray(b, p, n, size, t, encode) 252 } 253 } 254 255 func constructArrayDecodeFunc(size uintptr, t reflect.Type, decode decodeFunc) decodeFunc { 256 n := t.Len() 257 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 258 return d.decodeArray(b, p, n, size, t, decode) 259 } 260 } 261 262 func constructSliceCodec(t reflect.Type, seen map[reflect.Type]*structType) codec { 263 e := t.Elem() 264 s := alignedSize(e) 265 266 if e.Kind() == reflect.Uint8 { 267 // Go 1.7+ behavior: slices of byte types (and aliases) may override the 268 // default encoding and decoding behaviors by implementing marshaler and 269 // unmarshaler interfaces. 270 p := reflect.PtrTo(e) 271 c := codec{} 272 273 switch { 274 case e.Implements(jsonMarshalerType): 275 c.encode = constructJSONMarshalerEncodeFunc(e, false) 276 case e.Implements(textMarshalerType): 277 c.encode = constructTextMarshalerEncodeFunc(e, false) 278 case p.Implements(jsonMarshalerType): 279 c.encode = constructJSONMarshalerEncodeFunc(e, true) 280 case p.Implements(textMarshalerType): 281 c.encode = constructTextMarshalerEncodeFunc(e, true) 282 } 283 284 switch { 285 case e.Implements(jsonUnmarshalerType): 286 c.decode = constructJSONUnmarshalerDecodeFunc(e, false) 287 case e.Implements(textUnmarshalerType): 288 c.decode = constructTextUnmarshalerDecodeFunc(e, false) 289 case p.Implements(jsonUnmarshalerType): 290 c.decode = constructJSONUnmarshalerDecodeFunc(e, true) 291 case p.Implements(textUnmarshalerType): 292 c.decode = constructTextUnmarshalerDecodeFunc(e, true) 293 } 294 295 if c.encode != nil { 296 c.encode = constructSliceEncodeFunc(s, t, c.encode) 297 } else { 298 c.encode = encoder.encodeBytes 299 } 300 301 if c.decode != nil { 302 c.decode = constructSliceDecodeFunc(s, t, c.decode) 303 } else { 304 c.decode = decoder.decodeBytes 305 } 306 307 return c 308 } 309 310 c := constructCodec(e, seen, true) 311 return codec{ 312 encode: constructSliceEncodeFunc(s, t, c.encode), 313 decode: constructSliceDecodeFunc(s, t, c.decode), 314 } 315 } 316 317 func constructSliceEncodeFunc(size uintptr, t reflect.Type, encode encodeFunc) encodeFunc { 318 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 319 return e.encodeSlice(b, p, size, t, encode) 320 } 321 } 322 323 func constructSliceDecodeFunc(size uintptr, t reflect.Type, decode decodeFunc) decodeFunc { 324 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 325 return d.decodeSlice(b, p, size, t, decode) 326 } 327 } 328 329 func constructMapCodec(t reflect.Type, seen map[reflect.Type]*structType) codec { 330 var sortKeys sortFunc 331 k := t.Key() 332 v := t.Elem() 333 334 // Faster implementations for some common cases. 335 switch { 336 case k == stringType && v == interfaceType: 337 return codec{ 338 encode: encoder.encodeMapStringInterface, 339 decode: decoder.decodeMapStringInterface, 340 } 341 342 case k == stringType && v == rawMessageType: 343 return codec{ 344 encode: encoder.encodeMapStringRawMessage, 345 decode: decoder.decodeMapStringRawMessage, 346 } 347 } 348 349 kc := codec{} 350 vc := constructCodec(v, seen, false) 351 352 if k.Implements(textMarshalerType) || reflect.PtrTo(k).Implements(textUnmarshalerType) { 353 kc.encode = constructTextMarshalerEncodeFunc(k, false) 354 kc.decode = constructTextUnmarshalerDecodeFunc(k, true) 355 356 sortKeys = func(keys []reflect.Value) { 357 sort.Slice(keys, func(i, j int) bool { 358 // This is a performance abomination but the use case is rare 359 // enough that it shouldn't be a problem in practice. 360 k1, _ := keys[i].Interface().(encoding.TextMarshaler).MarshalText() 361 k2, _ := keys[j].Interface().(encoding.TextMarshaler).MarshalText() 362 return string(k1) < string(k2) 363 }) 364 } 365 } else { 366 switch k.Kind() { 367 case reflect.String: 368 kc.encode = encoder.encodeKey 369 kc.decode = decoder.decodeString 370 371 sortKeys = func(keys []reflect.Value) { 372 sort.Slice(keys, func(i, j int) bool { return keys[i].String() < keys[j].String() }) 373 } 374 375 case reflect.Int, 376 reflect.Int8, 377 reflect.Int16, 378 reflect.Int32, 379 reflect.Int64: 380 kc = constructStringCodec(k, seen, false) 381 382 sortKeys = func(keys []reflect.Value) { 383 sort.Slice(keys, func(i, j int) bool { return intStringsAreSorted(keys[i].Int(), keys[j].Int()) }) 384 } 385 386 case reflect.Uint, 387 reflect.Uintptr, 388 reflect.Uint8, 389 reflect.Uint16, 390 reflect.Uint32, 391 reflect.Uint64: 392 kc = constructStringCodec(k, seen, false) 393 394 sortKeys = func(keys []reflect.Value) { 395 sort.Slice(keys, func(i, j int) bool { return uintStringsAreSorted(keys[i].Uint(), keys[j].Uint()) }) 396 } 397 398 default: 399 return constructUnsupportedTypeCodec(t) 400 } 401 } 402 403 if inlined(v) { 404 vc.encode = constructInlineValueEncodeFunc(vc.encode) 405 } 406 407 return codec{ 408 encode: constructMapEncodeFunc(t, kc.encode, vc.encode, sortKeys), 409 decode: constructMapDecodeFunc(t, kc.decode, vc.decode), 410 } 411 } 412 413 func constructMapEncodeFunc(t reflect.Type, encodeKey, encodeValue encodeFunc, sortKeys sortFunc) encodeFunc { 414 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 415 return e.encodeMap(b, p, t, encodeKey, encodeValue, sortKeys) 416 } 417 } 418 419 func constructMapDecodeFunc(t reflect.Type, decodeKey, decodeValue decodeFunc) decodeFunc { 420 kt := t.Key() 421 vt := t.Elem() 422 kz := reflect.Zero(kt) 423 vz := reflect.Zero(vt) 424 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 425 return d.decodeMap(b, p, t, kt, vt, kz, vz, decodeKey, decodeValue) 426 } 427 } 428 429 func constructStructCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) codec { 430 st := constructStructType(t, seen, canAddr) 431 return codec{ 432 encode: constructStructEncodeFunc(st), 433 decode: constructStructDecodeFunc(st), 434 } 435 } 436 437 func constructStructType(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) *structType { 438 // Used for preventing infinite recursion on types that have pointers to 439 // themselves. 440 st := seen[t] 441 442 if st == nil { 443 st = &structType{ 444 fields: make([]structField, 0, t.NumField()), 445 fieldsIndex: make(map[string]*structField), 446 ficaseIndex: make(map[string]*structField), 447 typ: t, 448 } 449 450 seen[t] = st 451 st.fields = appendStructFields(st.fields, t, 0, seen, canAddr) 452 453 for i := range st.fields { 454 f := &st.fields[i] 455 s := strings.ToLower(f.name) 456 st.fieldsIndex[f.name] = f 457 // When there is ambiguity because multiple fields have the same 458 // case-insensitive representation, the first field must win. 459 if _, exists := st.ficaseIndex[s]; !exists { 460 st.ficaseIndex[s] = f 461 } 462 } 463 } 464 465 return st 466 } 467 468 func constructStructEncodeFunc(st *structType) encodeFunc { 469 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 470 return e.encodeStruct(b, p, st) 471 } 472 } 473 474 func constructStructDecodeFunc(st *structType) decodeFunc { 475 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 476 return d.decodeStruct(b, p, st) 477 } 478 } 479 480 func constructEmbeddedStructPointerCodec(t reflect.Type, unexported bool, offset uintptr, field codec) codec { 481 return codec{ 482 encode: constructEmbeddedStructPointerEncodeFunc(t, unexported, offset, field.encode), 483 decode: constructEmbeddedStructPointerDecodeFunc(t, unexported, offset, field.decode), 484 } 485 } 486 487 func constructEmbeddedStructPointerEncodeFunc(t reflect.Type, unexported bool, offset uintptr, encode encodeFunc) encodeFunc { 488 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 489 return e.encodeEmbeddedStructPointer(b, p, t, unexported, offset, encode) 490 } 491 } 492 493 func constructEmbeddedStructPointerDecodeFunc(t reflect.Type, unexported bool, offset uintptr, decode decodeFunc) decodeFunc { 494 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 495 return d.decodeEmbeddedStructPointer(b, p, t, unexported, offset, decode) 496 } 497 } 498 499 func appendStructFields(fields []structField, t reflect.Type, offset uintptr, seen map[reflect.Type]*structType, canAddr bool) []structField { 500 type embeddedField struct { 501 index int 502 offset uintptr 503 pointer bool 504 unexported bool 505 subtype *structType 506 subfield *structField 507 } 508 509 names := make(map[string]struct{}) 510 embedded := make([]embeddedField, 0, 10) 511 512 for i, n := 0, t.NumField(); i < n; i++ { 513 f := t.Field(i) 514 515 var ( 516 name = f.Name 517 anonymous = f.Anonymous 518 tag = false 519 omitempty = false 520 stringify = false 521 unexported = len(f.PkgPath) != 0 522 ) 523 524 if unexported && !anonymous { // unexported 525 continue 526 } 527 528 if parts := strings.Split(f.Tag.Get("json"), ","); len(parts) != 0 { 529 if len(parts[0]) != 0 { 530 name, tag = parts[0], true 531 } 532 533 if name == "-" && len(parts) == 1 { // ignored 534 continue 535 } 536 537 if !isValidTag(name) { 538 name = f.Name 539 } 540 541 for _, tag := range parts[1:] { 542 switch tag { 543 case "omitempty": 544 omitempty = true 545 case "string": 546 stringify = true 547 } 548 } 549 } 550 551 if anonymous && !tag { // embedded 552 typ := f.Type 553 ptr := f.Type.Kind() == reflect.Ptr 554 555 if ptr { 556 typ = f.Type.Elem() 557 } 558 559 if typ.Kind() == reflect.Struct { 560 // When the embedded fields is inlined the fields can be looked 561 // up by offset from the address of the wrapping object, so we 562 // simply add the embedded struct fields to the list of fields 563 // of the current struct type. 564 subtype := constructStructType(typ, seen, canAddr) 565 566 for j := range subtype.fields { 567 embedded = append(embedded, embeddedField{ 568 index: i<<32 | j, 569 offset: offset + f.Offset, 570 pointer: ptr, 571 unexported: unexported, 572 subtype: subtype, 573 subfield: &subtype.fields[j], 574 }) 575 } 576 577 continue 578 } 579 580 if unexported { // ignore unexported non-struct types 581 continue 582 } 583 } 584 585 codec := constructCodec(f.Type, seen, canAddr) 586 587 if stringify { 588 // https://golang.org/pkg/encoding/json/#Marshal 589 // 590 // The "string" option signals that a field is stored as JSON inside 591 // a JSON-encoded string. It applies only to fields of string, 592 // floating point, integer, or boolean types. This extra level of 593 // encoding is sometimes used when communicating with JavaScript 594 // programs: 595 typ := f.Type 596 597 if typ.Kind() == reflect.Ptr { 598 typ = typ.Elem() 599 } 600 601 switch typ.Kind() { 602 case reflect.Int, 603 reflect.Int8, 604 reflect.Int16, 605 reflect.Int32, 606 reflect.Int64, 607 reflect.Uint, 608 reflect.Uintptr, 609 reflect.Uint8, 610 reflect.Uint16, 611 reflect.Uint32, 612 reflect.Uint64: 613 codec.encode = constructStringEncodeFunc(codec.encode) 614 codec.decode = constructStringToIntDecodeFunc(typ, codec.decode) 615 case reflect.Bool, 616 reflect.Float32, 617 reflect.Float64, 618 reflect.String: 619 codec.encode = constructStringEncodeFunc(codec.encode) 620 codec.decode = constructStringDecodeFunc(codec.decode) 621 } 622 } 623 624 fields = append(fields, structField{ 625 codec: codec, 626 offset: offset + f.Offset, 627 empty: emptyFuncOf(f.Type), 628 tag: tag, 629 omitempty: omitempty, 630 name: name, 631 index: i << 32, 632 typ: f.Type, 633 zero: reflect.Zero(f.Type), 634 }) 635 636 names[name] = struct{}{} 637 } 638 639 // Only unambiguous embedded fields must be serialized. 640 ambiguousNames := make(map[string]int) 641 ambiguousTags := make(map[string]int) 642 643 // Embedded types can never override a field that was already present at 644 // the top-level. 645 for name := range names { 646 ambiguousNames[name]++ 647 ambiguousTags[name]++ 648 } 649 650 for _, embfield := range embedded { 651 ambiguousNames[embfield.subfield.name]++ 652 if embfield.subfield.tag { 653 ambiguousTags[embfield.subfield.name]++ 654 } 655 } 656 657 for _, embfield := range embedded { 658 subfield := *embfield.subfield 659 660 if ambiguousNames[subfield.name] > 1 && !(subfield.tag && ambiguousTags[subfield.name] == 1) { 661 continue // ambiguous embedded field 662 } 663 664 if embfield.pointer { 665 subfield.codec = constructEmbeddedStructPointerCodec(embfield.subtype.typ, embfield.unexported, subfield.offset, subfield.codec) 666 subfield.offset = embfield.offset 667 } else { 668 subfield.offset += embfield.offset 669 } 670 671 // To prevent dominant flags more than one level below the embedded one. 672 subfield.tag = false 673 674 // To ensure the order of the fields in the output is the same is in the 675 // struct type. 676 subfield.index = embfield.index 677 678 fields = append(fields, subfield) 679 } 680 681 for i := range fields { 682 fields[i].json = encodeString(fields[i].name, 0) 683 fields[i].html = encodeString(fields[i].name, EscapeHTML) 684 } 685 686 sort.Slice(fields, func(i, j int) bool { return fields[i].index < fields[j].index }) 687 return fields 688 } 689 690 func encodeString(s string, flags AppendFlags) string { 691 b := make([]byte, 0, len(s)+2) 692 e := encoder{flags: flags} 693 b, _ = e.doEncodeString(b, unsafe.Pointer(&s)) 694 return *(*string)(unsafe.Pointer(&b)) 695 } 696 697 func constructPointerCodec(t reflect.Type, seen map[reflect.Type]*structType) codec { 698 e := t.Elem() 699 c := constructCodec(e, seen, true) 700 return codec{ 701 encode: constructPointerEncodeFunc(e, c.encode), 702 decode: constructPointerDecodeFunc(e, c.decode), 703 } 704 } 705 706 func constructPointerEncodeFunc(t reflect.Type, encode encodeFunc) encodeFunc { 707 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 708 return e.encodePointer(b, p, t, encode) 709 } 710 } 711 712 func constructPointerDecodeFunc(t reflect.Type, decode decodeFunc) decodeFunc { 713 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 714 return d.decodePointer(b, p, t, decode) 715 } 716 } 717 718 func constructInterfaceCodec(t reflect.Type) codec { 719 return codec{ 720 encode: constructMaybeEmptyInterfaceEncoderFunc(t), 721 decode: constructMaybeEmptyInterfaceDecoderFunc(t), 722 } 723 } 724 725 func constructMaybeEmptyInterfaceEncoderFunc(t reflect.Type) encodeFunc { 726 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 727 return e.encodeMaybeEmptyInterface(b, p, t) 728 } 729 } 730 731 func constructMaybeEmptyInterfaceDecoderFunc(t reflect.Type) decodeFunc { 732 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 733 return d.decodeMaybeEmptyInterface(b, p, t) 734 } 735 } 736 737 func constructUnsupportedTypeCodec(t reflect.Type) codec { 738 return codec{ 739 encode: constructUnsupportedTypeEncodeFunc(t), 740 decode: constructUnsupportedTypeDecodeFunc(t), 741 } 742 } 743 744 func constructUnsupportedTypeEncodeFunc(t reflect.Type) encodeFunc { 745 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 746 return e.encodeUnsupportedTypeError(b, p, t) 747 } 748 } 749 750 func constructUnsupportedTypeDecodeFunc(t reflect.Type) decodeFunc { 751 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 752 return d.decodeUnmarshalTypeError(b, p, t) 753 } 754 } 755 756 func constructJSONMarshalerEncodeFunc(t reflect.Type, pointer bool) encodeFunc { 757 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 758 return e.encodeJSONMarshaler(b, p, t, pointer) 759 } 760 } 761 762 func constructJSONUnmarshalerDecodeFunc(t reflect.Type, pointer bool) decodeFunc { 763 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 764 return d.decodeJSONUnmarshaler(b, p, t, pointer) 765 } 766 } 767 768 func constructTextMarshalerEncodeFunc(t reflect.Type, pointer bool) encodeFunc { 769 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 770 return e.encodeTextMarshaler(b, p, t, pointer) 771 } 772 } 773 774 func constructTextUnmarshalerDecodeFunc(t reflect.Type, pointer bool) decodeFunc { 775 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 776 return d.decodeTextUnmarshaler(b, p, t, pointer) 777 } 778 } 779 780 func constructInlineValueEncodeFunc(encode encodeFunc) encodeFunc { 781 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 782 return encode(e, b, noescape(unsafe.Pointer(&p))) 783 } 784 } 785 786 // noescape hides a pointer from escape analysis. noescape is 787 // the identity function but escape analysis doesn't think the 788 // output depends on the input. noescape is inlined and currently 789 // compiles down to zero instructions. 790 // USE CAREFULLY! 791 // This was copied from the runtime; see issues 23382 and 7921. 792 //go:nosplit 793 func noescape(p unsafe.Pointer) unsafe.Pointer { 794 x := uintptr(p) 795 return unsafe.Pointer(x ^ 0) 796 } 797 798 func alignedSize(t reflect.Type) uintptr { 799 a := t.Align() 800 s := t.Size() 801 return align(uintptr(a), uintptr(s)) 802 } 803 804 func align(align, size uintptr) uintptr { 805 if align != 0 && (size%align) != 0 { 806 size = ((size / align) + 1) * align 807 } 808 return size 809 } 810 811 func inlined(t reflect.Type) bool { 812 switch t.Kind() { 813 case reflect.Ptr: 814 return true 815 case reflect.Map: 816 return true 817 case reflect.Struct: 818 return t.NumField() == 1 && inlined(t.Field(0).Type) 819 default: 820 return false 821 } 822 } 823 824 func isValidTag(s string) bool { 825 if s == "" { 826 return false 827 } 828 for _, c := range s { 829 switch { 830 case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): 831 // Backslash and quote chars are reserved, but 832 // otherwise any punctuation chars are allowed 833 // in a tag name. 834 default: 835 if !unicode.IsLetter(c) && !unicode.IsDigit(c) { 836 return false 837 } 838 } 839 } 840 return true 841 } 842 843 func emptyFuncOf(t reflect.Type) emptyFunc { 844 switch t { 845 case bytesType, rawMessageType: 846 return func(p unsafe.Pointer) bool { return (*slice)(p).len == 0 } 847 } 848 849 switch t.Kind() { 850 case reflect.Array: 851 if t.Len() == 0 { 852 return func(unsafe.Pointer) bool { return true } 853 } 854 855 case reflect.Map: 856 return func(p unsafe.Pointer) bool { return reflect.NewAt(t, p).Elem().Len() == 0 } 857 858 case reflect.Slice: 859 return func(p unsafe.Pointer) bool { return (*slice)(p).len == 0 } 860 861 case reflect.String: 862 return func(p unsafe.Pointer) bool { return len(*(*string)(p)) == 0 } 863 864 case reflect.Bool: 865 return func(p unsafe.Pointer) bool { return !*(*bool)(p) } 866 867 case reflect.Int, reflect.Uint: 868 return func(p unsafe.Pointer) bool { return *(*uint)(p) == 0 } 869 870 case reflect.Uintptr: 871 return func(p unsafe.Pointer) bool { return *(*uintptr)(p) == 0 } 872 873 case reflect.Int8, reflect.Uint8: 874 return func(p unsafe.Pointer) bool { return *(*uint8)(p) == 0 } 875 876 case reflect.Int16, reflect.Uint16: 877 return func(p unsafe.Pointer) bool { return *(*uint16)(p) == 0 } 878 879 case reflect.Int32, reflect.Uint32: 880 return func(p unsafe.Pointer) bool { return *(*uint32)(p) == 0 } 881 882 case reflect.Int64, reflect.Uint64: 883 return func(p unsafe.Pointer) bool { return *(*uint64)(p) == 0 } 884 885 case reflect.Float32: 886 return func(p unsafe.Pointer) bool { return *(*float32)(p) == 0 } 887 888 case reflect.Float64: 889 return func(p unsafe.Pointer) bool { return *(*float64)(p) == 0 } 890 891 case reflect.Ptr: 892 return func(p unsafe.Pointer) bool { return *(*unsafe.Pointer)(p) == nil } 893 894 case reflect.Interface: 895 return func(p unsafe.Pointer) bool { return (*iface)(p).ptr == nil } 896 } 897 898 return func(unsafe.Pointer) bool { return false } 899 } 900 901 type iface struct { 902 typ unsafe.Pointer 903 ptr unsafe.Pointer 904 } 905 906 type slice struct { 907 data unsafe.Pointer 908 len int 909 cap int 910 } 911 912 type structType struct { 913 fields []structField 914 fieldsIndex map[string]*structField 915 ficaseIndex map[string]*structField 916 typ reflect.Type 917 inlined bool 918 } 919 920 type structField struct { 921 codec codec 922 offset uintptr 923 empty emptyFunc 924 tag bool 925 omitempty bool 926 json string 927 html string 928 name string 929 typ reflect.Type 930 zero reflect.Value 931 index int 932 } 933 934 func unmarshalTypeError(b []byte, t reflect.Type) error { 935 return &UnmarshalTypeError{Value: strconv.Quote(prefix(b)), Type: t} 936 } 937 938 func unmarshalOverflow(b []byte, t reflect.Type) error { 939 return &UnmarshalTypeError{Value: "number " + prefix(b) + " overflows", Type: t} 940 } 941 942 func unexpectedEOF(b []byte) error { 943 return syntaxError(b, "unexpected end of JSON input") 944 } 945 946 var syntaxErrorMsgOffset = ^uintptr(0) 947 948 func init() { 949 t := reflect.TypeOf(SyntaxError{}) 950 for i, n := 0, t.NumField(); i < n; i++ { 951 if f := t.Field(i); f.Type.Kind() == reflect.String { 952 syntaxErrorMsgOffset = f.Offset 953 } 954 } 955 } 956 957 func syntaxError(b []byte, msg string, args ...interface{}) error { 958 e := new(SyntaxError) 959 i := syntaxErrorMsgOffset 960 if i != ^uintptr(0) { 961 s := "json: " + fmt.Sprintf(msg, args...) + ": " + prefix(b) 962 p := unsafe.Pointer(e) 963 // Hack to set the unexported `msg` field. 964 *(*string)(unsafe.Pointer(uintptr(p) + i)) = s 965 } 966 return e 967 } 968 969 func inputError(b []byte, t reflect.Type) ([]byte, error) { 970 if len(b) == 0 { 971 return nil, unexpectedEOF(b) 972 } 973 _, r, err := parseValue(b) 974 if err != nil { 975 return r, err 976 } 977 return skipSpaces(r), unmarshalTypeError(b, t) 978 } 979 980 func objectKeyError(b []byte, err error) ([]byte, error) { 981 if len(b) == 0 { 982 return nil, unexpectedEOF(b) 983 } 984 switch err.(type) { 985 case *UnmarshalTypeError: 986 err = syntaxError(b, "invalid character '%c' looking for beginning of object key", b[0]) 987 } 988 return b, err 989 } 990 991 func prefix(b []byte) string { 992 if len(b) < 32 { 993 return string(b) 994 } 995 return string(b[:32]) + "..." 996 } 997 998 func intStringsAreSorted(i0, i1 int64) bool { 999 var b0, b1 [32]byte 1000 return string(strconv.AppendInt(b0[:0], i0, 10)) < string(strconv.AppendInt(b1[:0], i1, 10)) 1001 } 1002 1003 func uintStringsAreSorted(u0, u1 uint64) bool { 1004 var b0, b1 [32]byte 1005 return string(strconv.AppendUint(b0[:0], u0, 10)) < string(strconv.AppendUint(b1[:0], u1, 10)) 1006 } 1007 1008 //go:nosplit 1009 func stringToBytes(s string) []byte { 1010 return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{ // nolint:govet // from segment's code 1011 Data: ((*reflect.StringHeader)(unsafe.Pointer(&s))).Data, 1012 Len: len(s), 1013 Cap: len(s), 1014 })) 1015 } 1016 1017 var ( 1018 nullType = reflect.TypeOf(nil) 1019 boolType = reflect.TypeOf(false) 1020 1021 intType = reflect.TypeOf(int(0)) 1022 int8Type = reflect.TypeOf(int8(0)) 1023 int16Type = reflect.TypeOf(int16(0)) 1024 int32Type = reflect.TypeOf(int32(0)) 1025 int64Type = reflect.TypeOf(int64(0)) 1026 1027 uintType = reflect.TypeOf(uint(0)) 1028 uint8Type = reflect.TypeOf(uint8(0)) 1029 uint16Type = reflect.TypeOf(uint16(0)) 1030 uint32Type = reflect.TypeOf(uint32(0)) 1031 uint64Type = reflect.TypeOf(uint64(0)) 1032 uintptrType = reflect.TypeOf(uintptr(0)) 1033 1034 float32Type = reflect.TypeOf(float32(0)) 1035 float64Type = reflect.TypeOf(float64(0)) 1036 1037 numberType = reflect.TypeOf(json.Number("")) 1038 stringType = reflect.TypeOf("") 1039 bytesType = reflect.TypeOf(([]byte)(nil)) 1040 durationType = reflect.TypeOf(time.Duration(0)) 1041 timeType = reflect.TypeOf(time.Time{}) 1042 rawMessageType = reflect.TypeOf(RawMessage(nil)) 1043 1044 numberPtrType = reflect.PtrTo(numberType) 1045 durationPtrType = reflect.PtrTo(durationType) 1046 timePtrType = reflect.PtrTo(timeType) 1047 rawMessagePtrType = reflect.PtrTo(rawMessageType) 1048 1049 sliceInterfaceType = reflect.TypeOf(([]interface{})(nil)) 1050 mapStringInterfaceType = reflect.TypeOf((map[string]interface{})(nil)) 1051 mapStringRawMessageType = reflect.TypeOf((map[string]RawMessage)(nil)) 1052 1053 interfaceType = reflect.TypeOf((*interface{})(nil)).Elem() 1054 jsonMarshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() 1055 jsonUnmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() 1056 textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() 1057 textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() 1058 ) 1059 1060 // ============================================================================= 1061 // Copyright 2009 The Go Authors. All rights reserved. 1062 // Use of this source code is governed by a BSD-style 1063 // license that can be found in the LICENSE file. 1064 1065 // appendDuration appends a human-readable representation of d to b. 1066 // 1067 // The function copies the implementation of time.Duration.String but prevents 1068 // Go from making a dynamic memory allocation on the returned value. 1069 func appendDuration(b []byte, d time.Duration) []byte { 1070 // Largest time is 2540400h10m10.000000000s 1071 var buf [32]byte 1072 w := len(buf) 1073 1074 u := uint64(d) 1075 neg := d < 0 1076 if neg { 1077 u = -u 1078 } 1079 1080 if u < uint64(time.Second) { 1081 // Special case: if duration is smaller than a second, 1082 // use smaller units, like 1.2ms 1083 var prec int 1084 w-- 1085 buf[w] = 's' 1086 w-- 1087 switch { 1088 case u == 0: 1089 return append(b, '0', 's') 1090 case u < uint64(time.Microsecond): 1091 // print nanoseconds 1092 prec = 0 1093 buf[w] = 'n' 1094 case u < uint64(time.Millisecond): 1095 // print microseconds 1096 prec = 3 1097 // U+00B5 'µ' micro sign == 0xC2 0xB5 1098 w-- // Need room for two bytes. 1099 copy(buf[w:], "µ") 1100 default: 1101 // print milliseconds 1102 prec = 6 1103 buf[w] = 'm' 1104 } 1105 w, u = fmtFrac(buf[:w], u, prec) 1106 w = fmtInt(buf[:w], u) 1107 } else { 1108 w-- 1109 buf[w] = 's' 1110 1111 w, u = fmtFrac(buf[:w], u, 9) 1112 1113 // u is now integer seconds 1114 w = fmtInt(buf[:w], u%60) 1115 u /= 60 1116 1117 // u is now integer minutes 1118 if u > 0 { 1119 w-- 1120 buf[w] = 'm' 1121 w = fmtInt(buf[:w], u%60) 1122 u /= 60 1123 1124 // u is now integer hours 1125 // Stop at hours because days can be different lengths. 1126 if u > 0 { 1127 w-- 1128 buf[w] = 'h' 1129 w = fmtInt(buf[:w], u) 1130 } 1131 } 1132 } 1133 1134 if neg { 1135 w-- 1136 buf[w] = '-' 1137 } 1138 1139 return append(b, buf[w:]...) 1140 } 1141 1142 // fmtFrac formats the fraction of v/10**prec (e.g., ".12345") into the 1143 // tail of buf, omitting trailing zeros. it omits the decimal 1144 // point too when the fraction is 0. It returns the index where the 1145 // output bytes begin and the value v/10**prec. 1146 func fmtFrac(buf []byte, v uint64, prec int) (nw int, nv uint64) { 1147 // Omit trailing zeros up to and including decimal point. 1148 w := len(buf) 1149 print := false 1150 for i := 0; i < prec; i++ { 1151 digit := v % 10 1152 print = print || digit != 0 1153 if print { 1154 w-- 1155 buf[w] = byte(digit) + '0' 1156 } 1157 v /= 10 1158 } 1159 if print { 1160 w-- 1161 buf[w] = '.' 1162 } 1163 return w, v 1164 } 1165 1166 // fmtInt formats v into the tail of buf. 1167 // It returns the index where the output begins. 1168 func fmtInt(buf []byte, v uint64) int { 1169 w := len(buf) 1170 if v == 0 { 1171 w-- 1172 buf[w] = '0' 1173 } else { 1174 for v > 0 { 1175 w-- 1176 buf[w] = byte(v%10) + '0' 1177 v /= 10 1178 } 1179 } 1180 return w 1181 } 1182 1183 // =============================================================================