json_parser.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. package responses
  2. import (
  3. "encoding/json"
  4. "io"
  5. "math"
  6. "strconv"
  7. "strings"
  8. "sync"
  9. "unsafe"
  10. "github.com/json-iterator/go"
  11. )
  12. const maxUint = ^uint(0)
  13. const maxInt = int(maxUint >> 1)
  14. const minInt = -maxInt - 1
  15. var jsonParser jsoniter.API
  16. var initJson = &sync.Once{}
  17. func initJsonParserOnce() {
  18. initJson.Do(func() {
  19. registerBetterFuzzyDecoder()
  20. jsonParser = jsoniter.ConfigCompatibleWithStandardLibrary
  21. })
  22. }
  23. func registerBetterFuzzyDecoder() {
  24. jsoniter.RegisterTypeDecoder("string", &nullableFuzzyStringDecoder{})
  25. jsoniter.RegisterTypeDecoder("bool", &fuzzyBoolDecoder{})
  26. jsoniter.RegisterTypeDecoder("float32", &nullableFuzzyFloat32Decoder{})
  27. jsoniter.RegisterTypeDecoder("float64", &nullableFuzzyFloat64Decoder{})
  28. jsoniter.RegisterTypeDecoder("int", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  29. if isFloat {
  30. val := iter.ReadFloat64()
  31. if val > float64(maxInt) || val < float64(minInt) {
  32. iter.ReportError("fuzzy decode int", "exceed range")
  33. return
  34. }
  35. *((*int)(ptr)) = int(val)
  36. } else {
  37. *((*int)(ptr)) = iter.ReadInt()
  38. }
  39. }})
  40. jsoniter.RegisterTypeDecoder("uint", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  41. if isFloat {
  42. val := iter.ReadFloat64()
  43. if val > float64(maxUint) || val < 0 {
  44. iter.ReportError("fuzzy decode uint", "exceed range")
  45. return
  46. }
  47. *((*uint)(ptr)) = uint(val)
  48. } else {
  49. *((*uint)(ptr)) = iter.ReadUint()
  50. }
  51. }})
  52. jsoniter.RegisterTypeDecoder("int8", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  53. if isFloat {
  54. val := iter.ReadFloat64()
  55. if val > float64(math.MaxInt8) || val < float64(math.MinInt8) {
  56. iter.ReportError("fuzzy decode int8", "exceed range")
  57. return
  58. }
  59. *((*int8)(ptr)) = int8(val)
  60. } else {
  61. *((*int8)(ptr)) = iter.ReadInt8()
  62. }
  63. }})
  64. jsoniter.RegisterTypeDecoder("uint8", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  65. if isFloat {
  66. val := iter.ReadFloat64()
  67. if val > float64(math.MaxUint8) || val < 0 {
  68. iter.ReportError("fuzzy decode uint8", "exceed range")
  69. return
  70. }
  71. *((*uint8)(ptr)) = uint8(val)
  72. } else {
  73. *((*uint8)(ptr)) = iter.ReadUint8()
  74. }
  75. }})
  76. jsoniter.RegisterTypeDecoder("int16", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  77. if isFloat {
  78. val := iter.ReadFloat64()
  79. if val > float64(math.MaxInt16) || val < float64(math.MinInt16) {
  80. iter.ReportError("fuzzy decode int16", "exceed range")
  81. return
  82. }
  83. *((*int16)(ptr)) = int16(val)
  84. } else {
  85. *((*int16)(ptr)) = iter.ReadInt16()
  86. }
  87. }})
  88. jsoniter.RegisterTypeDecoder("uint16", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  89. if isFloat {
  90. val := iter.ReadFloat64()
  91. if val > float64(math.MaxUint16) || val < 0 {
  92. iter.ReportError("fuzzy decode uint16", "exceed range")
  93. return
  94. }
  95. *((*uint16)(ptr)) = uint16(val)
  96. } else {
  97. *((*uint16)(ptr)) = iter.ReadUint16()
  98. }
  99. }})
  100. jsoniter.RegisterTypeDecoder("int32", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  101. if isFloat {
  102. val := iter.ReadFloat64()
  103. if val > float64(math.MaxInt32) || val < float64(math.MinInt32) {
  104. iter.ReportError("fuzzy decode int32", "exceed range")
  105. return
  106. }
  107. *((*int32)(ptr)) = int32(val)
  108. } else {
  109. *((*int32)(ptr)) = iter.ReadInt32()
  110. }
  111. }})
  112. jsoniter.RegisterTypeDecoder("uint32", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  113. if isFloat {
  114. val := iter.ReadFloat64()
  115. if val > float64(math.MaxUint32) || val < 0 {
  116. iter.ReportError("fuzzy decode uint32", "exceed range")
  117. return
  118. }
  119. *((*uint32)(ptr)) = uint32(val)
  120. } else {
  121. *((*uint32)(ptr)) = iter.ReadUint32()
  122. }
  123. }})
  124. jsoniter.RegisterTypeDecoder("int64", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  125. if isFloat {
  126. val := iter.ReadFloat64()
  127. if val > float64(math.MaxInt64) || val < float64(math.MinInt64) {
  128. iter.ReportError("fuzzy decode int64", "exceed range")
  129. return
  130. }
  131. *((*int64)(ptr)) = int64(val)
  132. } else {
  133. *((*int64)(ptr)) = iter.ReadInt64()
  134. }
  135. }})
  136. jsoniter.RegisterTypeDecoder("uint64", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  137. if isFloat {
  138. val := iter.ReadFloat64()
  139. if val > float64(math.MaxUint64) || val < 0 {
  140. iter.ReportError("fuzzy decode uint64", "exceed range")
  141. return
  142. }
  143. *((*uint64)(ptr)) = uint64(val)
  144. } else {
  145. *((*uint64)(ptr)) = iter.ReadUint64()
  146. }
  147. }})
  148. }
  149. type nullableFuzzyStringDecoder struct {
  150. }
  151. func (decoder *nullableFuzzyStringDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  152. valueType := iter.WhatIsNext()
  153. switch valueType {
  154. case jsoniter.NumberValue:
  155. var number json.Number
  156. iter.ReadVal(&number)
  157. *((*string)(ptr)) = string(number)
  158. case jsoniter.StringValue:
  159. *((*string)(ptr)) = iter.ReadString()
  160. case jsoniter.BoolValue:
  161. *((*string)(ptr)) = strconv.FormatBool(iter.ReadBool())
  162. case jsoniter.NilValue:
  163. iter.ReadNil()
  164. *((*string)(ptr)) = ""
  165. default:
  166. iter.ReportError("fuzzyStringDecoder", "not number or string or bool")
  167. }
  168. }
  169. type fuzzyBoolDecoder struct {
  170. }
  171. func (decoder *fuzzyBoolDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  172. valueType := iter.WhatIsNext()
  173. switch valueType {
  174. case jsoniter.BoolValue:
  175. *((*bool)(ptr)) = iter.ReadBool()
  176. case jsoniter.NumberValue:
  177. var number json.Number
  178. iter.ReadVal(&number)
  179. num, err := number.Int64()
  180. if err != nil {
  181. iter.ReportError("fuzzyBoolDecoder", "get value from json.number failed")
  182. }
  183. if num == 0 {
  184. *((*bool)(ptr)) = false
  185. } else {
  186. *((*bool)(ptr)) = true
  187. }
  188. case jsoniter.StringValue:
  189. strValue := strings.ToLower(iter.ReadString())
  190. if strValue == "true" {
  191. *((*bool)(ptr)) = true
  192. } else if strValue == "false" || strValue == "" {
  193. *((*bool)(ptr)) = false
  194. } else {
  195. iter.ReportError("fuzzyBoolDecoder", "unsupported bool value: "+strValue)
  196. }
  197. case jsoniter.NilValue:
  198. iter.ReadNil()
  199. *((*bool)(ptr)) = false
  200. default:
  201. iter.ReportError("fuzzyBoolDecoder", "not number or string or nil")
  202. }
  203. }
  204. type nullableFuzzyIntegerDecoder struct {
  205. fun func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator)
  206. }
  207. func (decoder *nullableFuzzyIntegerDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  208. valueType := iter.WhatIsNext()
  209. var str string
  210. switch valueType {
  211. case jsoniter.NumberValue:
  212. var number json.Number
  213. iter.ReadVal(&number)
  214. str = string(number)
  215. case jsoniter.StringValue:
  216. str = iter.ReadString()
  217. // support empty string
  218. if str == "" {
  219. str = "0"
  220. }
  221. case jsoniter.BoolValue:
  222. if iter.ReadBool() {
  223. str = "1"
  224. } else {
  225. str = "0"
  226. }
  227. case jsoniter.NilValue:
  228. iter.ReadNil()
  229. str = "0"
  230. default:
  231. iter.ReportError("fuzzyIntegerDecoder", "not number or string")
  232. }
  233. newIter := iter.Pool().BorrowIterator([]byte(str))
  234. defer iter.Pool().ReturnIterator(newIter)
  235. isFloat := strings.IndexByte(str, '.') != -1
  236. decoder.fun(isFloat, ptr, newIter)
  237. if newIter.Error != nil && newIter.Error != io.EOF {
  238. iter.Error = newIter.Error
  239. }
  240. }
  241. type nullableFuzzyFloat32Decoder struct {
  242. }
  243. func (decoder *nullableFuzzyFloat32Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  244. valueType := iter.WhatIsNext()
  245. var str string
  246. switch valueType {
  247. case jsoniter.NumberValue:
  248. *((*float32)(ptr)) = iter.ReadFloat32()
  249. case jsoniter.StringValue:
  250. str = iter.ReadString()
  251. // support empty string
  252. if str == "" {
  253. *((*float32)(ptr)) = 0
  254. return
  255. }
  256. newIter := iter.Pool().BorrowIterator([]byte(str))
  257. defer iter.Pool().ReturnIterator(newIter)
  258. *((*float32)(ptr)) = newIter.ReadFloat32()
  259. if newIter.Error != nil && newIter.Error != io.EOF {
  260. iter.Error = newIter.Error
  261. }
  262. case jsoniter.BoolValue:
  263. // support bool to float32
  264. if iter.ReadBool() {
  265. *((*float32)(ptr)) = 1
  266. } else {
  267. *((*float32)(ptr)) = 0
  268. }
  269. case jsoniter.NilValue:
  270. iter.ReadNil()
  271. *((*float32)(ptr)) = 0
  272. default:
  273. iter.ReportError("nullableFuzzyFloat32Decoder", "not number or string")
  274. }
  275. }
  276. type nullableFuzzyFloat64Decoder struct {
  277. }
  278. func (decoder *nullableFuzzyFloat64Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  279. valueType := iter.WhatIsNext()
  280. var str string
  281. switch valueType {
  282. case jsoniter.NumberValue:
  283. *((*float64)(ptr)) = iter.ReadFloat64()
  284. case jsoniter.StringValue:
  285. str = iter.ReadString()
  286. // support empty string
  287. if str == "" {
  288. *((*float64)(ptr)) = 0
  289. return
  290. }
  291. newIter := iter.Pool().BorrowIterator([]byte(str))
  292. defer iter.Pool().ReturnIterator(newIter)
  293. *((*float64)(ptr)) = newIter.ReadFloat64()
  294. if newIter.Error != nil && newIter.Error != io.EOF {
  295. iter.Error = newIter.Error
  296. }
  297. case jsoniter.BoolValue:
  298. // support bool to float64
  299. if iter.ReadBool() {
  300. *((*float64)(ptr)) = 1
  301. } else {
  302. *((*float64)(ptr)) = 0
  303. }
  304. case jsoniter.NilValue:
  305. // support empty string
  306. iter.ReadNil()
  307. *((*float64)(ptr)) = 0
  308. default:
  309. iter.ReportError("nullableFuzzyFloat64Decoder", "not number or string")
  310. }
  311. }