feature_iter_float.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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. hasMore := true
  89. for hasMore {
  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. hasMore = false
  98. break
  99. }
  100. }
  101. if hasMore {
  102. if !iter.loadMore() {
  103. break
  104. }
  105. }
  106. }
  107. if iter.Error != nil && iter.Error != io.EOF {
  108. return
  109. }
  110. val, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&str)), 32)
  111. if err != nil {
  112. iter.Error = err
  113. return
  114. }
  115. return float32(val)
  116. }
  117. // ReadFloat64 reads a json object as Float64
  118. func (iter *Iterator) ReadFloat64() (ret float64) {
  119. strBuf := [8]byte{}
  120. str := strBuf[0:0]
  121. hasMore := true
  122. for hasMore {
  123. for i := iter.head; i < iter.tail; i++ {
  124. c := iter.buf[i]
  125. switch c {
  126. case '-', '+', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  127. str = append(str, c)
  128. continue
  129. default:
  130. hasMore = false
  131. break
  132. }
  133. }
  134. if hasMore {
  135. if !iter.loadMore() {
  136. break
  137. }
  138. }
  139. }
  140. if iter.Error != nil && iter.Error != io.EOF {
  141. return
  142. }
  143. val, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&str)), 64)
  144. if err != nil {
  145. iter.Error = err
  146. return
  147. }
  148. return val
  149. }