Fixing StringReader to support skipping negative distances. This bizarre behaviour is required by the spec.

git-svn-id: https://svn.apache.org/repos/asf/harmony/enhanced/classlib/trunk@881092 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/modules/luni/src/main/java/java/io/StringReader.java b/modules/luni/src/main/java/java/io/StringReader.java
index c700b78..30561b0 100644
--- a/modules/luni/src/main/java/java/io/StringReader.java
+++ b/modules/luni/src/main/java/java/io/StringReader.java
@@ -221,13 +221,19 @@
     }
 
     /**
-     * Skips {@code amount} characters in the source string. Subsequent calls of
-     * {@code read} methods will not return these characters unless {@code
-     * reset()} is used.
-     * 
+     * Moves {@code ns} characters in the source string. Unlike the {@link
+     * Reader#skip(long) overridden method}, this method may skip negative skip
+     * distances: this rewinds the input so that characters may be read again.
+     * When the end of the source string has been reached, the input cannot be
+     * rewound.
+     *
      * @param ns
-     *            the maximum number of characters to skip.
-     * @return the number of characters actually skipped or 0 if {@code ns < 0}.
+     *            the maximum number of characters to skip. Positive values skip
+     *            forward; negative values skip backward.
+     * @return the number of characters actually skipped. This is bounded below
+     *            by the number of characters already read and above by the
+     *            number of characters remaining:<br> {@code -(num chars already
+     *            read) <= distance skipped <= num chars remaining}.
      * @throws IOException
      *             if this reader is closed.
      * @see #mark(int)
@@ -240,18 +246,18 @@
             if (isClosed()) {
                 throw new IOException(Msg.getString("K0083")); //$NON-NLS-1$
             }
-            if (ns <= 0) {
-                return 0;
+
+            int minSkip = -pos;
+            int maxSkip = count - pos;
+
+            if (maxSkip == 0 || ns > maxSkip) {
+                ns = maxSkip; // no rewinding if we're at the end
+            } else if (ns < minSkip) {
+                ns = minSkip;
             }
-            long skipped = 0;
-            if (ns < this.count - pos) {
-                pos = pos + (int) ns;
-                skipped = ns;
-            } else {
-                skipped = this.count - pos;
-                pos = this.count;
-            }
-            return skipped;
+
+            pos += ns;
+            return ns;
         }
     }
 }