-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathdec_obj.go
91 lines (85 loc) · 1.99 KB
/
dec_obj.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
81
82
83
84
85
86
87
88
89
90
91
package jx
import (
"github.com/ogen-go/errors"
)
func skipObjBytes(d *Decoder, _ []byte) error { return d.Skip() }
// ObjBytes calls f for every key in object, using byte slice as key.
//
// The key value is valid only until f is not returned.
func (d *Decoder) ObjBytes(f func(d *Decoder, key []byte) error) error {
skip := f == nil
if skip {
// No callback is provided, skipping object.
// Drop keys, skip values.
f = skipObjBytes
}
if err := d.consume('{'); err != nil {
return errors.Wrap(err, "start")
}
if err := d.incDepth(); err != nil {
return errors.Wrap(err, "inc")
}
c, err := d.more()
if err != nil {
return errors.Wrap(err, "next")
}
if c == '}' {
return d.decDepth()
}
d.unread()
k, err := d.str(value{ignore: skip})
if err != nil {
return errors.Wrap(err, "str")
}
if err := d.consume(':'); err != nil {
return errors.Wrap(err, "field")
}
// Skip whitespace.
if _, err = d.more(); err != nil {
return errors.Wrap(err, "more")
}
d.unread()
if err := f(d, k.buf); err != nil {
return errors.Wrap(err, "callback")
}
c, err = d.more()
if err != nil {
return errors.Wrap(err, "next")
}
for c == ',' {
k, err := d.str(value{ignore: skip})
if err != nil {
return errors.Wrap(err, "str")
}
if err := d.consume(':'); err != nil {
return errors.Wrap(err, "field")
}
// Check that value exists.
if _, err = d.more(); err != nil {
return errors.Wrap(err, "more")
}
d.unread()
if err := f(d, k.buf); err != nil {
return errors.Wrap(err, "callback")
}
if c, err = d.more(); err != nil {
return errors.Wrap(err, "next")
}
}
if c != '}' {
return errors.Wrap(badToken(c), "err")
}
return d.decDepth()
}
// Obj reads json object, calling f on each field.
//
// Use ObjBytes to reduce heap allocations for keys.
func (d *Decoder) Obj(f func(d *Decoder, key string) error) error {
if f == nil {
// Skipping object.
return d.ObjBytes(nil)
}
return d.ObjBytes(func(d *Decoder, key []byte) error {
return f(d, string(key))
})
}