...
1 package jsonpath
2
3 import (
4 "encoding/json"
5 "io"
6 )
7
8
9 type KeyString string
10
11
12 type Decoder struct {
13 json.Decoder
14
15 path JsonPath
16 context jsonContext
17 }
18
19
20 func NewDecoder(r io.Reader) *Decoder {
21 return &Decoder{Decoder: *json.NewDecoder(r)}
22 }
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 func (d *Decoder) SeekTo(path ...interface{}) (bool, error) {
41
42 if len(path) > 0 {
43 last := len(path) - 1
44 if i, ok := path[last].(int); ok {
45 path[last] = i - 1
46 }
47 }
48
49 for {
50 if len(path) == len(d.path) && d.path.Equal(path) {
51 return true, nil
52 }
53 _, err := d.Token()
54 if err == io.EOF {
55 return false, nil
56 } else if err != nil {
57 return false, err
58 }
59 }
60 }
61
62
63
64 func (d *Decoder) Decode(v interface{}) error {
65 switch d.context {
66 case objValue:
67 d.context = objKey
68 break
69 case arrValue:
70 d.path.incTop()
71 break
72 }
73 return d.Decoder.Decode(v)
74 }
75
76
77
78 func (d *Decoder) Path() JsonPath {
79 p := make(JsonPath, len(d.path))
80 copy(p, d.path)
81 return p
82 }
83
84
85
86
87 func (d *Decoder) Token() (json.Token, error) {
88 t, err := d.Decoder.Token()
89 if err != nil {
90 return t, err
91 }
92
93 if t == nil {
94 switch d.context {
95 case objValue:
96 d.context = objKey
97 break
98 case arrValue:
99 d.path.incTop()
100 break
101 }
102 return t, err
103 }
104
105 switch t := t.(type) {
106 case json.Delim:
107 switch t {
108 case json.Delim('{'):
109 if d.context == arrValue {
110 d.path.incTop()
111 }
112 d.path.push("")
113 d.context = objKey
114 break
115 case json.Delim('}'):
116 d.path.pop()
117 d.context = d.path.inferContext()
118 break
119 case json.Delim('['):
120 if d.context == arrValue {
121 d.path.incTop()
122 }
123 d.path.push(-1)
124 d.context = arrValue
125 break
126 case json.Delim(']'):
127 d.path.pop()
128 d.context = d.path.inferContext()
129 break
130 }
131 case float64, json.Number, bool:
132 switch d.context {
133 case objValue:
134 d.context = objKey
135 break
136 case arrValue:
137 d.path.incTop()
138 break
139 }
140 break
141 case string:
142 switch d.context {
143 case objKey:
144 d.path.nameTop(t)
145 d.context = objValue
146 return KeyString(t), err
147 case objValue:
148 d.context = objKey
149 case arrValue:
150 d.path.incTop()
151 }
152 break
153 }
154
155 return t, err
156 }
157
158
159
160
161
162 func (d *Decoder) Scan(ext *PathActions) (bool, error) {
163
164 rootPath := d.Path()
165
166
167 if rootPath.inferContext() == arrValue {
168 rootPath.incTop()
169 }
170
171 for {
172
173 _, err := d.Token()
174 if err != nil {
175 return false, err
176 }
177
178 match:
179 var relPath JsonPath
180
181
182 path := d.Path()
183
184 if len(path) > len(rootPath) {
185
186 relPath = path[len(rootPath):]
187 } else {
188
189
190 return d.Decoder.More(), nil
191 }
192
193
194 if node := ext.node.match(relPath); node != nil {
195 if node.action != nil {
196
197 err = node.action(d)
198 if err != nil {
199 return d.Decoder.More(), err
200 }
201
202
203 if d.path.inferContext() == arrValue && d.Decoder.More() {
204 goto match
205 }
206 }
207 }
208 }
209 }
210
View as plain text