From 317838e6fced8a01896444caa78b3e2a783d8925 Mon Sep 17 00:00:00 2001 From: Kim van der Riet Date: Wed, 25 Oct 2006 20:15:28 +0000 Subject: Some code tidy-up and debugging; first C++ templates and implementation of most of C++ MethodBody class generation methods. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@467750 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/gentools/README | 2 +- .../apache/qpid/gentools/AmqpDomainVersionMap.java | 8 + .../org/apache/qpid/gentools/AmqpMethod.java | 15 +- .../org/apache/qpid/gentools/CppGenerator.java | 625 ++++++++++++++++++--- .../org/apache/qpid/gentools/Generator.java | 5 +- qpid/gentools/org/apache/qpid/gentools/Main.java | 41 +- qpid/gentools/org/apache/qpid/gentools/Utils.java | 113 +--- .../templ.cpp/AMQP_ClientHandlerImpl.cpp.tmpl | 46 ++ .../templ.cpp/AMQP_ClientHandlerImpl.h.tmpl | 54 ++ .../templ.cpp/AMQP_ClientOperations.h.tmpl | 53 ++ qpid/gentools/templ.cpp/AMQP_ClientProxy.cpp.tmpl | 45 ++ qpid/gentools/templ.cpp/AMQP_ClientProxy.h.tmpl | 55 ++ .../templ.cpp/AMQP_ServerHandlerImpl.cpp.tmpl | 46 ++ .../templ.cpp/AMQP_ServerHandlerImpl.h.tmpl | 54 ++ .../templ.cpp/AMQP_ServerOperations.h.tmpl | 53 ++ qpid/gentools/templ.cpp/AMQP_ServerProxy.cpp.tmpl | 45 ++ qpid/gentools/templ.cpp/AMQP_ServerProxy.h.tmpl | 57 ++ qpid/gentools/templ.cpp/MethodBodyClass.h.tmpl | 139 +++++ qpid/gentools/templ.cpp/amqp_methods.cpp.tmpl | 42 ++ qpid/gentools/templ.cpp/amqp_methods.h.tmpl | 41 ++ 20 files changed, 1337 insertions(+), 202 deletions(-) create mode 100644 qpid/gentools/org/apache/qpid/gentools/AmqpDomainVersionMap.java create mode 100644 qpid/gentools/templ.cpp/AMQP_ClientHandlerImpl.cpp.tmpl create mode 100644 qpid/gentools/templ.cpp/AMQP_ClientHandlerImpl.h.tmpl create mode 100644 qpid/gentools/templ.cpp/AMQP_ClientOperations.h.tmpl create mode 100644 qpid/gentools/templ.cpp/AMQP_ClientProxy.cpp.tmpl create mode 100644 qpid/gentools/templ.cpp/AMQP_ClientProxy.h.tmpl create mode 100644 qpid/gentools/templ.cpp/AMQP_ServerHandlerImpl.cpp.tmpl create mode 100644 qpid/gentools/templ.cpp/AMQP_ServerHandlerImpl.h.tmpl create mode 100644 qpid/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl create mode 100644 qpid/gentools/templ.cpp/AMQP_ServerProxy.cpp.tmpl create mode 100644 qpid/gentools/templ.cpp/AMQP_ServerProxy.h.tmpl create mode 100644 qpid/gentools/templ.cpp/MethodBodyClass.h.tmpl create mode 100644 qpid/gentools/templ.cpp/amqp_methods.cpp.tmpl create mode 100644 qpid/gentools/templ.cpp/amqp_methods.h.tmpl diff --git a/qpid/gentools/README b/qpid/gentools/README index a128270c0b..12bfd10caf 100644 --- a/qpid/gentools/README +++ b/qpid/gentools/README @@ -21,7 +21,7 @@ out.java/: Output folder for generated Java files (will be created with use of - templ.cpp/: (Future:) Templates for C++ code generation. out.cpp/: Output folder for generated C++ files (will be created with use of -c flag on command-line). -For a more detaild description of the generator, see the Qpid Wiki (http://cwiki.apache.org/confluence/display/qpid/Multiple+AMQP+Version+Support). +For a more detaild description of the generator, see the Qpid Wiki (http://cwiki.apache.org/qpid/multiple-amqp-version-support). Please send comments and bugs to me (kim.vdriet [at] redhat.com) or via the Apache Qpid list (qpid-dev [at] incubator.apache.org). diff --git a/qpid/gentools/org/apache/qpid/gentools/AmqpDomainVersionMap.java b/qpid/gentools/org/apache/qpid/gentools/AmqpDomainVersionMap.java new file mode 100644 index 0000000000..2c202dc7d9 --- /dev/null +++ b/qpid/gentools/org/apache/qpid/gentools/AmqpDomainVersionMap.java @@ -0,0 +1,8 @@ +package org.apache.qpid.gentools; + +import java.util.TreeMap; + +public class AmqpDomainVersionMap extends TreeMap +{ + +} diff --git a/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java b/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java index 8de8643ac2..51304996a2 100644 --- a/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java +++ b/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java @@ -30,6 +30,8 @@ public class AmqpMethod implements Printable, NodeAware public AmqpFieldMap fieldMap; public String name; public AmqpOrdinalVersionMap indexMap; + public boolean clientMethodFlag; // Method called on client ( in XML) + public boolean serverMethodFlag; // Method called on server ( in XML) public AmqpMethod(String name, LanguageConverter converter) { @@ -38,6 +40,8 @@ public class AmqpMethod implements Printable, NodeAware versionSet = new AmqpVersionSet(); fieldMap = new AmqpFieldMap(); indexMap = new AmqpOrdinalVersionMap(); + clientMethodFlag = false; + serverMethodFlag = false; } public void addFromNode(Node methodNode, int ordinal, AmqpVersion version) @@ -70,6 +74,14 @@ public class AmqpMethod implements Printable, NodeAware } thisField.addFromNode(child, fieldCntr++, version); } + if (child.getNodeName().compareTo(Utils.ELEMENT_CHASSIS) == 0) + { + String chassisName = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_NAME); + if (chassisName.compareTo("server") == 0) + clientMethodFlag = true; + else if (chassisName.compareTo("client") == 0) + serverMethodFlag = true; + } } } @@ -77,7 +89,8 @@ public class AmqpMethod implements Printable, NodeAware { String margin = Utils.createSpaces(marginSize); String tab = Utils.createSpaces(tabSize); - out.println(margin + "[M] " + name + ": " + versionSet); + out.println(margin + "[M] " + name + " {" + (serverMethodFlag ? "S" : ".") + + (clientMethodFlag ? "C" : ".") + "}" + ": " + versionSet); Iterator iItr = indexMap.keySet().iterator(); while (iItr.hasNext()) diff --git a/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java b/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java index 3405e48984..101ab7e842 100644 --- a/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java +++ b/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java @@ -17,56 +17,210 @@ */ package org.apache.qpid.gentools; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Iterator; import java.util.TreeMap; public class CppGenerator extends Generator { + static String cr = Utils.lineSeparator; + private class DomainInfo { public String type; public String size; - public DomainInfo(String domain, String size) + public String encodeExpression; + public String decodeExpression; + public DomainInfo(String domain, String size, String encodeExpression, + String decodeExpression) { this.type = domain; this.size = size; + this.encodeExpression = encodeExpression; + this.decodeExpression = decodeExpression; } } private static TreeMap typeMap = new TreeMap(); + // Methods used for generation of code snippets called from the field map parsers + + // MessageBody methods + static private Method declarationGenerateMethod; + static private Method mangledDeclarationGenerateMethod; + static private Method mbGetGenerateMethod; + static private Method mbMangledGetGenerateMethod; + static private Method mbParamListGenerateMethod; + static private Method mbMangledParamListGenerateMethod; + static private Method mbParamDeclareListGenerateMethod; + static private Method mbMangledParamDeclareListGenerateMethod; + static private Method mbParamInitListGenerateMethod; + static private Method mbMangledParamInitListGenerateMethod; + + static private Method mbPrintGenerateMethod; + static private Method mbBitPrintGenerateMethod; + static private Method mbSizeGenerateMethod; + static private Method mbBitSizeGenerateMethod; + static private Method mbEncodeGenerateMethod; + static private Method mbBitEncodeGenerateMethod; + static private Method mbDecodeGenerateMethod; + static private Method mbBitDecodeGenerateMethod; + + static + { + // ******************************* + // Methods for MessageBody classes + // ******************************* + + // Methods for AmqpFieldMap.parseFieldMap() + + try { declarationGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateFieldDeclaration", String.class, AmqpField.class, + AmqpVersionSet.class, int.class, int.class, boolean.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + try { mangledDeclarationGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMangledFieldDeclaration", AmqpField.class, + int.class, int.class, boolean.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + try { mbGetGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMbGetMethod", String.class, AmqpField.class, + AmqpVersionSet.class, int.class, int.class, boolean.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + try { mbMangledGetGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMbMangledGetMethod", AmqpField.class, + int.class, int.class, boolean.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + try { mbParamListGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMbParamList", String.class, AmqpField.class, + AmqpVersionSet.class, int.class, int.class, boolean.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + try { mbMangledParamListGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMbMangledParamList", AmqpField.class, + int.class, int.class, boolean.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + try { mbParamDeclareListGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMbParamDeclareList", String.class, AmqpField.class, + AmqpVersionSet.class, int.class, int.class, boolean.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + try { mbMangledParamDeclareListGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMbMangledParamDeclareList", AmqpField.class, + int.class, int.class, boolean.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + try { mbParamInitListGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMbParamInitList", String.class, AmqpField.class, + AmqpVersionSet.class, int.class, int.class, boolean.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + try { mbMangledParamInitListGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMbMangledParamInitList", AmqpField.class, + int.class, int.class, boolean.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + // Methods for AmqpFieldMap.parseFieldMapOrdinally() + + try { mbPrintGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMbFieldPrint", String.class, String.class, + int.class, int.class, int.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + try { mbBitPrintGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMbBitFieldPrint", ArrayList.class, int.class, + int.class, int.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + try { mbSizeGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMbFieldSize", String.class, String.class, + int.class, int.class, int.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + try { mbBitSizeGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMbBitArrayFieldSize", ArrayList.class, int.class, + int.class, int.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + try { mbEncodeGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMbFieldEncode", String.class, String.class, + int.class, int.class, int.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + try { mbBitEncodeGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMbBitFieldEncode", ArrayList.class, int.class, + int.class, int.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + try { mbDecodeGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMbFieldDecode", String.class, String.class, + int.class, int.class, int.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + + try { mbBitDecodeGenerateMethod = CppGenerator.class.getDeclaredMethod( + "generateMbBitFieldDecode", ArrayList.class, int.class, + int.class, int.class); } + catch (NoSuchMethodException e) { e.printStackTrace(); } + } + public CppGenerator(AmqpVersionSet versionList) { super(versionList); // Load C++ type and size maps. // Adjust or add to these lists as new types are added/defined. - // The char '#' will be replaced by the field variable name. + // The char '#' will be replaced by the field variable name (any type). + // The char '~' will be replaced by the compacted bit array size (type bit only). typeMap.put("bit", new DomainInfo( - "bool", // domain - "1")); // size + "bool", // type + "~", // size + "", // encodeExpression + "")); // decodeExpression typeMap.put("long", new DomainInfo( - "u_int32_t", // domain - "4")); // size + "u_int32_t", // type + "4", // size + "buffer.putLong(#)", // encodeExpression + "buffer.getLong(#)")); // decodeExpression typeMap.put("longlong", new DomainInfo( - "u_int64_t", // domain - "8")); // size + "u_int64_t", // type + "8", // size + "buffer.putLongLong(#)", // encodeExpression + "buffer.getLongLong(#)")); // decodeExpression typeMap.put("longstr", new DomainInfo( - "string", // domain - "4 + #.length()")); // size + "string", // type + "4 + #.length()", // size + "buffer.putLongString(#)", // encodeExpression + "buffer.getLongString(#)")); // decodeExpression typeMap.put("octet", new DomainInfo( - "u_int8_t", // domain - "1")); // size + "u_int8_t", // type + "1", // size + "buffer.putOctet(#)", // encodeExpression + "buffer.getOctet(#)")); // decodeExpression typeMap.put("short", new DomainInfo( - "u_int16_t", // domain - "2")); // size + "u_int16_t", // type + "2", // size + "buffer.putShort(#)", // encodeExpression + "buffer.getShort(#)")); // decodeExpression typeMap.put("shortstr", new DomainInfo( - "string", // domain - "1 + #.length()")); // size + "string", // type + "1 + #.length()", // size + "buffer.putShortString(#)", // encodeExpression + "buffer.getShortString(#)")); // decodeExpression typeMap.put("table", new DomainInfo( - "FieldTable", // domain - "#.size()")); // size + "FieldTable", // type + "#.size()", // size + "buffer.putFieldTable(#)", // encodeExpression + "buffer.getFieldTable(#)")); // decodeExpression typeMap.put("timestamp", new DomainInfo( - "u_int64_t", // domain - "8")); // decode expression + "u_int64_t", // type + "8", // size + "buffer.putLongLong(#)", // encodeExpression + "buffer.getLongLong(#)")); // decodeExpression } // === Start of methods for Interface LanguageConverter === @@ -86,23 +240,21 @@ public class CppGenerator extends Generator return camelCaseName(domainName, false); } - public String getDomainType(String domainType, AmqpVersion version) + public String getDomainType(String domainName, AmqpVersion version) throws AmqpTypeMappingException { - String domain = globalDomainMap.getDomainType(domainType, version); - String type = typeMap.get(domain).type; - if (type == null) - throw new AmqpTypeMappingException("Domain type \"" + domainType + "\" not found in Java typemap."); - return type; + return globalDomainMap.getDomainType(domainName, version); } public String getGeneratedType(String domainName, AmqpVersion version) throws AmqpTypeMappingException { - String domainType = getDomainType(domainName, version); + String domainType = globalDomainMap.getDomainType(domainName, version); + if (domainType == null) + throw new AmqpTypeMappingException("Domain type \"" + domainName + "\" not found in C++ typemap."); return typeMap.get(domainType).type; } - + // === Abstract methods from class Generator - C++-specific implementation === @Override @@ -120,16 +272,25 @@ public class CppGenerator extends Generator } @Override - protected String processToken(String snipitKey, AmqpClass thisClass, AmqpMethod method, AmqpField field) + protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field) throws AmqpTemplateException { - if (snipitKey.compareTo("${property_flags_initializer}") == 0) - { - StringBuffer sb = new StringBuffer(); - // TODO - return sb.toString(); - } - throw new AmqpTemplateException("Template token " + snipitKey + " unknown."); + if (token.compareTo("${GENERATOR}") == 0) + return generatorInfo; + if (token.compareTo("${CLASS}") == 0 && thisClass != null) + return thisClass.name; + if (token.compareTo("${CLASS_ID_INIT}") == 0 && thisClass != null) + return generateIndexInitializer("classIdMap", thisClass.indexMap, 12); + if (token.compareTo("${METHOD}") == 0 && method != null) + return method.name; + if (token.compareTo("${METHOD_ID_INIT}") == 0 && method != null) + return generateIndexInitializer("methodIdMap", method.indexMap, 12); + if (token.compareTo("${FIELD}") == 0 && field != null) + return field.name; + +// if (token.compareTo("${mb_get_class_id}") == 0 || token.compareTo("${mb_get_method_id}") == 0) +// return("/* === TODO === */"); + throw new AmqpTemplateException("Template token " + token + " unknown."); } @Override @@ -149,57 +310,353 @@ public class CppGenerator extends Generator @Override protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, AmqpFieldMap fieldMap) - throws AmqpTypeMappingException, AmqpTemplateException + throws AmqpTypeMappingException, AmqpTemplateException, IllegalAccessException, + InvocationTargetException { -// TODO + String codeSnippet; + int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line + String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr + int tokxStart = tline.indexOf('$'); + String token = tline.substring(tokxStart).trim(); + sb.delete(listMarkerStartIndex, lend); + + // Field declarations - common to MethodBody and PropertyContentHeader classes + if (token.compareTo("${mb_field_declaration}") == 0) + { + codeSnippet = fieldMap.parseFieldMap(declarationGenerateMethod, + mangledDeclarationGenerateMethod, 4, 4, this); + } + else if (token.compareTo("${mb_field_get_method}") == 0) + { + codeSnippet = fieldMap.parseFieldMap(mbGetGenerateMethod, + mbMangledGetGenerateMethod, 4, 4, this); + } + else if (token.compareTo("${mb_field_print}") == 0) + { + codeSnippet = fieldMap.parseFieldMapOrdinally(mbPrintGenerateMethod, + mbBitPrintGenerateMethod, 8, 4, this); + } + else if (token.compareTo("${mb_body_size}") == 0) + { + codeSnippet = fieldMap.parseFieldMapOrdinally(mbSizeGenerateMethod, + mbBitSizeGenerateMethod, 8, 4, this); + } + else if (token.compareTo("${mb_encode}") == 0) + { + codeSnippet = fieldMap.parseFieldMapOrdinally(mbEncodeGenerateMethod, + mbBitEncodeGenerateMethod, 8, 4, this); + } + else if (token.compareTo("${mb_decode}") == 0) + { + codeSnippet = fieldMap.parseFieldMapOrdinally(mbDecodeGenerateMethod, + mbBitDecodeGenerateMethod, 8, 4, this); + } + else if (token.compareTo("${mb_field_list}") == 0) + { + codeSnippet = fieldMap.parseFieldMap(mbParamListGenerateMethod, + mbMangledParamListGenerateMethod, 8, 4, this); + } + else if (token.compareTo("${mb_field_list_initializer}") == 0) + { + codeSnippet = fieldMap.parseFieldMap(mbParamInitListGenerateMethod, + mbMangledParamInitListGenerateMethod, 8, 4, this); + } + else if (token.compareTo("${mb_field_list_declare}") == 0) + { + codeSnippet = fieldMap.parseFieldMap(mbParamDeclareListGenerateMethod, + mbMangledParamDeclareListGenerateMethod, 8, 4, this); + } + + else // Oops! + { + throw new AmqpTemplateException("Template token " + token + " unknown."); + } + sb.insert(listMarkerStartIndex, codeSnippet); } + + // === Protected and private helper functions unique to C++ implementation === + + // Methods used for generation of code snippets called from the field map parsers + + // Common methods -// @Override -// protected String generateFieldDeclaration(AmqpFieldMap fieldMap, int indentSize) -// throws AmqpTypeMappingException -// { -// String indent = Utils.createSpaces(indentSize); -// StringBuffer sb = new StringBuffer(indent + "// [FieldDeclaration]" + Utils.lineSeparator); -// // TODO -// return sb.toString(); -// } -// -// @Override -// protected String generateFieldGetMethod(AmqpFieldMap fieldMap, int indentSize, int tabSize) -// throws AmqpTypeMappingException -// { -// String indent = Utils.createSpaces(indentSize); -//// String tab = Utils.createSpaces(tabSize); -// StringBuffer sb = new StringBuffer(indent + "// [FieldGetMethod]" + Utils.lineSeparator); -// // TODO -// return sb.toString(); -// } -// -// @Override -// protected String generateContentHeaderGetSetMethod(AmqpFieldMap fieldMap, int indentSize, -// int tabSize) -// throws AmqpTypeMappingException -// { -// String indent = Utils.createSpaces(indentSize); -//// String tab = Utils.createSpaces(tabSize); -// StringBuffer sb = new StringBuffer(indent + "// Property get/set methods" + Utils.lineSeparator); -// // TODO -// return sb.toString(); -// } -// -// @Override -// protected String generateCodeSnippet(String token, AmqpFieldMap fieldMap, int indentSize, -// int tabSize) -// throws AmqpTypeMappingException -// { -// String indent = Utils.createSpaces(indentSize); -//// String tab = Utils.createSpaces(tabSize); -// StringBuffer sb = new StringBuffer(indent + "// [Code snippet " + token + "]" + Utils.lineSeparator); -// // TODO -// return sb.toString(); -// } - - // Private helper functions unique to C++ + protected String generateIndexInitializer(String mapName, AmqpOrdinalVersionMap indexMap, + int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + + Iterator iItr = indexMap.keySet().iterator(); + while (iItr.hasNext()) + { + int index = iItr.next(); + AmqpVersionSet versionSet = indexMap.get(index); + Iterator vItr = versionSet.iterator(); + while (vItr.hasNext()) + { + AmqpVersion version = vItr.next(); + sb.append(indent + mapName + "[\"" + version.toString() + "\"] = " + + index + ";" + cr); + } + } + return sb.toString(); + } + + protected String generateFieldDeclaration(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + return Utils.createSpaces(indentSize) + codeType + " " + field.name + + "; /* AMQP version(s): " + versionSet + " */" + cr; + } + + protected String generateMangledFieldDeclaration(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + throws AmqpTypeMappingException + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + Iterator dItr = field.domainMap.keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) + { + String domainName = dItr.next(); + AmqpVersionSet versionSet = field.domainMap.get(domainName); + String codeType = getGeneratedType(domainName, versionSet.first()); + sb.append(indent + codeType + " " + field.name + "_" + (domainCntr++) + + "; /* AMQP Version(s): " + versionSet + " */" + cr); + } + return sb.toString(); + } + + protected String generateMbGetMethod(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + String indent = Utils.createSpaces(indentSize); + return indent + "inline " + setRef(codeType) + " get" + + Utils.firstUpper(field.name) + "() { return " + field.name + + "; } /* AMQP Version(s): " + versionSet + " */" + cr; + } + + protected String generateMbMangledGetMethod(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + throws AmqpTypeMappingException + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + Iterator dItr = field.domainMap.keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) + { + String domainName = dItr.next(); + AmqpVersionSet versionSet = field.domainMap.get(domainName); + String codeType = getGeneratedType(domainName, versionSet.first()); + sb.append(indent + "inline " + setRef(codeType) + " get" + + Utils.firstUpper(field.name) + "() { return " + field.name + "_" + + domainCntr++ + "; } /* AMQP Version(s): " + versionSet + + " */" + cr); + } + return sb.toString(); + } + + protected String generateMbParamList(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + return mbParamList(codeType, field, versionSet, indentSize, nextFlag, false, false); + } + + protected String generateMbMangledParamList(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + throws AmqpTypeMappingException + { + return mbMangledParamList(field, indentSize, nextFlag, false, false); + } + + protected String generateMbParamDeclareList(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + return mbParamList(codeType, field, versionSet, indentSize, nextFlag, true, false); + } + + protected String generateMbMangledParamDeclareList(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + throws AmqpTypeMappingException + { + return mbMangledParamList(field, indentSize, nextFlag, true, false); + } + + protected String generateMbParamInitList(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + return mbParamList(codeType, field, versionSet, indentSize, nextFlag, false, true); + } + + protected String generateMbMangledParamInitList(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + throws AmqpTypeMappingException + { + return mbMangledParamList(field, indentSize, nextFlag, false, true); + } + + protected String mbParamList(String codeType, AmqpField field, AmqpVersionSet versionSet, + int indentSize, boolean nextFlag, boolean defineFlag, boolean initializerFlag) + { + return Utils.createSpaces(indentSize) + (defineFlag ? codeType + " " : "") + + (initializerFlag ? "this." : "") + field.name + + (initializerFlag ? "(" + field.name + ")" : "") + + (nextFlag ? "," : "") + " /* AMQP version(s): " + versionSet + " */" + cr; + } + + protected String mbMangledParamList(AmqpField field, int indentSize, + boolean nextFlag, boolean defineFlag, boolean initializerFlag) + throws AmqpTypeMappingException + { + StringBuffer sb = new StringBuffer(); + Iterator dItr = field.domainMap.keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) + { + String domainName = dItr.next(); + AmqpVersionSet versionSet = field.domainMap.get(domainName); + String codeType = getGeneratedType(domainName, versionSet.first()); + sb.append(Utils.createSpaces(indentSize) + (defineFlag ? codeType + " " : "") + + (initializerFlag ? "this." : "") + field.name + "_" + domainCntr + + (initializerFlag ? "(" + field.name + "_" + domainCntr + ")" : "") + + (nextFlag ? "," : "") + " /* AMQP version(s): " + versionSet + " */" + cr); + domainCntr++; + } + return sb.toString(); + } + + protected String generateMbFieldPrint(String domain, String fieldName, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(indent + "out << \""); + if (ordinal == 0) + sb.append(": \""); + else + sb.append("; \""); + sb.append(" << \"" + fieldName + "=\" << " + fieldName + ";" + cr); + return sb.toString(); + } + + protected String generateMbBitFieldPrint(ArrayList bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + for (int i=0; i bitFieldList, + int ordinal, int indentSize, int tabSize) + { + StringBuffer sb = new StringBuffer(); + int numBytes = ((bitFieldList.size() - 1) / 8) + 1; + String comment = bitFieldList.size() == 1 ? + bitFieldList.get(0) + ": bit" : + "Combinded bits: " + bitFieldList; + sb.append(Utils.createSpaces(indentSize) + "size += " + + typeMap.get("bit").size.replaceAll("~", String.valueOf(numBytes)) + + "; /* " + comment + " */" + cr); + return sb.toString(); + } + + protected String generateMbFieldEncode(String domain, String fieldName, + int ordinal, int indentSize, int tabSize) + { + StringBuffer sb = new StringBuffer(); + sb.append(Utils.createSpaces(indentSize) + + typeMap.get(domain).encodeExpression.replaceAll("#", fieldName) + + "; /* " + fieldName + ": " + domain + " */" + cr); + return sb.toString(); + } + + protected String generateMbBitFieldEncode(ArrayList bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + int numBytes = (bitFieldList.size() - 1)/8 + 1; + String bitArrayName = "flags_" + ordinal; + StringBuffer sb = new StringBuffer(indent + "u_int8_t[" + numBytes + "] " + + bitArrayName + " = {0};" + + (numBytes != 1 ? " /* All array elements will be initialized to 0 */" : "") + + cr); + for (int i=0; i bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + int numBytes = (bitFieldList.size() - 1)/8 + 1; + String bitArrayName = "flags_" + ordinal; + StringBuffer sb = new StringBuffer(indent + "u_int8_t[" + numBytes + "] " + + bitArrayName + ";" + cr); + for (int i=0; i 0 && line.charAt(0) != '#') +// if (line.length() > 0 && line.charAt(0) != '#') // Bad idea - '#' used in C/C++ files (#include)! + if (line.length() > 0) sb.append(line + Utils.lineSeparator); else sb.append(Utils.lineSeparator); diff --git a/qpid/gentools/org/apache/qpid/gentools/Main.java b/qpid/gentools/org/apache/qpid/gentools/Main.java index 6deed79024..2c288786c9 100644 --- a/qpid/gentools/org/apache/qpid/gentools/Main.java +++ b/qpid/gentools/org/apache/qpid/gentools/Main.java @@ -62,16 +62,33 @@ public class Main if (args[0].compareToIgnoreCase("-c") == 0) { // *** C++ generation *** + System.out.println("C++ generation mode."); generator = new CppGenerator(versionSet); domainMap = new AmqpDomainMap(generator); model = new AmqpModel(generator); -// classTemplateFiles = new File[]{ new File("templ.cpp/PropertyContentHeaderClass.tmpl") }; -// methodTemplateFiles = new File[]{ new File("templ.cpp/MethodBodyClass.tmpl") }; + modelTemplateFiles = new File[]{ + new File("templ.cpp/AMQP_ServerOperations.h.tmpl"), + new File("templ.cpp/AMQP_ClientOperations.h.tmpl"), + new File("templ.cpp/AMQP_ServerProxy.h.tmpl"), + new File("templ.cpp/AMQP_ClientProxy.h.tmpl"), + new File("templ.cpp/AMQP_ServerProxy.cpp.tmpl"), + new File("templ.cpp/AMQP_ClientProxy.cpp.tmpl"), + new File("templ.cpp/AMQP_ServerHandlerImpl.h.tmpl"), + new File("templ.cpp/AMQP_ClientHandlerImpl.h.tmpl"), + new File("templ.cpp/AMQP_ServerHandlerImpl.cpp.tmpl"), + new File("templ.cpp/AMQP_ClientHandlerImpl.cpp.tmpl"), + new File("templ.cpp/amqp_methods.h.tmpl"), + new File("templ.cpp/amqp_methods.cpp.tmpl") + }; + methodTemplateFiles = new File[]{ + new File("templ.cpp/MethodBodyClass.h.tmpl") + }; outDir += ".cpp"; } else if (args[0].compareToIgnoreCase("-j") == 0) { // *** Java generation *** + System.out.println("Java generation mode."); generator = new JavaGenerator(versionSet); domainMap = new AmqpDomainMap(generator); model = new AmqpModel(generator); @@ -88,15 +105,21 @@ public class Main System.err.println("ERROR: Required argument specifying language (C++ [-c] or Java [-j]) missing."); usage(); } + + if (modelTemplateFiles.length == 0 && classTemplateFiles.length == 0 && + methodTemplateFiles.length == 0 && fieldTemplateFiles.length == 0) + System.err.println(" WARNING: No template files."); + // 1. Suck in all the XML spec files provided on the command line. + System.out.println("Analyzing XML Specification files:"); for (int i=1; i buildVersionMap(Node n)throws AmqpParseException -// { -// Vector versionList = new Vector(); -// NodeList nl = n.getChildNodes(); -// for (int i=0; i buildFieldMap(Node n)throws AmqpParseException -// { -// Vector fieldList = new Vector(); -// NodeList nl = n.getChildNodes(); -// for (int i=0; i +#include +#include + +#include "qpid/framing/amqp_types.h" +#include "AMQP_ServerOperations.h" +#include "qpid/framing/AMQMethodBody.h" +#include "qpid/framing/Buffer.h" +#include "qpid/framing/FieldTable.h" + +#ifndef _${CLASS}${METHOD}Body_ +#define _${CLASS}${METHOD}Body_ + +namespace qpid { +namespace framing { + +class ${CLASS}${METHOD}Body : virtual public AMQMethodBody +{ + static std::map classIdMap; + static std::map methodIdMap; + static void initMaps() + { + if (classIdMap.empty()) + { +${CLASS_ID_INIT} + } + if (methodIdMap.empty()) + { +${METHOD_ID_INIT} + } + } + + /* Method field declarations */ + +%{FLIST} ${mb_field_declaration} + + +public: + typedef std::tr1::shared_ptr<${CLASS}${METHOD}Body> shared_ptr; + + ${CLASS}${METHOD}Body(u_int_8 major, u_int_8 minor) + { + super(major, minor); + initMaps(); + } + virtual ~${CLASS}${METHOD}Body() {} + +%{FLIST} ${mb_field_get_method} + + inline void print(std::ostream& out) const + { + out << "${CLASS}${METHOD}"; +%{FLIST} ${mb_field_print} + } + + inline u_int16_t amqpClassId() const + { + std::stringstream ss; + ss << major << "-" << minor; + return classIdMap[ss.str()]; + } + + inline u_int16_t amqpMethodId() const + { + std::stringstream ss; + ss << major << "-" << minor; + return methodIdMap[ss.str()]; + } + + inline u_int32_t bodySize() const + { + u_int32_t size = 0; +%{FLIST} ${mb_body_size} + return size; + } + + inline void encodeContent(Buffer& buffer) const + { +%{FLIST} ${mb_encode} + } + + inline void decodeContent(Buffer& buffer) + { +%{FLIST} ${mb_decode} + } + + inline void invoke(AMQP_ServerOperations& target, u_int16_t channel) + { + target.getBasicHandler()->consume( +%{FLIST} ${mb_field_list} + ); + } + + inline BasicConsumeBody( +%{FLIST} ${mb_field_list_declare} + ) : +%{FLIST} ${mb_field_list_initializer} + { + } + + inline BasicConsumeBody() + { + } +}; /* class ${CLASS}${METHOD}Body */ + +// Static member declarations +std::map ${CLASS}${METHOD}Body::classIdMap; +std::map ${CLASS}${METHOD}Body::methodIdMap; + +} /* namespace framing */ +} /* namespace qpid */ + +#endif + diff --git a/qpid/gentools/templ.cpp/amqp_methods.cpp.tmpl b/qpid/gentools/templ.cpp/amqp_methods.cpp.tmpl new file mode 100644 index 0000000000..d301b2b0b9 --- /dev/null +++ b/qpid/gentools/templ.cpp/amqp_methods.cpp.tmpl @@ -0,0 +1,42 @@ +&{amqp_methods.cpp} +/** +* +* Copyright (c) 2006 The Apache Software Foundation +* +* 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. +* +*/ + +/* + * This file is auto-generated by ${GENERATOR} - do not modify. + * Supported AMQP versions: +%{VLIST} * ${major}-${minor} + */ + +#include "amqp_methods.h" +#include "qpid/QpidError.h" + +namespace qpid { +namespace framing { + +AMQMethodBody* createAMQMethodBody(u_int16_t classId, u_int16_t methodId, u_int8_t major, u_int8_t minor) +{ + switch(classId * 1000 + methodId) + { +{MLIST} {m_create_method_body_class} + } + THROW_QPID_ERROR(FRAMING_ERROR, "Unknown method"); +} /* createAMQMethodBody() */ + +} /* namespace framing */ +} /* namespace qpid */ diff --git a/qpid/gentools/templ.cpp/amqp_methods.h.tmpl b/qpid/gentools/templ.cpp/amqp_methods.h.tmpl new file mode 100644 index 0000000000..51f84242f8 --- /dev/null +++ b/qpid/gentools/templ.cpp/amqp_methods.h.tmpl @@ -0,0 +1,41 @@ +&{amqp_methods.h} +/** +* +* Copyright (c) 2006 The Apache Software Foundation +* +* 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. +* +*/ + +/* + * This file is auto-generated by ${GENERATOR} - do not modify. + * Supported AMQP versions: +%{VLIST} * ${major}-${minor} + */ + +#ifndef AMQ_METHODS_H +#define AMQ_METHODS_H + +{MLIST} {m_method_body_class_indlude} + +namespace qpid { +namespace framing { + +{MLIST} {m_method_body_class_instance} + +AMQMethodBody* createAMQMethodBody(u_int16_t classId, u_int16_t methodId); + +} /* namespace framing */ +} /* namespace qpid */ + +#endif -- cgit v1.2.1