Support base64Binary and hexBinary
The xml generator is not supported the base64Binary and hexBinary. So,
the base64Binary and hexBinary were treated specially unlike other types.
Bug: 178068675
Test: m -j && atest xsdc-java-tests && atest xsdc-cpp-tests
Change-Id: I0261dec0548cc6e2b886d2187c721655fe568e99
diff --git a/src/com/android/xsdc/java/JavaCodeGenerator.java b/src/com/android/xsdc/java/JavaCodeGenerator.java
index b578148..d55c230 100644
--- a/src/com/android/xsdc/java/JavaCodeGenerator.java
+++ b/src/com/android/xsdc/java/JavaCodeGenerator.java
@@ -39,6 +39,7 @@
private boolean writer;
private boolean showNullability;
private boolean generateHasMethod;
+ private boolean useHexBinary;
public JavaCodeGenerator(XmlSchema xmlSchema, String packageName, boolean writer,
boolean showNullability, boolean generateHasMethod) throws JavaCodeGeneratorException {
@@ -47,6 +48,7 @@
this.writer = writer;
this.showNullability = showNullability;
this.generateHasMethod = generateHasMethod;
+ useHexBinary = false;
// class naming validation
{
@@ -124,6 +126,11 @@
printXmlWriter(out);
}
}
+ if (useHexBinary) {
+ try (CodeWriter out = new CodeWriter(fs.getPrintWriter("HexBinaryHelper.java"))) {
+ printHexBinaryHelper(out);
+ }
+ }
}
private void printEnumClass(CodeWriter out, String name, XsdRestriction restrictionType)
@@ -621,6 +628,33 @@
out.printf("}\n");
}
+ private void printHexBinaryHelper(CodeWriter out) throws JavaCodeGeneratorException {
+ out.printf("package %s;\n", packageName);
+ out.println();
+ out.println("public class HexBinaryHelper {");
+ out.print("public static byte[] hexStringToByteArray(String hexString) {\n"
+ + "if (hexString.length() % 2 != 0) {\n"
+ + "throw new IllegalArgumentException(\"length must be multiple of 2\");\n"
+ + "}\n"
+ + "byte[] outputBytes = new byte[hexString.length() / 2];\n"
+ + "for (int i = 0; i < hexString.length(); i += 2) {\n"
+ + "char c1 = hexString.charAt(i);\n"
+ + "char c2 = hexString.charAt(i + 1);\n"
+ + "outputBytes[i / 2] = (byte) ((Character.digit(c1, 16) << 4)"
+ + " + Character.digit(c2, 16));\n"
+ + "}\n"
+ + "return outputBytes;"
+ + "}\n\n"
+ + "public static String byteArrayToHexString(byte[] b) {\n"
+ + "StringBuffer s = new StringBuffer();\n"
+ + "for (int i = 0; i < b.length; i++) {\n"
+ + "s.append(Integer.toHexString(0x100 + (b[i] & 0xff)).substring(1));\n"
+ + "}\n"
+ + "return s.toString();\n"
+ + "}\n"
+ + "}\n");
+ }
+
private String getElementName(XsdElement element) {
if (element instanceof XsdChoice) {
return element.getName() + "_optional";
@@ -925,11 +959,16 @@
return new JavaSimpleType("float", "java.lang.Float", "Float.parseFloat(%s)",
false);
case "base64Binary":
- return new JavaSimpleType("byte[]", "java.util.Base64.getDecoder().decode(%s)",
+ return new JavaSimpleType("byte[]", "byte[]",
+ "java.util.Base64.getDecoder().decode(%s)",
+ "java.util.Base64.getEncoder().encodeToString(%s)",
false);
case "hexBinary":
- return new JavaSimpleType("java.math.BigInteger",
- "new java.math.BigInteger(%s, 16)", false);
+ useHexBinary = true;
+ return new JavaSimpleType("byte[]", "byte[]",
+ "HexBinaryHelper.hexStringToByteArray(%s)",
+ "HexBinaryHelper.byteArrayToHexString(%s)",
+ false);
}
throw new JavaCodeGeneratorException("unknown xsd predefined type : " + name);
}
diff --git a/src/com/android/xsdc/java/JavaSimpleType.java b/src/com/android/xsdc/java/JavaSimpleType.java
index 83c39b8..3535e89 100644
--- a/src/com/android/xsdc/java/JavaSimpleType.java
+++ b/src/com/android/xsdc/java/JavaSimpleType.java
@@ -20,19 +20,26 @@
final private String name;
final private String nullableName;
final private String rawParsingExpression;
+ final private String rawWritingExpression;
final private boolean list;
final private String fullName;
final private String nullableFullName;
- JavaSimpleType(String name, String nullableName, String rawParsingExpression, boolean list) {
+ JavaSimpleType(String name, String nullableName, String rawParsingExpression,
+ String rawWritingExpression, boolean list) {
this.name = name;
this.nullableName = nullableName;
this.rawParsingExpression = rawParsingExpression;
+ this.rawWritingExpression = rawWritingExpression;
this.list = list;
fullName = list ? String.format("java.util.List<%s>", nullableName) : name;
nullableFullName = list ? String.format("java.util.List<%s>", nullableName) : nullableName;
}
+ JavaSimpleType(String name, String nullableName, String rawParsingExpression, boolean list) {
+ this(name, nullableName, rawParsingExpression, "%s", list);
+ }
+
JavaSimpleType(String name, String rawParsingExpression, boolean list) {
this(name, name, rawParsingExpression, list);
}
@@ -91,7 +98,8 @@
expression.append("out.printf(\"%s\", v);\n}\n");
expression.append("}\n");
} else {
- expression.append(String.format("out.printf(\"%%s\", %s);\n", getValue));
+ expression.append(String.format("out.printf(\"%%s\", %s);\n",
+ String.format(rawWritingExpression, getValue)));
}
return expression.toString();
}
diff --git a/tests/main.cpp b/tests/main.cpp
index 02a8891..4dbf2d0 100644
--- a/tests/main.cpp
+++ b/tests/main.cpp
@@ -130,7 +130,7 @@
EXPECT_EQ(miscTypes.getAnyURI(), "https://www.google.com");
EXPECT_EQ(miscTypes.getBase64Binary(), "Z29vZ2xl");
EXPECT_TRUE(miscTypes.getBoolean());
- EXPECT_EQ(miscTypes.getHexBinary(), "516a75cb56d7e7");
+ EXPECT_EQ(miscTypes.getHexBinary(), "016a75cb56d7e7");
EXPECT_EQ(miscTypes.getQName(), "abcd");
EXPECT_EQ(miscTypes.getIDREF(), "abcd");
EXPECT_EQ(miscTypes.getIDREFS()[0], "abcd");
diff --git a/tests/resources/predefined_types.xml b/tests/resources/predefined_types.xml
index 7c4cf1b..9c24542 100644
--- a/tests/resources/predefined_types.xml
+++ b/tests/resources/predefined_types.xml
@@ -46,7 +46,7 @@
<anyURI>https://www.google.com</anyURI>
<base64Binary>Z29vZ2xl</base64Binary>
<boolean>true</boolean>
- <hexBinary>516a75cb56d7e7</hexBinary>
+ <hexBinary>016a75cb56d7e7</hexBinary>
<QName>abcd</QName>
<IDREF>abcd</IDREF>
<IDREFS>abcd abcd</IDREFS>
diff --git a/tests/resources/predefined_types/api/current.txt b/tests/resources/predefined_types/api/current.txt
index 6a5ab13..e7141d3 100644
--- a/tests/resources/predefined_types/api/current.txt
+++ b/tests/resources/predefined_types/api/current.txt
@@ -23,6 +23,12 @@
method public void setTime(javax.xml.datatype.XMLGregorianCalendar);
}
+ public class HexBinaryHelper {
+ ctor public HexBinaryHelper();
+ method public static String byteArrayToHexString(byte[]);
+ method public static byte[] hexStringToByteArray(String);
+ }
+
public class ListPrimitiveTypes {
ctor public ListPrimitiveTypes();
method public java.util.List<java.lang.Boolean> getListBoolean();
@@ -46,7 +52,7 @@
method public String getAnyType();
method public String getAnyURI();
method public byte[] getBase64Binary();
- method public java.math.BigInteger getHexBinary();
+ method public byte[] getHexBinary();
method public String getIDREF();
method public java.util.List<java.lang.String> getIDREFS();
method public String getQName();
@@ -56,7 +62,7 @@
method public void setAnyType(String);
method public void setAnyURI(String);
method public void setBase64Binary(byte[]);
- method public void setHexBinary(java.math.BigInteger);
+ method public void setHexBinary(byte[]);
method public void setIDREF(String);
method public void setIDREFS(java.util.List<java.lang.String>);
method public void setQName(String);
diff --git a/tests/src/com/android/xsdc/tests/XmlParserTest.java b/tests/src/com/android/xsdc/tests/XmlParserTest.java
index ed9aa08..f3b5eaf 100644
--- a/tests/src/com/android/xsdc/tests/XmlParserTest.java
+++ b/tests/src/com/android/xsdc/tests/XmlParserTest.java
@@ -180,7 +180,8 @@
assertThat(miscTypes.getAnyURI(), is("https://www.google.com"));
assertThat(miscTypes.getBase64Binary(), is(Base64.getDecoder().decode("Z29vZ2xl")));
assertThat(miscTypes.get_boolean(), is(true));
- assertThat(miscTypes.getHexBinary(), is(new BigInteger("516a75cb56d7e7", 16)));
+ assertThat(miscTypes.getHexBinary(),
+ is(predefined.types.HexBinaryHelper.hexStringToByteArray("016a75cb56d7e7")));
assertThat(miscTypes.getQName(), is("abcd"));
assertThat(miscTypes.getIDREF(), is("abcd"));
assertThat(miscTypes.getIDREFS(), is(Arrays.asList("abcd", "abcd")));
@@ -203,6 +204,21 @@
assertThat(listPrimitiveTypes.getListFloat(), is(Arrays.asList(123.4f, 456.1f)));
assertThat(listPrimitiveTypes.getListBoolean(), is(Arrays.asList(true, false)));
}
+
+ String actualStr, expectedStr;
+ try (InputStream str = this.getClass().getClassLoader().getResourceAsStream(
+ "predefined_types.xml")) {
+ expectedStr = new String(str.readAllBytes());
+ }
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+ try(predefined.types.XmlWriter writer =
+ new predefined.types.XmlWriter(new PrintWriter(baos))) {
+ predefined.types.XmlWriter.write(writer, type);
+ }
+ actualStr = new String(baos.toByteArray());
+ }
+
+ assertThat(new String(actualStr), is(expectedStr));
}
@Test