| 305 | } |
| 306 | |
| 307 | final class ElementIterator implements Iterator<Element>, NodeVisitor { |
| 308 | // listeners add to a next emit queue, as a single token read step may yield multiple elements |
| 309 | final private Queue<Element> emitQueue = new LinkedList<>(); |
| 310 | private @Nullable Element current; // most recently emitted |
| 311 | private @Nullable Element next; // element waiting to be picked up |
| 312 | private @Nullable Element tail; // The last tailed element (</html>), on hold for final pop |
| 313 | |
| 314 | void reset() { |
| 315 | emitQueue.clear(); |
| 316 | current = next = tail = null; |
| 317 | stopped = false; |
| 318 | } |
| 319 | |
| 320 | // Iterator Interface: |
| 321 | /** |
| 322 | {@inheritDoc} |
| 323 | @throws UncheckedIOException if the underlying Reader errors during a read |
| 324 | */ |
| 325 | @Override public boolean hasNext() { |
| 326 | maybeFindNext(); |
| 327 | return next != null; |
| 328 | } |
| 329 | |
| 330 | /** |
| 331 | {@inheritDoc} |
| 332 | @throws UncheckedIOException if the underlying Reader errors during a read |
| 333 | */ |
| 334 | @Override public Element next() { |
| 335 | maybeFindNext(); |
| 336 | if (next == null) throw new NoSuchElementException(); |
| 337 | current = next; |
| 338 | next = null; |
| 339 | return current; |
| 340 | } |
| 341 | |
| 342 | private void maybeFindNext() { |
| 343 | if (stopped || next != null) return; |
| 344 | |
| 345 | // drain the current queue before stepping to get more |
| 346 | if (!emitQueue.isEmpty()) { |
| 347 | next = emitQueue.remove(); |
| 348 | return; |
| 349 | } |
| 350 | |
| 351 | // step the parser, which will hit the node listeners to add to the queue: |
| 352 | while (treeBuilder.stepParser()) { |
| 353 | if (!emitQueue.isEmpty()) { |
| 354 | next = emitQueue.remove(); |
| 355 | return; |
| 356 | } |
| 357 | } |
| 358 | stop(); |
| 359 | close(); |
| 360 | |
| 361 | // send the final element out: |
| 362 | if (tail != null) { |
| 363 | next = tail; |
| 364 | tail = null; |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…