feature_reflect_map.go 7.1 KB

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