github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/iterator_float64.go (about) 1 package jzon 2 3 import ( 4 "io" 5 "strconv" 6 ) 7 8 func (it *Iterator) readFloat64(c byte) (float64, error) { 9 if c == '-' { 10 c, err := it.nextByte() 11 if err != nil { 12 return 0, err 13 } 14 it.head++ 15 f, buf, err := it.readPositiveFloat64(c, it.tmpBuffer[:0]) 16 it.tmpBuffer = buf 17 return -f, err 18 } 19 f, buf, err := it.readPositiveFloat64(c, it.tmpBuffer[:0]) 20 it.tmpBuffer = buf 21 return f, err 22 } 23 24 // ReadFloat64 reads a float64 value 25 func (it *Iterator) ReadFloat64() (float64, error) { 26 c, err := it.nextToken() 27 if err != nil { 28 return 0, err 29 } 30 it.head++ 31 return it.readFloat64(c) 32 } 33 34 func (it *Iterator) parseFloat64(buf []byte) (ret float64, err error) { 35 return strconv.ParseFloat(localByteToString(buf), 64) 36 } 37 38 func (it *Iterator) readFloat64ExponentPart(buf []byte) (ret float64, _ []byte, err error) { 39 c, err := it.nextByte() 40 if err != nil { 41 return 0, buf, err 42 } 43 it.head++ 44 if c == '+' || c == '-' { 45 buf = append(buf, c) 46 c, err = it.nextByte() 47 if err != nil { 48 return 0, buf, err 49 } 50 it.head++ 51 } 52 if intDigits[c] == invalidDigit { 53 return 0, buf, InvalidFloatError{c: c} 54 } 55 buf = append(buf, c) 56 for { 57 i := it.head 58 for ; i < it.tail; i++ { 59 c = it.buffer[i] 60 digit := intDigits[c] 61 if digit == invalidDigit { 62 buf = append(buf, it.buffer[it.head:i]...) 63 it.head = i 64 f, err := it.parseFloat64(buf) 65 return f, buf, err 66 } 67 } 68 // i == it.tail 69 buf = append(buf, it.buffer[it.head:i]...) 70 it.head = i 71 if err = it.readMore(); err != nil { 72 if err == io.EOF { 73 f, err := it.parseFloat64(buf) 74 return f, buf, err 75 } 76 return 0, buf, err 77 } 78 } 79 } 80 81 func (it *Iterator) readFloat64FractionPart(buf []byte) (ret float64, _ []byte, err error) { 82 c, err := it.nextByte() 83 if err != nil { 84 return 0, buf, err 85 } 86 if intDigits[c] == invalidDigit { 87 return 0, buf, InvalidFloatError{c: c} 88 } 89 it.head++ 90 buf = append(buf, c) 91 for { 92 i := it.head 93 for ; i < it.tail; i++ { 94 c = it.buffer[i] 95 digit := floatDigits[c] 96 if digit < 0 { 97 switch digit { 98 case expInNumber: 99 buf = append(buf, it.buffer[it.head:i+1]...) 100 it.head = i + 1 101 return it.readFloat64ExponentPart(buf) 102 default: 103 buf = append(buf, it.buffer[it.head:i]...) 104 it.head = i 105 f, err := it.parseFloat64(buf) 106 return f, buf, err 107 } 108 } 109 } 110 // i == it.tail 111 buf = append(buf, it.buffer[it.head:i]...) 112 it.head = i 113 if err = it.readMore(); err != nil { 114 if err == io.EOF { 115 f, err := it.parseFloat64(buf) 116 return f, buf, err 117 } 118 return 0, buf, err 119 } 120 } 121 } 122 123 func (it *Iterator) readPositiveFloat64(c byte, buf []byte) (ret float64, _ []byte, err error) { 124 u := intDigits[c] 125 if u == invalidDigit { 126 return 0, buf, InvalidFloatError{c: c} 127 } 128 129 buf = append(buf, c) 130 if u == 0 { 131 if it.head == it.tail { 132 if err = it.readMore(); err != nil { 133 if err == io.EOF { 134 return 0, buf, nil 135 } 136 return 0, buf, err 137 } 138 } 139 switch floatDigits[it.buffer[it.head]] { 140 case dotInNumber: 141 it.head++ 142 buf = append(buf, '.') 143 return it.readFloat64FractionPart(buf) 144 case expInNumber: 145 it.head++ 146 buf = append(buf, 'e') 147 return it.readFloat64ExponentPart(buf) 148 default: 149 return 0, buf, nil 150 } 151 } else { 152 for { 153 i := it.head 154 for ; i < it.tail; i++ { 155 c = it.buffer[i] 156 digit := floatDigits[c] 157 if digit < 0 { 158 switch digit { 159 case dotInNumber: 160 buf = append(buf, it.buffer[it.head:i+1]...) 161 it.head = i + 1 162 return it.readFloat64FractionPart(buf) 163 case expInNumber: 164 buf = append(buf, it.buffer[it.head:i+1]...) 165 it.head = i + 1 166 return it.readFloat64ExponentPart(buf) 167 default: 168 buf = append(buf, it.buffer[it.head:i]...) 169 it.head = i 170 f, err := it.parseFloat64(buf) 171 return f, buf, err 172 } 173 } 174 } 175 // i == it.tail 176 buf = append(buf, it.buffer[it.head:i]...) 177 it.head = i 178 if err = it.readMore(); err != nil { 179 if err == io.EOF { 180 f, err := it.parseFloat64(buf) 181 return f, buf, err 182 } 183 return 0, buf, err 184 } 185 } 186 } 187 }