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)
| 1526 | // SYS-REQ-006, SYS-REQ-028, SYS-REQ-029, SYS-REQ-052, SYS-REQ-053, SYS-REQ-055, SYS-REQ-083 |
| 1527 | // ArrayEach is used when iterating arrays, accepts a callback function with the same return arguments as `Get`. |
| 1528 | func ArrayEach(data []byte, cb func(value []byte, dataType ValueType, offset int, err error), keys ...string) (offset int, err error) { |
| 1529 | if len(data) == 0 { |
| 1530 | return -1, MalformedObjectError |
| 1531 | } |
| 1532 | |
| 1533 | nT := nextToken(data) |
| 1534 | if nT == -1 { |
| 1535 | return -1, MalformedJsonError |
| 1536 | } |
| 1537 | |
| 1538 | // Guard: when ArrayEach is called without a key path, the addressed |
| 1539 | // root value must be an array. Without this guard, the main loop below |
| 1540 | // happily parses the first token of a non-array value (e.g. the opening |
| 1541 | // key of an object, or a bare number) as if it were an array element, |
| 1542 | // invoking the callback once with bogus data before eventually returning |
| 1543 | // MalformedArrayError. A caller performing side effects in the callback |
| 1544 | // would observe a spurious invocation on input that is not an array at |
| 1545 | // all. (SYS-REQ-029 partition: non-array root, no key path.) |
| 1546 | // When a key path IS provided, the keys block below already enforces the |
| 1547 | // same contract via its own `data[offset] != '['` check after resolving |
| 1548 | // the path, so the guard is only needed for the no-keys case. |
| 1549 | if len(keys) == 0 && data[nT] != '[' { |
| 1550 | return -1, MalformedArrayError |
| 1551 | } |
| 1552 | |
| 1553 | offset = nT + 1 |
| 1554 | |
| 1555 | if len(keys) > 0 { |
| 1556 | if offset = searchKeys(data, keys...); offset == -1 { |
| 1557 | return offset, KeyPathNotFoundError |
| 1558 | } |
| 1559 | |
| 1560 | // Go to closest value |
| 1561 | nO := nextToken(data[offset:]) |
| 1562 | if nO == -1 { |
| 1563 | return offset, MalformedJsonError |
| 1564 | } |
| 1565 | |
| 1566 | offset += nO |
| 1567 | |
| 1568 | if data[offset] != '[' { |
| 1569 | return offset, MalformedArrayError |
| 1570 | } |
| 1571 | |
| 1572 | offset++ |
| 1573 | } |
| 1574 | |
| 1575 | nO := nextToken(data[offset:]) |
| 1576 | if nO == -1 { |
| 1577 | return offset, MalformedJsonError |
| 1578 | } |
| 1579 | |
| 1580 | offset += nO |
| 1581 | |
| 1582 | if data[offset] == ']' { |
| 1583 | return offset, nil |
| 1584 | } |
| 1585 |