Author: desruisseaux
Date: Sat Dec 15 09:45:05 2012
New Revision: 1422209

URL: http://svn.apache.org/viewvc?rev=1422209&view=rev
Log:
Added a CharSequences.lastIndexOf(...) method, and documentation updates.

Modified:
    
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
    
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java

Modified: 
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java?rev=1422209&r1=1422208&r2=1422209&view=diff
==============================================================================
--- 
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
 (original)
+++ 
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
 Sat Dec 15 09:45:05 2012
@@ -301,57 +301,6 @@ public final class CharSequences extends
     }
 
     /**
-     * Returns the index within the given character sequence of the first 
occurrence of the
-     * specified character, starting the search at the specified index. If the 
character is
-     * not found, then this method returns -1.
-     *
-     * <p>There is no restriction on the value of {@code fromIndex}. If 
negative or greater
-     * than {@code toIndex}, then the behavior of this method is as if the 
search started
-     * from 0 or {@code toIndex} respectively. This is consistent with the 
behavior documented
-     * in {@link String#indexOf(int, int)}.</p>
-     *
-     * @param  text      The character sequence in which to perform the 
search, or {@code null}.
-     * @param  toSearch  The Unicode code point of the character to search.
-     * @param  fromIndex The index to start the search from.
-     * @param  toIndex   The index after the last character where to perform 
the search.
-     * @return The index of the first occurrence of the given character in the 
text, or -1
-     *         if no occurrence has been found or if the {@code text} argument 
is null.
-     *
-     * @see String#indexOf(int, int)
-     */
-    public static int indexOf(final CharSequence text, final int toSearch, int 
fromIndex, int toIndex) {
-        if (text != null) {
-            final int length = text.length();
-            if (toIndex > length) {
-                toIndex = length;
-            }
-            if (text instanceof String && toIndex == length) {
-                // String provides a faster implementation.
-                return ((String) text).indexOf(toSearch, fromIndex);
-            }
-            if (fromIndex < 0) {
-                fromIndex = 0;
-            }
-            char head  = (char) toSearch;
-            char tail  = (char) 0;
-            if (head != toSearch) { // Outside BMP plane?
-                head = highSurrogate(toSearch);
-                tail = lowSurrogate (toSearch);
-                toIndex--;
-            }
-            while (fromIndex < toIndex) {
-                if (text.charAt(fromIndex) == head) {
-                    if (tail == 0 || text.charAt(fromIndex+1) == tail) {
-                        return fromIndex;
-                    }
-                }
-                fromIndex++;
-            }
-        }
-        return -1;
-    }
-
-    /**
      * Returns the index within the given strings of the first occurrence of 
the specified part,
      * starting at the specified index. This method is equivalent to the 
following method call,
      * except that this method works on arbitrary {@link CharSequence} objects 
instead than
@@ -414,6 +363,107 @@ search:     for (; fromIndex <= toIndex;
     }
 
     /**
+     * Returns the index within the given character sequence of the first 
occurrence of the
+     * specified character, starting the search at the specified index. If the 
character is
+     * not found, then this method returns -1.
+     *
+     * <p>There is no restriction on the value of {@code fromIndex}. If 
negative or greater
+     * than {@code toIndex}, then the behavior of this method is as if the 
search started
+     * from 0 or {@code toIndex} respectively. This is consistent with the 
behavior documented
+     * in {@link String#indexOf(int, int)}.</p>
+     *
+     * @param  text      The character sequence in which to perform the 
search, or {@code null}.
+     * @param  toSearch  The Unicode code point of the character to search.
+     * @param  fromIndex The index to start the search from.
+     * @param  toIndex   The index after the last character where to perform 
the search.
+     * @return The index of the first occurrence of the given character in the 
specified sub-sequence,
+     *         or -1 if no occurrence has been found or if the {@code text} 
argument is null.
+     *
+     * @see String#indexOf(int, int)
+     */
+    public static int indexOf(final CharSequence text, final int toSearch, int 
fromIndex, int toIndex) {
+        if (text != null) {
+            final int length = text.length();
+            if (toIndex >= length) {
+                if (text instanceof String) {
+                    // String provides a faster implementation.
+                    return ((String) text).indexOf(toSearch, fromIndex);
+                }
+                toIndex = length;
+            }
+            if (fromIndex < 0) {
+                fromIndex = 0;
+            }
+            char head = (char) toSearch;
+            char tail = (char) 0;
+            if (head != toSearch) { // Outside BMP plane?
+                head = highSurrogate(toSearch);
+                tail = lowSurrogate (toSearch);
+                toIndex--;
+            }
+            while (fromIndex < toIndex) {
+                if (text.charAt(fromIndex) == head) {
+                    if (tail == 0 || text.charAt(fromIndex+1) == tail) {
+                        return fromIndex;
+                    }
+                }
+                fromIndex++;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Returns the index within the given character sequence of the last 
occurrence of the
+     * specified character, searching backward in the given index range.
+     * If the character is not found, then this method returns -1.
+     *
+     * <p>There is no restriction on the value of {@code toIndex}. If greater 
than the text length
+     * or less than {@code fromIndex}, then the behavior of this method is as 
if the search started
+     * from {@code length} or {@code fromIndex} respectively. This is 
consistent with the behavior
+     * documented in {@link String#lastIndexOf(int, int)}.</p>
+     *
+     * @param  text      The character sequence in which to perform the 
search, or {@code null}.
+     * @param  toSearch  The Unicode code point of the character to search.
+     * @param  fromIndex The index of the first character in the range where 
to perform the search.
+     * @param  toIndex   The index after the last character in the range where 
to perform the search.
+     * @return The index of the last occurrence of the given character in the 
specified sub-sequence,
+     *         or -1 if no occurrence has been found or if the {@code text} 
argument is null.
+     *
+     * @see String#lastIndexOf(int, int)
+     */
+    public static int lastIndexOf(final CharSequence text, final int toSearch, 
int fromIndex, int toIndex) {
+        if (text != null) {
+            if (fromIndex <= 0) {
+                if (text instanceof String) {
+                    // String provides a faster implementation.
+                    return ((String) text).lastIndexOf(toSearch, toIndex - 1);
+                }
+                fromIndex = 0;
+            }
+            final int length = text.length();
+            if (toIndex > length) {
+                toIndex = length;
+            }
+            char tail = (char) toSearch;
+            char head = (char) 0;
+            if (tail != toSearch) { // Outside BMP plane?
+                tail = lowSurrogate (toSearch);
+                head = highSurrogate(toSearch);
+                fromIndex++;
+            }
+            while (toIndex > fromIndex) {
+                if (text.charAt(--toIndex) == tail) {
+                    if (head == 0 || text.charAt(--toIndex) == head) {
+                        return toIndex;
+                    }
+                }
+            }
+        }
+        return -1;
+    }
+
+    /**
      * Returns the index of the first character after the given number of 
lines.
      * This method counts the number of occurrence of {@code '\n'}, {@code 
'\r'}
      * or {@code "\r\n"} starting from the given position. When {@code 
numLines}
@@ -482,11 +532,10 @@ search:     for (; fromIndex <= toIndex;
     }
 
     /**
-     * Returns the index of the first character after all leading whitespace 
characters
-     * in the given range. If the given range contains only space characters, 
then this method
-     * returns the index of the first character after the given range, which 
is always equals
-     * or greater than {@code toIndex}. Note that this character may not exist 
if {@code toIndex}
-     * is equals to the text length.
+     * Returns the index of the first non-white character in the given range.
+     * If the given range contains only space characters, then this method 
returns the index of the
+     * first character after the given range, which is always equals or 
greater than {@code toIndex}.
+     * Note that this character may not exist if {@code toIndex} is equals to 
the text length.
      *
      * <p>Special cases:</p>
      * <ul>
@@ -494,7 +543,7 @@ search:     for (; fromIndex <= toIndex;
      *       then this method unconditionally returns {@code fromIndex}.</li>
      *   <li>If the given range contains only space characters and the 
character at {@code toIndex-1}
      *       is the high surrogate of a valid supplementary code point, then 
this method returns
-     *       {@code toIndex+1} since that value is the index of the next code 
point.</li>
+     *       {@code toIndex+1}, which is the index of the next code point.</li>
      *   <li>If {@code fromIndex} is negative or {@code toIndex} is greater 
than the text length,
      *       then the behavior of this method is undefined.</li>
      * </ul>
@@ -520,10 +569,9 @@ search:     for (; fromIndex <= toIndex;
     }
 
     /**
-     * Returns the index of the last character before all trailing whitespace 
characters
-     * in the given range. If the given range contains only space characters, 
then this method
-     * returns the index of the first character in the given range, which is 
always equals or
-     * lower than {@code fromIndex}.
+     * Returns the index <em>after</em> the last non-white character in the 
given range.
+     * If the given range contains only space characters, then this method 
returns the index of the
+     * first character in the given range, which is always equals or lower 
than {@code fromIndex}.
      *
      * <p>Special cases:</p>
      * <ul>
@@ -531,7 +579,7 @@ search:     for (; fromIndex <= toIndex;
      *       then this method unconditionally returns {@code toIndex}.</li>
      *   <li>If the given range contains only space characters and the 
character at {@code fromIndex}
      *       is the low surrogate of a valid supplementary code point, then 
this method returns
-     *       {@code fromIndex-1} since that value is the index of the code 
point.</li>
+     *       {@code fromIndex-1}, which is the index of the code point.</li>
      *   <li>If {@code fromIndex} is negative or {@code toIndex} is greater 
than the text length,
      *       then the behavior of this method is undefined.</li>
      * </ul>

Modified: 
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java?rev=1422209&r1=1422208&r2=1422209&view=diff
==============================================================================
--- 
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
 (original)
+++ 
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
 Sat Dec 15 09:45:05 2012
@@ -100,6 +100,39 @@ public final strictfp class CharSequence
     }
 
     /**
+     * Tests the {@link CharSequences#indexOf(CharSequence, int, int)} and
+     * {@link CharSequences#lastIndexOf(CharSequence, int, int)} methods.
+     * We test two time with different kind of character sequences, in order
+     * to test the {@link String} optimization case.
+     */
+    @Test
+    public void testIndexOfChar() {
+        for (int i=0; i<2; i++) {
+            CharSequence string = "An ordinary sentence.";
+            switch (i) {
+                case 0:  /* Test directly on the String instance. */  break;
+                case 1:  string = new StringBuilder((String) string); break;
+                default: throw new AssertionError(i);
+            }
+            final int length = string.length();
+            assertEquals(-1,           indexOf(string, 'x', 0, length));
+            assertEquals(-1,       lastIndexOf(string, 'x', 0, length));
+            assertEquals( 0,           indexOf(string, 'A', 0, length));
+            assertEquals( 0,       lastIndexOf(string, 'A', 0, length));
+            assertEquals(-1,           indexOf(string, 'A', 1, length));
+            assertEquals(-1,       lastIndexOf(string, 'A', 1, length));
+            assertEquals(length-1,     indexOf(string, '.', 0, length));
+            assertEquals(length-1, lastIndexOf(string, '.', 0, length));
+            assertEquals(-1,           indexOf(string, '.', 0, length-1));
+            assertEquals(-1,       lastIndexOf(string, '.', 0, length-1));
+            assertEquals(10,           indexOf(string, 'y', 0, length));
+            assertEquals(10,       lastIndexOf(string, 'y', 0, length));
+            assertEquals(13,           indexOf(string, 'e', 0, length));
+            assertEquals(19,       lastIndexOf(string, 'e', 0, length));
+        }
+    }
+
+    /**
      * Tests the {@link CharSequences#indexOfLineStart(CharSequence, int, 
int)} method.
      */
     @Test
@@ -118,6 +151,7 @@ public final strictfp class CharSequence
      * Tests {@link CharSequences#split(CharSequence, char)}.
      */
     @Test
+    @DependsOnMethod("testIndexOfChar")
     public void testSplit() {
         assertArrayEquals(new String[] {"lundi", "mardi", "", "mercredi"}, 
split("lundi , mardi,,mercredi ", ','));
         assertArrayEquals(new String[] {"lundi", "mardi", "", "mercredi"}, 
split("lundi \n mardi\r\n\nmercredi ", '\n'));
@@ -127,6 +161,7 @@ public final strictfp class CharSequence
      * Tests the {@link CharSequences#splitOnEOL(CharSequence)} method.
      */
     @Test
+    @DependsOnMethod("testIndexOfChar")
     public void testSplitOnEOL() {
         final CharSequence[] splitted = splitOnEOL("\nOne\r\nTwo\rThree 
\rFour\n Five\n\r Six \n");
         assertArrayEquals(new String[] {


Reply via email to