-
Notifications
You must be signed in to change notification settings - Fork 4
/
dec_num.go
77 lines (67 loc) · 1.47 KB
/
dec_num.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
package jx
import (
"github.com/go-faster/errors"
)
// Num decodes number.
//
// Do not retain returned value, it references underlying buffer.
func (d *Decoder) Num() (Num, error) {
return d.num(nil, false)
}
// NumAppend appends number.
func (d *Decoder) NumAppend(v Num) (Num, error) {
return d.num(v, true)
}
// num decodes number.
func (d *Decoder) num(v Num, forceAppend bool) (Num, error) {
switch d.Next() {
case String:
offset := d.offset()
start := d.head
str, err := d.str(value{raw: true})
if err != nil {
return Num{}, errors.Wrap(err, "str")
}
// Validate number.
{
d := Decoder{}
d.ResetBytes(str.buf)
c, err := d.next()
if err != nil {
return Num{}, err
}
switch c {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-':
d.unread()
if err := d.skipNumber(); err != nil {
return Num{}, errors.Wrap(err, "skip number")
}
default:
return nil, badToken(c, offset)
}
}
// If string is escaped or decoder is streaming, copy it.
if !str.raw || forceAppend {
v = append(v, '"')
v = append(v, str.buf...)
v = append(v, '"')
return v, nil
}
return d.buf[start:d.head], nil
case Number: // float or integer
if forceAppend {
raw, err := d.RawAppend(Raw(v))
if err != nil {
return nil, err
}
return Num(raw), nil
}
raw, err := d.Raw()
if err != nil {
return nil, err
}
return Num(raw), nil
default:
return v, errors.Errorf("unexpected %s", d.Next())
}
}