feature_reflect_map.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package jsoniter
  2. import (
  3. "unsafe"
  4. "reflect"
  5. "encoding/json"
  6. "encoding"
  7. "strconv"
  8. )
  9. type mapDecoder struct {
  10. mapType reflect.Type
  11. keyType reflect.Type
  12. elemType reflect.Type
  13. elemDecoder Decoder
  14. mapInterface emptyInterface
  15. }
  16. func (decoder *mapDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
  17. // dark magic to cast unsafe.Pointer back to interface{} using reflect.Type
  18. mapInterface := decoder.mapInterface
  19. mapInterface.word = ptr
  20. realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
  21. realVal := reflect.ValueOf(*realInterface).Elem()
  22. if realVal.IsNil() {
  23. realVal.Set(reflect.MakeMap(realVal.Type()))
  24. }
  25. iter.ReadObjectCB(func(iter *Iterator, keyStr string) bool{
  26. elem := reflect.New(decoder.elemType)
  27. decoder.elemDecoder.decode(unsafe.Pointer(elem.Pointer()), iter)
  28. // to put into map, we have to use reflection
  29. realVal.SetMapIndex(decodeMapKey(iter, keyStr, decoder.keyType), elem.Elem())
  30. return true
  31. })
  32. }
  33. func decodeMapKey(iter *Iterator, keyStr string, keyType reflect.Type) reflect.Value {
  34. switch {
  35. case keyType.Kind() == reflect.String:
  36. return reflect.ValueOf(keyStr)
  37. //case reflect.PtrTo(kt).Implements(textUnmarshalerType):
  38. // kv = reflect.New(v.Type().Key())
  39. // d.literalStore(item, kv, true)
  40. // kv = kv.Elem()
  41. default:
  42. switch keyType.Kind() {
  43. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  44. n, err := strconv.ParseInt(keyStr, 10, 64)
  45. if err != nil || reflect.Zero(keyType).OverflowInt(n) {
  46. iter.reportError("read map key as int64", "read int64 failed")
  47. return reflect.ValueOf("")
  48. }
  49. return reflect.ValueOf(n).Convert(keyType)
  50. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  51. n, err := strconv.ParseUint(keyStr, 10, 64)
  52. if err != nil || reflect.Zero(keyType).OverflowUint(n) {
  53. iter.reportError("read map key as uint64", "read uint64 failed")
  54. return reflect.ValueOf("")
  55. }
  56. return reflect.ValueOf(n).Convert(keyType)
  57. }
  58. }
  59. iter.reportError("read map key", "json: Unexpected key type")
  60. return reflect.ValueOf("")
  61. }
  62. type mapEncoder struct {
  63. mapType reflect.Type
  64. elemType reflect.Type
  65. elemEncoder Encoder
  66. mapInterface emptyInterface
  67. }
  68. func (encoder *mapEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
  69. mapInterface := encoder.mapInterface
  70. mapInterface.word = ptr
  71. realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
  72. realVal := reflect.ValueOf(*realInterface)
  73. stream.WriteObjectStart()
  74. for i, key := range realVal.MapKeys() {
  75. if i != 0 {
  76. stream.WriteMore()
  77. }
  78. encodeMapKey(key, stream)
  79. stream.writeByte(':')
  80. val := realVal.MapIndex(key).Interface()
  81. encoder.elemEncoder.encodeInterface(val, stream)
  82. }
  83. stream.WriteObjectEnd()
  84. }
  85. func encodeMapKey(key reflect.Value, stream *Stream) {
  86. if key.Kind() == reflect.String {
  87. stream.WriteString(key.String())
  88. return
  89. }
  90. if tm, ok := key.Interface().(encoding.TextMarshaler); ok {
  91. buf, err := tm.MarshalText()
  92. if err != nil {
  93. stream.Error = err
  94. return
  95. }
  96. stream.writeByte('"')
  97. stream.Write(buf)
  98. stream.writeByte('"')
  99. return
  100. }
  101. switch key.Kind() {
  102. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  103. stream.writeByte('"')
  104. stream.WriteInt64(key.Int())
  105. stream.writeByte('"')
  106. return
  107. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  108. stream.writeByte('"')
  109. stream.WriteUint64(key.Uint())
  110. stream.writeByte('"')
  111. return
  112. }
  113. stream.Error = &json.UnsupportedTypeError{key.Type()}
  114. }
  115. func (encoder *mapEncoder) encodeInterface(val interface{}, stream *Stream) {
  116. writeToStream(val, stream, encoder)
  117. }
  118. func (encoder *mapEncoder) isEmpty(ptr unsafe.Pointer) bool {
  119. mapInterface := encoder.mapInterface
  120. mapInterface.word = ptr
  121. realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
  122. realVal := reflect.ValueOf(*realInterface)
  123. return realVal.Len() == 0
  124. }
  125. type mapInterfaceEncoder struct {
  126. mapType reflect.Type
  127. elemType reflect.Type
  128. elemEncoder Encoder
  129. mapInterface emptyInterface
  130. }
  131. func (encoder *mapInterfaceEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
  132. mapInterface := encoder.mapInterface
  133. mapInterface.word = ptr
  134. realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
  135. realVal := reflect.ValueOf(*realInterface)
  136. stream.WriteObjectStart()
  137. for i, key := range realVal.MapKeys() {
  138. if i != 0 {
  139. stream.WriteMore()
  140. }
  141. switch key.Interface().(type) {
  142. case string:
  143. stream.WriteObjectField(key.String())
  144. default:
  145. stream.Error = &json.UnsupportedTypeError{key.Type()}
  146. return
  147. }
  148. val := realVal.MapIndex(key).Interface()
  149. encoder.elemEncoder.encode(unsafe.Pointer(&val), stream)
  150. }
  151. stream.WriteObjectEnd()
  152. }
  153. func (encoder *mapInterfaceEncoder) encodeInterface(val interface{}, stream *Stream) {
  154. writeToStream(val, stream, encoder)
  155. }
  156. func (encoder *mapInterfaceEncoder) isEmpty(ptr unsafe.Pointer) bool {
  157. mapInterface := encoder.mapInterface
  158. mapInterface.word = ptr
  159. realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
  160. realVal := reflect.ValueOf(*realInterface)
  161. return realVal.Len() == 0
  162. }