feature_reflect_map.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. package jsoniter
  2. import (
  3. "encoding"
  4. "reflect"
  5. "sort"
  6. "strconv"
  7. "unsafe"
  8. "github.com/v2pro/plz/reflect2"
  9. "fmt"
  10. )
  11. func decoderOfMap(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
  12. decoder := decoderOfType(cfg, prefix+"[map]->", typ.Elem())
  13. mapInterface := reflect.New(typ).Interface()
  14. return &mapDecoder{typ, typ.Key(), typ.Elem(), decoder, extractInterface(mapInterface)}
  15. }
  16. func encoderOfMap(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
  17. if cfg.sortMapKeys {
  18. return &sortKeysMapEncoder{
  19. mapType: reflect2.Type2(typ).(*reflect2.UnsafeMapType),
  20. keyEncoder: encoderOfMapKey(cfg, prefix+" [mapKey]", typ.Key()),
  21. elemEncoder: encoderOfType(cfg, prefix+" [mapElem]", typ.Elem()),
  22. }
  23. }
  24. return &mapEncoder{
  25. mapType: reflect2.Type2(typ).(*reflect2.UnsafeMapType),
  26. keyEncoder: encoderOfMapKey(cfg, prefix+" [mapKey]", typ.Key()),
  27. elemEncoder: encoderOfType(cfg, prefix+" [mapElem]", typ.Elem()),
  28. }
  29. }
  30. func encoderOfMapKey(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
  31. switch typ.Kind() {
  32. case reflect.String:
  33. return encoderOfType(cfg, prefix, reflect2.DefaultTypeOfKind(reflect.String).Type1())
  34. case reflect.Bool,
  35. reflect.Uint8, reflect.Int8,
  36. reflect.Uint16, reflect.Int16,
  37. reflect.Uint32, reflect.Int32,
  38. reflect.Uint64, reflect.Int64,
  39. reflect.Uint, reflect.Int,
  40. reflect.Float32, reflect.Float64,
  41. reflect.Uintptr:
  42. typ = reflect2.DefaultTypeOfKind(typ.Kind()).Type1()
  43. return &numericMapKeyEncoder{encoderOfType(cfg, prefix, typ)}
  44. default:
  45. if typ == textMarshalerType {
  46. return &directTextMarshalerEncoder{
  47. stringEncoder: cfg.EncoderOf(reflect.TypeOf("")),
  48. }
  49. }
  50. if typ.Implements(textMarshalerType) {
  51. return &textMarshalerEncoder{
  52. valType: reflect2.Type2(typ),
  53. stringEncoder: cfg.EncoderOf(reflect.TypeOf("")),
  54. }
  55. }
  56. return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
  57. }
  58. }
  59. type mapDecoder struct {
  60. mapType reflect.Type
  61. keyType reflect.Type
  62. elemType reflect.Type
  63. elemDecoder ValDecoder
  64. mapInterface emptyInterface
  65. }
  66. func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  67. // dark magic to cast unsafe.Pointer back to interface{} using reflect.Type
  68. mapInterface := decoder.mapInterface
  69. mapInterface.word = ptr
  70. realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
  71. realVal := reflect.ValueOf(*realInterface).Elem()
  72. if iter.ReadNil() {
  73. realVal.Set(reflect.Zero(decoder.mapType))
  74. return
  75. }
  76. if realVal.IsNil() {
  77. realVal.Set(reflect.MakeMap(realVal.Type()))
  78. }
  79. iter.ReadMapCB(func(iter *Iterator, keyStr string) bool {
  80. elem := reflect.New(decoder.elemType)
  81. decoder.elemDecoder.Decode(extractInterface(elem.Interface()).word, iter)
  82. // to put into map, we have to use reflection
  83. keyType := decoder.keyType
  84. // TODO: remove this from loop
  85. switch {
  86. case keyType.Kind() == reflect.String:
  87. realVal.SetMapIndex(reflect.ValueOf(keyStr).Convert(keyType), elem.Elem())
  88. return true
  89. case keyType.Implements(textUnmarshalerType):
  90. textUnmarshaler := reflect.New(keyType.Elem()).Interface().(encoding.TextUnmarshaler)
  91. err := textUnmarshaler.UnmarshalText([]byte(keyStr))
  92. if err != nil {
  93. iter.ReportError("read map key as TextUnmarshaler", err.Error())
  94. return false
  95. }
  96. realVal.SetMapIndex(reflect.ValueOf(textUnmarshaler), elem.Elem())
  97. return true
  98. case reflect.PtrTo(keyType).Implements(textUnmarshalerType):
  99. textUnmarshaler := reflect.New(keyType).Interface().(encoding.TextUnmarshaler)
  100. err := textUnmarshaler.UnmarshalText([]byte(keyStr))
  101. if err != nil {
  102. iter.ReportError("read map key as TextUnmarshaler", err.Error())
  103. return false
  104. }
  105. realVal.SetMapIndex(reflect.ValueOf(textUnmarshaler).Elem(), elem.Elem())
  106. return true
  107. default:
  108. switch keyType.Kind() {
  109. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  110. n, err := strconv.ParseInt(keyStr, 10, 64)
  111. if err != nil || reflect.Zero(keyType).OverflowInt(n) {
  112. iter.ReportError("read map key as int64", "read int64 failed")
  113. return false
  114. }
  115. realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem())
  116. return true
  117. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  118. n, err := strconv.ParseUint(keyStr, 10, 64)
  119. if err != nil || reflect.Zero(keyType).OverflowUint(n) {
  120. iter.ReportError("read map key as uint64", "read uint64 failed")
  121. return false
  122. }
  123. realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem())
  124. return true
  125. }
  126. }
  127. iter.ReportError("read map key", "unexpected map key type "+keyType.String())
  128. return true
  129. })
  130. }
  131. type numericMapKeyEncoder struct {
  132. encoder ValEncoder
  133. }
  134. func (encoder *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  135. stream.writeByte('"')
  136. encoder.encoder.Encode(ptr, stream)
  137. stream.writeByte('"')
  138. }
  139. func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  140. return false
  141. }
  142. type mapEncoder struct {
  143. mapType *reflect2.UnsafeMapType
  144. keyEncoder ValEncoder
  145. elemEncoder ValEncoder
  146. }
  147. func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  148. stream.WriteObjectStart()
  149. iter := encoder.mapType.UnsafeIterate(ptr)
  150. for i := 0; iter.HasNext(); i++ {
  151. if i != 0 {
  152. stream.WriteMore()
  153. }
  154. key, elem := iter.UnsafeNext()
  155. encoder.keyEncoder.Encode(key, stream)
  156. if stream.indention > 0 {
  157. stream.writeTwoBytes(byte(':'), byte(' '))
  158. } else {
  159. stream.writeByte(':')
  160. }
  161. encoder.elemEncoder.Encode(elem, stream)
  162. }
  163. stream.WriteObjectEnd()
  164. }
  165. func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  166. iter := encoder.mapType.UnsafeIterate(ptr)
  167. return !iter.HasNext()
  168. }
  169. type sortKeysMapEncoder struct {
  170. mapType *reflect2.UnsafeMapType
  171. keyEncoder ValEncoder
  172. elemEncoder ValEncoder
  173. }
  174. func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  175. if *(*unsafe.Pointer)(ptr) == nil {
  176. stream.WriteNil()
  177. return
  178. }
  179. stream.WriteObjectStart()
  180. mapIter := encoder.mapType.UnsafeIterate(ptr)
  181. subStream := stream.cfg.BorrowStream(nil)
  182. subIter := stream.cfg.BorrowIterator(nil)
  183. keyValues := encodedKeyValues{}
  184. for mapIter.HasNext() {
  185. subStream.buf = make([]byte, 0, 64)
  186. key, elem := mapIter.UnsafeNext()
  187. encoder.keyEncoder.Encode(key, subStream)
  188. encodedKey := subStream.Buffer()
  189. subIter.ResetBytes(encodedKey)
  190. decodedKey := subIter.ReadString()
  191. if stream.indention > 0 {
  192. subStream.writeTwoBytes(byte(':'), byte(' '))
  193. } else {
  194. subStream.writeByte(':')
  195. }
  196. encoder.elemEncoder.Encode(elem, subStream)
  197. keyValues = append(keyValues, encodedKV{
  198. key: decodedKey,
  199. keyValue: subStream.Buffer(),
  200. })
  201. }
  202. sort.Sort(keyValues)
  203. for i, keyValue := range keyValues {
  204. if i != 0 {
  205. stream.WriteMore()
  206. }
  207. stream.Write(keyValue.keyValue)
  208. }
  209. stream.WriteObjectEnd()
  210. stream.cfg.ReturnStream(subStream)
  211. stream.cfg.ReturnIterator(subIter)
  212. }
  213. func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  214. iter := encoder.mapType.UnsafeIterate(ptr)
  215. return !iter.HasNext()
  216. }
  217. type encodedKeyValues []encodedKV
  218. type encodedKV struct {
  219. key string
  220. keyValue []byte
  221. }
  222. func (sv encodedKeyValues) Len() int { return len(sv) }
  223. func (sv encodedKeyValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
  224. func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key }