fuzzy_decoder.go 5.7 KB

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