Skip to content

Commit 16b91a7

Browse files
committed
Should not ignore paths with same level
1 parent cd6d38b commit 16b91a7

File tree

2 files changed

+54
-12
lines changed

2 files changed

+54
-12
lines changed

parser.go

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,24 @@ func init() {
189189
}
190190
}
191191

192+
func sameTree(p1, p2 []string) bool {
193+
if len(p1) == 1 && len(p2) == 1 {
194+
return true
195+
}
196+
197+
for pi_1, p_1 := range p1[:len(p1)-1] {
198+
if len(p2)-2 < pi_1 {
199+
break
200+
}
201+
202+
if p2[pi_1] != p_1 {
203+
return false
204+
}
205+
}
206+
207+
return true
208+
}
209+
192210
func EachKey(data []byte, cb func(int, []byte, ValueType, error), paths ...[]string) int {
193211
var pathFlags, ignorePathFlags int64
194212
var level, pathsMatched, i int
@@ -219,7 +237,7 @@ func EachKey(data []byte, cb func(int, []byte, ValueType, error), paths ...[]str
219237

220238
// if string is a key, and key level match
221239
if data[i] == ':' {
222-
match := false
240+
match := -1
223241
key := data[keyBegin:keyEnd]
224242

225243
// for unescape: if there are no escape sequences, this is cheap; if there are, it is a
@@ -239,7 +257,7 @@ func EachKey(data []byte, cb func(int, []byte, ValueType, error), paths ...[]str
239257
}
240258

241259
if equalStr(&keyUnesc, p[level-1]) {
242-
match = true
260+
match = pi
243261

244262
if len(p) == level {
245263
i++
@@ -257,12 +275,10 @@ func EachKey(data []byte, cb func(int, []byte, ValueType, error), paths ...[]str
257275
return i
258276
}
259277
}
260-
} else {
261-
ignorePathFlags |= bitwiseFlags[pi]
262278
}
263279
}
264280

265-
if !match {
281+
if match == -1 {
266282
ignorePathFlags = 0
267283
tokenOffset := nextToken(data[i+1:])
268284
i += tokenOffset
@@ -271,6 +287,22 @@ func EachKey(data []byte, cb func(int, []byte, ValueType, error), paths ...[]str
271287
blockSkip := blockEnd(data[i:], '{', '}')
272288
i += blockSkip + 1
273289
}
290+
} else {
291+
m_p := paths[match]
292+
293+
for pi, p := range paths {
294+
if pi == match {
295+
continue
296+
}
297+
298+
if len(p) < level || (pathFlags & bitwiseFlags[pi]) != 0 || (ignorePathFlags & bitwiseFlags[pi] != 0) {
299+
continue
300+
}
301+
302+
if !sameTree(m_p, p) {
303+
ignorePathFlags |= bitwiseFlags[pi]
304+
}
305+
}
274306
}
275307

276308
switch data[i] {

parser_test.go

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,9 @@ var testJson = []byte(`{"name": "Name", "order": "Order", "sum": 100, "len": 12,
655655
func TestEachKey(t *testing.T) {
656656
paths := [][]string{
657657
[]string{"name"},
658+
[]string{"order"},
658659
[]string{"nested", "a"},
660+
[]string{"nested", "b"},
659661
[]string{"nested2", "a"},
660662
[]string{"nested", "nested3", "b"},
661663
}
@@ -671,24 +673,32 @@ func TestEachKey(t *testing.T) {
671673
t.Errorf("Should find 1 key")
672674
}
673675
case 1:
674-
if string(value) != "test" {
676+
if string(value) != "Order" {
675677
t.Errorf("Should find 2 key")
676678
}
677679
case 2:
678-
if string(value) != "test2" {
679-
t.Error("Should find 3 key", string(value))
680+
if string(value) != "test" {
681+
t.Errorf("Should find 2 key")
680682
}
681683
case 3:
684+
if string(value) != "2" {
685+
t.Errorf("Should find 3 key")
686+
}
687+
case 4:
688+
if string(value) != "test2" {
689+
t.Error("Should find 4 key", string(value))
690+
}
691+
case 5:
682692
if string(value) != "4" {
683-
t.Errorf("Should find 4 key")
693+
t.Errorf("Should find 5 key")
684694
}
685695
default:
686-
t.Errorf("Should found only 4 keys")
696+
t.Errorf("Should found only 6 keys")
687697
}
688698
}, paths...)
689699

690-
if keysFound != 4 {
691-
t.Errorf("Should find 4 keys: %d", keysFound)
700+
if keysFound != 6 {
701+
t.Errorf("Should find 6 keys: %d", keysFound)
692702
}
693703
}
694704

0 commit comments

Comments
 (0)