Please review the following patch to add the missing codePoint-related
methods to StringBuilder/StringBuffer (there is also a small javadoc
correction in Character). I needed these methods in the UCD branch and we
had an oustanding item to add these for 1.6, so I went ahead and ported them
to the current trunk.
One issue: appendCodepoint() essentially inlines Character.toChars() for
efficiency -- it seemed appropriate given the lengths we went to for
efficiency in this code anyway.
Finally, it looks like we are not testing StringBuilder at all -- since
StringBuffer no longer delegates to StringBuilder, I think it needs to be
tested as well to make sure no cut-and-paste error slips in. A related
question -- would it not be better to have code generate one version from
the other rather than rely on manually keeping them in sync?
--
John A. Tamplin
Software Engineer (GWT), Google
--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---
Index: user/test/com/google/gwt/emultest/java/lang/StringBufferTest.java
===================================================================
--- user/test/com/google/gwt/emultest/java/lang/StringBufferTest.java (revision 3626)
+++ user/test/com/google/gwt/emultest/java/lang/StringBufferTest.java (working copy)
@@ -27,6 +27,7 @@
* @return the module name.
* @see com.google.gwt.junit.client.GWTTestCase#getModuleName()
*/
+ @Override
public String getModuleName() {
return "com.google.gwt.emultest.EmulSuite";
}
@@ -91,6 +92,34 @@
}
/**
+ * Test the various codePoint-related methods.
+ */
+ public void testCodepoint() {
+ StringBuffer buf = new StringBuffer();
+ buf.appendCodePoint('C');
+ buf.appendCodePoint(67328);
+ buf.append('T');
+ assertEquals("C\uD801\uDF00T", buf.toString());
+ assertEquals('C', buf.codePointAt(0));
+ assertEquals(67328, buf.codePointAt(1));
+ assertEquals(0xDF00, buf.codePointAt(2));
+ assertEquals('T', buf.codePointAt(3));
+ assertEquals('C', buf.codePointBefore(1));
+ assertEquals(0xD801, buf.codePointBefore(2));
+ assertEquals(67328, buf.codePointBefore(3));
+ assertEquals('T', buf.codePointBefore(4));
+ assertEquals(3, buf.codePointCount(0, 4));
+ assertEquals(2, buf.codePointCount(0, 3));
+ assertEquals(2, buf.codePointCount(0, 2));
+ assertEquals(1, buf.codePointCount(1, 3));
+ assertEquals(1, buf.offsetByCodePoints(0, 1));
+ assertEquals(3, buf.offsetByCodePoints(1, 1));
+ assertEquals(3, buf.offsetByCodePoints(0, 2));
+ assertEquals(1, buf.offsetByCodePoints(3, -1));
+ assertEquals(0, buf.offsetByCodePoints(1, -1));
+ }
+
+ /**
* This method tests string creation and equality.
*/
public void testContructor() {
@@ -350,6 +379,7 @@
bld = new StringBuilder();
bld.append(new Object() {
+ @Override
public String toString() {
return "obj";
}
@@ -440,6 +470,7 @@
bld = new StringBuilder("01234");
bld.insert(2, new Object() {
+ @Override
public String toString() {
return "obj";
}
Index: user/super/com/google/gwt/emul/java/lang/StringBuffer.java
===================================================================
--- user/super/com/google/gwt/emul/java/lang/StringBuffer.java (revision 3626)
+++ user/super/com/google/gwt/emul/java/lang/StringBuffer.java (working copy)
@@ -121,6 +121,21 @@
return this;
}
+ public StringBuffer appendCodePoint(int codePoint) {
+ if (codePoint < 0 || codePoint > Character.MAX_CODE_POINT) {
+ throw new IllegalArgumentException();
+ }
+ if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+ impl.appendNonNull(data, String.valueOf(
+ Character.getHighSurrogate(codePoint)));
+ impl.appendNonNull(data, String.valueOf(
+ Character.getLowSurrogate(codePoint)));
+ } else {
+ impl.appendNonNull(data, String.valueOf((char) codePoint));
+ }
+ return this;
+ }
+
/**
* This implementation does not track capacity; always returns
* [EMAIL PROTECTED] Integer#MAX_VALUE}.
@@ -133,6 +148,18 @@
return toString().charAt(index);
}
+ public int codePointAt(int index) {
+ return toString().codePointAt(index);
+ }
+
+ public int codePointBefore(int index) {
+ return toString().codePointBefore(index);
+ }
+
+ public int codePointCount(int beginIndex, int endIndex) {
+ return toString().codePointCount(beginIndex, endIndex);
+ }
+
public StringBuffer delete(int start, int end) {
return replace(start, end, "");
}
@@ -226,6 +253,10 @@
return impl.length(data);
}
+ public int offsetByCodePoints(int index, int codePointOffset) {
+ return toString().offsetByCodePoints(index, codePointOffset);
+ }
+
public StringBuffer replace(int start, int end, String toInsert) {
impl.replace(data, start, end, toInsert);
return this;
Index: user/super/com/google/gwt/emul/java/lang/StringBuilder.java
===================================================================
--- user/super/com/google/gwt/emul/java/lang/StringBuilder.java (revision 3626)
+++ user/super/com/google/gwt/emul/java/lang/StringBuilder.java (working copy)
@@ -121,6 +121,21 @@
return this;
}
+ public StringBuilder appendCodePoint(int codePoint) {
+ if (codePoint < 0 || codePoint > Character.MAX_CODE_POINT) {
+ throw new IllegalArgumentException();
+ }
+ if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+ impl.appendNonNull(data, String.valueOf(
+ Character.getHighSurrogate(codePoint)));
+ impl.appendNonNull(data, String.valueOf(
+ Character.getLowSurrogate(codePoint)));
+ } else {
+ impl.appendNonNull(data, String.valueOf((char) codePoint));
+ }
+ return this;
+ }
+
/**
* This implementation does not track capacity; always returns
* [EMAIL PROTECTED] Integer#MAX_VALUE}.
@@ -133,6 +148,18 @@
return toString().charAt(index);
}
+ public int codePointAt(int index) {
+ return toString().codePointAt(index);
+ }
+
+ public int codePointBefore(int index) {
+ return toString().codePointBefore(index);
+ }
+
+ public int codePointCount(int beginIndex, int endIndex) {
+ return toString().codePointCount(beginIndex, endIndex);
+ }
+
public StringBuilder delete(int start, int end) {
return replace(start, end, "");
}
@@ -226,6 +253,10 @@
return impl.length(data);
}
+ public int offsetByCodePoints(int index, int codePointOffset) {
+ return toString().offsetByCodePoints(index, codePointOffset);
+ }
+
public StringBuilder replace(int start, int end, String toInsert) {
impl.replace(data, start, end, toInsert);
return this;
Index: user/super/com/google/gwt/emul/java/lang/Character.java
===================================================================
--- user/super/com/google/gwt/emul/java/lang/Character.java (revision 3626)
+++ user/super/com/google/gwt/emul/java/lang/Character.java (working copy)
@@ -412,7 +412,7 @@
/**
* Computes the high surrogate character of the UTF16 representation of a
- * non-BMP code point. See [EMAIL PROTECTED] getLowSurrogate}.
+ * non-BMP code point. See [EMAIL PROTECTED] #getLowSurrogate}.
*
* @param codePoint requested codePoint, required to be >=
* MIN_SUPPLEMENTARY_CODE_POINT
@@ -425,7 +425,7 @@
/**
* Computes the low surrogate character of the UTF16 representation of a
- * non-BMP code point. See [EMAIL PROTECTED] getHighSurrogate}.
+ * non-BMP code point. See [EMAIL PROTECTED] #getHighSurrogate}.
*
* @param codePoint requested codePoint, required to be >=
* MIN_SUPPLEMENTARY_CODE_POINT