feature_reflect_map.go 5.7 KB

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