Refine TypedXmlPullParser API interface.
Techincally our additions should match the shape of the upstream XmlPullParser interface, which throws XmlPullParserException when there is a parsing issue; IOException should be reserved for actual disk I/O issues. Improve BinaryXmlPullParser handling of invalid inputs to match how ForcedTypedXmlPullParser throws on any parsing trouble. Bug: 171832118 Test: atest FrameworksCoreTests:android.util.XmlTest Test: atest FrameworksCoreTests:android.util.BinaryXmlTest Change-Id: I8f0e95d536b53570055a9e174f0849cf635da48c
This commit is contained in:
@@ -20,8 +20,7 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
/**
|
||||
* Specialization of {@link XmlPullParser} which adds explicit methods to
|
||||
@@ -31,67 +30,93 @@ import java.io.IOException;
|
||||
*/
|
||||
public interface TypedXmlPullParser extends XmlPullParser {
|
||||
/**
|
||||
* @return decoded strongly-typed {@link #getAttributeValue}, or
|
||||
* {@code null} if malformed or undefined
|
||||
* @return decoded strongly-typed {@link #getAttributeValue}
|
||||
* @throws XmlPullParserException if the value is malformed or undefined
|
||||
*/
|
||||
@Nullable byte[] getAttributeBytesHex(@Nullable String namespace, @NonNull String name)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* @return decoded strongly-typed {@link #getAttributeValue}, or
|
||||
* {@code null} if malformed or undefined
|
||||
*/
|
||||
@Nullable byte[] getAttributeBytesBase64(@Nullable String namespace, @NonNull String name)
|
||||
throws IOException;
|
||||
@NonNull byte[] getAttributeBytesHex(@Nullable String namespace, @NonNull String name)
|
||||
throws XmlPullParserException;
|
||||
|
||||
/**
|
||||
* @return decoded strongly-typed {@link #getAttributeValue}
|
||||
* @throws IOException if the value is malformed or undefined
|
||||
* @throws XmlPullParserException if the value is malformed or undefined
|
||||
*/
|
||||
@NonNull byte[] getAttributeBytesBase64(@Nullable String namespace, @NonNull String name)
|
||||
throws XmlPullParserException;
|
||||
|
||||
/**
|
||||
* @return decoded strongly-typed {@link #getAttributeValue}
|
||||
* @throws XmlPullParserException if the value is malformed or undefined
|
||||
*/
|
||||
int getAttributeInt(@Nullable String namespace, @NonNull String name)
|
||||
throws IOException;
|
||||
throws XmlPullParserException;
|
||||
|
||||
/**
|
||||
* @return decoded strongly-typed {@link #getAttributeValue}
|
||||
* @throws IOException if the value is malformed or undefined
|
||||
* @throws XmlPullParserException if the value is malformed or undefined
|
||||
*/
|
||||
int getAttributeIntHex(@Nullable String namespace, @NonNull String name)
|
||||
throws IOException;
|
||||
throws XmlPullParserException;
|
||||
|
||||
/**
|
||||
* @return decoded strongly-typed {@link #getAttributeValue}
|
||||
* @throws IOException if the value is malformed or undefined
|
||||
* @throws XmlPullParserException if the value is malformed or undefined
|
||||
*/
|
||||
long getAttributeLong(@Nullable String namespace, @NonNull String name)
|
||||
throws IOException;
|
||||
throws XmlPullParserException;
|
||||
|
||||
/**
|
||||
* @return decoded strongly-typed {@link #getAttributeValue}
|
||||
* @throws IOException if the value is malformed or undefined
|
||||
* @throws XmlPullParserException if the value is malformed or undefined
|
||||
*/
|
||||
long getAttributeLongHex(@Nullable String namespace, @NonNull String name)
|
||||
throws IOException;
|
||||
throws XmlPullParserException;
|
||||
|
||||
/**
|
||||
* @return decoded strongly-typed {@link #getAttributeValue}
|
||||
* @throws IOException if the value is malformed or undefined
|
||||
* @throws XmlPullParserException if the value is malformed or undefined
|
||||
*/
|
||||
float getAttributeFloat(@Nullable String namespace, @NonNull String name)
|
||||
throws IOException;
|
||||
throws XmlPullParserException;
|
||||
|
||||
/**
|
||||
* @return decoded strongly-typed {@link #getAttributeValue}
|
||||
* @throws IOException if the value is malformed or undefined
|
||||
* @throws XmlPullParserException if the value is malformed or undefined
|
||||
*/
|
||||
double getAttributeDouble(@Nullable String namespace, @NonNull String name)
|
||||
throws IOException;
|
||||
throws XmlPullParserException;
|
||||
|
||||
/**
|
||||
* @return decoded strongly-typed {@link #getAttributeValue}
|
||||
* @throws IOException if the value is malformed or undefined
|
||||
* @throws XmlPullParserException if the value is malformed or undefined
|
||||
*/
|
||||
boolean getAttributeBoolean(@Nullable String namespace, @NonNull String name)
|
||||
throws IOException;
|
||||
throws XmlPullParserException;
|
||||
|
||||
/**
|
||||
* @return decoded strongly-typed {@link #getAttributeValue}, otherwise
|
||||
* default value if the value is malformed or undefined
|
||||
*/
|
||||
default @Nullable byte[] getAttributeBytesHex(@Nullable String namespace,
|
||||
@NonNull String name, @Nullable byte[] defaultValue) {
|
||||
try {
|
||||
return getAttributeBytesHex(namespace, name);
|
||||
} catch (Exception ignored) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return decoded strongly-typed {@link #getAttributeValue}, otherwise
|
||||
* default value if the value is malformed or undefined
|
||||
*/
|
||||
default @Nullable byte[] getAttributeBytesBase64(@Nullable String namespace,
|
||||
@NonNull String name, @Nullable byte[] defaultValue) {
|
||||
try {
|
||||
return getAttributeBytesBase64(namespace, name);
|
||||
} catch (Exception ignored) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return decoded strongly-typed {@link #getAttributeValue}, otherwise
|
||||
|
||||
@@ -36,21 +36,21 @@ public interface TypedXmlSerializer extends XmlSerializer {
|
||||
* canonicalized, similar to {@link String#intern()}.
|
||||
*/
|
||||
@NonNull XmlSerializer attributeInterned(@Nullable String namespace, @NonNull String name,
|
||||
@Nullable String value) throws IOException;
|
||||
@NonNull String value) throws IOException;
|
||||
|
||||
/**
|
||||
* Encode the given strongly-typed value and serialize using
|
||||
* {@link #attribute(String, String, String)}.
|
||||
*/
|
||||
@NonNull XmlSerializer attributeBytesHex(@Nullable String namespace, @NonNull String name,
|
||||
byte[] value) throws IOException;
|
||||
@NonNull byte[] value) throws IOException;
|
||||
|
||||
/**
|
||||
* Encode the given strongly-typed value and serialize using
|
||||
* {@link #attribute(String, String, String)}.
|
||||
*/
|
||||
@NonNull XmlSerializer attributeBytesBase64(@Nullable String namespace, @NonNull String name,
|
||||
byte[] value) throws IOException;
|
||||
@NonNull byte[] value) throws IOException;
|
||||
|
||||
/**
|
||||
* Encode the given strongly-typed value and serialize using
|
||||
|
||||
@@ -418,13 +418,14 @@ public final class BinaryXmlPullParser implements TypedXmlPullParser {
|
||||
* Search through the pool of currently allocated {@link Attribute}
|
||||
* instances for one that matches the given name.
|
||||
*/
|
||||
private @NonNull Attribute findAttribute(@NonNull String name) throws IOException {
|
||||
private @NonNull Attribute findAttribute(@NonNull String name)
|
||||
throws XmlPullParserException {
|
||||
for (int i = 0; i < mAttributeCount; i++) {
|
||||
if (Objects.equals(mAttributes[i].name, name)) {
|
||||
return mAttributes[i];
|
||||
}
|
||||
}
|
||||
throw new IOException("Missing attribute " + name);
|
||||
throw new XmlPullParserException("Missing attribute " + name);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -432,7 +433,7 @@ public final class BinaryXmlPullParser implements TypedXmlPullParser {
|
||||
if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
|
||||
try {
|
||||
return findAttribute(name).getValueString();
|
||||
} catch (IOException e) {
|
||||
} catch (XmlPullParserException e) {
|
||||
// Missing attributes default to null
|
||||
return null;
|
||||
}
|
||||
@@ -444,55 +445,64 @@ public final class BinaryXmlPullParser implements TypedXmlPullParser {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getAttributeBytesHex(String namespace, String name) throws IOException {
|
||||
public byte[] getAttributeBytesHex(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
|
||||
return findAttribute(name).getValueBytesHex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getAttributeBytesBase64(String namespace, String name) throws IOException {
|
||||
public byte[] getAttributeBytesBase64(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
|
||||
return findAttribute(name).getValueBytesBase64();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAttributeInt(String namespace, String name) throws IOException {
|
||||
public int getAttributeInt(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
|
||||
return findAttribute(name).getValueInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAttributeIntHex(String namespace, String name) throws IOException {
|
||||
public int getAttributeIntHex(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
|
||||
return findAttribute(name).getValueIntHex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAttributeLong(String namespace, String name) throws IOException {
|
||||
public long getAttributeLong(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
|
||||
return findAttribute(name).getValueLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAttributeLongHex(String namespace, String name) throws IOException {
|
||||
public long getAttributeLongHex(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
|
||||
return findAttribute(name).getValueLongHex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAttributeFloat(String namespace, String name) throws IOException {
|
||||
public float getAttributeFloat(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
|
||||
return findAttribute(name).getValueFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getAttributeDouble(String namespace, String name) throws IOException {
|
||||
public double getAttributeDouble(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
|
||||
return findAttribute(name).getValueDouble();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAttributeBoolean(String namespace, String name) throws IOException {
|
||||
public boolean getAttributeBoolean(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
|
||||
return findAttribute(name).getValueBoolean();
|
||||
}
|
||||
@@ -742,7 +752,7 @@ public final class BinaryXmlPullParser implements TypedXmlPullParser {
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable byte[] getValueBytesHex() throws IOException {
|
||||
public @Nullable byte[] getValueBytesHex() throws XmlPullParserException {
|
||||
switch (type) {
|
||||
case TYPE_NULL:
|
||||
return null;
|
||||
@@ -750,13 +760,18 @@ public final class BinaryXmlPullParser implements TypedXmlPullParser {
|
||||
case TYPE_BYTES_BASE64:
|
||||
return valueBytes;
|
||||
case TYPE_STRING:
|
||||
return hexStringToBytes(valueString);
|
||||
case TYPE_STRING_INTERNED:
|
||||
try {
|
||||
return hexStringToBytes(valueString);
|
||||
} catch (Exception e) {
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + e);
|
||||
}
|
||||
default:
|
||||
throw new IOException("Invalid conversion from " + type);
|
||||
throw new XmlPullParserException("Invalid conversion from " + type);
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable byte[] getValueBytesBase64() throws IOException {
|
||||
public @Nullable byte[] getValueBytesBase64() throws XmlPullParserException {
|
||||
switch (type) {
|
||||
case TYPE_NULL:
|
||||
return null;
|
||||
@@ -764,98 +779,135 @@ public final class BinaryXmlPullParser implements TypedXmlPullParser {
|
||||
case TYPE_BYTES_BASE64:
|
||||
return valueBytes;
|
||||
case TYPE_STRING:
|
||||
return Base64.decode(valueString, Base64.NO_WRAP);
|
||||
case TYPE_STRING_INTERNED:
|
||||
try {
|
||||
return Base64.decode(valueString, Base64.NO_WRAP);
|
||||
} catch (Exception e) {
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + e);
|
||||
}
|
||||
default:
|
||||
throw new IOException("Invalid conversion from " + type);
|
||||
throw new XmlPullParserException("Invalid conversion from " + type);
|
||||
}
|
||||
}
|
||||
|
||||
public int getValueInt() throws IOException {
|
||||
public int getValueInt() throws XmlPullParserException {
|
||||
switch (type) {
|
||||
case TYPE_INT:
|
||||
case TYPE_INT_HEX:
|
||||
return valueInt;
|
||||
case TYPE_STRING:
|
||||
return Integer.parseInt(valueString);
|
||||
case TYPE_STRING_INTERNED:
|
||||
try {
|
||||
return Integer.parseInt(valueString);
|
||||
} catch (Exception e) {
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + e);
|
||||
}
|
||||
default:
|
||||
throw new IOException("Invalid conversion from " + type);
|
||||
throw new XmlPullParserException("Invalid conversion from " + type);
|
||||
}
|
||||
}
|
||||
|
||||
public int getValueIntHex() throws IOException {
|
||||
public int getValueIntHex() throws XmlPullParserException {
|
||||
switch (type) {
|
||||
case TYPE_INT:
|
||||
case TYPE_INT_HEX:
|
||||
return valueInt;
|
||||
case TYPE_STRING:
|
||||
return Integer.parseInt(valueString, 16);
|
||||
case TYPE_STRING_INTERNED:
|
||||
try {
|
||||
return Integer.parseInt(valueString, 16);
|
||||
} catch (Exception e) {
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + e);
|
||||
}
|
||||
default:
|
||||
throw new IOException("Invalid conversion from " + type);
|
||||
throw new XmlPullParserException("Invalid conversion from " + type);
|
||||
}
|
||||
}
|
||||
|
||||
public long getValueLong() throws IOException {
|
||||
public long getValueLong() throws XmlPullParserException {
|
||||
switch (type) {
|
||||
case TYPE_LONG:
|
||||
case TYPE_LONG_HEX:
|
||||
return valueLong;
|
||||
case TYPE_STRING:
|
||||
return Long.parseLong(valueString);
|
||||
case TYPE_STRING_INTERNED:
|
||||
try {
|
||||
return Long.parseLong(valueString);
|
||||
} catch (Exception e) {
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + e);
|
||||
}
|
||||
default:
|
||||
throw new IOException("Invalid conversion from " + type);
|
||||
throw new XmlPullParserException("Invalid conversion from " + type);
|
||||
}
|
||||
}
|
||||
|
||||
public long getValueLongHex() throws IOException {
|
||||
public long getValueLongHex() throws XmlPullParserException {
|
||||
switch (type) {
|
||||
case TYPE_LONG:
|
||||
case TYPE_LONG_HEX:
|
||||
return valueLong;
|
||||
case TYPE_STRING:
|
||||
return Long.parseLong(valueString, 16);
|
||||
case TYPE_STRING_INTERNED:
|
||||
try {
|
||||
return Long.parseLong(valueString, 16);
|
||||
} catch (Exception e) {
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + e);
|
||||
}
|
||||
default:
|
||||
throw new IOException("Invalid conversion from " + type);
|
||||
throw new XmlPullParserException("Invalid conversion from " + type);
|
||||
}
|
||||
}
|
||||
|
||||
public float getValueFloat() throws IOException {
|
||||
public float getValueFloat() throws XmlPullParserException {
|
||||
switch (type) {
|
||||
case TYPE_FLOAT:
|
||||
return valueFloat;
|
||||
case TYPE_STRING:
|
||||
return Float.parseFloat(valueString);
|
||||
case TYPE_STRING_INTERNED:
|
||||
try {
|
||||
return Float.parseFloat(valueString);
|
||||
} catch (Exception e) {
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + e);
|
||||
}
|
||||
default:
|
||||
throw new IOException("Invalid conversion from " + type);
|
||||
throw new XmlPullParserException("Invalid conversion from " + type);
|
||||
}
|
||||
}
|
||||
|
||||
public double getValueDouble() throws IOException {
|
||||
public double getValueDouble() throws XmlPullParserException {
|
||||
switch (type) {
|
||||
case TYPE_DOUBLE:
|
||||
return valueDouble;
|
||||
case TYPE_STRING:
|
||||
return Double.parseDouble(valueString);
|
||||
case TYPE_STRING_INTERNED:
|
||||
try {
|
||||
return Double.parseDouble(valueString);
|
||||
} catch (Exception e) {
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + e);
|
||||
}
|
||||
default:
|
||||
throw new IOException("Invalid conversion from " + type);
|
||||
throw new XmlPullParserException("Invalid conversion from " + type);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getValueBoolean() throws IOException {
|
||||
public boolean getValueBoolean() throws XmlPullParserException {
|
||||
switch (type) {
|
||||
case TYPE_BOOLEAN_TRUE:
|
||||
return true;
|
||||
case TYPE_BOOLEAN_FALSE:
|
||||
return false;
|
||||
case TYPE_STRING:
|
||||
case TYPE_STRING_INTERNED:
|
||||
if ("true".equalsIgnoreCase(valueString)) {
|
||||
return true;
|
||||
} else if ("false".equalsIgnoreCase(valueString)) {
|
||||
return false;
|
||||
} else {
|
||||
throw new IOException("Invalid boolean: " + valueString);
|
||||
throw new XmlPullParserException(
|
||||
"Invalid attribute " + name + ": " + valueString);
|
||||
}
|
||||
default:
|
||||
throw new IOException("Invalid conversion from " + type);
|
||||
throw new XmlPullParserException("Invalid conversion from " + type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -865,11 +917,11 @@ public final class BinaryXmlPullParser implements TypedXmlPullParser {
|
||||
private final static char[] HEX_DIGITS =
|
||||
{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
|
||||
private static int toByte(char c) throws IOException {
|
||||
private static int toByte(char c) {
|
||||
if (c >= '0' && c <= '9') return (c - '0');
|
||||
if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
|
||||
if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
|
||||
throw new IOException("Invalid hex char '" + c + "'");
|
||||
throw new IllegalArgumentException("Invalid hex char '" + c + "'");
|
||||
}
|
||||
|
||||
static String bytesToHexString(byte[] value) {
|
||||
@@ -884,10 +936,10 @@ public final class BinaryXmlPullParser implements TypedXmlPullParser {
|
||||
return new String(buf);
|
||||
}
|
||||
|
||||
static byte[] hexStringToBytes(String value) throws IOException {
|
||||
static byte[] hexStringToBytes(String value) {
|
||||
final int length = value.length();
|
||||
if (length % 2 != 0) {
|
||||
throw new IOException("Invalid hex length " + length);
|
||||
throw new IllegalArgumentException("Invalid hex length " + length);
|
||||
}
|
||||
byte[] buffer = new byte[length / 2];
|
||||
for (int i = 0; i < length; i += 2) {
|
||||
|
||||
@@ -140,87 +140,95 @@ public class XmlUtils {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getAttributeBytesHex(String namespace, String name) throws IOException {
|
||||
public byte[] getAttributeBytesHex(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
try {
|
||||
return HexDump.hexStringToByteArray(getAttributeValue(namespace, name));
|
||||
} catch (Exception e) {
|
||||
throw new IOException("Invalid attribute " + name, e);
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getAttributeBytesBase64(String namespace, String name) throws IOException {
|
||||
public byte[] getAttributeBytesBase64(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
try {
|
||||
return Base64.decode(getAttributeValue(namespace, name), Base64.NO_WRAP);
|
||||
} catch (Exception e) {
|
||||
throw new IOException("Invalid attribute " + name, e);
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAttributeInt(String namespace, String name) throws IOException {
|
||||
public int getAttributeInt(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
try {
|
||||
return Integer.parseInt(getAttributeValue(namespace, name));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IOException("Invalid attribute " + name, e);
|
||||
} catch (Exception e) {
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAttributeIntHex(String namespace, String name) throws IOException {
|
||||
public int getAttributeIntHex(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
try {
|
||||
return Integer.parseInt(getAttributeValue(namespace, name), 16);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IOException("Invalid attribute " + name, e);
|
||||
} catch (Exception e) {
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAttributeLong(String namespace, String name) throws IOException {
|
||||
public long getAttributeLong(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
try {
|
||||
return Long.parseLong(getAttributeValue(namespace, name));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IOException("Invalid attribute " + name, e);
|
||||
} catch (Exception e) {
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAttributeLongHex(String namespace, String name) throws IOException {
|
||||
public long getAttributeLongHex(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
try {
|
||||
return Long.parseLong(getAttributeValue(namespace, name), 16);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IOException("Invalid attribute " + name, e);
|
||||
} catch (Exception e) {
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAttributeFloat(String namespace, String name) throws IOException {
|
||||
public float getAttributeFloat(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
try {
|
||||
return Float.parseFloat(getAttributeValue(namespace, name));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IOException("Invalid attribute " + name, e);
|
||||
} catch (Exception e) {
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getAttributeDouble(String namespace, String name) throws IOException {
|
||||
public double getAttributeDouble(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
try {
|
||||
return Double.parseDouble(getAttributeValue(namespace, name));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IOException("Invalid attribute " + name, e);
|
||||
} catch (Exception e) {
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAttributeBoolean(String namespace, String name) throws IOException {
|
||||
public boolean getAttributeBoolean(String namespace, String name)
|
||||
throws XmlPullParserException {
|
||||
final String value = getAttributeValue(namespace, name);
|
||||
if ("true".equalsIgnoreCase(value)) {
|
||||
return true;
|
||||
} else if ("false".equalsIgnoreCase(value)) {
|
||||
return false;
|
||||
} else {
|
||||
throw new IOException("Invalid attribute " + name,
|
||||
new IllegalArgumentException("For input string: \"" + value + "\""));
|
||||
throw new XmlPullParserException("Invalid attribute " + name + ": " + value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +135,10 @@ public class XmlTest {
|
||||
outer.putDoubleArray("double[]", new double[] { 43d, 44d, 45d });
|
||||
outer.putStringArray("string[]", new String[] { "foo", "bar", "baz" });
|
||||
|
||||
outer.putString("nullString", null);
|
||||
outer.putObject("nullObject", null);
|
||||
outer.putIntArray("nullArray", null);
|
||||
|
||||
final PersistableBundle nested = new PersistableBundle();
|
||||
nested.putString("nested_key", "nested_value");
|
||||
outer.putPersistableBundle("nested", nested);
|
||||
@@ -197,7 +201,9 @@ public class XmlTest {
|
||||
}
|
||||
|
||||
private static final String TEST_STRING = "com.example";
|
||||
private static final String TEST_STRING_EMPTY = "";
|
||||
private static final byte[] TEST_BYTES = new byte[] { 0, 1, 2, 3, 4, 3, 2, 1, 0 };
|
||||
private static final byte[] TEST_BYTES_EMPTY = new byte[0];
|
||||
|
||||
private static void doVerifyWrite(TypedXmlSerializer out) throws Exception {
|
||||
out.startDocument(StandardCharsets.UTF_8.name(), true);
|
||||
@@ -206,9 +212,11 @@ public class XmlTest {
|
||||
out.startTag(null, "two");
|
||||
{
|
||||
out.attribute(null, "string", TEST_STRING);
|
||||
out.attribute(null, "stringNumber", "49");
|
||||
out.attribute(null, "stringEmpty", TEST_STRING_EMPTY);
|
||||
out.attributeBytesHex(null, "bytesHex", TEST_BYTES);
|
||||
out.attributeBytesHex(null, "bytesHexEmpty", TEST_BYTES_EMPTY);
|
||||
out.attributeBytesBase64(null, "bytesBase64", TEST_BYTES);
|
||||
out.attributeBytesBase64(null, "bytesBase64Empty", TEST_BYTES_EMPTY);
|
||||
out.attributeInt(null, "int", 43);
|
||||
out.attributeIntHex(null, "intHex", 44);
|
||||
out.attributeLong(null, "long", 45L);
|
||||
@@ -216,6 +224,7 @@ public class XmlTest {
|
||||
out.attributeFloat(null, "float", 47f);
|
||||
out.attributeDouble(null, "double", 48d);
|
||||
out.attributeBoolean(null, "boolean", true);
|
||||
out.attribute(null, "stringNumber", "49");
|
||||
}
|
||||
out.endTag(null, "two");
|
||||
|
||||
@@ -241,10 +250,20 @@ public class XmlTest {
|
||||
{
|
||||
assertNext(in, START_TAG, "two", 2);
|
||||
{
|
||||
assertEquals(11, in.getAttributeCount());
|
||||
assertEquals(TEST_STRING, in.getAttributeValue(null, "string"));
|
||||
assertArrayEquals(TEST_BYTES, in.getAttributeBytesHex(null, "bytesHex"));
|
||||
assertArrayEquals(TEST_BYTES, in.getAttributeBytesBase64(null, "bytesBase64"));
|
||||
assertEquals(14, in.getAttributeCount());
|
||||
assertEquals(TEST_STRING,
|
||||
in.getAttributeValue(null, "string"));
|
||||
assertEquals(TEST_STRING_EMPTY,
|
||||
in.getAttributeValue(null, "stringEmpty"));
|
||||
assertArrayEquals(TEST_BYTES,
|
||||
in.getAttributeBytesHex(null, "bytesHex"));
|
||||
assertArrayEquals(TEST_BYTES_EMPTY,
|
||||
in.getAttributeBytesHex(null, "bytesHexEmpty"));
|
||||
assertArrayEquals(TEST_BYTES,
|
||||
in.getAttributeBytesBase64(null, "bytesBase64"));
|
||||
assertArrayEquals(TEST_BYTES_EMPTY,
|
||||
in.getAttributeBytesBase64(null, "bytesBase64Empty"));
|
||||
|
||||
assertEquals(43, in.getAttributeInt(null, "int"));
|
||||
assertEquals(44, in.getAttributeIntHex(null, "intHex"));
|
||||
assertEquals(45L, in.getAttributeLong(null, "long"));
|
||||
|
||||
@@ -18,8 +18,12 @@ package com.android.internal.util;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
|
||||
import android.util.TypedXmlPullParser;
|
||||
import android.util.TypedXmlSerializer;
|
||||
import android.util.Xml;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
@@ -27,11 +31,6 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
public class XmlUtilsTest extends TestCase {
|
||||
|
||||
// https://code.google.com/p/android/issues/detail?id=63717
|
||||
@@ -52,14 +51,14 @@ public class XmlUtilsTest extends TestCase {
|
||||
byte[] testByteArray = {0x1 , 0xa, 0xb, 0x9, 0x34, (byte) 0xaa, (byte) 0xba, (byte) 0x99};
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
|
||||
XmlSerializer serializer = new FastXmlSerializer();
|
||||
TypedXmlSerializer serializer = Xml.newFastSerializer();
|
||||
serializer.setOutput(baos, StandardCharsets.UTF_8.name());
|
||||
serializer.startDocument(null, true);
|
||||
XmlUtils.writeValueXml(testByteArray, "testByteArray", serializer);
|
||||
serializer.endDocument();
|
||||
|
||||
InputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
XmlPullParser pullParser = Xml.newPullParser();
|
||||
TypedXmlPullParser pullParser = Xml.newFastPullParser();
|
||||
pullParser.setInput(bais, StandardCharsets.UTF_8.name());
|
||||
String[] name = new String[1];
|
||||
byte[] testByteArrayDeserialized = (byte[]) XmlUtils.readValueXml(pullParser, name);
|
||||
|
||||
Reference in New Issue
Block a user