json_parser.go 9.1 KB

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