feature_iter_float.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. package jsoniter
  2. import (
  3. "io"
  4. "strconv"
  5. "unsafe"
  6. )
  7. var zeroToNineDigits []int8
  8. const invalidCharForNumber = int8(-1)
  9. const endOfNumber = int8(-2)
  10. const dotInNumber = int8(-3)
  11. const safeToMultiple10 = uint64(0xffffffffffffffff) / 10 - 10
  12. func init() {
  13. zeroToNineDigits = make([]int8, 256)
  14. for i := 0; i < len(zeroToNineDigits); i++ {
  15. zeroToNineDigits[i] = invalidCharForNumber
  16. }
  17. for i := int8('0'); i < int8('9'); i++ {
  18. zeroToNineDigits[i] = i - int8('0')
  19. }
  20. zeroToNineDigits[','] = endOfNumber;
  21. zeroToNineDigits[']'] = endOfNumber;
  22. zeroToNineDigits['}'] = endOfNumber;
  23. zeroToNineDigits[' '] = endOfNumber;
  24. zeroToNineDigits['.'] = dotInNumber;
  25. }
  26. func (iter *Iterator) ReadFloat32() (ret float32) {
  27. c := iter.nextToken()
  28. if c == '-' {
  29. return -iter.readPositiveFloat32()
  30. } else {
  31. iter.unreadByte()
  32. return iter.readPositiveFloat32()
  33. }
  34. }
  35. func (iter *Iterator) readPositiveFloat32() (ret float32) {
  36. value := uint64(0)
  37. c := byte(' ')
  38. i := iter.head
  39. non_decimal_loop:
  40. for ; i < iter.tail; i++ {
  41. c = iter.buf[i]
  42. ind := zeroToNineDigits[c]
  43. switch ind {
  44. case invalidCharForNumber:
  45. return iter.readFloat32SlowPath()
  46. case endOfNumber:
  47. iter.head = i
  48. return float32(value)
  49. case dotInNumber:
  50. break non_decimal_loop
  51. }
  52. if value > safeToMultiple10 {
  53. return iter.readFloat32SlowPath()
  54. }
  55. value = (value << 3) + (value << 1) + uint64(ind); // value = value * 10 + ind;
  56. }
  57. if c == '.' {
  58. i++
  59. decimalPlaces := 0;
  60. for ; i < iter.tail; i++ {
  61. c = iter.buf[i]
  62. ind := zeroToNineDigits[c];
  63. switch ind {
  64. case endOfNumber:
  65. if decimalPlaces > 0 && decimalPlaces < len(POW10) {
  66. iter.head = i
  67. return float32(float64(value) / float64(POW10[decimalPlaces]))
  68. }
  69. // too many decimal places
  70. return iter.readFloat32SlowPath()
  71. case invalidCharForNumber:
  72. fallthrough
  73. case dotInNumber:
  74. return iter.readFloat32SlowPath()
  75. }
  76. decimalPlaces++
  77. if value > safeToMultiple10 {
  78. return iter.readFloat32SlowPath()
  79. }
  80. value = (value << 3) + (value << 1) + uint64(ind)
  81. }
  82. }
  83. return iter.readFloat32SlowPath()
  84. }
  85. func (iter *Iterator) readFloat32SlowPath() (ret float32) {
  86. strBuf := [16]byte{}
  87. str := strBuf[0:0]
  88. load_loop:
  89. for {
  90. for i := iter.head; i < iter.tail; i++ {
  91. c := iter.buf[i]
  92. switch c {
  93. case '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  94. str = append(str, c)
  95. continue
  96. default:
  97. break load_loop
  98. }
  99. }
  100. if !iter.loadMore() {
  101. break
  102. }
  103. }
  104. if iter.Error != nil && iter.Error != io.EOF {
  105. return
  106. }
  107. val, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&str)), 32)
  108. if err != nil {
  109. iter.Error = err
  110. return
  111. }
  112. return float32(val)
  113. }
  114. func (iter *Iterator) ReadFloat64() (ret float64) {
  115. c := iter.nextToken()
  116. if c == '-' {
  117. return -iter.readPositiveFloat64()
  118. } else {
  119. iter.unreadByte()
  120. return iter.readPositiveFloat64()
  121. }
  122. }
  123. func (iter *Iterator) readPositiveFloat64() (ret float64) {
  124. value := uint64(0)
  125. c := byte(' ')
  126. i := iter.head
  127. non_decimal_loop:
  128. for ; i < iter.tail; i++ {
  129. c = iter.buf[i]
  130. ind := zeroToNineDigits[c]
  131. switch ind {
  132. case invalidCharForNumber:
  133. return iter.readFloat64SlowPath()
  134. case endOfNumber:
  135. iter.head = i
  136. return float64(value)
  137. case dotInNumber:
  138. break non_decimal_loop
  139. }
  140. if value > safeToMultiple10 {
  141. return iter.readFloat64SlowPath()
  142. }
  143. value = (value << 3) + (value << 1) + uint64(ind); // value = value * 10 + ind;
  144. }
  145. if c == '.' {
  146. i++
  147. decimalPlaces := 0;
  148. for ; i < iter.tail; i++ {
  149. c = iter.buf[i]
  150. ind := zeroToNineDigits[c];
  151. switch ind {
  152. case endOfNumber:
  153. if decimalPlaces > 0 && decimalPlaces < len(POW10) {
  154. iter.head = i
  155. return float64(value) / float64(POW10[decimalPlaces])
  156. }
  157. // too many decimal places
  158. return iter.readFloat64SlowPath()
  159. case invalidCharForNumber:
  160. fallthrough
  161. case dotInNumber:
  162. return iter.readFloat64SlowPath()
  163. }
  164. decimalPlaces++
  165. if value > safeToMultiple10 {
  166. return iter.readFloat64SlowPath()
  167. }
  168. value = (value << 3) + (value << 1) + uint64(ind)
  169. }
  170. }
  171. return iter.readFloat64SlowPath()
  172. }
  173. func (iter *Iterator) readFloat64SlowPath() (ret float64) {
  174. strBuf := [16]byte{}
  175. str := strBuf[0:0]
  176. load_loop:
  177. for {
  178. for i := iter.head; i < iter.tail; i++ {
  179. c := iter.buf[i]
  180. switch c {
  181. case '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  182. str = append(str, c)
  183. continue
  184. default:
  185. break load_loop
  186. }
  187. }
  188. if !iter.loadMore() {
  189. break
  190. }
  191. }
  192. if iter.Error != nil && iter.Error != io.EOF {
  193. return
  194. }
  195. val, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&str)), 64)
  196. if err != nil {
  197. iter.Error = err
  198. return
  199. }
  200. return val
  201. }