SYS-REQ-006, SYS-REQ-028, SYS-REQ-029, SYS-REQ-052, SYS-REQ-053, SYS-REQ-055, SYS-REQ-083 ArrayEach is used when iterating arrays, accepts a callback function with the same return arguments as `Get`.
(data []byte, cb func(value []byte, dataType ValueType, offset int, err error), keys ...string)
| 1260 | // SYS-REQ-006, SYS-REQ-028, SYS-REQ-029, SYS-REQ-052, SYS-REQ-053, SYS-REQ-055, SYS-REQ-083 |
| 1261 | // ArrayEach is used when iterating arrays, accepts a callback function with the same return arguments as `Get`. |
| 1262 | func ArrayEach(data []byte, cb func(value []byte, dataType ValueType, offset int, err error), keys ...string) (offset int, err error) { |
| 1263 | if len(data) == 0 { |
| 1264 | return -1, MalformedObjectError |
| 1265 | } |
| 1266 | |
| 1267 | nT := nextToken(data) |
| 1268 | if nT == -1 { |
| 1269 | return -1, MalformedJsonError |
| 1270 | } |
| 1271 | |
| 1272 | // Guard: when ArrayEach is called without a key path, the addressed |
| 1273 | // root value must be an array. Without this guard, the main loop below |
| 1274 | // happily parses the first token of a non-array value (e.g. the opening |
| 1275 | // key of an object, or a bare number) as if it were an array element, |
| 1276 | // invoking the callback once with bogus data before eventually returning |
| 1277 | // MalformedArrayError. A caller performing side effects in the callback |
| 1278 | // would observe a spurious invocation on input that is not an array at |
| 1279 | // all. (SYS-REQ-029 partition: non-array root, no key path.) |
| 1280 | // When a key path IS provided, the keys block below already enforces the |
| 1281 | // same contract via its own `data[offset] != '['` check after resolving |
| 1282 | // the path, so the guard is only needed for the no-keys case. |
| 1283 | if len(keys) == 0 && data[nT] != '[' { |
| 1284 | return -1, MalformedArrayError |
| 1285 | } |
| 1286 | |
| 1287 | offset = nT + 1 |
| 1288 | |
| 1289 | if len(keys) > 0 { |
| 1290 | if offset = searchKeys(data, keys...); offset == -1 { |
| 1291 | return offset, KeyPathNotFoundError |
| 1292 | } |
| 1293 | |
| 1294 | // Go to closest value |
| 1295 | nO := nextToken(data[offset:]) |
| 1296 | if nO == -1 { |
| 1297 | return offset, MalformedJsonError |
| 1298 | } |
| 1299 | |
| 1300 | offset += nO |
| 1301 | |
| 1302 | if data[offset] != '[' { |
| 1303 | return offset, MalformedArrayError |
| 1304 | } |
| 1305 | |
| 1306 | offset++ |
| 1307 | } |
| 1308 | |
| 1309 | nO := nextToken(data[offset:]) |
| 1310 | if nO == -1 { |
| 1311 | return offset, MalformedJsonError |
| 1312 | } |
| 1313 | |
| 1314 | offset += nO |
| 1315 | |
| 1316 | if data[offset] == ']' { |
| 1317 | return offset, nil |
| 1318 | } |
| 1319 |