jsoniter_reflect.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package jsoniter
  2. import (
  3. "reflect"
  4. "errors"
  5. "fmt"
  6. "unsafe"
  7. "sync/atomic"
  8. )
  9. type Decoder interface {
  10. decode(ptr unsafe.Pointer, iter *Iterator)
  11. }
  12. type stringDecoder struct {
  13. }
  14. func (decoder *stringDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
  15. *((*string)(ptr)) = iter.ReadString()
  16. }
  17. type structDecoder struct {
  18. fields map[string]Decoder
  19. }
  20. func (decoder *structDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
  21. for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
  22. fieldDecoder := decoder.fields[field]
  23. if fieldDecoder == nil {
  24. iter.Skip()
  25. } else {
  26. fieldDecoder.decode(ptr, iter)
  27. }
  28. }
  29. }
  30. type structFieldDecoder struct {
  31. offset uintptr
  32. fieldDecoder Decoder
  33. }
  34. func (decoder *structFieldDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
  35. fieldPtr := uintptr(ptr) + decoder.offset
  36. decoder.fieldDecoder.decode(unsafe.Pointer(fieldPtr), iter)
  37. }
  38. var DECODER_STRING *stringDecoder
  39. var DECODERS_STRUCT unsafe.Pointer
  40. func init() {
  41. DECODER_STRING = &stringDecoder{}
  42. atomic.StorePointer(&DECODERS_STRUCT, unsafe.Pointer(&map[string]*structDecoder{}))
  43. }
  44. // emptyInterface is the header for an interface{} value.
  45. type emptyInterface struct {
  46. typ *struct{}
  47. word unsafe.Pointer
  48. }
  49. func (iter *Iterator) Read(obj interface{}) {
  50. type_ := reflect.TypeOf(obj)
  51. decoder, err := decoderOfType(type_)
  52. if err != nil {
  53. iter.Error = err
  54. return
  55. }
  56. e := (*emptyInterface)(unsafe.Pointer(&obj))
  57. decoder.decode(e.word, iter)
  58. }
  59. type prefix string
  60. func (p prefix) addTo(decoder Decoder, err error) (Decoder, error) {
  61. if err != nil {
  62. return nil, fmt.Errorf("%s: %s", p, err.Error())
  63. }
  64. return decoder, err
  65. }
  66. func decoderOfType(type_ reflect.Type) (Decoder, error) {
  67. switch type_.Kind() {
  68. case reflect.Ptr:
  69. return prefix("ptr").addTo(decoderOfPtr(type_.Elem()))
  70. default:
  71. return nil, errors.New("expect ptr")
  72. }
  73. }
  74. func decoderOfPtr(type_ reflect.Type) (Decoder, error) {
  75. switch type_.Kind() {
  76. case reflect.String:
  77. return DECODER_STRING, nil
  78. case reflect.Struct:
  79. return decoderOfStruct(type_)
  80. default:
  81. return nil, errors.New("expect string")
  82. }
  83. }
  84. func decoderOfStruct(type_ reflect.Type) (Decoder, error) {
  85. cacheKey := type_.String()
  86. cachedDecoder := getStructDecoderFromCache(cacheKey)
  87. if cachedDecoder == nil {
  88. fields := map[string]Decoder{}
  89. for i := 0; i < type_.NumField(); i++ {
  90. field := type_.Field(i)
  91. decoder, err := decoderOfPtr(field.Type)
  92. if err != nil {
  93. return prefix(fmt.Sprintf("[%s]", field.Name)).addTo(decoder, err)
  94. }
  95. fields[field.Name] = &structFieldDecoder{field.Offset, decoder}
  96. }
  97. cachedDecoder = &structDecoder{fields}
  98. addStructDecoderToCache(cacheKey, cachedDecoder)
  99. }
  100. return cachedDecoder, nil
  101. }
  102. func addStructDecoderToCache(cacheKey string, decoder *structDecoder) {
  103. retry := true
  104. for retry {
  105. ptr := atomic.LoadPointer(&DECODERS_STRUCT)
  106. cache := *(*map[string]*structDecoder)(ptr)
  107. copy := map[string]*structDecoder{}
  108. for k, v := range cache {
  109. copy[k] = v
  110. }
  111. copy[cacheKey] = decoder
  112. retry = !atomic.CompareAndSwapPointer(&DECODERS_STRUCT, ptr, unsafe.Pointer(&copy))
  113. }
  114. }
  115. func getStructDecoderFromCache(cacheKey string) *structDecoder {
  116. ptr := atomic.LoadPointer(&DECODERS_STRUCT)
  117. cache := *(*map[string]*structDecoder)(ptr)
  118. return cache[cacheKey]
  119. }