fuzzy_decoder.go 5.9 KB

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