Skip to content

Commit 6c0395c

Browse files
committed
Merge branch 'pendo-io-cleanup-trailingbracket'
2 parents 1a60c8e + 4e16fcd commit 6c0395c

File tree

1 file changed

+22
-32
lines changed

1 file changed

+22
-32
lines changed

parser.go

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ import (
1212
// Find position of next character which is not ' ', ',', '}' or ']'
1313
func nextValue(data []byte) int {
1414
for i, c := range data {
15-
if c != ' ' && c != '\n' && c != '\r' && c != '\t' && c != ',' {
15+
switch c {
16+
case ' ', '\n', '\r', '\t', ',':
17+
continue
18+
default:
1619
return i
1720
}
1821
}
@@ -43,45 +46,33 @@ func stringEnd(data []byte) int {
4346

4447
// Find end of the data structure, array or object.
4548
// For array openSym and closeSym will be '[' and ']', for object '{' and '}'
46-
// Know about nested structures
47-
func trailingBracket(data []byte, openSym byte, closeSym byte) int {
49+
func blockEnd(data []byte, openSym byte, closeSym byte) int {
4850
level := 0
4951
i := 0
5052
ln := len(data)
5153

52-
for true {
53-
if i >= ln {
54-
return -1
55-
}
56-
57-
c := data[i]
58-
59-
// If inside string, skip it
60-
if c == '"' {
61-
//sFrom := i
62-
i++
63-
64-
se := stringEnd(data[i:])
54+
for i < ln {
55+
switch data[i] {
56+
case '"': // If inside string, skip it
57+
se := stringEnd(data[i+1:])
6558
if se == -1 {
6659
return -1
6760
}
68-
i += se - 1
69-
}
70-
71-
if c == openSym {
61+
i += se
62+
case openSym: // If open symbol, increase level
7263
level++
73-
} else if c == closeSym {
64+
case closeSym: // If close symbol, increase level
7465
level--
75-
}
7666

77-
i++
78-
79-
if level == 0 {
80-
break
67+
// If we have returned to the original level, we're done
68+
if level == 0 {
69+
return i + 1
70+
}
8171
}
72+
i++
8273
}
8374

84-
return i
75+
return -1
8576
}
8677

8778
func searchKeys(data []byte, keys ...string) int {
@@ -134,8 +125,8 @@ func searchKeys(data []byte, keys ...string) int {
134125
level--
135126
case '[':
136127
// Do not search for keys inside arrays
137-
aOff := trailingBracket(data[i:], '[', ']')
138-
i += aOff
128+
arraySkip := blockEnd(data[i:], '[', ']')
129+
i += arraySkip
139130
}
140131

141132
i++
@@ -169,7 +160,6 @@ Accept multiple keys to specify path to JSON value (in case of quering nested st
169160
If no keys provided it will try to extract closest JSON value (simple ones or object/array), useful for reading streams or arrays, see `ArrayEach` implementation.
170161
*/
171162
func Get(data []byte, keys ...string) (value []byte, dataType int, offset int, err error) {
172-
173163
if len(keys) > 0 {
174164
if offset = searchKeys(data, keys...); offset == -1 {
175165
return []byte{}, NotExist, -1, errors.New("Key path not found")
@@ -198,7 +188,7 @@ func Get(data []byte, keys ...string) (value []byte, dataType int, offset int, e
198188
} else if data[offset] == '[' { // if array value
199189
dataType = Array
200190
// break label, for stopping nested loops
201-
endOffset = trailingBracket(data[offset:], '[', ']')
191+
endOffset = blockEnd(data[offset:], '[', ']')
202192

203193
if endOffset == -1 {
204194
return []byte{}, dataType, offset, errors.New("Value is array, but can't find closing ']' symbol")
@@ -208,7 +198,7 @@ func Get(data []byte, keys ...string) (value []byte, dataType int, offset int, e
208198
} else if data[offset] == '{' { // if object value
209199
dataType = Object
210200
// break label, for stopping nested loops
211-
endOffset = trailingBracket(data[offset:], '{', '}')
201+
endOffset = blockEnd(data[offset:], '{', '}')
212202

213203
if endOffset == -1 {
214204
return []byte{}, dataType, offset, errors.New("Value looks like object, but can't find closing '}' symbol")

0 commit comments

Comments
 (0)