feature_iter_float.go 4.5 KB

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