iterator.go raw
1 /*
2 * Copyright 2021 ByteDance Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package ast
18
19 import (
20 "fmt"
21
22 "github.com/bytedance/sonic/internal/caching"
23 "github.com/bytedance/sonic/internal/native/types"
24 )
25
26 type Pair struct {
27 hash uint64
28 Key string
29 Value Node
30 }
31
32 func NewPair(key string, val Node) Pair {
33 return Pair{
34 hash: caching.StrHash(key),
35 Key: key,
36 Value: val,
37 }
38 }
39
40 // Values returns iterator for array's children traversal
41 func (self *Node) Values() (ListIterator, error) {
42 if err := self.should(types.V_ARRAY); err != nil {
43 return ListIterator{}, err
44 }
45 return self.values(), nil
46 }
47
48 func (self *Node) values() ListIterator {
49 return ListIterator{Iterator{p: self}}
50 }
51
52 // Properties returns iterator for object's children traversal
53 func (self *Node) Properties() (ObjectIterator, error) {
54 if err := self.should(types.V_OBJECT); err != nil {
55 return ObjectIterator{}, err
56 }
57 return self.properties(), nil
58 }
59
60 func (self *Node) properties() ObjectIterator {
61 return ObjectIterator{Iterator{p: self}}
62 }
63
64 type Iterator struct {
65 i int
66 p *Node
67 }
68
69 func (self *Iterator) Pos() int {
70 return self.i
71 }
72
73 func (self *Iterator) Len() int {
74 return self.p.len()
75 }
76
77 // HasNext reports if it is the end of iteration or has error.
78 func (self *Iterator) HasNext() bool {
79 if !self.p.isLazy() {
80 return self.p.Valid() && self.i < self.p.len()
81 } else if self.p.t == _V_ARRAY_LAZY {
82 return self.p.skipNextNode().Valid()
83 } else if self.p.t == _V_OBJECT_LAZY {
84 pair := self.p.skipNextPair()
85 if pair == nil {
86 return false
87 }
88 return pair.Value.Valid()
89 }
90 return false
91 }
92
93 // ListIterator is specialized iterator for V_ARRAY
94 type ListIterator struct {
95 Iterator
96 }
97
98 // ObjectIterator is specialized iterator for V_ARRAY
99 type ObjectIterator struct {
100 Iterator
101 }
102
103 func (self *ListIterator) next() *Node {
104 next_start:
105 if !self.HasNext() {
106 return nil
107 } else {
108 n := self.p.nodeAt(self.i)
109 self.i++
110 if !n.Exists() {
111 goto next_start
112 }
113 return n
114 }
115 }
116
117 // Next scans through children of underlying V_ARRAY,
118 // copies each child to v, and returns .HasNext().
119 func (self *ListIterator) Next(v *Node) bool {
120 n := self.next()
121 if n == nil {
122 return false
123 }
124 *v = *n
125 return true
126 }
127
128 func (self *ObjectIterator) next() *Pair {
129 next_start:
130 if !self.HasNext() {
131 return nil
132 } else {
133 n := self.p.pairAt(self.i)
134 self.i++
135 if n == nil || !n.Value.Exists() {
136 goto next_start
137 }
138 return n
139 }
140 }
141
142 // Next scans through children of underlying V_OBJECT,
143 // copies each child to v, and returns .HasNext().
144 func (self *ObjectIterator) Next(p *Pair) bool {
145 n := self.next()
146 if n == nil {
147 return false
148 }
149 *p = *n
150 return true
151 }
152
153 // Sequence represents scanning path of single-layer nodes.
154 // Index indicates the value's order in both V_ARRAY and V_OBJECT json.
155 // Key is the value's key (for V_OBJECT json only, otherwise it will be nil).
156 type Sequence struct {
157 Index int
158 Key *string
159 // Level int
160 }
161
162 // String is string representation of one Sequence
163 func (s Sequence) String() string {
164 k := ""
165 if s.Key != nil {
166 k = *s.Key
167 }
168 return fmt.Sprintf("Sequence(%d, %q)", s.Index, k)
169 }
170
171 type Scanner func(path Sequence, node *Node) bool
172
173 // ForEach scans one V_OBJECT node's children from JSON head to tail,
174 // and pass the Sequence and Node of corresponding JSON value.
175 //
176 // Especially, if the node is not V_ARRAY or V_OBJECT,
177 // the node itself will be returned and Sequence.Index == -1.
178 //
179 // NOTICE: A unsetted node WON'T trigger sc, but its index still counts into Path.Index
180 func (self *Node) ForEach(sc Scanner) error {
181 if err := self.checkRaw(); err != nil {
182 return err
183 }
184 switch self.itype() {
185 case types.V_ARRAY:
186 iter, err := self.Values()
187 if err != nil {
188 return err
189 }
190 v := iter.next()
191 for v != nil {
192 if !sc(Sequence{iter.i-1, nil}, v) {
193 return nil
194 }
195 v = iter.next()
196 }
197 case types.V_OBJECT:
198 iter, err := self.Properties()
199 if err != nil {
200 return err
201 }
202 v := iter.next()
203 for v != nil {
204 if !sc(Sequence{iter.i-1, &v.Key}, &v.Value) {
205 return nil
206 }
207 v = iter.next()
208 }
209 default:
210 if self.Check() != nil {
211 return self
212 }
213 sc(Sequence{-1, nil}, self)
214 }
215 return nil
216 }
217