jdk/src/java.base/share/classes/java/util/Scanner.java
changeset 44855 30e9f8892612
parent 44844 b2b4d98404ba
--- a/jdk/src/java.base/share/classes/java/util/Scanner.java	Fri Apr 28 14:16:33 2017 +0100
+++ b/jdk/src/java.base/share/classes/java/util/Scanner.java	Fri Apr 28 12:16:30 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2846,6 +2846,7 @@
     class FindSpliterator extends Spliterators.AbstractSpliterator<MatchResult> {
         final Pattern pattern;
         int expectedCount = -1;
+        private boolean advance = false; // true if we need to auto-advance
 
         FindSpliterator(Pattern pattern) {
             super(Long.MAX_VALUE,
@@ -2861,12 +2862,15 @@
                     throw new ConcurrentModificationException();
                 }
             } else {
+                // init
+                matchValid = false;
+                matcher.usePattern(pattern);
                 expectedCount = modCount;
             }
 
             while (true) {
                 // assert expectedCount == modCount
-                if (findPatternInBuffer(pattern, 0)) { // doesn't increment modCount
+                if (nextInBuffer()) { // doesn't increment modCount
                     cons.accept(matcher.toMatchResult());
                     if (expectedCount != modCount) {
                         throw new ConcurrentModificationException();
@@ -2879,6 +2883,29 @@
                     return false; // reached end of input
             }
         }
+
+        // reimplementation of findPatternInBuffer with auto-advance on zero-length matches
+        private boolean nextInBuffer() {
+            if (advance) {
+                if (position + 1 > buf.limit()) {
+                    if (!sourceClosed)
+                        needInput = true;
+                    return false;
+                }
+                position++;
+                advance = false;
+            }
+            matcher.region(position, buf.limit());
+            if (matcher.find() && (!matcher.hitEnd() || sourceClosed)) {
+                 // Did not hit end, or hit real end
+                 position = matcher.end();
+                 advance = matcher.start() == position;
+                 return true;
+            }
+            if (!sourceClosed)
+                needInput = true;
+            return false;
+        }
     }
 
     /** Small LRU cache of Patterns. */