feature_reflect_map.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. package jsoniter
  2. import (
  3. "encoding"
  4. "encoding/json"
  5. "reflect"
  6. "sort"
  7. "strconv"
  8. "unsafe"
  9. )
  10. func decoderOfMap(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
  11. decoder := decoderOfType(cfg, prefix+"[map]->", typ.Elem())
  12. mapInterface := reflect.New(typ).Interface()
  13. return &mapDecoder{typ, typ.Key(), typ.Elem(), decoder, extractInterface(mapInterface)}
  14. }
  15. func encoderOfMap(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
  16. elemType := typ.Elem()
  17. encoder := encoderOfType(cfg, prefix+"[map]->", elemType)
  18. mapInterface := reflect.New(typ).Elem().Interface()
  19. if cfg.sortMapKeys {
  20. return &sortKeysMapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}
  21. }
  22. return &mapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}
  23. }
  24. type mapDecoder struct {
  25. mapType reflect.Type
  26. keyType reflect.Type
  27. elemType reflect.Type
  28. elemDecoder ValDecoder
  29. mapInterface emptyInterface
  30. }
  31. func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  32. // dark magic to cast unsafe.Pointer back to interface{} using reflect.Type
  33. mapInterface := decoder.mapInterface
  34. mapInterface.word = ptr
  35. realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
  36. realVal := reflect.ValueOf(*realInterface).Elem()
  37. if iter.ReadNil() {
  38. realVal.Set(reflect.Zero(decoder.mapType))
  39. return
  40. }
  41. if realVal.IsNil() {
  42. realVal.Set(reflect.MakeMap(realVal.Type()))
  43. }
  44. iter.ReadMapCB(func(iter *Iterator, keyStr string) bool {
  45. elem := reflect.New(decoder.elemType)
  46. decoder.elemDecoder.Decode(extractInterface(elem.Interface()).word, iter)
  47. // to put into map, we have to use reflection
  48. keyType := decoder.keyType
  49. // TODO: remove this from loop
  50. switch {
  51. case keyType.Kind() == reflect.String:
  52. realVal.SetMapIndex(reflect.ValueOf(keyStr).Convert(keyType), elem.Elem())
  53. return true
  54. case keyType.Implements(textUnmarshalerType):
  55. textUnmarshaler := reflect.New(keyType.Elem()).Interface().(encoding.TextUnmarshaler)
  56. err := textUnmarshaler.UnmarshalText([]byte(keyStr))
  57. if err != nil {
  58. iter.ReportError("read map key as TextUnmarshaler", err.Error())
  59. return false
  60. }
  61. realVal.SetMapIndex(reflect.ValueOf(textUnmarshaler), elem.Elem())
  62. return true
  63. case reflect.PtrTo(keyType).Implements(textUnmarshalerType):
  64. textUnmarshaler := reflect.New(keyType).Interface().(encoding.TextUnmarshaler)
  65. err := textUnmarshaler.UnmarshalText([]byte(keyStr))
  66. if err != nil {
  67. iter.ReportError("read map key as TextUnmarshaler", err.Error())
  68. return false
  69. }
  70. realVal.SetMapIndex(reflect.ValueOf(textUnmarshaler).Elem(), elem.Elem())
  71. return true
  72. default:
  73. switch keyType.Kind() {
  74. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  75. n, err := strconv.ParseInt(keyStr, 10, 64)
  76. if err != nil || reflect.Zero(keyType).OverflowInt(n) {
  77. iter.ReportError("read map key as int64", "read int64 failed")
  78. return false
  79. }
  80. realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem())
  81. return true
  82. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  83. n, err := strconv.ParseUint(keyStr, 10, 64)
  84. if err != nil || reflect.Zero(keyType).OverflowUint(n) {
  85. iter.ReportError("read map key as uint64", "read uint64 failed")
  86. return false
  87. }
  88. realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem())
  89. return true
  90. }
  91. }
  92. iter.ReportError("read map key", "unexpected map key type "+keyType.String())
  93. return true
  94. })
  95. }
  96. type mapEncoder struct {
  97. mapType reflect.Type
  98. elemType reflect.Type
  99. elemEncoder ValEncoder
  100. mapInterface emptyInterface
  101. }
  102. func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  103. mapInterface := encoder.mapInterface
  104. mapInterface.word = ptr
  105. realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
  106. realVal := reflect.ValueOf(*realInterface)
  107. stream.WriteObjectStart()
  108. for i, key := range realVal.MapKeys() {
  109. if i != 0 {
  110. stream.WriteMore()
  111. }
  112. encodeMapKey(key, stream)
  113. if stream.indention > 0 {
  114. stream.writeTwoBytes(byte(':'), byte(' '))
  115. } else {
  116. stream.writeByte(':')
  117. }
  118. val := realVal.MapIndex(key).Interface()
  119. encoder.elemEncoder.EncodeInterface(val, stream)
  120. }
  121. stream.WriteObjectEnd()
  122. }
  123. func encodeMapKey(key reflect.Value, stream *Stream) {
  124. if key.Kind() == reflect.String {
  125. stream.WriteString(key.String())
  126. return
  127. }
  128. if tm, ok := key.Interface().(encoding.TextMarshaler); ok {
  129. buf, err := tm.MarshalText()
  130. if err != nil {
  131. stream.Error = err
  132. return
  133. }
  134. stream.writeByte('"')
  135. stream.Write(buf)
  136. stream.writeByte('"')
  137. return
  138. }
  139. switch key.Kind() {
  140. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  141. stream.writeByte('"')
  142. stream.WriteInt64(key.Int())
  143. stream.writeByte('"')
  144. return
  145. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  146. stream.writeByte('"')
  147. stream.WriteUint64(key.Uint())
  148. stream.writeByte('"')
  149. return
  150. }
  151. stream.Error = &json.UnsupportedTypeError{Type: key.Type()}
  152. }
  153. func (encoder *mapEncoder) EncodeInterface(val interface{}, stream *Stream) {
  154. WriteToStream(val, stream, encoder)
  155. }
  156. func (encoder *mapEncoder) 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. }
  163. type sortKeysMapEncoder struct {
  164. mapType reflect.Type
  165. elemType reflect.Type
  166. elemEncoder ValEncoder
  167. mapInterface emptyInterface
  168. }
  169. func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  170. mapInterface := encoder.mapInterface
  171. mapInterface.word = ptr
  172. realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
  173. realVal := reflect.ValueOf(*realInterface)
  174. // Extract and sort the keys.
  175. keys := realVal.MapKeys()
  176. sv := stringValues(make([]reflectWithString, len(keys)))
  177. for i, v := range keys {
  178. sv[i].v = v
  179. if err := sv[i].resolve(); err != nil {
  180. stream.Error = err
  181. return
  182. }
  183. }
  184. sort.Sort(sv)
  185. stream.WriteObjectStart()
  186. for i, key := range sv {
  187. if i != 0 {
  188. stream.WriteMore()
  189. }
  190. stream.WriteVal(key.s) // might need html escape, so can not WriteString directly
  191. if stream.indention > 0 {
  192. stream.writeTwoBytes(byte(':'), byte(' '))
  193. } else {
  194. stream.writeByte(':')
  195. }
  196. val := realVal.MapIndex(key.v).Interface()
  197. encoder.elemEncoder.EncodeInterface(val, stream)
  198. }
  199. stream.WriteObjectEnd()
  200. }
  201. // stringValues is a slice of reflect.Value holding *reflect.StringValue.
  202. // It implements the methods to sort by string.
  203. type stringValues []reflectWithString
  204. type reflectWithString struct {
  205. v reflect.Value
  206. s string
  207. }
  208. func (w *reflectWithString) resolve() error {
  209. if w.v.Kind() == reflect.String {
  210. w.s = w.v.String()
  211. return nil
  212. }
  213. if tm, ok := w.v.Interface().(encoding.TextMarshaler); ok {
  214. buf, err := tm.MarshalText()
  215. w.s = string(buf)
  216. return err
  217. }
  218. switch w.v.Kind() {
  219. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  220. w.s = strconv.FormatInt(w.v.Int(), 10)
  221. return nil
  222. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  223. w.s = strconv.FormatUint(w.v.Uint(), 10)
  224. return nil
  225. }
  226. return &json.UnsupportedTypeError{Type: w.v.Type()}
  227. }
  228. func (sv stringValues) Len() int { return len(sv) }
  229. func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
  230. func (sv stringValues) Less(i, j int) bool { return sv[i].s < sv[j].s }
  231. func (encoder *sortKeysMapEncoder) EncodeInterface(val interface{}, stream *Stream) {
  232. WriteToStream(val, stream, encoder)
  233. }
  234. func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  235. mapInterface := encoder.mapInterface
  236. mapInterface.word = ptr
  237. realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
  238. realVal := reflect.ValueOf(*realInterface)
  239. return realVal.Len() == 0
  240. }