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)
| 1286 | // SYS-REQ-006, SYS-REQ-028, SYS-REQ-029, SYS-REQ-052, SYS-REQ-053, SYS-REQ-055, SYS-REQ-083 |
| 1287 | // ArrayEach is used when iterating arrays, accepts a callback function with the same return arguments as `Get`. |
| 1288 | func ArrayEach(data []byte, cb func(value []byte, dataType ValueType, offset int, err error), keys ...string) (offset int, err error) { |
| 1289 | if len(data) == 0 { |
| 1290 | return -1, MalformedObjectError |
| 1291 | } |
| 1292 | |
| 1293 | nT := nextToken(data) |
| 1294 | if nT == -1 { |
| 1295 | return -1, MalformedJsonError |
| 1296 | } |
| 1297 | |
| 1298 | // Guard: when ArrayEach is called without a key path, the addressed |
| 1299 | // root value must be an array. Without this guard, the main loop below |
| 1300 | // happily parses the first token of a non-array value (e.g. the opening |
| 1301 | // key of an object, or a bare number) as if it were an array element, |
| 1302 | // invoking the callback once with bogus data before eventually returning |
| 1303 | // MalformedArrayError. A caller performing side effects in the callback |
| 1304 | // would observe a spurious invocation on input that is not an array at |
| 1305 | // all. (SYS-REQ-029 partition: non-array root, no key path.) |
| 1306 | // When a key path IS provided, the keys block below already enforces the |
| 1307 | // same contract via its own `data[offset] != '['` check after resolving |
| 1308 | // the path, so the guard is only needed for the no-keys case. |
| 1309 | if len(keys) == 0 && data[nT] != '[' { |
| 1310 | return -1, MalformedArrayError |
| 1311 | } |
| 1312 | |
| 1313 | offset = nT + 1 |
| 1314 | |
| 1315 | if len(keys) > 0 { |
| 1316 | if offset = searchKeys(data, keys...); offset == -1 { |
| 1317 | return offset, KeyPathNotFoundError |
| 1318 | } |
| 1319 | |
| 1320 | // Go to closest value |
| 1321 | nO := nextToken(data[offset:]) |
| 1322 | if nO == -1 { |
| 1323 | return offset, MalformedJsonError |
| 1324 | } |
| 1325 | |
| 1326 | offset += nO |
| 1327 | |
| 1328 | if data[offset] != '[' { |
| 1329 | return offset, MalformedArrayError |
| 1330 | } |
| 1331 | |
| 1332 | offset++ |
| 1333 | } |
| 1334 | |
| 1335 | nO := nextToken(data[offset:]) |
| 1336 | if nO == -1 { |
| 1337 | return offset, MalformedJsonError |
| 1338 | } |
| 1339 | |
| 1340 | offset += nO |
| 1341 | |
| 1342 | if data[offset] == ']' { |
| 1343 | return offset, nil |
| 1344 | } |
| 1345 |