json_parser.go 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. package responses
  2. import (
  3. "encoding/json"
  4. "github.com/json-iterator/go"
  5. "io"
  6. "math"
  7. "strconv"
  8. "strings"
  9. "sync"
  10. "unsafe"
  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 tolerateEmptyArrayDecoder struct {
  205. valDecoder jsoniter.ValDecoder
  206. }
  207. func (decoder *tolerateEmptyArrayDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  208. if iter.WhatIsNext() == jsoniter.ArrayValue {
  209. iter.Skip()
  210. newIter := iter.Pool().BorrowIterator([]byte("{}"))
  211. defer iter.Pool().ReturnIterator(newIter)
  212. decoder.valDecoder.Decode(ptr, newIter)
  213. } else {
  214. decoder.valDecoder.Decode(ptr, iter)
  215. }
  216. }
  217. type nullableFuzzyIntegerDecoder struct {
  218. fun func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator)
  219. }
  220. func (decoder *nullableFuzzyIntegerDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  221. valueType := iter.WhatIsNext()
  222. var str string
  223. switch valueType {
  224. case jsoniter.NumberValue:
  225. var number json.Number
  226. iter.ReadVal(&number)
  227. str = string(number)
  228. case jsoniter.StringValue:
  229. str = iter.ReadString()
  230. // support empty string
  231. if str == "" {
  232. str = "0"
  233. }
  234. case jsoniter.BoolValue:
  235. if iter.ReadBool() {
  236. str = "1"
  237. } else {
  238. str = "0"
  239. }
  240. case jsoniter.NilValue:
  241. iter.ReadNil()
  242. str = "0"
  243. default:
  244. iter.ReportError("fuzzyIntegerDecoder", "not number or string")
  245. }
  246. newIter := iter.Pool().BorrowIterator([]byte(str))
  247. defer iter.Pool().ReturnIterator(newIter)
  248. isFloat := strings.IndexByte(str, '.') != -1
  249. decoder.fun(isFloat, ptr, newIter)
  250. if newIter.Error != nil && newIter.Error != io.EOF {
  251. iter.Error = newIter.Error
  252. }
  253. }
  254. type nullableFuzzyFloat32Decoder struct {
  255. }
  256. func (decoder *nullableFuzzyFloat32Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  257. valueType := iter.WhatIsNext()
  258. var str string
  259. switch valueType {
  260. case jsoniter.NumberValue:
  261. *((*float32)(ptr)) = iter.ReadFloat32()
  262. case jsoniter.StringValue:
  263. str = iter.ReadString()
  264. // support empty string
  265. if str == "" {
  266. *((*float32)(ptr)) = 0
  267. return
  268. }
  269. newIter := iter.Pool().BorrowIterator([]byte(str))
  270. defer iter.Pool().ReturnIterator(newIter)
  271. *((*float32)(ptr)) = newIter.ReadFloat32()
  272. if newIter.Error != nil && newIter.Error != io.EOF {
  273. iter.Error = newIter.Error
  274. }
  275. case jsoniter.BoolValue:
  276. // support bool to float32
  277. if iter.ReadBool() {
  278. *((*float32)(ptr)) = 1
  279. } else {
  280. *((*float32)(ptr)) = 0
  281. }
  282. case jsoniter.NilValue:
  283. iter.ReadNil()
  284. *((*float32)(ptr)) = 0
  285. default:
  286. iter.ReportError("nullableFuzzyFloat32Decoder", "not number or string")
  287. }
  288. }
  289. type nullableFuzzyFloat64Decoder struct {
  290. }
  291. func (decoder *nullableFuzzyFloat64Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  292. valueType := iter.WhatIsNext()
  293. var str string
  294. switch valueType {
  295. case jsoniter.NumberValue:
  296. *((*float64)(ptr)) = iter.ReadFloat64()
  297. case jsoniter.StringValue:
  298. str = iter.ReadString()
  299. // support empty string
  300. if str == "" {
  301. *((*float64)(ptr)) = 0
  302. return
  303. }
  304. newIter := iter.Pool().BorrowIterator([]byte(str))
  305. defer iter.Pool().ReturnIterator(newIter)
  306. *((*float64)(ptr)) = newIter.ReadFloat64()
  307. if newIter.Error != nil && newIter.Error != io.EOF {
  308. iter.Error = newIter.Error
  309. }
  310. case jsoniter.BoolValue:
  311. // support bool to float64
  312. if iter.ReadBool() {
  313. *((*float64)(ptr)) = 1
  314. } else {
  315. *((*float64)(ptr)) = 0
  316. }
  317. case jsoniter.NilValue:
  318. // support empty string
  319. iter.ReadNil()
  320. *((*float64)(ptr)) = 0
  321. default:
  322. iter.ReportError("nullableFuzzyFloat32Decoder", "not number or string")
  323. }
  324. }