2
* Copyright 2021 ByteDance Inc.
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
8
* http://www.apache.org/licenses/LICENSE-2.0
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.
22
`github.com/bytedance/sonic/internal/native/types`
30
// Values returns iterator for array's children traversal
31
func (self *Node) Values() (ListIterator, error) {
32
if err := self.should(types.V_ARRAY, "an array"); err != nil {
33
return ListIterator{}, err
35
return ListIterator{Iterator{p: self}}, nil
38
// Properties returns iterator for object's children traversal
39
func (self *Node) Properties() (ObjectIterator, error) {
40
if err := self.should(types.V_OBJECT, "an object"); err != nil {
41
return ObjectIterator{}, err
43
return ObjectIterator{Iterator{p: self}}, nil
51
func (self *Iterator) Pos() int {
55
func (self *Iterator) Len() int {
59
// HasNext reports if it is the end of iteration or has error.
60
func (self *Iterator) HasNext() bool {
62
return self.p.Valid() && self.i < self.p.len()
63
} else if self.p.t == _V_ARRAY_LAZY {
64
return self.p.skipNextNode().Valid()
65
} else if self.p.t == _V_OBJECT_LAZY {
66
pair := self.p.skipNextPair()
70
return pair.Value.Valid()
75
// ListIterator is specialized iterator for V_ARRAY
76
type ListIterator struct {
80
// ObjectIterator is specialized iterator for V_ARRAY
81
type ObjectIterator struct {
85
func (self *ListIterator) next() *Node {
90
n := self.p.nodeAt(self.i)
99
// Next scans through children of underlying V_ARRAY,
100
// copies each child to v, and returns .HasNext().
101
func (self *ListIterator) Next(v *Node) bool {
110
func (self *ObjectIterator) next() *Pair {
115
n := self.p.pairAt(self.i)
117
if !n.Value.Exists() {
124
// Next scans through children of underlying V_OBJECT,
125
// copies each child to v, and returns .HasNext().
126
func (self *ObjectIterator) Next(p *Pair) bool {
135
// Sequence represents scanning path of single-layer nodes.
136
// Index indicates the value's order in both V_ARRAY and V_OBJECT json.
137
// Key is the value's key (for V_OBJECT json only, otherwise it will be nil).
138
type Sequence struct {
144
// String is string representation of one Sequence
145
func (s Sequence) String() string {
150
return fmt.Sprintf("Sequence(%d, %q)", s.Index, k)
153
type Scanner func(path Sequence, node *Node) bool
155
// ForEach scans one V_OBJECT node's children from JSON head to tail,
156
// and pass the Sequence and Node of corresponding JSON value.
158
// Especailly, if the node is not V_ARRAY or V_OBJECT,
159
// the node itself will be returned and Sequence.Index == -1.
161
// NOTICE: A unsetted node WON'T trigger sc, but its index still counts into Path.Index
162
func (self *Node) ForEach(sc Scanner) error {
163
switch self.itype() {
165
iter, err := self.Values()
171
if !sc(Sequence{iter.i-1, nil}, v) {
177
iter, err := self.Properties()
183
if !sc(Sequence{iter.i-1, &v.Key}, &v.Value) {
189
if self.Check() != nil {
192
sc(Sequence{-1, nil}, self)