Skip to content

Commit 2d47b9e

Browse files
committed
add ArrayIterator to iterator over array values
1 parent 61b32cf commit 2d47b9e

File tree

1 file changed

+81
-4
lines changed

1 file changed

+81
-4
lines changed

Diff for: parser.go

+81-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ var (
1919
OverflowIntegerError = errors.New("Value is number, but overflowed while parsing")
2020
MalformedStringEscapeError = errors.New("Encountered an invalid escape sequence in a string")
2121
NullValueError = errors.New("Value is null")
22+
DoneError = errors.New("Done. Reached End of Iterator")
2223
)
2324

2425
// How much stack space to allocate for unescaping JSON strings; if a string longer
@@ -707,12 +708,10 @@ func WriteToBuffer(buffer []byte, str string) int {
707708
}
708709

709710
/*
710-
711711
Del - Receives existing data structure, path to delete.
712712
713713
Returns:
714714
`data` - return modified data
715-
716715
*/
717716
func Delete(data []byte, keys ...string) []byte {
718717
lk := len(keys)
@@ -793,13 +792,11 @@ func Delete(data []byte, keys ...string) []byte {
793792
}
794793

795794
/*
796-
797795
Set - Receives existing data structure, path to set, and data to set at that key.
798796
799797
Returns:
800798
`value` - modified byte array
801799
`err` - On any parsing error
802-
803800
*/
804801
func Set(data []byte, setValue []byte, keys ...string) (value []byte, err error) {
805802
// ensure keys are set
@@ -1069,6 +1066,86 @@ func ArrayEach(data []byte, cb func(value []byte, dataType ValueType, offset int
10691066
return offset, nil
10701067
}
10711068

1069+
func ArrayIterator(data []byte, keys ...string) (next func() ([]byte, ValueType, int, error), err error) {
1070+
1071+
makeNextError := func(err error) func() ([]byte, ValueType, int, error) {
1072+
return func() ([]byte, ValueType, int, error) { return nil, NotExist, -1, err }
1073+
}
1074+
1075+
if len(data) == 0 {
1076+
return makeNextError(MalformedObjectError), MalformedObjectError
1077+
}
1078+
1079+
nT := nextToken(data)
1080+
if nT == -1 {
1081+
return makeNextError(MalformedJsonError), MalformedJsonError
1082+
}
1083+
1084+
offset := nT + 1
1085+
1086+
if len(keys) > 0 {
1087+
if offset = searchKeys(data, keys...); offset == -1 {
1088+
return makeNextError(KeyPathNotFoundError), KeyPathNotFoundError
1089+
}
1090+
1091+
// Go to closest value
1092+
nO := nextToken(data[offset:])
1093+
if nO == -1 {
1094+
return makeNextError(MalformedJsonError), MalformedJsonError
1095+
}
1096+
1097+
offset += nO
1098+
1099+
if data[offset] != '[' {
1100+
return makeNextError(MalformedArrayError), MalformedArrayError
1101+
}
1102+
1103+
offset++
1104+
}
1105+
1106+
isFirst, nextOffset := true, offset
1107+
1108+
next = func() ([]byte, ValueType, int, error) {
1109+
offset = nextOffset
1110+
1111+
nO := nextToken(data[offset:])
1112+
if nO == -1 {
1113+
return nil, NotExist, -1, MalformedJsonError
1114+
}
1115+
offset += nO
1116+
if data[offset] == ']' {
1117+
return nil, NotExist, -1, DoneError
1118+
}
1119+
1120+
if !isFirst && data[offset] != ',' {
1121+
return nil, NotExist, -1, MalformedArrayError
1122+
}
1123+
if !isFirst {
1124+
offset++
1125+
}
1126+
1127+
v, t, o, e := Get(data[offset:])
1128+
1129+
if e != nil {
1130+
return nil, NotExist, -1, e
1131+
}
1132+
1133+
if o == 0 {
1134+
return nil, NotExist, -1, DoneError
1135+
}
1136+
1137+
if t == NotExist {
1138+
return nil, NotExist, -1, DoneError
1139+
}
1140+
1141+
isFirst = false
1142+
nextOffset = offset + o
1143+
1144+
return v, t, offset - len(v), e
1145+
}
1146+
return next, nil
1147+
}
1148+
10721149
// ObjectEach iterates over the key-value pairs of a JSON object, invoking a given callback for each such entry
10731150
func ObjectEach(data []byte, callback func(key []byte, value []byte, dataType ValueType, offset int) error, keys ...string) (err error) {
10741151
offset := 0

0 commit comments

Comments
 (0)