feature_reflect_map.go 5.6 KB

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