fuzzy_decoder.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. package extra
  2. import (
  3. "github.com/json-iterator/go"
  4. "unsafe"
  5. "encoding/json"
  6. "strings"
  7. "math"
  8. "reflect"
  9. )
  10. const MaxUint = ^uint(0)
  11. const MaxInt = int(MaxUint >> 1)
  12. const MinInt = -MaxInt - 1
  13. func RegisterFuzzyDecoders() {
  14. jsoniter.RegisterExtension(&tolerateEmptyArrayExtension{})
  15. jsoniter.RegisterTypeDecoder("string", &FuzzyStringDecoder{})
  16. jsoniter.RegisterTypeDecoder("float32", &FuzzyFloat32Decoder{})
  17. jsoniter.RegisterTypeDecoder("float64", &FuzzyFloat64Decoder{})
  18. jsoniter.RegisterTypeDecoder("int", &FuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  19. if isFloat {
  20. val := iter.ReadFloat64()
  21. if val > float64(MaxInt) || val < float64(MinInt) {
  22. iter.ReportError("fuzzy decode int", "exceed range")
  23. return
  24. }
  25. *((*int)(ptr)) = int(val)
  26. } else {
  27. *((*int)(ptr)) = iter.ReadInt()
  28. }
  29. }})
  30. jsoniter.RegisterTypeDecoder("uint", &FuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  31. if isFloat {
  32. val := iter.ReadFloat64()
  33. if val > float64(MaxUint) || val < 0 {
  34. iter.ReportError("fuzzy decode uint", "exceed range")
  35. return
  36. }
  37. *((*uint)(ptr)) = uint(val)
  38. } else {
  39. *((*uint)(ptr)) = iter.ReadUint()
  40. }
  41. }})
  42. jsoniter.RegisterTypeDecoder("int8", &FuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  43. if isFloat {
  44. val := iter.ReadFloat64()
  45. if val > float64(math.MaxInt8) || val < float64(math.MinInt8) {
  46. iter.ReportError("fuzzy decode int8", "exceed range")
  47. return
  48. }
  49. *((*int8)(ptr)) = int8(val)
  50. } else {
  51. *((*int8)(ptr)) = iter.ReadInt8()
  52. }
  53. }})
  54. jsoniter.RegisterTypeDecoder("uint8", &FuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  55. if isFloat {
  56. val := iter.ReadFloat64()
  57. if val > float64(math.MaxUint8) || val < 0 {
  58. iter.ReportError("fuzzy decode uint8", "exceed range")
  59. return
  60. }
  61. *((*uint8)(ptr)) = uint8(val)
  62. } else {
  63. *((*uint8)(ptr)) = iter.ReadUint8()
  64. }
  65. }})
  66. jsoniter.RegisterTypeDecoder("int16", &FuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  67. if isFloat {
  68. val := iter.ReadFloat64()
  69. if val > float64(math.MaxInt16) || val < float64(math.MinInt16) {
  70. iter.ReportError("fuzzy decode int16", "exceed range")
  71. return
  72. }
  73. *((*int16)(ptr)) = int16(val)
  74. } else {
  75. *((*int16)(ptr)) = iter.ReadInt16()
  76. }
  77. }})
  78. jsoniter.RegisterTypeDecoder("uint16", &FuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  79. if isFloat {
  80. val := iter.ReadFloat64()
  81. if val > float64(math.MaxUint16) || val < 0 {
  82. iter.ReportError("fuzzy decode uint16", "exceed range")
  83. return
  84. }
  85. *((*uint16)(ptr)) = uint16(val)
  86. } else {
  87. *((*uint16)(ptr)) = iter.ReadUint16()
  88. }
  89. }})
  90. jsoniter.RegisterTypeDecoder("int32", &FuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  91. if isFloat {
  92. val := iter.ReadFloat64()
  93. if val > float64(math.MaxInt32) || val < float64(math.MinInt32) {
  94. iter.ReportError("fuzzy decode int32", "exceed range")
  95. return
  96. }
  97. *((*int32)(ptr)) = int32(val)
  98. } else {
  99. *((*int32)(ptr)) = iter.ReadInt32()
  100. }
  101. }})
  102. jsoniter.RegisterTypeDecoder("uint32", &FuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  103. if isFloat {
  104. val := iter.ReadFloat64()
  105. if val > float64(math.MaxUint32) || val < 0 {
  106. iter.ReportError("fuzzy decode uint32", "exceed range")
  107. return
  108. }
  109. *((*uint32)(ptr)) = uint32(val)
  110. } else {
  111. *((*uint32)(ptr)) = iter.ReadUint32()
  112. }
  113. }})
  114. jsoniter.RegisterTypeDecoder("int64", &FuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  115. if isFloat {
  116. val := iter.ReadFloat64()
  117. if val > float64(math.MaxInt64) || val < float64(math.MinInt64) {
  118. iter.ReportError("fuzzy decode int64", "exceed range")
  119. return
  120. }
  121. *((*int64)(ptr)) = int64(val)
  122. } else {
  123. *((*int64)(ptr)) = iter.ReadInt64()
  124. }
  125. }})
  126. jsoniter.RegisterTypeDecoder("uint64", &FuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  127. if isFloat {
  128. val := iter.ReadFloat64()
  129. if val > float64(math.MaxUint64) || val < 0 {
  130. iter.ReportError("fuzzy decode uint64", "exceed range")
  131. return
  132. }
  133. *((*uint64)(ptr)) = uint64(val)
  134. } else {
  135. *((*uint64)(ptr)) = iter.ReadUint64()
  136. }
  137. }})
  138. }
  139. type tolerateEmptyArrayExtension struct {
  140. jsoniter.DummyExtension
  141. }
  142. func (extension *tolerateEmptyArrayExtension) DecorateDecoder(typ reflect.Type, decoder jsoniter.ValDecoder) jsoniter.ValDecoder {
  143. if typ.Kind() == reflect.Struct || typ.Kind() == reflect.Map {
  144. return &tolerateEmptyArrayDecoder{decoder}
  145. }
  146. return decoder
  147. }
  148. type tolerateEmptyArrayDecoder struct {
  149. valDecoder jsoniter.ValDecoder
  150. }
  151. func (decoder *tolerateEmptyArrayDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  152. if iter.WhatIsNext() == jsoniter.Array {
  153. iter.Skip()
  154. newIter := iter.Config().BorrowIterator([]byte("{}"))
  155. defer iter.Config().ReturnIterator(newIter)
  156. decoder.valDecoder.Decode(ptr, newIter)
  157. } else {
  158. decoder.valDecoder.Decode(ptr, iter)
  159. }
  160. }
  161. type FuzzyStringDecoder struct {
  162. }
  163. func (decoder *FuzzyStringDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  164. valueType := iter.WhatIsNext()
  165. switch valueType {
  166. case jsoniter.Number:
  167. var number json.Number
  168. iter.ReadVal(&number)
  169. *((*string)(ptr)) = string(number)
  170. case jsoniter.String:
  171. *((*string)(ptr)) = iter.ReadString()
  172. default:
  173. iter.ReportError("FuzzyStringDecoder", "not number or string")
  174. }
  175. }
  176. type FuzzyIntegerDecoder struct {
  177. fun func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator)
  178. }
  179. func (decoder *FuzzyIntegerDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  180. valueType := iter.WhatIsNext()
  181. var str string
  182. switch valueType {
  183. case jsoniter.Number:
  184. var number json.Number
  185. iter.ReadVal(&number)
  186. str = string(number)
  187. case jsoniter.String:
  188. str = iter.ReadString()
  189. default:
  190. iter.ReportError("FuzzyIntegerDecoder", "not number or string")
  191. }
  192. newIter := iter.Config().BorrowIterator([]byte(str))
  193. defer iter.Config().ReturnIterator(newIter)
  194. isFloat := strings.IndexByte(str, '.') != -1
  195. decoder.fun(isFloat, ptr, newIter)
  196. if newIter.Error != nil {
  197. iter.Error = newIter.Error
  198. }
  199. }
  200. type FuzzyFloat32Decoder struct {
  201. }
  202. func (decoder *FuzzyFloat32Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  203. valueType := iter.WhatIsNext()
  204. var str string
  205. switch valueType {
  206. case jsoniter.Number:
  207. *((*float32)(ptr)) = iter.ReadFloat32()
  208. case jsoniter.String:
  209. str = iter.ReadString()
  210. newIter := iter.Config().BorrowIterator([]byte(str))
  211. defer iter.Config().ReturnIterator(newIter)
  212. *((*float32)(ptr)) = newIter.ReadFloat32()
  213. if newIter.Error != nil {
  214. iter.Error = newIter.Error
  215. }
  216. default:
  217. iter.ReportError("FuzzyFloat32Decoder", "not number or string")
  218. }
  219. }
  220. type FuzzyFloat64Decoder struct {
  221. }
  222. func (decoder *FuzzyFloat64Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  223. valueType := iter.WhatIsNext()
  224. var str string
  225. switch valueType {
  226. case jsoniter.Number:
  227. *((*float64)(ptr)) = iter.ReadFloat64()
  228. case jsoniter.String:
  229. str = iter.ReadString()
  230. newIter := iter.Config().BorrowIterator([]byte(str))
  231. defer iter.Config().ReturnIterator(newIter)
  232. *((*float64)(ptr)) = newIter.ReadFloat64()
  233. if newIter.Error != nil {
  234. iter.Error = newIter.Error
  235. }
  236. default:
  237. iter.ReportError("FuzzyFloat32Decoder", "not number or string")
  238. }
  239. }