12 var floatDigits []int8
14 const invalidCharForNumber = int8(-1)
15 const endOfNumber = int8(-2)
16 const dotInNumber = int8(-3)
19 floatDigits = make([]int8, 256)
20 for i := 0; i < len(floatDigits); i++ {
21 floatDigits[i] = invalidCharForNumber
23 for i := int8('0'); i <= int8('9'); i++ {
24 floatDigits[i] = i - int8('0')
26 floatDigits[','] = endOfNumber
27 floatDigits[']'] = endOfNumber
28 floatDigits['}'] = endOfNumber
29 floatDigits[' '] = endOfNumber
30 floatDigits['\t'] = endOfNumber
31 floatDigits['\n'] = endOfNumber
32 floatDigits['.'] = dotInNumber
35 // ReadBigFloat read big.Float
36 func (iter *Iterator) ReadBigFloat() (ret *big.Float) {
37 str := iter.readNumberAsString()
38 if iter.Error != nil && iter.Error != io.EOF {
45 val, _, err := big.ParseFloat(str, 10, uint(prec), big.ToZero)
53 // ReadBigInt read big.Int
54 func (iter *Iterator) ReadBigInt() (ret *big.Int) {
55 str := iter.readNumberAsString()
56 if iter.Error != nil && iter.Error != io.EOF {
61 ret, success = ret.SetString(str, 10)
63 iter.ReportError("ReadBigInt", "invalid big int")
69 //ReadFloat32 read float32
70 func (iter *Iterator) ReadFloat32() (ret float32) {
73 return -iter.readPositiveFloat32()
76 return iter.readPositiveFloat32()
79 func (iter *Iterator) readPositiveFloat32() (ret float32) {
83 return iter.readFloat32SlowPath()
89 case invalidCharForNumber:
90 return iter.readFloat32SlowPath()
92 iter.ReportError("readFloat32", "empty number")
95 iter.ReportError("readFloat32", "leading dot is invalid")
99 return iter.readFloat32SlowPath()
103 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
104 iter.ReportError("readFloat32", "leading zero is invalid")
111 for ; i < iter.tail; i++ {
113 ind := floatDigits[c]
115 case invalidCharForNumber:
116 return iter.readFloat32SlowPath()
119 return float32(value)
121 break non_decimal_loop
123 if value > uint64SafeToMultiple10 {
124 return iter.readFloat32SlowPath()
126 value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind;
133 return iter.readFloat32SlowPath()
135 for ; i < iter.tail; i++ {
137 ind := floatDigits[c]
140 if decimalPlaces > 0 && decimalPlaces < len(pow10) {
142 return float32(float64(value) / float64(pow10[decimalPlaces]))
144 // too many decimal places
145 return iter.readFloat32SlowPath()
146 case invalidCharForNumber, dotInNumber:
147 return iter.readFloat32SlowPath()
150 if value > uint64SafeToMultiple10 {
151 return iter.readFloat32SlowPath()
153 value = (value << 3) + (value << 1) + uint64(ind)
156 return iter.readFloat32SlowPath()
159 func (iter *Iterator) readNumberAsString() (ret string) {
164 for i := iter.head; i < iter.tail; i++ {
167 case '+', '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
175 if !iter.loadMore() {
179 if iter.Error != nil && iter.Error != io.EOF {
183 iter.ReportError("readNumberAsString", "invalid number")
185 return *(*string)(unsafe.Pointer(&str))
188 func (iter *Iterator) readFloat32SlowPath() (ret float32) {
189 str := iter.readNumberAsString()
190 if iter.Error != nil && iter.Error != io.EOF {
193 errMsg := validateFloat(str)
195 iter.ReportError("readFloat32SlowPath", errMsg)
198 val, err := strconv.ParseFloat(str, 32)
206 // ReadFloat64 read float64
207 func (iter *Iterator) ReadFloat64() (ret float64) {
208 c := iter.nextToken()
210 return -iter.readPositiveFloat64()
213 return iter.readPositiveFloat64()
216 func (iter *Iterator) readPositiveFloat64() (ret float64) {
220 return iter.readFloat64SlowPath()
224 ind := floatDigits[c]
226 case invalidCharForNumber:
227 return iter.readFloat64SlowPath()
229 iter.ReportError("readFloat64", "empty number")
232 iter.ReportError("readFloat64", "leading dot is invalid")
236 return iter.readFloat64SlowPath()
240 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
241 iter.ReportError("readFloat64", "leading zero is invalid")
248 for ; i < iter.tail; i++ {
250 ind := floatDigits[c]
252 case invalidCharForNumber:
253 return iter.readFloat64SlowPath()
256 return float64(value)
258 break non_decimal_loop
260 if value > uint64SafeToMultiple10 {
261 return iter.readFloat64SlowPath()
263 value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind;
270 return iter.readFloat64SlowPath()
272 for ; i < iter.tail; i++ {
274 ind := floatDigits[c]
277 if decimalPlaces > 0 && decimalPlaces < len(pow10) {
279 return float64(value) / float64(pow10[decimalPlaces])
281 // too many decimal places
282 return iter.readFloat64SlowPath()
283 case invalidCharForNumber, dotInNumber:
284 return iter.readFloat64SlowPath()
287 if value > uint64SafeToMultiple10 {
288 return iter.readFloat64SlowPath()
290 value = (value << 3) + (value << 1) + uint64(ind)
293 return iter.readFloat64SlowPath()
296 func (iter *Iterator) readFloat64SlowPath() (ret float64) {
297 str := iter.readNumberAsString()
298 if iter.Error != nil && iter.Error != io.EOF {
301 errMsg := validateFloat(str)
303 iter.ReportError("readFloat64SlowPath", errMsg)
306 val, err := strconv.ParseFloat(str, 64)
314 func validateFloat(str string) string {
315 // strconv.ParseFloat is not validating `1.` or `1.e1`
317 return "empty number"
320 return "-- is not valid"
322 dotPos := strings.IndexByte(str, '.')
324 if dotPos == len(str)-1 {
325 return "dot can not be last character"
327 switch str[dotPos+1] {
328 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
330 return "missing digit after dot"
336 // ReadNumber read json.Number
337 func (iter *Iterator) ReadNumber() (ret json.Number) {
338 return json.Number(iter.readNumberAsString())