feature_iter_float.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. package jsoniter
  2. import (
  3. "io"
  4. "math/big"
  5. "strconv"
  6. "strings"
  7. "unsafe"
  8. )
  9. var floatDigits []int8
  10. const invalidCharForNumber = int8(-1)
  11. const endOfNumber = int8(-2)
  12. const dotInNumber = int8(-3)
  13. func init() {
  14. floatDigits = make([]int8, 256)
  15. for i := 0; i < len(floatDigits); i++ {
  16. floatDigits[i] = invalidCharForNumber
  17. }
  18. for i := int8('0'); i <= int8('9'); i++ {
  19. floatDigits[i] = i - int8('0')
  20. }
  21. floatDigits[','] = endOfNumber
  22. floatDigits[']'] = endOfNumber
  23. floatDigits['}'] = endOfNumber
  24. floatDigits[' '] = endOfNumber
  25. floatDigits['\t'] = endOfNumber
  26. floatDigits['\n'] = endOfNumber
  27. floatDigits['.'] = dotInNumber
  28. }
  29. // ReadBigFloat read big.Float
  30. func (iter *Iterator) ReadBigFloat() (ret *big.Float) {
  31. str := iter.readNumberAsString()
  32. if iter.Error != nil && iter.Error != io.EOF {
  33. return nil
  34. }
  35. prec := 64
  36. if len(str) > prec {
  37. prec = len(str)
  38. }
  39. val, _, err := big.ParseFloat(str, 10, uint(prec), big.ToZero)
  40. if err != nil {
  41. iter.Error = err
  42. return nil
  43. }
  44. return val
  45. }
  46. // ReadBigInt read big.Int
  47. func (iter *Iterator) ReadBigInt() (ret *big.Int) {
  48. str := iter.readNumberAsString()
  49. if iter.Error != nil && iter.Error != io.EOF {
  50. return nil
  51. }
  52. ret = big.NewInt(0)
  53. var success bool
  54. ret, success = ret.SetString(str, 10)
  55. if !success {
  56. iter.ReportError("ReadBigInt", "invalid big int")
  57. return nil
  58. }
  59. return ret
  60. }
  61. //ReadFloat32 read float32
  62. func (iter *Iterator) ReadFloat32() (ret float32) {
  63. c := iter.nextToken()
  64. if c == '-' {
  65. return -iter.readPositiveFloat32()
  66. }
  67. iter.unreadByte()
  68. return iter.readPositiveFloat32()
  69. }
  70. func (iter *Iterator) readPositiveFloat32() (ret float32) {
  71. value := uint64(0)
  72. c := byte(' ')
  73. i := iter.head
  74. // first char
  75. if i == iter.tail {
  76. return iter.readFloat32SlowPath()
  77. }
  78. c = iter.buf[i]
  79. i++
  80. ind := floatDigits[c]
  81. switch ind {
  82. case invalidCharForNumber:
  83. return iter.readFloat32SlowPath()
  84. case endOfNumber:
  85. iter.ReportError("readFloat32", "empty number")
  86. return
  87. case dotInNumber:
  88. iter.ReportError("readFloat32", "leading dot is invalid")
  89. return
  90. case 0:
  91. if i == iter.tail {
  92. return iter.readFloat32SlowPath()
  93. }
  94. c = iter.buf[i]
  95. switch c {
  96. case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  97. iter.ReportError("readFloat32", "leading zero is invalid")
  98. return
  99. }
  100. }
  101. value = uint64(ind)
  102. // chars before dot
  103. non_decimal_loop:
  104. for ; i < iter.tail; i++ {
  105. c = iter.buf[i]
  106. ind := floatDigits[c]
  107. switch ind {
  108. case invalidCharForNumber:
  109. return iter.readFloat32SlowPath()
  110. case endOfNumber:
  111. iter.head = i
  112. return float32(value)
  113. case dotInNumber:
  114. break non_decimal_loop
  115. }
  116. if value > uint64SafeToMultiple10 {
  117. return iter.readFloat32SlowPath()
  118. }
  119. value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind;
  120. }
  121. // chars after dot
  122. if c == '.' {
  123. i++
  124. decimalPlaces := 0
  125. if i == iter.tail {
  126. return iter.readFloat32SlowPath()
  127. }
  128. for ; i < iter.tail; i++ {
  129. c = iter.buf[i]
  130. ind := floatDigits[c]
  131. switch ind {
  132. case endOfNumber:
  133. if decimalPlaces > 0 && decimalPlaces < len(pow10) {
  134. iter.head = i
  135. return float32(float64(value) / float64(pow10[decimalPlaces]))
  136. }
  137. // too many decimal places
  138. return iter.readFloat32SlowPath()
  139. case invalidCharForNumber:
  140. fallthrough
  141. case dotInNumber:
  142. return iter.readFloat32SlowPath()
  143. }
  144. decimalPlaces++
  145. if value > uint64SafeToMultiple10 {
  146. return iter.readFloat32SlowPath()
  147. }
  148. value = (value << 3) + (value << 1) + uint64(ind)
  149. }
  150. }
  151. return iter.readFloat32SlowPath()
  152. }
  153. func (iter *Iterator) readNumberAsString() (ret string) {
  154. strBuf := [16]byte{}
  155. str := strBuf[0:0]
  156. load_loop:
  157. for {
  158. for i := iter.head; i < iter.tail; i++ {
  159. c := iter.buf[i]
  160. switch c {
  161. case '+', '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  162. str = append(str, c)
  163. continue
  164. default:
  165. iter.head = i
  166. break load_loop
  167. }
  168. }
  169. if !iter.loadMore() {
  170. break
  171. }
  172. }
  173. if iter.Error != nil && iter.Error != io.EOF {
  174. return
  175. }
  176. if len(str) == 0 {
  177. iter.ReportError("readNumberAsString", "invalid number")
  178. }
  179. return *(*string)(unsafe.Pointer(&str))
  180. }
  181. func (iter *Iterator) readFloat32SlowPath() (ret float32) {
  182. str := iter.readNumberAsString()
  183. if iter.Error != nil && iter.Error != io.EOF {
  184. return
  185. }
  186. errMsg := validateFloat(str)
  187. if errMsg != "" {
  188. iter.ReportError("readFloat32SlowPath", errMsg)
  189. return
  190. }
  191. val, err := strconv.ParseFloat(str, 32)
  192. if err != nil {
  193. iter.Error = err
  194. return
  195. }
  196. return float32(val)
  197. }
  198. // ReadFloat64 read float64
  199. func (iter *Iterator) ReadFloat64() (ret float64) {
  200. c := iter.nextToken()
  201. if c == '-' {
  202. return -iter.readPositiveFloat64()
  203. }
  204. iter.unreadByte()
  205. return iter.readPositiveFloat64()
  206. }
  207. func (iter *Iterator) readPositiveFloat64() (ret float64) {
  208. value := uint64(0)
  209. c := byte(' ')
  210. i := iter.head
  211. // first char
  212. if i == iter.tail {
  213. return iter.readFloat64SlowPath()
  214. }
  215. c = iter.buf[i]
  216. i++
  217. ind := floatDigits[c]
  218. switch ind {
  219. case invalidCharForNumber:
  220. return iter.readFloat64SlowPath()
  221. case endOfNumber:
  222. iter.ReportError("readFloat64", "empty number")
  223. return
  224. case dotInNumber:
  225. iter.ReportError("readFloat64", "leading dot is invalid")
  226. return
  227. case 0:
  228. if i == iter.tail {
  229. return iter.readFloat64SlowPath()
  230. }
  231. c = iter.buf[i]
  232. switch c {
  233. case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  234. iter.ReportError("readFloat64", "leading zero is invalid")
  235. return
  236. }
  237. }
  238. value = uint64(ind)
  239. // chars before dot
  240. non_decimal_loop:
  241. for ; i < iter.tail; i++ {
  242. c = iter.buf[i]
  243. ind := floatDigits[c]
  244. switch ind {
  245. case invalidCharForNumber:
  246. return iter.readFloat64SlowPath()
  247. case endOfNumber:
  248. iter.head = i
  249. return float64(value)
  250. case dotInNumber:
  251. break non_decimal_loop
  252. }
  253. if value > uint64SafeToMultiple10 {
  254. return iter.readFloat64SlowPath()
  255. }
  256. value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind;
  257. }
  258. // chars after dot
  259. if c == '.' {
  260. i++
  261. decimalPlaces := 0
  262. if i == iter.tail {
  263. return iter.readFloat64SlowPath()
  264. }
  265. for ; i < iter.tail; i++ {
  266. c = iter.buf[i]
  267. ind := floatDigits[c]
  268. switch ind {
  269. case endOfNumber:
  270. if decimalPlaces > 0 && decimalPlaces < len(pow10) {
  271. iter.head = i
  272. return float64(value) / float64(pow10[decimalPlaces])
  273. }
  274. // too many decimal places
  275. return iter.readFloat64SlowPath()
  276. case invalidCharForNumber:
  277. fallthrough
  278. case dotInNumber:
  279. return iter.readFloat64SlowPath()
  280. }
  281. decimalPlaces++
  282. if value > uint64SafeToMultiple10 {
  283. return iter.readFloat64SlowPath()
  284. }
  285. value = (value << 3) + (value << 1) + uint64(ind)
  286. }
  287. }
  288. return iter.readFloat64SlowPath()
  289. }
  290. func (iter *Iterator) readFloat64SlowPath() (ret float64) {
  291. str := iter.readNumberAsString()
  292. if iter.Error != nil && iter.Error != io.EOF {
  293. return
  294. }
  295. errMsg := validateFloat(str)
  296. if errMsg != "" {
  297. iter.ReportError("readFloat64SlowPath", errMsg)
  298. return
  299. }
  300. val, err := strconv.ParseFloat(str, 64)
  301. if err != nil {
  302. iter.Error = err
  303. return
  304. }
  305. return val
  306. }
  307. func validateFloat(str string) string {
  308. // strconv.ParseFloat is not validating `1.` or `1.e1`
  309. if len(str) == 0 {
  310. return "empty number"
  311. }
  312. if str[0] == '-' {
  313. return "-- is not valid"
  314. }
  315. dotPos := strings.IndexByte(str, '.')
  316. if dotPos != -1 {
  317. if dotPos == len(str)-1 {
  318. return "dot can not be last character"
  319. }
  320. switch str[dotPos+1] {
  321. case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  322. default:
  323. return "missing digit after dot"
  324. }
  325. }
  326. return ""
  327. }