-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathdec_float_big.go
80 lines (72 loc) · 1.45 KB
/
dec_float_big.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package jx
import (
"io"
"math/big"
"github.com/go-faster/errors"
)
// BigFloat read big.Float
func (d *Decoder) BigFloat() (*big.Float, error) {
str, err := d.numberAppend(nil)
if err != nil {
return nil, errors.Wrap(err, "number")
}
prec := 64
if len(str) > prec {
prec = len(str)
}
val, _, err := big.ParseFloat(string(str), 10, uint(prec), big.ToZero)
if err != nil {
return nil, errors.Wrap(err, "float")
}
return val, nil
}
// BigInt read big.Int
func (d *Decoder) BigInt() (*big.Int, error) {
str, err := d.numberAppend(nil)
if err != nil {
return nil, errors.Wrap(err, "number")
}
v := big.NewInt(0)
var ok bool
if v, ok = v.SetString(string(str), 10); !ok {
return nil, errors.New("invalid")
}
return v, nil
}
func (d *Decoder) number() ([]byte, error) {
start := d.head
buf := d.buf[d.head:d.tail]
for i, c := range buf {
switch floatDigits[c] {
case invalidCharForNumber:
return nil, badToken(c, d.offset()+i)
case endOfNumber:
// End of number.
d.head += i
return d.buf[start:d.head], nil
default:
continue
}
}
// Buffer is number within head:tail.
d.head = d.tail
return d.buf[start:d.tail], nil
}
func (d *Decoder) numberAppend(b []byte) ([]byte, error) {
for {
r, err := d.number()
if err != nil {
return nil, err
}
b = append(b, r...)
if d.head != d.tail {
return b, nil
}
if err := d.read(); err != nil {
if err == io.EOF {
return b, nil
}
return b, err
}
}
}