podman

Форк
0
195 строк · 4.7 Кб
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
func (self *ListIterator) next() *Node {
86
next_start:
87
    if !self.HasNext() {
88
        return nil
89
    } else {
90
        n := self.p.nodeAt(self.i)
91
        self.i++
92
        if !n.Exists() {
93
            goto next_start
94
        }
95
        return n
96
    }
97
}
98

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 {
102
    n := self.next()
103
    if n == nil {
104
        return false
105
    }
106
    *v = *n
107
    return true
108
}
109

110
func (self *ObjectIterator) next() *Pair {
111
next_start:
112
    if !self.HasNext() {
113
        return nil
114
    } else {
115
        n := self.p.pairAt(self.i)
116
        self.i++
117
        if !n.Value.Exists() {
118
            goto next_start
119
        }
120
        return n
121
    }
122
}
123

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 {
127
    n := self.next()
128
    if n == nil {
129
        return false
130
    }
131
    *p = *n
132
    return true
133
}
134

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 {
139
    Index int 
140
    Key *string
141
    // Level int
142
}
143

144
// String is string representation of one Sequence
145
func (s Sequence) String() string {
146
    k := ""
147
    if s.Key != nil {
148
        k = *s.Key
149
    }
150
    return fmt.Sprintf("Sequence(%d, %q)", s.Index, k)
151
}
152

153
type Scanner func(path Sequence, node *Node) bool
154

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.
157
//
158
// Especailly, if the node is not V_ARRAY or V_OBJECT, 
159
// the node itself will be returned and Sequence.Index == -1.
160
// 
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() {
164
    case types.V_ARRAY:
165
        iter, err := self.Values()
166
        if err != nil {
167
            return err
168
        }
169
        v := iter.next()
170
        for v != nil {
171
            if !sc(Sequence{iter.i-1, nil}, v) {
172
                return nil
173
            }
174
            v = iter.next()
175
        }
176
    case types.V_OBJECT:
177
        iter, err := self.Properties()
178
        if err != nil {
179
            return err
180
        }
181
        v := iter.next()
182
        for v != nil {
183
            if !sc(Sequence{iter.i-1, &v.Key}, &v.Value) {
184
                return nil
185
            }
186
            v = iter.next()
187
        }
188
    default:
189
        if self.Check() != nil {
190
            return self
191
        }
192
        sc(Sequence{-1, nil}, self)
193
    }
194
    return nil
195
}
196

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.