iterator.go (4273B)
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/native/types` 23 ) 24 25 type Pair struct { 26 Key string 27 Value Node 28 } 29 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 34 } 35 return ListIterator{Iterator{p: self}}, nil 36 } 37 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 42 } 43 return ObjectIterator{Iterator{p: self}}, nil 44 } 45 46 type Iterator struct { 47 i int 48 p *Node 49 } 50 51 func (self *Iterator) Pos() int { 52 return self.i 53 } 54 55 func (self *Iterator) Len() int { 56 return self.p.len() 57 } 58 59 // HasNext reports if it is the end of iteration or has error. 60 func (self *Iterator) HasNext() bool { 61 if !self.p.isLazy() { 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() 67 if pair == nil { 68 return false 69 } 70 return pair.Value.Valid() 71 } 72 return false 73 } 74 75 // ListIterator is specialized iterator for V_ARRAY 76 type ListIterator struct { 77 Iterator 78 } 79 80 // ObjectIterator is specialized iterator for V_ARRAY 81 type ObjectIterator struct { 82 Iterator 83 } 84 85 // Next scans through children of underlying V_ARRAY, 86 // copies each child to v, and returns .HasNext(). 87 func (self *ListIterator) Next(v *Node) bool { 88 if !self.HasNext() { 89 return false 90 } else { 91 *v, self.i = *self.p.nodeAt(self.i), self.i + 1 92 return true 93 } 94 } 95 96 // Next scans through children of underlying V_OBJECT, 97 // copies each child to v, and returns .HasNext(). 98 func (self *ObjectIterator) Next(p *Pair) bool { 99 if !self.HasNext() { 100 return false 101 } else { 102 *p, self.i = *self.p.pairAt(self.i), self.i + 1 103 return true 104 } 105 } 106 107 // Sequence represents scanning path of single-layer nodes. 108 // Index indicates the value's order in both V_ARRAY and V_OBJECT json. 109 // Key is the value's key (for V_OBJECT json only, otherwise it will be nil). 110 type Sequence struct { 111 Index int 112 Key *string 113 // Level int 114 } 115 116 // String is string representation of one Sequence 117 func (s Sequence) String() string { 118 k := "" 119 if s.Key != nil { 120 k = *s.Key 121 } 122 return fmt.Sprintf("Sequence(%d, %q)", s.Index, k) 123 } 124 125 type Scanner func(path Sequence, node *Node) bool 126 127 // ForEach scans one V_OBJECT node's children from JSON head to tail, 128 // and pass the Sequence and Node of corresponding JSON value. 129 // 130 // Especailly, if the node is not V_ARRAY or V_OBJECT, 131 // the node itself will be returned and Sequence.Index == -1. 132 func (self *Node) ForEach(sc Scanner) error { 133 switch self.itype() { 134 case types.V_ARRAY: 135 ns, err := self.UnsafeArray() 136 if err != nil { 137 return err 138 } 139 for i := range ns { 140 if !sc(Sequence{i, nil}, &ns[i]) { 141 return err 142 } 143 } 144 case types.V_OBJECT: 145 ns, err := self.UnsafeMap() 146 if err != nil { 147 return err 148 } 149 for i := range ns { 150 if !sc(Sequence{i, &ns[i].Key}, &ns[i].Value) { 151 return err 152 } 153 } 154 default: 155 sc(Sequence{-1, nil}, self) 156 } 157 return self.Check() 158 } 159 160 type PairSlice []Pair 161 162 func (self PairSlice) Sort() { 163 radixQsort(self, 0, maxDepth(len(self))) 164 }