diff options
author | Mikhail Naganov <mnaganov@google.com> | 2021-02-23 02:21:03 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-02-23 02:21:03 +0000 |
commit | fcf13b67d15723b32da321df7d00128aa9781e5e (patch) | |
tree | 57624dfde525ab400676998f859f7c2c2cd80232 | |
parent | 7f109231171d41e94454886e1f200a2281ae001d (diff) | |
parent | 2b3040434ef85b51f87c546ca3193dc0f2581981 (diff) | |
download | xsdc-fcf13b67d15723b32da321df7d00128aa9781e5e.tar.gz |
Split C++ generated code into "enums" and "parser" parts am: 70dbbc6c8d am: d69b0fc8f4 am: 2b3040434e
Original change: https://android-review.googlesource.com/c/platform/system/tools/xsdc/+/1595434
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: Id6b7736bdeb08c2c0946af61b3ab5cb2a371d003
-rw-r--r-- | build/xsdc.go | 63 | ||||
-rw-r--r-- | src/com/android/xsdc/CodeWriter.java | 21 | ||||
-rw-r--r-- | src/com/android/xsdc/Main.java | 29 | ||||
-rw-r--r-- | src/com/android/xsdc/cpp/CppCodeGenerator.java | 373 | ||||
-rw-r--r-- | tests/Android.bp | 55 | ||||
-rw-r--r-- | tests/main.cpp | 306 | ||||
-rw-r--r-- | tests/resources/simple_type/Android.bp | 16 | ||||
-rw-r--r-- | tests/simple_type.cpp | 52 | ||||
-rw-r--r-- | tests/simple_type_enumsonly.cpp | 28 | ||||
-rw-r--r-- | tests/tests.cpp | 282 | ||||
-rw-r--r-- | tests/xmltest.h | 29 |
11 files changed, 761 insertions, 493 deletions
diff --git a/build/xsdc.go b/build/xsdc.go index 22c0fc5..492d68e 100644 --- a/build/xsdc.go +++ b/build/xsdc.go @@ -69,7 +69,14 @@ type xsdConfigProperties struct { // Whether has{element or atrribute} methods are set to public. // It is not applied to C++, because these methods are always // generated to public for C++. - Gen_has *bool + Gen_has *bool + // Only generate code for enum converters. Applies to C++ only. + // This is useful for memory footprint reduction since it avoids + // depending on libxml2. + Enums_only *bool + // Only generate complementary code for XML parser. Applies to C++ only. + // The code being generated depends on the enum converters module. + Parser_only *bool } type xsdConfig struct { @@ -79,13 +86,13 @@ type xsdConfig struct { genOutputDir android.Path genOutputs_j android.WritablePath - genOutputs_c android.WritablePath - genOutputs_h android.WritablePath + genOutputs_c android.WritablePaths + genOutputs_h android.WritablePaths docsPath android.Path xsdConfigPath android.OptionalPath - genOutputs android.Paths + genOutputs android.Paths } var _ android.SourceFileProducer = (*xsdConfig)(nil) @@ -112,7 +119,7 @@ type DroidstubsProperties struct { } func (module *xsdConfig) GeneratedSourceFiles() android.Paths { - return android.Paths{module.genOutputs_c} + return module.genOutputs_c.Paths() } func (module *xsdConfig) Srcs() android.Paths { @@ -120,7 +127,7 @@ func (module *xsdConfig) Srcs() android.Paths { } func (module *xsdConfig) GeneratedDeps() android.Paths { - return android.Paths{module.genOutputs_h} + return module.genOutputs_h.Paths() } func (module *xsdConfig) GeneratedHeaderDirs() android.Paths { @@ -179,6 +186,14 @@ func (module *xsdConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) args = args + " -g " } + if proptools.Bool(module.properties.Enums_only) { + args = args + " -e " + } + + if proptools.Bool(module.properties.Parser_only) { + args = args + " -x " + } + module.genOutputs_j = android.PathForModuleGen(ctx, "java", filenameStem+"_xsdcgen.srcjar") ctx.Build(pctx, android.BuildParams{ @@ -189,25 +204,41 @@ func (module *xsdConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) Output: module.genOutputs_j, Args: map[string]string{ "pkgName": pkgName, - "args": args, + "args": args, }, }) - module.genOutputs_c = android.PathForModuleGen(ctx, "cpp", filenameStem+".cpp") - module.genOutputs_h = android.PathForModuleGen(ctx, "cpp", "include/"+filenameStem+".h") + if proptools.Bool(module.properties.Enums_only) { + module.genOutputs_c = android.WritablePaths{ + android.PathForModuleGen(ctx, "cpp", filenameStem+"_enums.cpp")} + module.genOutputs_h = android.WritablePaths{ + android.PathForModuleGen(ctx, "cpp", "include/"+filenameStem+"_enums.h")} + } else if proptools.Bool(module.properties.Parser_only) { + module.genOutputs_c = android.WritablePaths{ + android.PathForModuleGen(ctx, "cpp", filenameStem+".cpp")} + module.genOutputs_h = android.WritablePaths{ + android.PathForModuleGen(ctx, "cpp", "include/"+filenameStem+".h")} + } else { + module.genOutputs_c = android.WritablePaths{ + android.PathForModuleGen(ctx, "cpp", filenameStem+".cpp"), + android.PathForModuleGen(ctx, "cpp", filenameStem+"_enums.cpp")} + module.genOutputs_h = android.WritablePaths{ + android.PathForModuleGen(ctx, "cpp", "include/"+filenameStem+".h"), + android.PathForModuleGen(ctx, "cpp", "include/"+filenameStem+"_enums.h")} + } module.genOutputDir = android.PathForModuleGen(ctx, "cpp", "include") ctx.Build(pctx, android.BuildParams{ - Rule: xsdcCppRule, - Description: "xsdc " + xsdFile.String(), - Input: xsdFile, - Implicit: module.docsPath, - Output: module.genOutputs_c, - ImplicitOutput: module.genOutputs_h, + Rule: xsdcCppRule, + Description: "xsdc " + xsdFile.String(), + Input: xsdFile, + Implicit: module.docsPath, + Outputs: module.genOutputs_c, + ImplicitOutputs: module.genOutputs_h, Args: map[string]string{ "pkgName": pkgName, "outDir": android.PathForModuleGen(ctx, "cpp").String(), - "args": args, + "args": args, }, }) module.xsdConfigPath = android.ExistentPathForSource(ctx, xsdFile.String()) diff --git a/src/com/android/xsdc/CodeWriter.java b/src/com/android/xsdc/CodeWriter.java index 1ffe801..489ccdc 100644 --- a/src/com/android/xsdc/CodeWriter.java +++ b/src/com/android/xsdc/CodeWriter.java @@ -24,6 +24,10 @@ public class CodeWriter implements Closeable { private int indent; private boolean startLine; + public CodeWriter() { + this(null); + } + public CodeWriter(PrintWriter printWriter) { out = printWriter; indent = 0; @@ -33,13 +37,15 @@ public class CodeWriter implements Closeable { private void printIndent() { assert startLine; for (int i = 0; i < indent; ++i) { - out.print(" "); + printImpl(" "); } startLine = false; } public void println() { - out.println(); + if (out != null) { + out.println(); + } startLine = true; } @@ -58,13 +64,12 @@ public class CodeWriter implements Closeable { if (startLine && !line.isEmpty()) { printIndent(); } - out.print(line); + printImpl(line); if (line.endsWith("{")) { ++indent; } if (i + 1 < lines.length) { - out.println(); - startLine = true; + println(); } } } @@ -79,4 +84,10 @@ public class CodeWriter implements Closeable { out.close(); } } + + private void printImpl(String code) { + if (out != null) { + out.print(code); + } + } } diff --git a/src/com/android/xsdc/Main.java b/src/com/android/xsdc/Main.java index 5f786f3..caac98b 100644 --- a/src/com/android/xsdc/Main.java +++ b/src/com/android/xsdc/Main.java @@ -29,7 +29,9 @@ import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.OptionGroup; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; @@ -75,6 +77,24 @@ public class Main { .hasArgs(0) .withDescription("Generate public hasX() method") .create("g")); + Option genEnumsOnly = OptionBuilder + .withLongOpt("genEnumsOnly") + .hasArgs(0) + .withDescription("Only generate enum converters in Cpp code.") + .create("e"); + options.addOption(genEnumsOnly); + Option genParserOnly = OptionBuilder + .withLongOpt("genParserOnly") + .hasArgs(0) + .withDescription("Only generate XML parser in Cpp code.") + .create("x"); + options.addOption(genParserOnly); + // "Only generate enums" and "Only generate parser" options are mutually exclusive. + OptionGroup genOnlyGroup = new OptionGroup(); + genOnlyGroup.setRequired(false); + genOnlyGroup.addOption(genEnumsOnly); + genOnlyGroup.addOption(genParserOnly); + options.addOptionGroup(genOnlyGroup); CommandLineParser CommandParser = new GnuParser(); CommandLine cmd; @@ -93,9 +113,11 @@ public class Main { boolean writer = cmd.hasOption('w'); boolean nullability = cmd.hasOption('n'); boolean genHas = cmd.hasOption('g'); + boolean enumsOnly = cmd.hasOption('e'); + boolean parserOnly = cmd.hasOption('x'); if (xsdFile.length != 1 || packageName == null) { - System.err.println("Error: no xsd files or pacakge name"); + System.err.println("Error: no xsd files or package name"); help(options); } @@ -116,8 +138,11 @@ public class Main { File includeDir = new File(Paths.get(outDir, "include").toString()); includeDir.mkdirs(); FileSystem fs = new FileSystem(new File(outDir)); + int generators = enumsOnly ? CppCodeGenerator.GENERATE_ENUMS : + (parserOnly ? CppCodeGenerator.GENERATE_PARSER : + CppCodeGenerator.GENERATE_ENUMS | CppCodeGenerator.GENERATE_PARSER); CppCodeGenerator cppCodeGenerator = - new CppCodeGenerator(xmlSchema, packageName, writer); + new CppCodeGenerator(xmlSchema, packageName, writer, generators); cppCodeGenerator.print(fs); } } diff --git a/src/com/android/xsdc/cpp/CppCodeGenerator.java b/src/com/android/xsdc/cpp/CppCodeGenerator.java index e2a98c8..561d3f5 100644 --- a/src/com/android/xsdc/cpp/CppCodeGenerator.java +++ b/src/com/android/xsdc/cpp/CppCodeGenerator.java @@ -34,21 +34,28 @@ import java.util.Set; import javax.xml.namespace.QName; public class CppCodeGenerator { + public static final int GENERATE_ENUMS = 1 << 0; + public static final int GENERATE_PARSER = 1 << 1; + private XmlSchema xmlSchema; private String pkgName; private Map<String, CppSimpleType> cppSimpleTypeMap; - private CodeWriter cppFile; - private CodeWriter headerFile; + private CodeWriter enumsCppFile; + private CodeWriter enumsHeaderFile; + private CodeWriter parserCppFile; + private CodeWriter parserHeaderFile; private boolean hasAttr; private boolean writer; + private int generators; private static final String UNKNOWN_ENUM = "UNKNOWN"; - public CppCodeGenerator(XmlSchema xmlSchema, String pkgName, boolean writer) + public CppCodeGenerator(XmlSchema xmlSchema, String pkgName, boolean writer, int generators) throws CppCodeGeneratorException { this.xmlSchema = xmlSchema; this.pkgName = pkgName; this.writer = writer; + this.generators = generators; // class naming validation { @@ -95,11 +102,26 @@ public class CppCodeGenerator { public void print(FileSystem fs) throws CppCodeGeneratorException, IOException { - // cpp file, headr file init - String cppFileName = pkgName.replace(".", "_") + ".cpp"; - String hFileName = pkgName.replace(".", "_") + ".h"; - cppFile = new CodeWriter(fs.getPrintWriter(cppFileName)); - headerFile = new CodeWriter(fs.getPrintWriter("include/" + hFileName)); + // cpp file, header file init + String fileNameStem = pkgName.replace('.', '_'); + String enumsCppFileName = fileNameStem + "_enums.cpp"; + String enumsHeaderFileName = fileNameStem + "_enums.h"; + String parserCppFileName = fileNameStem + ".cpp"; + String parserHeaderFileName = fileNameStem + ".h"; + if ((this.generators & GENERATE_ENUMS) == GENERATE_ENUMS) { + enumsCppFile = new CodeWriter(fs.getPrintWriter(enumsCppFileName)); + enumsHeaderFile = new CodeWriter(fs.getPrintWriter("include/" + enumsHeaderFileName)); + } else { + enumsCppFile = new CodeWriter(); + enumsHeaderFile = new CodeWriter(); + } + if ((this.generators & GENERATE_PARSER) == GENERATE_PARSER) { + parserCppFile = new CodeWriter(fs.getPrintWriter(parserCppFileName)); + parserHeaderFile = new CodeWriter(fs.getPrintWriter("include/" + parserHeaderFileName)); + } else { + parserCppFile = new CodeWriter(); + parserHeaderFile = new CodeWriter(); + } boolean hasEnums = false; for (XsdType type : xmlSchema.getTypeMap().values()) { @@ -110,33 +132,46 @@ public class CppCodeGenerator { } } - String headerMacro = hFileName.toUpperCase().replace(".", "_"); - headerFile.printf("#ifndef %s\n", headerMacro); - headerFile.printf("#define %s\n", headerMacro); - headerFile.printf("\n"); - headerFile.printf("#include <array>\n"); - headerFile.printf("#include <map>\n"); - headerFile.printf("#include <optional>\n"); - headerFile.printf("#include <string>\n"); - headerFile.printf("#include <vector>\n"); + String enumsHeaderMacro = enumsHeaderFileName.toUpperCase().replace('.', '_'); + String parserHeaderMacro = parserHeaderFileName.toUpperCase().replace('.', '_'); + enumsHeaderFile.printf("#ifndef %s\n", enumsHeaderMacro); + enumsHeaderFile.printf("#define %s\n", enumsHeaderMacro); + enumsHeaderFile.printf("\n"); + enumsHeaderFile.printf("#include <array>\n"); + enumsHeaderFile.printf("#include <string>\n"); + enumsHeaderFile.printf("\n"); + parserHeaderFile.printf("#ifndef %s\n", parserHeaderMacro); + parserHeaderFile.printf("#define %s\n", parserHeaderMacro); + parserHeaderFile.printf("\n"); + parserHeaderFile.printf("#include <array>\n"); + parserHeaderFile.printf("#include <map>\n"); + parserHeaderFile.printf("#include <optional>\n"); + parserHeaderFile.printf("#include <string>\n"); + parserHeaderFile.printf("#include <vector>\n"); if (writer) { - headerFile.printf("#include <iostream>\n"); - } - headerFile.printf("\n"); - headerFile.printf("#if __has_include(<libxml/parser.h>)\n"); - headerFile.printf("#include <libxml/parser.h>\n"); - headerFile.printf("#include <libxml/xinclude.h>\n"); - headerFile.printf("#else\n"); - headerFile.printf("#error Require libxml2 library. "); - headerFile.printf("Please add libxml2 to shared_libs or static_libs\n"); - headerFile.printf("#endif\n"); + parserHeaderFile.printf("#include <iostream>\n"); + } + parserHeaderFile.printf("\n"); + parserHeaderFile.printf("#if __has_include(<libxml/parser.h>)\n"); + parserHeaderFile.printf("#include <libxml/parser.h>\n"); + parserHeaderFile.printf("#include <libxml/xinclude.h>\n"); + parserHeaderFile.printf("#else\n"); + parserHeaderFile.printf("#error Require libxml2 library. "); + parserHeaderFile.printf("Please add libxml2 to shared_libs or static_libs\n"); + parserHeaderFile.printf("#endif\n"); if (hasEnums) { - headerFile.printf("#include <xsdc/XsdcSupport.h>\n"); + enumsHeaderFile.printf("#include <xsdc/XsdcSupport.h>\n"); + enumsHeaderFile.printf("\n"); } - headerFile.printf("\n"); + parserHeaderFile.printf("\n"); + parserHeaderFile.printf("#include \"%s\"\n", enumsHeaderFileName); + parserHeaderFile.printf("\n"); - cppFile.printf("#define LOG_TAG \"%s\"\n", pkgName); - cppFile.printf("#include \"%s\"\n\n", hFileName); + enumsCppFile.printf("#include <map>\n"); + enumsCppFile.printf("\n"); + enumsCppFile.printf("#include \"%s\"\n\n", enumsHeaderFileName); + parserCppFile.printf("#define LOG_TAG \"%s\"\n", pkgName); + parserCppFile.printf("#include \"%s\"\n\n", parserHeaderFileName); List<String> namespace = new java.util.ArrayList<>(); for (String token : pkgName.split("\\.")) { @@ -147,8 +182,10 @@ public class CppCodeGenerator { token = "_" + token; } namespace.add(token); - headerFile.printf("namespace %s {\n", token); - cppFile.printf("namespace %s {\n", token); + enumsHeaderFile.printf("namespace %s {\n", token); + enumsCppFile.printf("namespace %s {\n", token); + parserHeaderFile.printf("namespace %s {\n", token); + parserCppFile.printf("namespace %s {\n", token); } printPrototype(); @@ -183,13 +220,15 @@ public class CppCodeGenerator { Collections.reverse(namespace); for (String token : namespace) { - headerFile.printf("} // %s\n", token); - cppFile.printf("} // %s\n", token); + enumsHeaderFile.printf("} // %s\n", token); + enumsCppFile.printf("} // %s\n", token); + parserHeaderFile.printf("} // %s\n", token); + parserCppFile.printf("} // %s\n", token); } if (hasEnums) { - headerFile.printf("\n//\n// global type declarations for package\n//\n\n"); - headerFile.printf("namespace android {\nnamespace details {\n"); + enumsHeaderFile.printf("\n//\n// global type declarations for package\n//\n\n"); + enumsHeaderFile.printf("namespace android {\nnamespace details {\n"); Collections.reverse(namespace); for (XsdType type : xmlSchema.getTypeMap().values()) { if (type instanceof XsdRestriction && @@ -199,82 +238,79 @@ public class CppCodeGenerator { printEnumValues(namespace, name, restrictionType); } } - headerFile.printf("} // namespace details\n} // namespace android\n\n"); + enumsHeaderFile.printf("} // namespace details\n} // namespace android\n\n"); } - headerFile.printf("#endif // %s\n", headerMacro); - cppFile.close(); - headerFile.close(); + parserHeaderFile.printf("#endif // %s\n", parserHeaderMacro); + enumsHeaderFile.printf("#endif // %s\n", enumsHeaderMacro); + parserCppFile.close(); + parserHeaderFile.close(); + enumsCppFile.close(); + enumsHeaderFile.close(); } private void printEnum(String name, XsdRestriction restrictionType) throws CppCodeGeneratorException { - headerFile.printf("enum class %s {\n", name); - cppFile.printf("const std::map<std::string, %s> %sString {\n", name, name); + enumsHeaderFile.printf("enum class %s {\n", name); + enumsCppFile.printf("const std::map<std::string, %s> %sString {\n", name, name); List<XsdEnumeration> enums = restrictionType.getEnums(); - headerFile.printf("%s = %d,\n", UNKNOWN_ENUM, -1); + enumsHeaderFile.printf("%s = %d,\n", UNKNOWN_ENUM, -1); for (XsdEnumeration tag : enums) { String value = tag.getValue(); - headerFile.printf("%s,\n", Utils.toEnumName(value)); - cppFile.printf("{ \"%s\", %s::%s },\n", tag.getValue(), name, + enumsHeaderFile.printf("%s,\n", Utils.toEnumName(value)); + enumsCppFile.printf("{ \"%s\", %s::%s },\n", tag.getValue(), name, Utils.toEnumName(value)); } - headerFile.printf("};\n"); - cppFile.printf("};\n\n"); + enumsHeaderFile.printf("};\n"); + enumsCppFile.printf("};\n\n"); - headerFile.printf("%s stringTo%s(const std::string& value);\n", + enumsHeaderFile.printf("%s stringTo%s(const std::string& value);\n", name, name); - cppFile.printf("%s stringTo%s(const std::string& value) {\n" + enumsCppFile.printf("%s stringTo%s(const std::string& value) {\n" + "auto enumValue = %sString.find(value);\n" + "return enumValue != %sString.end() ? enumValue->second : %s::%s;\n" + "}\n\n", name, name, name, name, name, UNKNOWN_ENUM); - headerFile.printf("std::string toString(%s o);\n\n", name); - cppFile.printf("std::string toString(%s o) {\n", name); - cppFile.printf("switch (o) {\n"); + enumsHeaderFile.printf("std::string toString(%s o);\n\n", name); + enumsCppFile.printf("std::string toString(%s o) {\n", name); + enumsCppFile.printf("switch (o) {\n"); for (XsdEnumeration tag : enums) { String value = tag.getValue(); - cppFile.printf("case %s::%s: return \"%s\";\n", + enumsCppFile.printf("case %s::%s: return \"%s\";\n", name, Utils.toEnumName(value), tag.getValue()); } - cppFile.printf("default: return std::to_string(static_cast<int>(o));\n}\n"); - cppFile.printf("}\n\n"); + enumsCppFile.printf("default: return std::to_string(static_cast<int>(o));\n}\n"); + enumsCppFile.printf("}\n\n"); } private void printEnumValues(List<String> namespace, String name, XsdRestriction restrictionType) throws CppCodeGeneratorException { List<XsdEnumeration> enums = restrictionType.getEnums(); String absoluteNamespace = "::" + String.join("::", namespace); - headerFile.printf("template<> inline constexpr std::array<%s::%s, %d> " + enumsHeaderFile.printf("template<> inline constexpr std::array<%s::%s, %d> " + "xsdc_enum_values<%s::%s> = {\n", absoluteNamespace, name, enums.size(), absoluteNamespace, name); for (XsdEnumeration tag : enums) { String value = tag.getValue(); - headerFile.printf("%s::%s::%s,\n", absoluteNamespace, name, Utils.toEnumName(value)); + enumsHeaderFile.printf("%s::%s::%s,\n", + absoluteNamespace, name, Utils.toEnumName(value)); } - headerFile.printf("};\n"); + enumsHeaderFile.printf("};\n"); } private void printPrototype() throws CppCodeGeneratorException { for (XsdType type : xmlSchema.getTypeMap().values()) { - if (type instanceof XsdRestriction && - ((XsdRestriction)type).getEnums() != null) { - String name = Utils.toClassName(type.getName()); - headerFile.printf("enum class %s;\n", name); - } - } - for (XsdType type : xmlSchema.getTypeMap().values()) { if (type instanceof XsdComplexType) { String name = Utils.toClassName(type.getName()); - headerFile.printf("class %s;\n", name); + parserHeaderFile.printf("class %s;\n", name); } } for (XsdElement element : xmlSchema.getElementMap().values()) { XsdType type = element.getType(); if (type.getRef() == null && type instanceof XsdComplexType) { String name = Utils.toClassName(element.getName()); - headerFile.printf("class %s;\n", name); + parserHeaderFile.printf("class %s;\n", name); } } } @@ -288,12 +324,12 @@ public class CppCodeGenerator { CppSimpleType valueType = (complexType instanceof XsdSimpleContent) ? getValueType((XsdSimpleContent) complexType, false) : null; - headerFile.printf("class %s ", name); + parserHeaderFile.printf("class %s ", name); if (baseName != null) { - headerFile.printf(": public %s {\n", baseName); + parserHeaderFile.printf(": public %s {\n", baseName); } else { - headerFile.println("{"); + parserHeaderFile.println("{"); } // parse types for elements and attributes @@ -308,11 +344,11 @@ public class CppCodeGenerator { if (element.getRef() == null && element.getType().getRef() == null && element.getType() instanceof XsdComplexType) { // print inner class for anonymous types - headerFile.printf("public:\n"); + parserHeaderFile.printf("public:\n"); String innerName = Utils.toClassName(getElementName(element)); XsdComplexType innerType = (XsdComplexType) element.getType(); printClass(innerName, nameScope + name + "::", innerType); - headerFile.println(); + parserHeaderFile.println(); cppType = new CppComplexType(nameScope + name + "::"+ innerName); } else { cppType = parseType(elementValue.getType(), getElementName(elementValue)); @@ -333,14 +369,14 @@ public class CppCodeGenerator { // print member variables - headerFile.printf("private:\n"); + parserHeaderFile.printf("private:\n"); for (int i = 0; i < elementTypes.size(); ++i) { CppType type = elementTypes.get(i); XsdElement element = elements.get(i); XsdElement elementValue = resolveElement(element); String typeName = Utils.elementTypeName(type.getName(), element.isMultiple() || type instanceof CppComplexType); - headerFile.printf("const %s %s_;\n", typeName, + parserHeaderFile.printf("const %s %s_;\n", typeName, Utils.toVariableName(getElementName(elementValue))); } for (int i = 0; i < attributeTypes.size(); ++i) { @@ -348,16 +384,17 @@ public class CppCodeGenerator { XsdAttribute attribute = resolveAttribute(attributes.get(i)); String variableName = Utils.toVariableName(attribute.getName()); if (attribute.isRequired()) { - headerFile.printf("const %s %s_;\n", type.getName(), variableName); + parserHeaderFile.printf("const %s %s_;\n", type.getName(), variableName); } else { - headerFile.printf("const std::optional<%s> %s_;\n", type.getName(), variableName); + parserHeaderFile.printf("const std::optional<%s> %s_;\n", + type.getName(), variableName); } } if (valueType != null) { - headerFile.printf("const std::optional<%s> _value;\n", valueType.getName()); + parserHeaderFile.printf("const std::optional<%s> _value;\n", valueType.getName()); } - headerFile.printf("public:\n"); + parserHeaderFile.printf("public:\n"); String constructorArgs = printConstructor(name, nameScope, complexType, elements, attributes, baseName); @@ -388,7 +425,7 @@ public class CppCodeGenerator { printWriter(name, nameScope, complexType); } - headerFile.println("};\n"); + parserHeaderFile.println("};\n"); } private void printParser(String name, String nameScope, XsdComplexType complexType, String args) @@ -413,51 +450,51 @@ public class CppCodeGenerator { } String fullName = nameScope + name; - headerFile.printf("static %s read(xmlNode *root);\n", fullName, Utils.lowerize(name)); - cppFile.printf("\n%s %s::read(xmlNode *root) {\n", fullName, fullName); + parserHeaderFile.printf("static %s read(xmlNode *root);\n", fullName, Utils.lowerize(name)); + parserCppFile.printf("\n%s %s::read(xmlNode *root) {\n", fullName, fullName); - cppFile.print("std::string raw;\n"); + parserCppFile.print("std::string raw;\n"); for (int i = 0; i < allAttributes.size(); ++i) { CppSimpleType type = allAttributeTypes.get(i); XsdAttribute attribute = resolveAttribute(allAttributes.get(i)); String variableName = Utils.toVariableName(attribute.getName()); - cppFile.printf("raw = getXmlAttribute(root, \"%s\");\n", attribute.getName()); + parserCppFile.printf("raw = getXmlAttribute(root, \"%s\");\n", attribute.getName()); if (attribute.isRequired()) { if (type.isEnum()) { - cppFile.printf("%s %s = %s::%s;\n", + parserCppFile.printf("%s %s = %s::%s;\n", type.getName(), variableName, type.getName(), UNKNOWN_ENUM); } else { - cppFile.printf("%s %s{};\n", type.getName(), variableName); + parserCppFile.printf("%s %s{};\n", type.getName(), variableName); } } else { - cppFile.printf("std::optional<%s> %s = std::nullopt;\n", type.getName(), + parserCppFile.printf("std::optional<%s> %s = std::nullopt;\n", type.getName(), variableName); } - cppFile.printf("if (raw != \"\") {\n"); - cppFile.print(type.getParsingExpression()); - cppFile.printf("%s = value;\n}\n", variableName); + parserCppFile.printf("if (raw != \"\") {\n"); + parserCppFile.print(type.getParsingExpression()); + parserCppFile.printf("%s = value;\n}\n", variableName); } if (baseValueType != null) { - cppFile.printf("auto xmlValue = make_xmlUnique(xmlNodeListGetString(" + parserCppFile.printf("auto xmlValue = make_xmlUnique(xmlNodeListGetString(" + "root->doc, root->xmlChildrenNode, 1));\n" + "if (xmlValue != nullptr) {\n" + "raw = reinterpret_cast<const char*>(xmlValue.get());\n"); - cppFile.print(baseValueType.getParsingExpression()); - cppFile.printf("instance.setValue(value);\n"); - cppFile.printf("}\n"); + parserCppFile.print(baseValueType.getParsingExpression()); + parserCppFile.printf("instance.setValue(value);\n"); + parserCppFile.printf("}\n"); } else if (!allElements.isEmpty()) { for (int i = 0; i < allElements.size(); ++i) { CppType type = allElementTypes.get(i); XsdElement element = allElements.get(i); XsdElement elementValue = resolveElement(element); String variableName = Utils.toVariableName(getElementName(elementValue)); - cppFile.printf("%s %s;\n", Utils.elementTypeName(type.getName(), + parserCppFile.printf("%s %s;\n", Utils.elementTypeName(type.getName(), element.isMultiple() || type instanceof CppComplexType), variableName); } - cppFile.print("for (xmlNode *child = root->xmlChildrenNode; child != nullptr;" + parserCppFile.print("for (xmlNode *child = root->xmlChildrenNode; child != nullptr;" + " child = child->next) {\n"); for (int i = 0; i < allElements.size(); ++i) { CppType type = allElementTypes.get(i); @@ -465,29 +502,31 @@ public class CppCodeGenerator { XsdElement elementValue = resolveElement(element); String variableName = Utils.toVariableName(getElementName(elementValue)); - if (i != 0) cppFile.printf("} else "); - cppFile.print("if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>"); - cppFile.printf("(\"%s\"))) {\n", elementValue.getName()); + if (i != 0) parserCppFile.printf("} else "); + parserCppFile.print("if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>"); + parserCppFile.printf("(\"%s\"))) {\n", elementValue.getName()); if (type instanceof CppSimpleType) { - cppFile.print("auto xmlValue = make_xmlUnique(xmlNodeListGetString("); - cppFile.print("child->doc, child->xmlChildrenNode, 1));\n"); - cppFile.print("if (xmlValue == nullptr) {\nraw = \"\";\n} else {\n"); - cppFile.print("raw = reinterpret_cast<const char*>(xmlValue.get());\n}\n"); + parserCppFile.print("auto xmlValue = make_xmlUnique(xmlNodeListGetString("); + parserCppFile.print("child->doc, child->xmlChildrenNode, 1));\n"); + parserCppFile.print("if (xmlValue == nullptr) {\nraw = \"\";\n} else {\n"); + parserCppFile.print("raw = reinterpret_cast<const char*>(xmlValue.get());\n}"); + parserCppFile.print("\n"); } - cppFile.print(type.getParsingExpression()); + parserCppFile.print(type.getParsingExpression()); if (element.isMultiple() || type instanceof CppComplexType) { - cppFile.printf("%s.push_back(std::move(value));\n", variableName); + parserCppFile.printf("%s.push_back(std::move(value));\n", variableName); } else { - cppFile.printf("%s = std::move(value);\n", variableName); + parserCppFile.printf("%s = std::move(value);\n", variableName); } } - cppFile.printf("}\n}\n"); + parserCppFile.printf("}\n}\n"); } - cppFile.printf("%s instance%s;\n", fullName, args.length() > 0 ? "(" + args + ")" : ""); - cppFile.print("return instance;\n}\n"); + parserCppFile.printf("%s instance%s;\n", + fullName, args.length() > 0 ? "(" + args + ")" : ""); + parserCppFile.print("return instance;\n}\n"); } private void printWriter(String name, String nameScope, XsdComplexType complexType) @@ -512,23 +551,24 @@ public class CppCodeGenerator { } String fullName = nameScope + name; - headerFile.printf("void write(std::ostream& out, const std::string& name) const;\n"); - cppFile.printf("\nvoid %s::write(std::ostream& out, const std::string& name) const {\n", + parserHeaderFile.printf("void write(std::ostream& out, const std::string& name) const;\n"); + parserCppFile.printf( + "\nvoid %s::write(std::ostream& out, const std::string& name) const {\n", fullName); - cppFile.printf("out << printIndent() << \"<\" << name;\n"); + parserCppFile.printf("out << printIndent() << \"<\" << name;\n"); for (int i = 0; i < allAttributes.size(); ++i) { CppType type = allAttributeTypes.get(i); XsdAttribute attribute = resolveAttribute(allAttributes.get(i)); String variableName = Utils.toVariableName(attribute.getName()); - cppFile.printf("if (has%s()) {\n", Utils.capitalize(variableName)); - cppFile.printf("out << \" %s=\\\"\";\n", attribute.getName()); - cppFile.print(type.getWritingExpression(String.format("get%s()", + parserCppFile.printf("if (has%s()) {\n", Utils.capitalize(variableName)); + parserCppFile.printf("out << \" %s=\\\"\";\n", attribute.getName()); + parserCppFile.print(type.getWritingExpression(String.format("get%s()", Utils.capitalize(variableName)), attribute.getName())); - cppFile.printf("out << \"\\\"\";\n}\n"); + parserCppFile.printf("out << \"\\\"\";\n}\n"); } - cppFile.print("out << \">\" << std::endl;\n"); - cppFile.print("++indentIndex;\n"); + parserCppFile.print("out << \">\" << std::endl;\n"); + parserCppFile.print("++indentIndex;\n"); if (!allElements.isEmpty()) { for (int i = 0; i < allElements.size(); ++i) { @@ -539,37 +579,38 @@ public class CppCodeGenerator { String variableName = Utils.toVariableName(elementName); if (type instanceof CppComplexType || element.isMultiple()) { - cppFile.printf("for (auto& value : get%s()) {\n", + parserCppFile.printf("for (auto& value : get%s()) {\n", Utils.capitalize(variableName)); if (type instanceof CppSimpleType) { - cppFile.printf("out << printIndent() << \"<%s>\";\n", + parserCppFile.printf("out << printIndent() << \"<%s>\";\n", elementValue.getName()); } - cppFile.printf(type.getWritingExpression("value", elementValue.getName())); + parserCppFile.printf( + type.getWritingExpression("value", elementValue.getName())); if (type instanceof CppSimpleType) { - cppFile.printf("out << \"</%s>\" << std::endl;\n", + parserCppFile.printf("out << \"</%s>\" << std::endl;\n", elementValue.getName()); } - cppFile.printf("}\n"); + parserCppFile.printf("}\n"); } else { - cppFile.printf("if (has%s()) {\n", Utils.capitalize(variableName)); + parserCppFile.printf("if (has%s()) {\n", Utils.capitalize(variableName)); if (type instanceof CppSimpleType) { - cppFile.printf("out << printIndent() << \"<%s>\";\n", + parserCppFile.printf("out << printIndent() << \"<%s>\";\n", elementValue.getName()); } - cppFile.print(type.getWritingExpression(String.format("get%s()", + parserCppFile.print(type.getWritingExpression(String.format("get%s()", Utils.capitalize(variableName)), elementValue.getName())); if (type instanceof CppSimpleType) { - cppFile.printf("out << \"</%s>\" << std::endl;\n", + parserCppFile.printf("out << \"</%s>\" << std::endl;\n", elementValue.getName()); } - cppFile.print("}\n"); + parserCppFile.print("}\n"); } } } - cppFile.print("--indentIndex;\n"); - cppFile.printf("out << printIndent() << \"</\" << name << \">\" << std::endl;\n"); - cppFile.printf("}\n"); + parserCppFile.print("--indentIndex;\n"); + parserCppFile.printf("out << printIndent() << \"</\" << name << \">\" << std::endl;\n"); + parserCppFile.printf("}\n"); } private void printGetter(String name, CppType type, String variableName, @@ -577,32 +618,33 @@ public class CppCodeGenerator { String typeName = isMultiple ? String.format("std::vector<%s>", type.getName()) : type.getName(); - headerFile.printf("const %s& get%s() const;\n", typeName, Utils.capitalize(variableName)); + parserHeaderFile.printf("const %s& get%s() const;\n", typeName, + Utils.capitalize(variableName)); - cppFile.println(); - cppFile.printf("const %s& %s::get%s() const {\n" + parserCppFile.println(); + parserCppFile.printf("const %s& %s::get%s() const {\n" + "return %s;\n}\n\n", typeName, name, Utils.capitalize(variableName), isMultiple || isRequired ? variableName + "_" : String.format("%s_.value()", variableName)); - headerFile.printf("bool has%s() const;\n", Utils.capitalize(variableName)); - cppFile.printf("bool %s::has%s() const {\n", name, Utils.capitalize(variableName)); + parserHeaderFile.printf("bool has%s() const;\n", Utils.capitalize(variableName)); + parserCppFile.printf("bool %s::has%s() const {\n", name, Utils.capitalize(variableName)); if (isMultiple) { - cppFile.printf("return !(%s_.empty());\n}\n", variableName); + parserCppFile.printf("return !(%s_.empty());\n}\n", variableName); } else if (isRequired){ - cppFile.print("return true;\n}\n"); + parserCppFile.print("return true;\n}\n"); } else { - cppFile.printf("return %s_.has_value();\n}\n", variableName); + parserCppFile.printf("return %s_.has_value();\n}\n", variableName); } if (isMultiple || isMultipleType) { String elementTypeName = type instanceof CppComplexType ? type.getName() : ((CppSimpleType)type).getTypeName(); if (elementTypeName.equals("bool")) { - headerFile.printf("%s getFirst%s() const;\n", + parserHeaderFile.printf("%s getFirst%s() const;\n", elementTypeName, Utils.capitalize(variableName)); - cppFile.println(); - cppFile.printf("%s %s::getFirst%s() const {\n" + parserCppFile.println(); + parserCppFile.printf("%s %s::getFirst%s() const {\n" + "if (%s_%sempty()) {\n" + "return false;\n" + "}\n" @@ -613,10 +655,10 @@ public class CppCodeGenerator { isMultiple ? String.format("%s_[0]", variableName) : String.format("%s_.value()[0]", variableName)); } else { - headerFile.printf("const %s* getFirst%s() const;\n", + parserHeaderFile.printf("const %s* getFirst%s() const;\n", elementTypeName, Utils.capitalize(variableName)); - cppFile.println(); - cppFile.printf("const %s* %s::getFirst%s() const {\n" + parserCppFile.println(); + parserCppFile.printf("const %s* %s::getFirst%s() const {\n" + "if (%s_%sempty()) {\n" + "return nullptr;\n" + "}\n" @@ -692,17 +734,17 @@ public class CppCodeGenerator { if (constructorArgsString.length() > 0) { constructorArgsString = constructorArgsString.substring(2); } - headerFile.printf("%s(%s);\n", name, constructorArgsString); - cppFile.printf("\n%s::%s(%s) : ", fullName, name, constructorArgsString); + parserHeaderFile.printf("%s(%s);\n", name, constructorArgsString); + parserCppFile.printf("\n%s::%s(%s) : ", fullName, name, constructorArgsString); String parentArgsString = parentArgs.toString(); if (parentArgsString.length() > 0) { parentArgsString = parentArgsString.substring(2); - cppFile.printf("%s(%s)", baseName, parentArgsString); + parserCppFile.printf("%s(%s)", baseName, parentArgsString); } else { constructorString = constructorString.substring(2); } - cppFile.printf("%s {\n}\n", constructorString); + parserCppFile.printf("%s {\n}\n", constructorString); String argsString = args.toString(); if (argsString.length() > 0) { @@ -712,7 +754,7 @@ public class CppCodeGenerator { } private void printXmlParser() throws CppCodeGeneratorException { - cppFile.printf("template <class T>\n" + parserCppFile.printf("template <class T>\n" + "constexpr void (*xmlDeleter)(T* t);\n" + "template <>\nconstexpr auto xmlDeleter<xmlDoc> = xmlFreeDoc;\n" + "template <>\nauto xmlDeleter<xmlChar> = [](xmlChar *s) { xmlFree(s); };\n\n" @@ -723,7 +765,7 @@ public class CppCodeGenerator { + "}\n\n"); if (hasAttr) { - cppFile.printf("static std::string getXmlAttribute" + parserCppFile.printf("static std::string getXmlAttribute" + "(const xmlNode *cur, const char *attribute) {\n" + "auto xmlValue = make_xmlUnique(xmlGetProp(cur, " + "reinterpret_cast<const xmlChar*>(attribute)));\n" @@ -745,11 +787,11 @@ public class CppCodeGenerator { String typeName = cppType instanceof CppSimpleType ? cppType.getName() : Utils.toClassName(cppType.getName()); - headerFile.printf("std::optional<%s> read%s(const char* configFile);\n\n", + parserHeaderFile.printf("std::optional<%s> read%s(const char* configFile);\n\n", typeName, isMultiRootElement ? Utils.capitalize(typeName) : ""); - cppFile.printf("std::optional<%s> read%s(const char* configFile) {\n", + parserCppFile.printf("std::optional<%s> read%s(const char* configFile) {\n", typeName, isMultiRootElement ? Utils.capitalize(typeName) : ""); - cppFile.printf("auto doc = make_xmlUnique(xmlParseFile(configFile));\n" + parserCppFile.printf("auto doc = make_xmlUnique(xmlParseFile(configFile));\n" + "if (doc == nullptr) {\n" + "return std::nullopt;\n" + "}\n" @@ -765,14 +807,14 @@ public class CppCodeGenerator { elementName); if (cppType instanceof CppSimpleType) { - cppFile.printf("%s value = getXmlAttribute(child, \"%s\");\n", + parserCppFile.printf("%s value = getXmlAttribute(child, \"%s\");\n", elementName, elementName); } else { - cppFile.printf(cppType.getParsingExpression()); + parserCppFile.printf(cppType.getParsingExpression()); } - cppFile.printf("return value;\n}\n"); - cppFile.printf("return std::nullopt;\n"); - cppFile.printf("}\n\n"); + parserCppFile.printf("return value;\n}\n"); + parserCppFile.printf("return std::nullopt;\n"); + parserCppFile.printf("}\n\n"); } } @@ -783,17 +825,18 @@ public class CppCodeGenerator { String VariableName = Utils.toVariableName(elementName); String typeName = cppType instanceof CppSimpleType ? cppType.getName() : Utils.toClassName(cppType.getName()); - headerFile.printf("void write(std::ostream& out, %s& %s);\n\n", + parserHeaderFile.printf("void write(std::ostream& out, %s& %s);\n\n", typeName, VariableName); - cppFile.printf("void write(std::ostream& out, %s& %s) {\n", + parserCppFile.printf("void write(std::ostream& out, %s& %s) {\n", typeName, VariableName); - cppFile.print("out << \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\";\n"); - cppFile.printf("%s.write(out, \"%s\");\n", VariableName, elementName); - cppFile.printf("}\n\n"); + parserCppFile.print( + "out << \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\";\n"); + parserCppFile.printf("%s.write(out, \"%s\");\n", VariableName, elementName); + parserCppFile.printf("}\n\n"); } - cppFile.print("static int indentIndex = 0;\n" + parserCppFile.print("static int indentIndex = 0;\n" + "std::string printIndent() {\n" + "std::string s = \"\";\n" + "for (int index = 0; index < indentIndex; ++index) {\n" diff --git a/tests/Android.bp b/tests/Android.bp index d49369b..ab44220 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -32,6 +32,8 @@ java_test_host { cc_test_host { name: "xsdc-cpp-tests", srcs: [ + "simple_type.cpp", + "tests.cpp", "main.cpp", ], test_options: { @@ -67,3 +69,56 @@ cc_test_host { data: ["resources/*.xml"], test_suites: ["general-tests"], } + +// These tests verify that enums-only and parser-only +// modules can be combined later. +cc_test_host { + name: "xsdc-cpp-tests-split", + srcs: [ + "simple_type.cpp", + "main.cpp", + ], + test_options: { + unit_test: true, + }, + generated_sources: [ + "xsdc_simple_type_tests_enums", + "xsdc_simple_type_tests_parser", + ], + generated_headers: [ + "xsdc_simple_type_tests_enums", + "xsdc_simple_type_tests_parser", + ], + header_libs: ["libxsdc-utils"], + shared_libs: [ + "libbase", + "libxml2", + ], + data: ["resources/*.xml"], + test_suites: ["general-tests"], +} + +// These tests verify that enums-only module can be used on +// its own and it does not depend on libxml2. +cc_test_host { + name: "xsdc-cpp-tests-enums", + srcs: [ + "simple_type_enumsonly.cpp", + "main.cpp", + ], + test_options: { + unit_test: true, + }, + generated_sources: [ + "xsdc_simple_type_tests_enums", + ], + generated_headers: [ + "xsdc_simple_type_tests_enums", + ], + header_libs: ["libxsdc-utils"], + shared_libs: [ + "libbase", + ], + data: ["resources/*.xml"], + test_suites: ["general-tests"], +} diff --git a/tests/main.cpp b/tests/main.cpp index 4dbf2d0..5e91e2d 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,311 +14,7 @@ * limitations under the License. */ -#include <iostream> -#include <fstream> -#include <string> -#include <optional> - -#include <android-base/file.h> #include <gtest/gtest.h> -#include "nested_type.h" -#include "purchase_simple.h" -#include "simple_complex_content.h" - -#include "predefined_types.h" -#include "reference.h" -#include "simple_type.h" -#include "attr_group_simple.h" -#include "group.h" - -using namespace std; -using ::android::base::GetExecutableDirectory; - -class XmlTest : public ::testing::Test { -public: - virtual void SetUp() override { - } - virtual void TearDown() override { - } - std::string Resource(const std::string& filename) { - return GetExecutableDirectory() + "/resources/" + filename; - } -}; - -TEST_F(XmlTest, Simpletype) { - using namespace simple::type; - for (const auto v : android::xsdc_enum_range<EnumType>()) { - EXPECT_NE(v, EnumType::UNKNOWN); - EXPECT_EQ(stringToEnumType(toString(v)), v); - } - - string file_name = Resource("simple_type.xml"); - SimpleTypes simple = *readSimpleTypes(file_name.c_str()); - - for (int i = 0; i < simple.getListInt().size(); ++i) { - EXPECT_EQ(simple.getListInt()[i], i + 1); - } - EXPECT_EQ(*simple.getFirstUnionTest(), "100"); - EXPECT_EQ(simple.getYesOrNo()[0], EnumType::YES); - EXPECT_EQ(simple.getYesOrNo()[1], EnumType::EMPTY); - ofstream out("old_simple_type.xml"); - write(out, simple); - SimpleTypes simple2 = *readSimpleTypes("old_simple_type.xml"); - for (int i = 0; i < simple.getListInt().size(); ++i) { - EXPECT_EQ(simple.getListInt()[i], simple2.getListInt()[i]); - } - EXPECT_EQ(*simple.getFirstUnionTest(), *simple2.getFirstUnionTest()); - EXPECT_EQ(simple.getYesOrNo()[0], simple2.getYesOrNo()[0]); - EXPECT_EQ(simple.getYesOrNo()[1], simple2.getYesOrNo()[1]); -} - -TEST_F(XmlTest, Predefinedtypes) { - using namespace predefined::types; - Types type = *read(Resource("predefined_types.xml").c_str()); - - StringTypes stringTypes = *type.getFirstStringTypes(); - DateTypes dateTypes = *type.getFirstDateTypes(); - NumericTypes numericTypes = *type.getFirstNumericTypes(); - MiscTypes miscTypes = *type.getFirstMiscTypes(); - ListPrimitiveTypes listPrimitiveTypes = *type.getFirstListPrimitiveTypes(); - - EXPECT_EQ(stringTypes.getString(), "abcd"); - EXPECT_EQ(stringTypes.getToken(), "abcd"); - EXPECT_EQ(stringTypes.getNormalizedString(), "abcd"); - EXPECT_EQ(stringTypes.getLanguage(), "abcd"); - EXPECT_EQ(stringTypes.getEntity(), "abcd"); - EXPECT_EQ(stringTypes.getEntities()[0], "a"); - EXPECT_EQ(stringTypes.getEntities()[1], "b"); - EXPECT_EQ(stringTypes.getEntities()[2], "c"); - EXPECT_EQ(stringTypes.getEntities()[3], "d"); - EXPECT_EQ(stringTypes.getId(), "abcd"); - EXPECT_EQ(stringTypes.getName(), "abcd"); - EXPECT_EQ(stringTypes.getNcname(), "abcd"); - EXPECT_EQ(stringTypes.getNmtoken(), "abcd"); - EXPECT_EQ(stringTypes.getNmtokens()[0], "a"); - EXPECT_EQ(stringTypes.getNmtokens()[1], "b"); - EXPECT_EQ(stringTypes.getNmtokens()[2], "c"); - EXPECT_EQ(stringTypes.getNmtokens()[3], "d"); - - - EXPECT_EQ(dateTypes.getDate(), "2018-06-18"); - EXPECT_EQ(dateTypes.getDateTime(), "2018-06-18T21:32:52"); - EXPECT_EQ(dateTypes.getDuration(), "P3M"); - EXPECT_EQ(dateTypes.getGDay(), "---18"); - EXPECT_EQ(dateTypes.getGMonth(), "--06"); - EXPECT_EQ(dateTypes.getGMonthDay(), "--06-18"); - EXPECT_EQ(dateTypes.getGYear(), "2018"); - EXPECT_EQ(dateTypes.getGYearMonth(), "2018-06"); - EXPECT_EQ(dateTypes.getTime(), "21:32:52"); - - EXPECT_EQ(numericTypes.getDecimal(), 1234.57); - EXPECT_EQ(numericTypes.getInteger(), 1234567890123456789); - EXPECT_EQ(numericTypes.get_long(), 9223372036854775807); - EXPECT_EQ(numericTypes.get_int(), 2147483647); - EXPECT_EQ(numericTypes.get_short(), 32767); - EXPECT_EQ((int)numericTypes.getByte(), 127); - EXPECT_EQ(numericTypes.getNegativeInteger(), -1234); - EXPECT_EQ(numericTypes.getNonNegativeInteger(), 1234); - EXPECT_EQ(numericTypes.getPositiveInteger(), 1234); - EXPECT_EQ(numericTypes.getNonPositiveInteger(), -1234); - EXPECT_EQ(numericTypes.getUnsignedLong(), 1234); - EXPECT_EQ(numericTypes.getUnsignedInt(), 1234); - EXPECT_EQ(numericTypes.getUnsignedShort(), 1234); - EXPECT_EQ((int)(numericTypes.getUnsignedByte()), 255); - - EXPECT_EQ(miscTypes.get_double(), 1234.57); - EXPECT_EQ(miscTypes.getAnyURI(), "https://www.google.com"); - EXPECT_EQ(miscTypes.getBase64Binary(), "Z29vZ2xl"); - EXPECT_TRUE(miscTypes.getBoolean()); - EXPECT_EQ(miscTypes.getHexBinary(), "016a75cb56d7e7"); - EXPECT_EQ(miscTypes.getQName(), "abcd"); - EXPECT_EQ(miscTypes.getIDREF(), "abcd"); - EXPECT_EQ(miscTypes.getIDREFS()[0], "abcd"); - EXPECT_EQ(miscTypes.getIDREFS()[1], "abcd"); - EXPECT_EQ(miscTypes.getAnyType(), "abcd"); - - EXPECT_EQ(listPrimitiveTypes.getListInt()[0], -2147483648); - EXPECT_EQ(listPrimitiveTypes.getListInt()[1], 2147483647); - EXPECT_EQ(listPrimitiveTypes.getListShort()[0], -32768); - EXPECT_EQ(listPrimitiveTypes.getListShort()[1], 32767); - EXPECT_EQ((int)listPrimitiveTypes.getListByte()[0], -128); - EXPECT_EQ((int)listPrimitiveTypes.getListByte()[1], 127); - EXPECT_EQ(listPrimitiveTypes.getListDouble()[0], 1234.56); - EXPECT_EQ(listPrimitiveTypes.getListDouble()[1], 5678.12); - EXPECT_TRUE(listPrimitiveTypes.getListBoolean()[0]); - EXPECT_FALSE(listPrimitiveTypes.getListBoolean()[1]); - - ofstream out("old_predefined_types.xml"); - write(out, type); - Types type2 = *read("old_predefined_types.xml"); - - NumericTypes numericTypes2 = *type.getFirstNumericTypes(); - ListPrimitiveTypes listPrimitiveTypes2 = *type.getFirstListPrimitiveTypes(); - - EXPECT_EQ(numericTypes.getDecimal(), numericTypes2.getDecimal()); - EXPECT_EQ(numericTypes.getInteger(), numericTypes2.getInteger()); - EXPECT_EQ(numericTypes.get_long(), numericTypes2.get_long()); - EXPECT_EQ(numericTypes.get_int(), numericTypes2.get_int()); - EXPECT_EQ(numericTypes.get_short(), numericTypes2.get_short()); - EXPECT_EQ(numericTypes.getByte(), numericTypes2.getByte()); - EXPECT_EQ(numericTypes.getNegativeInteger(), numericTypes2.getNegativeInteger()); - EXPECT_EQ(numericTypes.getNonNegativeInteger(), numericTypes2.getNonNegativeInteger()); - EXPECT_EQ(numericTypes.getPositiveInteger(), numericTypes2.getPositiveInteger()); - EXPECT_EQ(numericTypes.getNonPositiveInteger(), numericTypes2.getNonPositiveInteger()); - EXPECT_EQ(numericTypes.getUnsignedLong(), numericTypes2.getUnsignedLong()); - EXPECT_EQ(numericTypes.getUnsignedInt(), numericTypes2.getUnsignedInt()); - EXPECT_EQ(numericTypes.getUnsignedShort(), numericTypes2.getUnsignedShort()); - EXPECT_EQ((numericTypes.getUnsignedByte()), numericTypes2.getUnsignedByte()); - - EXPECT_EQ(listPrimitiveTypes.getListInt()[0], listPrimitiveTypes2.getListInt()[0]); - EXPECT_EQ(listPrimitiveTypes.getListInt()[1], listPrimitiveTypes2.getListInt()[1]); - EXPECT_EQ(listPrimitiveTypes.getListShort()[0], listPrimitiveTypes2.getListShort()[0]); - EXPECT_EQ(listPrimitiveTypes.getListShort()[1], listPrimitiveTypes2.getListShort()[1]); - EXPECT_EQ(listPrimitiveTypes.getListByte()[0], listPrimitiveTypes2.getListByte()[0]); - EXPECT_EQ(listPrimitiveTypes.getListByte()[1], listPrimitiveTypes2.getListByte()[1]); - EXPECT_EQ(listPrimitiveTypes.getListDouble()[0], listPrimitiveTypes2.getListDouble()[0]); - EXPECT_EQ(listPrimitiveTypes.getListDouble()[1], listPrimitiveTypes2.getListDouble()[1]); - EXPECT_EQ(listPrimitiveTypes.getListBoolean()[0], listPrimitiveTypes2.getListBoolean()[0]); - EXPECT_EQ(listPrimitiveTypes.getListBoolean()[1], listPrimitiveTypes2.getListBoolean()[1]); -} - -TEST_F(XmlTest, Nestedtype) { - using namespace nested::type; - Employee employee = *read(Resource("nested_type.xml").c_str()); - - Employee::Address address = *employee.getFirstAddress(); - Employee::Address::Extra extra = *address.getFirstExtra(); - - EXPECT_EQ((int)employee.getId(), 1); - EXPECT_EQ(employee.getName(), "Peter"); - EXPECT_EQ(address.getCountry(), "US"); - EXPECT_EQ(address.getState(), "Mountain View"); - EXPECT_EQ(address.getZip(), 3342); - EXPECT_EQ(extra.getLine1(), "Donga 303-111"); - EXPECT_EQ(extra.getLine2(), "Good Street"); - - ofstream out("old_nested_type.xml"); - write(out, employee); -} - -TEST_F(XmlTest, Purchasesimple) { - using namespace purchase::simple; - PurchaseOrderType orderType = *read(Resource("purchase_simple.xml").c_str()); - - EXPECT_EQ(orderType.getOrderDate(), "1900-01-01"); - - EXPECT_EQ(orderType.getShipTo()[0].getName(), "name1"); - EXPECT_EQ(orderType.getShipTo()[0].getStreet(), "street1"); - EXPECT_EQ(orderType.getShipTo()[0].getCity(), "city1"); - EXPECT_EQ(orderType.getShipTo()[0].getState(), "state1"); - EXPECT_EQ(orderType.getShipTo()[0].getZip(), 1); - EXPECT_EQ(orderType.getShipTo()[0].getCountry(), "US"); - EXPECT_EQ(orderType.getShipTo()[1].getName(), "name2"); - EXPECT_EQ(orderType.getShipTo()[1].getStreet(), "street2"); - EXPECT_EQ(orderType.getShipTo()[1].getCity(), "city2"); - EXPECT_EQ(orderType.getShipTo()[1].getState(), "state2"); - EXPECT_EQ(orderType.getShipTo()[1].getZip(), -7922816251426433759); - EXPECT_EQ(orderType.getShipTo()[1].getCountry(), "US"); - - EXPECT_EQ(orderType.getBillTo()[0].getName(), "billName"); - EXPECT_EQ(orderType.getBillTo()[0].getStreet(), "billStreet"); - EXPECT_EQ(orderType.getBillTo()[0].getCity(), "billCity"); - EXPECT_EQ(orderType.getBillTo()[0].getState(), "billState"); - EXPECT_EQ(orderType.getBillTo()[0].getZip(), 1); - EXPECT_EQ(orderType.getBillTo()[0].getCountry(), "US"); - - ofstream out("old_purchase_simple.xml"); - write(out, orderType); - - PurchaseOrderType orderType2 = *read("old_purchase_simple.xml"); - - EXPECT_EQ(orderType.getOrderDate(), orderType2.getOrderDate()); - - EXPECT_EQ(orderType.getShipTo()[0].getName(), orderType2.getShipTo()[0].getName()); - EXPECT_EQ(orderType.getShipTo()[0].getStreet(), orderType2.getShipTo()[0].getStreet()); - EXPECT_EQ(orderType.getShipTo()[0].getCity(), orderType2.getShipTo()[0].getCity()); - EXPECT_EQ(orderType.getShipTo()[0].getState(), orderType2.getShipTo()[0].getState()); - EXPECT_EQ(orderType.getShipTo()[0].getZip(), orderType2.getShipTo()[0].getZip()); - EXPECT_EQ(orderType.getShipTo()[0].getCountry(), orderType2.getShipTo()[0].getCountry()); - EXPECT_EQ(orderType.getShipTo()[1].getName(), orderType2.getShipTo()[1].getName()); - EXPECT_EQ(orderType.getShipTo()[1].getStreet(), orderType2.getShipTo()[1].getStreet()); - EXPECT_EQ(orderType.getShipTo()[1].getCity(), orderType2.getShipTo()[1].getCity()); - EXPECT_EQ(orderType.getShipTo()[1].getState(), orderType2.getShipTo()[1].getState()); - EXPECT_EQ(orderType.getShipTo()[1].getZip(), orderType2.getShipTo()[1].getZip()); - EXPECT_EQ(orderType.getShipTo()[1].getCountry(), orderType2.getShipTo()[1].getCountry()); - - EXPECT_EQ(orderType.getBillTo()[0].getName(), orderType2.getBillTo()[0].getName()); - EXPECT_EQ(orderType.getBillTo()[0].getStreet(), orderType2.getBillTo()[0].getStreet()); - EXPECT_EQ(orderType.getBillTo()[0].getCity(), orderType2.getBillTo()[0].getCity()); - EXPECT_EQ(orderType.getBillTo()[0].getState(), orderType2.getBillTo()[0].getState()); - EXPECT_EQ(orderType.getBillTo()[0].getZip(), orderType2.getBillTo()[0].getZip()); - EXPECT_EQ(orderType.getBillTo()[0].getCountry(), orderType2.getBillTo()[0].getCountry()); -} - -TEST_F(XmlTest, Reference) { - using namespace reference; - Class _class = *read(Resource("reference.xml").c_str()); - - EXPECT_EQ(_class.getStudent()[0], "Sam"); - EXPECT_EQ(_class.getStudent()[1], "Paul"); - EXPECT_EQ(_class.getStudent()[2], "Peter"); - - ofstream out("old_reference.xml"); - write(out, _class); -} - -TEST_F(XmlTest, Simplecomplexcontent) { - using namespace simple::complex::content; - Person person = *readPerson(Resource("simple_complex_content.xml").c_str()); - USAddressP uSAddressP = *person.getFirstUSAddressP(); - KRAddress kRAddress = *person.getFirstKRAddress(); - SubAddress subAddress = *person.getFirstSubAddress(); - - EXPECT_EQ(person.getName(), "Petr"); - - EXPECT_EQ(uSAddressP.getName(), "404"); - EXPECT_EQ(uSAddressP.getStreet(), "street fighter"); - EXPECT_EQ(uSAddressP.getCity(), "New York"); - EXPECT_EQ(uSAddressP.getState(), "Washington"); - EXPECT_EQ(uSAddressP.getZipcode(), 323232318329852); - - EXPECT_EQ(kRAddress.getName(), "Donga Studio"); - EXPECT_EQ(kRAddress.getStreet(), "Nokdu Street"); - EXPECT_EQ(kRAddress.getCity(), "Seoul"); - - EXPECT_EQ(subAddress.getChoice1_optional(), "Temp"); - - ofstream out("old_simple_complex_content.xml"); - write(out, person); -} - -TEST_F(XmlTest, Attrgroupsimple) { - using namespace attr::group::simple; - Student student = *read(Resource("attr_group_simple.xml").c_str()); - - EXPECT_EQ(student.getName(), "Jun"); - EXPECT_EQ(student.getCity(), "Mountain View"); - EXPECT_EQ(student.getState(), "CA"); - EXPECT_EQ(student.getRoad(), "Street 101"); - EXPECT_EQ(student.getList()[0], 1); - EXPECT_EQ(student.getList()[1], 2); - EXPECT_EQ(student.getList()[2], 3); - - ofstream out("old_attr_group_simple.xml"); - write(out, student); -} - -TEST_F(XmlTest, Group) { - using namespace group; - Student student = *read(Resource("group.xml").c_str()); - - EXPECT_EQ(student.getCity(), "Mountain View"); - EXPECT_EQ(student.getState(), "CA"); - EXPECT_EQ(student.getRoad(), "Street 101"); - - ofstream out("old_group.xml"); - write(out, student); -} int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/tests/resources/simple_type/Android.bp b/tests/resources/simple_type/Android.bp index 9bf2a52..b6a681d 100644 --- a/tests/resources/simple_type/Android.bp +++ b/tests/resources/simple_type/Android.bp @@ -9,3 +9,19 @@ xsd_config { package_name: "simple.type", gen_writer: true, } + +xsd_config { + name: "xsdc_simple_type_tests_enums", + srcs: ["simple_type.xsd"], + package_name: "simple.type", + enums_only: true, + gen_writer: true, +} + +xsd_config { + name: "xsdc_simple_type_tests_parser", + srcs: ["simple_type.xsd"], + package_name: "simple.type", + parser_only: true, + gen_writer: true, +} diff --git a/tests/simple_type.cpp b/tests/simple_type.cpp new file mode 100644 index 0000000..5162c6d --- /dev/null +++ b/tests/simple_type.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <iostream> +#include <fstream> + +#include <android-base/macros.h> + +#include "simple_type.h" +#include "xmltest.h" + +using namespace std; + +TEST_F(XmlTest, Simpletype) { + using namespace simple::type; + for (const auto v : android::xsdc_enum_range<EnumType>()) { + EXPECT_NE(v, EnumType::UNKNOWN); + EXPECT_EQ(stringToEnumType(toString(v)), v); + } + + string file_name = Resource("simple_type.xml"); + SimpleTypes simple = *readSimpleTypes(file_name.c_str()); + + for (int i = 0; i < simple.getListInt().size(); ++i) { + EXPECT_EQ(simple.getListInt()[i], i + 1); + } + EXPECT_EQ(*simple.getFirstUnionTest(), "100"); + EXPECT_EQ(simple.getYesOrNo()[0], EnumType::YES); + EXPECT_EQ(simple.getYesOrNo()[1], EnumType::EMPTY); + ofstream out("old_simple_type.xml"); + write(out, simple); + SimpleTypes simple2 = *readSimpleTypes("old_simple_type.xml"); + for (int i = 0; i < simple.getListInt().size(); ++i) { + EXPECT_EQ(simple.getListInt()[i], simple2.getListInt()[i]); + } + EXPECT_EQ(*simple.getFirstUnionTest(), *simple2.getFirstUnionTest()); + EXPECT_EQ(simple.getYesOrNo()[0], simple2.getYesOrNo()[0]); + EXPECT_EQ(simple.getYesOrNo()[1], simple2.getYesOrNo()[1]); +} diff --git a/tests/simple_type_enumsonly.cpp b/tests/simple_type_enumsonly.cpp new file mode 100644 index 0000000..b083a6c --- /dev/null +++ b/tests/simple_type_enumsonly.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/macros.h> + +#include "simple_type_enums.h" +#include "xmltest.h" + +TEST_F(XmlTest, SimpletypeEnumsOnly) { + using namespace simple::type; + for (const auto v : android::xsdc_enum_range<EnumType>()) { + EXPECT_NE(v, EnumType::UNKNOWN); + EXPECT_EQ(stringToEnumType(toString(v)), v); + } +} diff --git a/tests/tests.cpp b/tests/tests.cpp new file mode 100644 index 0000000..c143f4e --- /dev/null +++ b/tests/tests.cpp @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <iostream> +#include <fstream> +#include <string> +#include <optional> + +#include <android-base/macros.h> +#include <gtest/gtest.h> +#include "nested_type.h" +#include "purchase_simple.h" +#include "simple_complex_content.h" + +#include "predefined_types.h" +#include "reference.h" +#include "attr_group_simple.h" +#include "group.h" +#include "xmltest.h" + +using namespace std; + +TEST_F(XmlTest, Predefinedtypes) { + using namespace predefined::types; + Types type = *read(Resource("predefined_types.xml").c_str()); + + StringTypes stringTypes = *type.getFirstStringTypes(); + DateTypes dateTypes = *type.getFirstDateTypes(); + NumericTypes numericTypes = *type.getFirstNumericTypes(); + MiscTypes miscTypes = *type.getFirstMiscTypes(); + ListPrimitiveTypes listPrimitiveTypes = *type.getFirstListPrimitiveTypes(); + + EXPECT_EQ(stringTypes.getString(), "abcd"); + EXPECT_EQ(stringTypes.getToken(), "abcd"); + EXPECT_EQ(stringTypes.getNormalizedString(), "abcd"); + EXPECT_EQ(stringTypes.getLanguage(), "abcd"); + EXPECT_EQ(stringTypes.getEntity(), "abcd"); + EXPECT_EQ(stringTypes.getEntities()[0], "a"); + EXPECT_EQ(stringTypes.getEntities()[1], "b"); + EXPECT_EQ(stringTypes.getEntities()[2], "c"); + EXPECT_EQ(stringTypes.getEntities()[3], "d"); + EXPECT_EQ(stringTypes.getId(), "abcd"); + EXPECT_EQ(stringTypes.getName(), "abcd"); + EXPECT_EQ(stringTypes.getNcname(), "abcd"); + EXPECT_EQ(stringTypes.getNmtoken(), "abcd"); + EXPECT_EQ(stringTypes.getNmtokens()[0], "a"); + EXPECT_EQ(stringTypes.getNmtokens()[1], "b"); + EXPECT_EQ(stringTypes.getNmtokens()[2], "c"); + EXPECT_EQ(stringTypes.getNmtokens()[3], "d"); + + + EXPECT_EQ(dateTypes.getDate(), "2018-06-18"); + EXPECT_EQ(dateTypes.getDateTime(), "2018-06-18T21:32:52"); + EXPECT_EQ(dateTypes.getDuration(), "P3M"); + EXPECT_EQ(dateTypes.getGDay(), "---18"); + EXPECT_EQ(dateTypes.getGMonth(), "--06"); + EXPECT_EQ(dateTypes.getGMonthDay(), "--06-18"); + EXPECT_EQ(dateTypes.getGYear(), "2018"); + EXPECT_EQ(dateTypes.getGYearMonth(), "2018-06"); + EXPECT_EQ(dateTypes.getTime(), "21:32:52"); + + EXPECT_EQ(numericTypes.getDecimal(), 1234.57); + EXPECT_EQ(numericTypes.getInteger(), 1234567890123456789); + EXPECT_EQ(numericTypes.get_long(), 9223372036854775807); + EXPECT_EQ(numericTypes.get_int(), 2147483647); + EXPECT_EQ(numericTypes.get_short(), 32767); + EXPECT_EQ((int)numericTypes.getByte(), 127); + EXPECT_EQ(numericTypes.getNegativeInteger(), -1234); + EXPECT_EQ(numericTypes.getNonNegativeInteger(), 1234); + EXPECT_EQ(numericTypes.getPositiveInteger(), 1234); + EXPECT_EQ(numericTypes.getNonPositiveInteger(), -1234); + EXPECT_EQ(numericTypes.getUnsignedLong(), 1234); + EXPECT_EQ(numericTypes.getUnsignedInt(), 1234); + EXPECT_EQ(numericTypes.getUnsignedShort(), 1234); + EXPECT_EQ((int)(numericTypes.getUnsignedByte()), 255); + + EXPECT_EQ(miscTypes.get_double(), 1234.57); + EXPECT_EQ(miscTypes.getAnyURI(), "https://www.google.com"); + EXPECT_EQ(miscTypes.getBase64Binary(), "Z29vZ2xl"); + EXPECT_TRUE(miscTypes.getBoolean()); + EXPECT_EQ(miscTypes.getHexBinary(), "016a75cb56d7e7"); + EXPECT_EQ(miscTypes.getQName(), "abcd"); + EXPECT_EQ(miscTypes.getIDREF(), "abcd"); + EXPECT_EQ(miscTypes.getIDREFS()[0], "abcd"); + EXPECT_EQ(miscTypes.getIDREFS()[1], "abcd"); + EXPECT_EQ(miscTypes.getAnyType(), "abcd"); + + EXPECT_EQ(listPrimitiveTypes.getListInt()[0], -2147483648); + EXPECT_EQ(listPrimitiveTypes.getListInt()[1], 2147483647); + EXPECT_EQ(listPrimitiveTypes.getListShort()[0], -32768); + EXPECT_EQ(listPrimitiveTypes.getListShort()[1], 32767); + EXPECT_EQ((int)listPrimitiveTypes.getListByte()[0], -128); + EXPECT_EQ((int)listPrimitiveTypes.getListByte()[1], 127); + EXPECT_EQ(listPrimitiveTypes.getListDouble()[0], 1234.56); + EXPECT_EQ(listPrimitiveTypes.getListDouble()[1], 5678.12); + EXPECT_TRUE(listPrimitiveTypes.getListBoolean()[0]); + EXPECT_FALSE(listPrimitiveTypes.getListBoolean()[1]); + + ofstream out("old_predefined_types.xml"); + write(out, type); + Types type2 = *read("old_predefined_types.xml"); + + NumericTypes numericTypes2 = *type.getFirstNumericTypes(); + ListPrimitiveTypes listPrimitiveTypes2 = *type.getFirstListPrimitiveTypes(); + + EXPECT_EQ(numericTypes.getDecimal(), numericTypes2.getDecimal()); + EXPECT_EQ(numericTypes.getInteger(), numericTypes2.getInteger()); + EXPECT_EQ(numericTypes.get_long(), numericTypes2.get_long()); + EXPECT_EQ(numericTypes.get_int(), numericTypes2.get_int()); + EXPECT_EQ(numericTypes.get_short(), numericTypes2.get_short()); + EXPECT_EQ(numericTypes.getByte(), numericTypes2.getByte()); + EXPECT_EQ(numericTypes.getNegativeInteger(), numericTypes2.getNegativeInteger()); + EXPECT_EQ(numericTypes.getNonNegativeInteger(), numericTypes2.getNonNegativeInteger()); + EXPECT_EQ(numericTypes.getPositiveInteger(), numericTypes2.getPositiveInteger()); + EXPECT_EQ(numericTypes.getNonPositiveInteger(), numericTypes2.getNonPositiveInteger()); + EXPECT_EQ(numericTypes.getUnsignedLong(), numericTypes2.getUnsignedLong()); + EXPECT_EQ(numericTypes.getUnsignedInt(), numericTypes2.getUnsignedInt()); + EXPECT_EQ(numericTypes.getUnsignedShort(), numericTypes2.getUnsignedShort()); + EXPECT_EQ((numericTypes.getUnsignedByte()), numericTypes2.getUnsignedByte()); + + EXPECT_EQ(listPrimitiveTypes.getListInt()[0], listPrimitiveTypes2.getListInt()[0]); + EXPECT_EQ(listPrimitiveTypes.getListInt()[1], listPrimitiveTypes2.getListInt()[1]); + EXPECT_EQ(listPrimitiveTypes.getListShort()[0], listPrimitiveTypes2.getListShort()[0]); + EXPECT_EQ(listPrimitiveTypes.getListShort()[1], listPrimitiveTypes2.getListShort()[1]); + EXPECT_EQ(listPrimitiveTypes.getListByte()[0], listPrimitiveTypes2.getListByte()[0]); + EXPECT_EQ(listPrimitiveTypes.getListByte()[1], listPrimitiveTypes2.getListByte()[1]); + EXPECT_EQ(listPrimitiveTypes.getListDouble()[0], listPrimitiveTypes2.getListDouble()[0]); + EXPECT_EQ(listPrimitiveTypes.getListDouble()[1], listPrimitiveTypes2.getListDouble()[1]); + EXPECT_EQ(listPrimitiveTypes.getListBoolean()[0], listPrimitiveTypes2.getListBoolean()[0]); + EXPECT_EQ(listPrimitiveTypes.getListBoolean()[1], listPrimitiveTypes2.getListBoolean()[1]); +} + +TEST_F(XmlTest, Nestedtype) { + using namespace nested::type; + Employee employee = *read(Resource("nested_type.xml").c_str()); + + Employee::Address address = *employee.getFirstAddress(); + Employee::Address::Extra extra = *address.getFirstExtra(); + + EXPECT_EQ((int)employee.getId(), 1); + EXPECT_EQ(employee.getName(), "Peter"); + EXPECT_EQ(address.getCountry(), "US"); + EXPECT_EQ(address.getState(), "Mountain View"); + EXPECT_EQ(address.getZip(), 3342); + EXPECT_EQ(extra.getLine1(), "Donga 303-111"); + EXPECT_EQ(extra.getLine2(), "Good Street"); + + ofstream out("old_nested_type.xml"); + write(out, employee); +} + +TEST_F(XmlTest, Purchasesimple) { + using namespace purchase::simple; + PurchaseOrderType orderType = *read(Resource("purchase_simple.xml").c_str()); + + EXPECT_EQ(orderType.getOrderDate(), "1900-01-01"); + + EXPECT_EQ(orderType.getShipTo()[0].getName(), "name1"); + EXPECT_EQ(orderType.getShipTo()[0].getStreet(), "street1"); + EXPECT_EQ(orderType.getShipTo()[0].getCity(), "city1"); + EXPECT_EQ(orderType.getShipTo()[0].getState(), "state1"); + EXPECT_EQ(orderType.getShipTo()[0].getZip(), 1); + EXPECT_EQ(orderType.getShipTo()[0].getCountry(), "US"); + EXPECT_EQ(orderType.getShipTo()[1].getName(), "name2"); + EXPECT_EQ(orderType.getShipTo()[1].getStreet(), "street2"); + EXPECT_EQ(orderType.getShipTo()[1].getCity(), "city2"); + EXPECT_EQ(orderType.getShipTo()[1].getState(), "state2"); + EXPECT_EQ(orderType.getShipTo()[1].getZip(), -7922816251426433759); + EXPECT_EQ(orderType.getShipTo()[1].getCountry(), "US"); + + EXPECT_EQ(orderType.getBillTo()[0].getName(), "billName"); + EXPECT_EQ(orderType.getBillTo()[0].getStreet(), "billStreet"); + EXPECT_EQ(orderType.getBillTo()[0].getCity(), "billCity"); + EXPECT_EQ(orderType.getBillTo()[0].getState(), "billState"); + EXPECT_EQ(orderType.getBillTo()[0].getZip(), 1); + EXPECT_EQ(orderType.getBillTo()[0].getCountry(), "US"); + + ofstream out("old_purchase_simple.xml"); + write(out, orderType); + + PurchaseOrderType orderType2 = *read("old_purchase_simple.xml"); + + EXPECT_EQ(orderType.getOrderDate(), orderType2.getOrderDate()); + + EXPECT_EQ(orderType.getShipTo()[0].getName(), orderType2.getShipTo()[0].getName()); + EXPECT_EQ(orderType.getShipTo()[0].getStreet(), orderType2.getShipTo()[0].getStreet()); + EXPECT_EQ(orderType.getShipTo()[0].getCity(), orderType2.getShipTo()[0].getCity()); + EXPECT_EQ(orderType.getShipTo()[0].getState(), orderType2.getShipTo()[0].getState()); + EXPECT_EQ(orderType.getShipTo()[0].getZip(), orderType2.getShipTo()[0].getZip()); + EXPECT_EQ(orderType.getShipTo()[0].getCountry(), orderType2.getShipTo()[0].getCountry()); + EXPECT_EQ(orderType.getShipTo()[1].getName(), orderType2.getShipTo()[1].getName()); + EXPECT_EQ(orderType.getShipTo()[1].getStreet(), orderType2.getShipTo()[1].getStreet()); + EXPECT_EQ(orderType.getShipTo()[1].getCity(), orderType2.getShipTo()[1].getCity()); + EXPECT_EQ(orderType.getShipTo()[1].getState(), orderType2.getShipTo()[1].getState()); + EXPECT_EQ(orderType.getShipTo()[1].getZip(), orderType2.getShipTo()[1].getZip()); + EXPECT_EQ(orderType.getShipTo()[1].getCountry(), orderType2.getShipTo()[1].getCountry()); + + EXPECT_EQ(orderType.getBillTo()[0].getName(), orderType2.getBillTo()[0].getName()); + EXPECT_EQ(orderType.getBillTo()[0].getStreet(), orderType2.getBillTo()[0].getStreet()); + EXPECT_EQ(orderType.getBillTo()[0].getCity(), orderType2.getBillTo()[0].getCity()); + EXPECT_EQ(orderType.getBillTo()[0].getState(), orderType2.getBillTo()[0].getState()); + EXPECT_EQ(orderType.getBillTo()[0].getZip(), orderType2.getBillTo()[0].getZip()); + EXPECT_EQ(orderType.getBillTo()[0].getCountry(), orderType2.getBillTo()[0].getCountry()); +} + +TEST_F(XmlTest, Reference) { + using namespace reference; + Class _class = *read(Resource("reference.xml").c_str()); + + EXPECT_EQ(_class.getStudent()[0], "Sam"); + EXPECT_EQ(_class.getStudent()[1], "Paul"); + EXPECT_EQ(_class.getStudent()[2], "Peter"); + + ofstream out("old_reference.xml"); + write(out, _class); +} + +TEST_F(XmlTest, Simplecomplexcontent) { + using namespace simple::complex::content; + Person person = *readPerson(Resource("simple_complex_content.xml").c_str()); + USAddressP uSAddressP = *person.getFirstUSAddressP(); + KRAddress kRAddress = *person.getFirstKRAddress(); + SubAddress subAddress = *person.getFirstSubAddress(); + + EXPECT_EQ(person.getName(), "Petr"); + + EXPECT_EQ(uSAddressP.getName(), "404"); + EXPECT_EQ(uSAddressP.getStreet(), "street fighter"); + EXPECT_EQ(uSAddressP.getCity(), "New York"); + EXPECT_EQ(uSAddressP.getState(), "Washington"); + EXPECT_EQ(uSAddressP.getZipcode(), 323232318329852); + + EXPECT_EQ(kRAddress.getName(), "Donga Studio"); + EXPECT_EQ(kRAddress.getStreet(), "Nokdu Street"); + EXPECT_EQ(kRAddress.getCity(), "Seoul"); + + EXPECT_EQ(subAddress.getChoice1_optional(), "Temp"); + + ofstream out("old_simple_complex_content.xml"); + write(out, person); +} + +TEST_F(XmlTest, Attrgroupsimple) { + using namespace attr::group::simple; + Student student = *read(Resource("attr_group_simple.xml").c_str()); + + EXPECT_EQ(student.getName(), "Jun"); + EXPECT_EQ(student.getCity(), "Mountain View"); + EXPECT_EQ(student.getState(), "CA"); + EXPECT_EQ(student.getRoad(), "Street 101"); + EXPECT_EQ(student.getList()[0], 1); + EXPECT_EQ(student.getList()[1], 2); + EXPECT_EQ(student.getList()[2], 3); + + ofstream out("old_attr_group_simple.xml"); + write(out, student); +} + +TEST_F(XmlTest, Group) { + using namespace group; + Student student = *read(Resource("group.xml").c_str()); + + EXPECT_EQ(student.getCity(), "Mountain View"); + EXPECT_EQ(student.getState(), "CA"); + EXPECT_EQ(student.getRoad(), "Street 101"); + + ofstream out("old_group.xml"); + write(out, student); +} diff --git a/tests/xmltest.h b/tests/xmltest.h new file mode 100644 index 0000000..b645b98 --- /dev/null +++ b/tests/xmltest.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <string> + +#include <android-base/file.h> +#include <gtest/gtest.h> + +class XmlTest : public ::testing::Test { +public: + std::string Resource(const std::string& filename) { + return ::android::base::GetExecutableDirectory() + "/resources/" + filename; + } +}; |