add StringBuffer/Builder.reverse
fixes ISSUE 449
Change-Id: I342e7ed86c0e4efa90d09bdfe0d72c79db2654c5
Review-Link: https://gwt-review.googlesource.com/#/c/2431/
Review by: goktug@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@11591 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/core/client/impl/StringBufferImpl.java b/user/src/com/google/gwt/core/client/impl/StringBufferImpl.java
index 23a7202..86c9b52 100644
--- a/user/src/com/google/gwt/core/client/impl/StringBufferImpl.java
+++ b/user/src/com/google/gwt/core/client/impl/StringBufferImpl.java
@@ -15,6 +15,7 @@
*/
package com.google.gwt.core.client.impl;
+
/**
* <p>
* The interface to defer bound implementations of {@link StringBuilder} and
@@ -29,9 +30,35 @@
*/
public abstract class StringBufferImpl {
+ public static String reverseString(String s) {
+ int length = s.length();
+
+ if (length <= 1) {
+ return s;
+ }
+
+ char[] buffer = new char[length];
+
+ buffer[0] = s.charAt(length - 1);
+
+ for (int i = 1; i < length; i++) {
+ buffer[i] = s.charAt(length - 1 - i);
+ if (Character.isSurrogatePair(buffer[i], buffer[i - 1])) {
+ swap(buffer, i - 1, i);
+ }
+ }
+
+ return new String(buffer);
+ }
+
+ private static void swap(char[] buffer, int f, int s) {
+ char tmp = buffer[f];
+ buffer[f] = buffer[s];
+ buffer[s] = tmp;
+ }
+
/**
- * Append for primitive; the value can be stored and only later converted to a
- * string.
+ * Append for primitive; the value can be stored and only later converted to a string.
*/
public abstract void append(Object data, boolean x);
@@ -86,6 +113,11 @@
public abstract void replace(Object data, int start, int end, String toInsert);
/**
+ * Reverses the whole StringBuffer/Builder
+ */
+ public abstract void reverse(Object data);
+
+ /**
* Returns the string buffer as a String.
*/
public abstract String toString(Object data);
diff --git a/user/src/com/google/gwt/core/client/impl/StringBufferImplAppend.java b/user/src/com/google/gwt/core/client/impl/StringBufferImplAppend.java
index 6dd2ed5..15c97b3 100644
--- a/user/src/com/google/gwt/core/client/impl/StringBufferImplAppend.java
+++ b/user/src/com/google/gwt/core/client/impl/StringBufferImplAppend.java
@@ -73,7 +73,13 @@
}
@Override
+ public void reverse(Object data) {
+ string = reverseString(string);
+ }
+
+ @Override
public String toString(Object data) {
return string;
}
+
}
diff --git a/user/src/com/google/gwt/core/client/impl/StringBufferImplArrayBase.java b/user/src/com/google/gwt/core/client/impl/StringBufferImplArrayBase.java
index 227ef93..fd5600b 100644
--- a/user/src/com/google/gwt/core/client/impl/StringBufferImplArrayBase.java
+++ b/user/src/com/google/gwt/core/client/impl/StringBufferImplArrayBase.java
@@ -76,6 +76,13 @@
}
@Override
+ public void reverse(Object a) {
+ String s = takeString(a);
+ s = reverseString(s);
+ appendNonNull(a, s);
+ }
+
+ @Override
public final String toString(Object a) {
String s = takeString(a);
appendNonNull(a, s);
@@ -87,4 +94,5 @@
a.length = a.explicitLength = 0;
return s;
}-*/;
+
}
diff --git a/user/super/com/google/gwt/emul/java/lang/StringBuffer.java b/user/super/com/google/gwt/emul/java/lang/StringBuffer.java
index 2b24557..b7b1a53 100644
--- a/user/super/com/google/gwt/emul/java/lang/StringBuffer.java
+++ b/user/super/com/google/gwt/emul/java/lang/StringBuffer.java
@@ -231,6 +231,11 @@
return this;
}
+ public StringBuffer reverse() {
+ impl.reverse(data);
+ return this;
+ }
+
/**
* Warning! This method is <b>much</b> slower than the JRE implementation. If
* you need to do character level manipulation, you are strongly advised to
diff --git a/user/super/com/google/gwt/emul/java/lang/StringBuilder.java b/user/super/com/google/gwt/emul/java/lang/StringBuilder.java
index e6d495a..37eb242 100644
--- a/user/super/com/google/gwt/emul/java/lang/StringBuilder.java
+++ b/user/super/com/google/gwt/emul/java/lang/StringBuilder.java
@@ -231,6 +231,11 @@
return this;
}
+ public StringBuilder reserve() {
+ impl.reverse(data);
+ return this;
+ }
+
/**
* Warning! This method is <b>much</b> slower than the JRE implementation. If
* you need to do character level manipulation, you are strongly advised to
diff --git a/user/test/com/google/gwt/emultest/java/lang/StringBufferTest.java b/user/test/com/google/gwt/emultest/java/lang/StringBufferTest.java
index e92c177..fa0e807 100644
--- a/user/test/com/google/gwt/emultest/java/lang/StringBufferTest.java
+++ b/user/test/com/google/gwt/emultest/java/lang/StringBufferTest.java
@@ -21,6 +21,11 @@
* This class tests classes StringBuffer and StringBuilder.
*/
public class StringBufferTest extends GWTTestCase {
+
+ private static void assertEqualsReverse(String expected, String input) {
+ assertEquals(expected, new StringBuffer(input).reverse().toString());
+ }
+
/**
* This method gets the module name.
*
@@ -270,6 +275,35 @@
assertEquals("xxYYxx", x.toString());
}
+ public void testReverse() {
+ assertEqualsReverse("", "");
+ assertEqualsReverse(" ", " ");
+
+ assertEqualsReverse("gwt", "twg");
+ assertEqualsReverse("gwt is great", "taerg si twg");
+
+ // Java uses UTF-16
+ // char values between 0x0000 - 0xD7FF and 0xE000 - 0xFFFF
+ // are considered to be one char
+ // if the value is between 0xD800 - 0xDBFF the char is considered
+ // to be the lead surrogate (first) of a surrogate pair
+ // if the value is between 0xDC00 - 0xDFFFF the char is considered
+ // to be the trail surrogate (second) of a surrogate pair
+ //
+ // single appearances of surrogates are invalid in a String!
+
+ // surrogate pair test (first one)
+ assertEqualsReverse("\uD800\uDC00", "\uD800\uDC00");
+ // surrogate pair test (last one)
+ assertEqualsReverse("\uDBFF\uDFFF", "\uDBFF\uDFFF");
+ // last one before surrogates start
+ assertEqualsReverse("\uD7FF\uD7FE", "\uD7FE\uD7FF");
+ // first none surrogate
+ assertEqualsReverse("\uE000\uE001", "\uE001\uE000");
+ // more than one surrogate pair
+ assertEqualsReverse("\uD801\uDC00_123_\uD802\uDC01", "\uD802\uDC01_321_\uD801\uDC00");
+ }
+
/**
* This method tests <code>setLength</code>.
*/