ArrayEach incrementally iterates a root JSON array. Callback value slices are valid for the duration of the callback and must be copied if retained. Memory use is bounded by the largest element plus the sliding read window. SYS-REQ-116
(cb func(value []byte, vt ValueType, err error))
| 114 | // Memory use is bounded by the largest element plus the sliding read window. |
| 115 | // SYS-REQ-116 |
| 116 | func (rp *ReaderParser) ArrayEach(cb func(value []byte, vt ValueType, err error)) error { |
| 117 | if err := rp.skipWhitespace(); err != nil { |
| 118 | if err == io.EOF { |
| 119 | return MalformedObjectError |
| 120 | } |
| 121 | return err |
| 122 | } |
| 123 | |
| 124 | b, err := rp.peekByte(false) |
| 125 | if err != nil { |
| 126 | return err |
| 127 | } |
| 128 | if b != '[' { |
| 129 | return MalformedArrayError |
| 130 | } |
| 131 | rp.pos++ |
| 132 | |
| 133 | if err := rp.skipWhitespace(); err != nil { |
| 134 | if err == io.EOF { |
| 135 | return MalformedArrayError |
| 136 | } |
| 137 | return err |
| 138 | } |
| 139 | b, err = rp.peekByte(false) |
| 140 | if err != nil { |
| 141 | return err |
| 142 | } |
| 143 | if b == ']' { |
| 144 | rp.pos++ |
| 145 | return nil |
| 146 | } |
| 147 | |
| 148 | for { |
| 149 | raw, captureErr := rp.captureValue() |
| 150 | if captureErr != nil { |
| 151 | cb(nil, Unknown, captureErr) |
| 152 | return captureErr |
| 153 | } |
| 154 | |
| 155 | value, vt, _, valueErr := rp.config.Get(raw) |
| 156 | cb(value, vt, valueErr) |
| 157 | if valueErr != nil { |
| 158 | return valueErr |
| 159 | } |
| 160 | |
| 161 | if err := rp.skipWhitespace(); err != nil { |
| 162 | if err == io.EOF { |
| 163 | return MalformedArrayError |
| 164 | } |
| 165 | return err |
| 166 | } |
| 167 | b, err = rp.peekByte(false) |
| 168 | if err != nil { |
| 169 | return err |
| 170 | } |
| 171 | switch b { |
| 172 | case ']': |
| 173 | rp.pos++ |