Merge "Make FastXmlSerializer more suitable to persist arbitrary strings" into nyc-dev
This commit is contained in:
@@ -28,6 +28,7 @@ import java.nio.CharBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
import java.nio.charset.IllegalCharsetNameException;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
|
||||
@@ -38,14 +39,14 @@ import java.nio.charset.UnsupportedCharsetException;
|
||||
*/
|
||||
public class FastXmlSerializer implements XmlSerializer {
|
||||
private static final String ESCAPE_TABLE[] = new String[] {
|
||||
null, null, null, null, null, null, null, null, // 0-7
|
||||
null, null, null, null, null, null, null, null, // 8-15
|
||||
null, null, null, null, null, null, null, null, // 16-23
|
||||
null, null, null, null, null, null, null, null, // 24-31
|
||||
null, null, """, null, null, null, "&", null, // 32-39
|
||||
null, null, null, null, null, null, null, null, // 40-47
|
||||
null, null, null, null, null, null, null, null, // 48-55
|
||||
null, null, null, null, "<", null, ">", null, // 56-63
|
||||
"�", "", "", "", "", "", "", "", // 0-7
|
||||
"", "	", " ", "", "", " ", "", "", // 8-15
|
||||
"", "", "", "", "", "", "", "", // 16-23
|
||||
"", "", "", "", "", "", "", "", // 24-31
|
||||
null, null, """, null, null, null, "&", null, // 32-39
|
||||
null, null, null, null, null, null, null, null, // 40-47
|
||||
null, null, null, null, null, null, null, null, // 48-55
|
||||
null, null, null, null, "<", null, ">", null, // 56-63
|
||||
};
|
||||
|
||||
private static final int BUFFER_LEN = 8192;
|
||||
@@ -310,7 +311,9 @@ public class FastXmlSerializer implements XmlSerializer {
|
||||
throw new IllegalArgumentException();
|
||||
if (true) {
|
||||
try {
|
||||
mCharset = Charset.forName(encoding).newEncoder();
|
||||
mCharset = Charset.forName(encoding).newEncoder()
|
||||
.onMalformedInput(CodingErrorAction.REPLACE)
|
||||
.onUnmappableCharacter(CodingErrorAction.REPLACE);
|
||||
} catch (IllegalCharsetNameException e) {
|
||||
throw (UnsupportedEncodingException) (new UnsupportedEncodingException(
|
||||
encoding).initCause(e));
|
||||
|
||||
@@ -16,16 +16,32 @@
|
||||
|
||||
package com.android.internal.util;
|
||||
|
||||
import android.test.suitebuilder.annotation.LargeTest;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Tests for {@link FastXmlSerializer}
|
||||
*/
|
||||
@SmallTest
|
||||
public class FastXmlSerializerTest extends TestCase {
|
||||
private static final String TAG = "FastXmlSerializerTest";
|
||||
|
||||
private static final boolean ENABLE_DUMP = false; // DO NOT SUBMIT WITH TRUE.
|
||||
|
||||
private static final String ROOT_TAG = "root";
|
||||
private static final String ATTR = "attr";
|
||||
|
||||
public void testEmptyText() throws Exception {
|
||||
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
|
||||
@@ -44,4 +60,93 @@ public class FastXmlSerializerTest extends TestCase {
|
||||
assertEquals("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
|
||||
+ "<string name=\"meow\"></string>\n", stream.toString());
|
||||
}
|
||||
|
||||
private boolean checkPreserved(String description, String str) {
|
||||
boolean ok = true;
|
||||
byte[] data;
|
||||
try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||
final XmlSerializer out = new FastXmlSerializer();
|
||||
out.setOutput(baos, StandardCharsets.UTF_16.name());
|
||||
out.startDocument(null, true);
|
||||
|
||||
out.startTag(null, ROOT_TAG);
|
||||
out.attribute(null, ATTR, str);
|
||||
out.text(str);
|
||||
out.endTag(null, ROOT_TAG);
|
||||
|
||||
out.endDocument();
|
||||
baos.flush();
|
||||
data = baos.toByteArray();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Unable to serialize: " + description, e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ENABLE_DUMP) {
|
||||
Log.d(TAG, "Dump:");
|
||||
Log.d(TAG, new String(data));
|
||||
}
|
||||
|
||||
try (final ByteArrayInputStream baos = new ByteArrayInputStream(data)) {
|
||||
XmlPullParser parser = Xml.newPullParser();
|
||||
parser.setInput(baos, StandardCharsets.UTF_16.name());
|
||||
|
||||
int type;
|
||||
String tag = null;
|
||||
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||
if (type == XmlPullParser.START_TAG) {
|
||||
tag = parser.getName();
|
||||
if (ROOT_TAG.equals(tag)) {
|
||||
String read = parser.getAttributeValue(null, ATTR);
|
||||
if (!str.equals(read)) {
|
||||
Log.e(TAG, "Attribute not preserved: " + description
|
||||
+ " input=\"" + str + "\", but read=\"" + read + "\"");
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type == XmlPullParser.TEXT && ROOT_TAG.equals(tag)) {
|
||||
String read = parser.getText();
|
||||
if (!str.equals(parser.getText())) {
|
||||
Log.e(TAG, "Text not preserved: " + description
|
||||
+ " input=\"" + str + "\", but read=\"" + read + "\"");
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Unable to parse: " + description, e);
|
||||
return false;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
private boolean check(String description, String str) throws Exception {
|
||||
boolean ok = false;
|
||||
ok |= checkPreserved(description, str);
|
||||
ok |= checkPreserved(description + " wrapped with spaces" ," " + str + " ");
|
||||
return ok;
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
public void testAllCharacters() throws Exception {
|
||||
boolean ok = true;
|
||||
for (int i = 0; i < 0xffff; i++) {
|
||||
if (0xd800 <= i && i <= 0xdfff) {
|
||||
// Surrogate pair characters.
|
||||
continue;
|
||||
}
|
||||
ok &= check("char: " + i, String.valueOf((char) i));
|
||||
}
|
||||
// Dangling surrogate pairs. We can't preserve them.
|
||||
assertFalse(check("+ud800", "\ud800"));
|
||||
assertFalse(check("+udc00", "\udc00"));
|
||||
|
||||
for (int i = 0xd800; i < 0xdc00; i ++) {
|
||||
for (int j = 0xdc00; j < 0xe000; j++) {
|
||||
ok &= check("char: " + i, String.valueOf((char) i) + String.valueOf((char) j));
|
||||
}
|
||||
}
|
||||
assertTrue("Some tests failed. See logcat for details.", ok);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user