diff options
author | Kim van der Riet <kpvdr@apache.org> | 2006-10-30 19:35:40 +0000 |
---|---|---|
committer | Kim van der Riet <kpvdr@apache.org> | 2006-10-30 19:35:40 +0000 |
commit | c627d4d8324ed09bf4eb1a1d28dca9c448c97fd1 (patch) | |
tree | 6ac7731c756a75fd168334969a029a939fbeba50 /qpid/gentools | |
parent | 280bff8336167763e11c02ce4acc11bf9b90558d (diff) | |
download | qpid-python-c627d4d8324ed09bf4eb1a1d28dca9c448c97fd1.tar.gz |
First draft of C++ generator creating MethodBody classes divided into C++ namespaces by version.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@469247 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/gentools')
13 files changed, 774 insertions, 462 deletions
diff --git a/qpid/gentools/org/apache/qpid/gentools/AmqpClass.java b/qpid/gentools/org/apache/qpid/gentools/AmqpClass.java index 8c0fc83e4a..d27e9596f5 100644 --- a/qpid/gentools/org/apache/qpid/gentools/AmqpClass.java +++ b/qpid/gentools/org/apache/qpid/gentools/AmqpClass.java @@ -26,7 +26,7 @@ import org.w3c.dom.NodeList; public class AmqpClass implements Printable, NodeAware { public LanguageConverter converter; - public AmqpVersionSet versionList; + public AmqpVersionSet versionSet; public AmqpFieldMap fieldMap; public AmqpMethodMap methodMap; public String name; @@ -36,7 +36,7 @@ public class AmqpClass implements Printable, NodeAware { this.name = name; this.converter = converter; - versionList = new AmqpVersionSet(); + versionSet = new AmqpVersionSet(); fieldMap = new AmqpFieldMap(); methodMap = new AmqpMethodMap(); indexMap = new AmqpOrdinalVersionMap(); @@ -45,7 +45,7 @@ public class AmqpClass implements Printable, NodeAware public void addFromNode(Node classNode, int ordinal, AmqpVersion version) throws AmqpParseException, AmqpTypeMappingException { - versionList.add(version); + versionSet.add(version); int index = Utils.getNamedIntegerAttribute(classNode, "index"); AmqpVersionSet versionSet = indexMap.get(index); if (versionSet != null) @@ -92,7 +92,7 @@ public class AmqpClass implements Printable, NodeAware { String margin = Utils.createSpaces(marginSize); String tab = Utils.createSpaces(tabSize); - out.println(margin + "[C] " + name + ": " + versionList); + out.println(margin + "[C] " + name + ": " + versionSet); Iterator<Integer> iItr = indexMap.keySet().iterator(); while (iItr.hasNext()) diff --git a/qpid/gentools/org/apache/qpid/gentools/AmqpDomainVersionMap.java b/qpid/gentools/org/apache/qpid/gentools/AmqpDomainVersionMap.java index 2c202dc7d9..a243d873f0 100644 --- a/qpid/gentools/org/apache/qpid/gentools/AmqpDomainVersionMap.java +++ b/qpid/gentools/org/apache/qpid/gentools/AmqpDomainVersionMap.java @@ -2,7 +2,13 @@ package org.apache.qpid.gentools; import java.util.TreeMap; -public class AmqpDomainVersionMap extends TreeMap<String, AmqpVersionSet> -{ - +@SuppressWarnings("serial") +public class AmqpDomainVersionMap extends TreeMap<String, AmqpVersionSet> implements VersionConsistencyCheck +{ + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + if (size() != 1) + return false; + return get(firstKey()).equals(globalVersionSet); + } } diff --git a/qpid/gentools/org/apache/qpid/gentools/AmqpField.java b/qpid/gentools/org/apache/qpid/gentools/AmqpField.java index 9f8321e22a..e2d3f63281 100644 --- a/qpid/gentools/org/apache/qpid/gentools/AmqpField.java +++ b/qpid/gentools/org/apache/qpid/gentools/AmqpField.java @@ -23,7 +23,7 @@ import java.util.Iterator; import org.w3c.dom.Node; -public class AmqpField implements Printable, NodeAware +public class AmqpField implements Printable, NodeAware, VersionConsistencyCheck { public LanguageConverter converter; public AmqpVersionSet versionSet; @@ -125,4 +125,15 @@ public class AmqpField implements Printable, NodeAware out.println(margin + " [D] " + domainKey + " : " + versionList.toString()); } } + + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + if (!versionSet.equals(globalVersionSet)) + return false; + if (!domainMap.isVersionConsistent(globalVersionSet)) + return false; + if (!ordinalMap.isVersionConsistent(globalVersionSet)) + return false; + return true; + } } diff --git a/qpid/gentools/org/apache/qpid/gentools/AmqpFieldMap.java b/qpid/gentools/org/apache/qpid/gentools/AmqpFieldMap.java index 8e7421b45a..e4fb686f0e 100644 --- a/qpid/gentools/org/apache/qpid/gentools/AmqpFieldMap.java +++ b/qpid/gentools/org/apache/qpid/gentools/AmqpFieldMap.java @@ -24,24 +24,64 @@ import java.util.Iterator; import java.util.TreeMap; @SuppressWarnings("serial") -public class AmqpFieldMap extends TreeMap<String, AmqpField> +public class AmqpFieldMap extends TreeMap<String, AmqpField> implements VersionConsistencyCheck { public AmqpFieldMap getFieldMapForOrdinal(int ordinal) { AmqpFieldMap newMap = new AmqpFieldMap(); - Iterator<String> i = keySet().iterator(); - while (i.hasNext()) + Iterator<String> fItr = keySet().iterator(); + while (fItr.hasNext()) { - String fieldName = i.next(); - AmqpField field = get(fieldName); + AmqpField field = get(fItr.next()); TreeMap<Integer, AmqpVersionSet> ordinalMap = field.ordinalMap; AmqpVersionSet ordinalVersions = ordinalMap.get(ordinal); if (ordinalVersions != null) - newMap.put(fieldName, field); + newMap.put(field.name, field); } return newMap; } + public AmqpOrdinalFieldMap getMapForVersion(AmqpVersion version) + { + AmqpOrdinalFieldMap ordinalFieldMap = new AmqpOrdinalFieldMap(); + Iterator<String> fItr = keySet().iterator(); + while (fItr.hasNext()) + { + AmqpField field = get(fItr.next()); + if (version == null || field.versionSet.contains(version)) + { + String domain = ""; + boolean dFound = false; + Iterator<String> dItr = field.domainMap.keySet().iterator(); + while (dItr.hasNext() && !dFound) + { + domain = dItr.next(); + AmqpVersionSet versionSet = field.domainMap.get(domain); + if (version == null || versionSet.contains(version)) + dFound = true; + } + + int ordinal = -1; + boolean oFound = false; + Iterator<Integer> oItr = field.ordinalMap.keySet().iterator(); + while (oItr.hasNext() && !oFound) + { + ordinal = oItr.next(); + AmqpVersionSet versionSet = field.ordinalMap.get(ordinal); + if (version == null || versionSet.contains(version)) + oFound = true; + } + + if (dFound && oFound) + { + String[] fieldDomainPair = {field.name, domain}; + ordinalFieldMap.put(ordinal, fieldDomainPair); + } + } + } + return ordinalFieldMap; + } + public boolean isDomainConsistent(Generator generator, AmqpVersionSet versionSet) throws AmqpTypeMappingException { @@ -268,4 +308,16 @@ public class AmqpFieldMap extends TreeMap<String, AmqpField> indentSize, tabSize)); return sb.toString(); } + + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + Iterator<String> fItr = keySet().iterator(); + while (fItr.hasNext()) + { + AmqpField field = get(fItr.next()); + if (!field.isVersionConsistent(globalVersionSet)) + return false; + } + return true; + } } diff --git a/qpid/gentools/org/apache/qpid/gentools/AmqpFlagMap.java b/qpid/gentools/org/apache/qpid/gentools/AmqpFlagMap.java new file mode 100644 index 0000000000..db230fff4e --- /dev/null +++ b/qpid/gentools/org/apache/qpid/gentools/AmqpFlagMap.java @@ -0,0 +1,27 @@ +package org.apache.qpid.gentools; + +import java.util.TreeMap; + +@SuppressWarnings("serial") +public class AmqpFlagMap extends TreeMap<Boolean, AmqpVersionSet> implements VersionConsistencyCheck +{ + public boolean isSet() + { + return containsKey(true); + } + + public String toString() + { + AmqpVersionSet versionSet = get(true); + if (versionSet != null) + return versionSet.toString(); + return ""; + } + + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + if (size() != 1) + return false; + return get(firstKey()).equals(globalVersionSet); + } +} diff --git a/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java b/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java index 51304996a2..9dd4157a02 100644 --- a/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java +++ b/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java @@ -23,15 +23,15 @@ import java.util.Iterator; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -public class AmqpMethod implements Printable, NodeAware +public class AmqpMethod implements Printable, NodeAware, VersionConsistencyCheck { public LanguageConverter converter; public AmqpVersionSet versionSet; public AmqpFieldMap fieldMap; public String name; public AmqpOrdinalVersionMap indexMap; - public boolean clientMethodFlag; // Method called on client (<chassis name="server"> in XML) - public boolean serverMethodFlag; // Method called on server (<chassis name="client"> in XML) + public AmqpFlagMap clientMethodFlagMap; // Method called on client (<chassis name="server"> in XML) + public AmqpFlagMap serverMethodFlagMap; // Method called on server (<chassis name="client"> in XML) public AmqpMethod(String name, LanguageConverter converter) { @@ -40,13 +40,15 @@ public class AmqpMethod implements Printable, NodeAware versionSet = new AmqpVersionSet(); fieldMap = new AmqpFieldMap(); indexMap = new AmqpOrdinalVersionMap(); - clientMethodFlag = false; - serverMethodFlag = false; + clientMethodFlagMap = new AmqpFlagMap(); + serverMethodFlagMap = new AmqpFlagMap(); } public void addFromNode(Node methodNode, int ordinal, AmqpVersion version) throws AmqpParseException, AmqpTypeMappingException { + boolean serverChassisFlag = false; + boolean clientChassisFlag = false; versionSet.add(version); int index = Utils.getNamedIntegerAttribute(methodNode, "index"); AmqpVersionSet versionSet = indexMap.get(index); @@ -78,19 +80,21 @@ public class AmqpMethod implements Printable, NodeAware { String chassisName = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_NAME); if (chassisName.compareTo("server") == 0) - clientMethodFlag = true; + serverChassisFlag = true; else if (chassisName.compareTo("client") == 0) - serverMethodFlag = true; + clientChassisFlag = true; } - } + } + processChassisFlags(serverChassisFlag, clientChassisFlag, version); } public void print(PrintStream out, int marginSize, int tabSize) { String margin = Utils.createSpaces(marginSize); String tab = Utils.createSpaces(tabSize); - out.println(margin + "[M] " + name + " {" + (serverMethodFlag ? "S" : ".") + - (clientMethodFlag ? "C" : ".") + "}" + ": " + versionSet); + out.println(margin + "[M] " + name + " {" + (serverMethodFlagMap.isSet() ? "S " + + serverMethodFlagMap + (clientMethodFlagMap.isSet() ? ", " : "") : "") + + (clientMethodFlagMap.isSet() ? "C " + clientMethodFlagMap : "") + "}" + ": " + versionSet); Iterator<Integer> iItr = indexMap.keySet().iterator(); while (iItr.hasNext()) @@ -107,4 +111,42 @@ public class AmqpMethod implements Printable, NodeAware thisField.print(out, marginSize + tabSize, tabSize); } } + + protected void processChassisFlags(boolean serverFlag, boolean clientFlag, AmqpVersion version) + { + AmqpVersionSet versionSet = serverMethodFlagMap.get(serverFlag); + if (versionSet != null) + versionSet.add(version); + else + { + versionSet = new AmqpVersionSet(); + versionSet.add(version); + serverMethodFlagMap.put(serverFlag, versionSet); + } + + versionSet = clientMethodFlagMap.get(clientFlag); + if (versionSet != null) + versionSet.add(version); + else + { + versionSet = new AmqpVersionSet(); + versionSet.add(version); + clientMethodFlagMap.put(clientFlag, versionSet); + } + } + + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + if (!versionSet.equals(globalVersionSet)) + return false; + if (!clientMethodFlagMap.isVersionConsistent(globalVersionSet)) + return false; + if (!serverMethodFlagMap.isVersionConsistent(globalVersionSet)) + return false; + if (!indexMap.isVersionConsistent(globalVersionSet)) + return false; + if (!fieldMap.isVersionConsistent(globalVersionSet)) + return false; + return true; + } } diff --git a/qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java b/qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java new file mode 100644 index 0000000000..8eb4bfa57b --- /dev/null +++ b/qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java @@ -0,0 +1,9 @@ +package org.apache.qpid.gentools; + +import java.util.TreeMap; + +@SuppressWarnings("serial") +public class AmqpOrdinalFieldMap extends TreeMap<Integer, String[]> +{ + +} diff --git a/qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java b/qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java index 3ec8d59842..a2eb64c65d 100644 --- a/qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java +++ b/qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java @@ -3,7 +3,12 @@ package org.apache.qpid.gentools; import java.util.TreeMap; @SuppressWarnings("serial") -public class AmqpOrdinalVersionMap extends TreeMap<Integer, AmqpVersionSet> +public class AmqpOrdinalVersionMap extends TreeMap<Integer, AmqpVersionSet> implements VersionConsistencyCheck { - + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + if (size() != 1) + return false; + return get(firstKey()).equals(globalVersionSet); + } } diff --git a/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java b/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java index 101ab7e842..3bd7687057 100644 --- a/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java +++ b/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java @@ -17,6 +17,8 @@ */ package org.apache.qpid.gentools; +import java.io.File; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; @@ -25,7 +27,12 @@ import java.util.TreeMap; public class CppGenerator extends Generator { - static String cr = Utils.lineSeparator; + protected static final String cr = Utils.lineSeparator; + protected static final String versionNamespaceStartToken = "${version_namespace_start}"; + protected static final String versionNamespaceEndToken = "${version_namespace_end}"; + protected static final int FIELD_NAME = 0; + protected static final int FIELD_DOMAIN = 1; + private class DomainInfo { @@ -44,130 +51,6 @@ public class CppGenerator extends Generator } private static TreeMap<String, DomainInfo> typeMap = new TreeMap<String, DomainInfo>(); - - // 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) { @@ -251,12 +134,13 @@ public class CppGenerator extends Generator { String domainType = globalDomainMap.getDomainType(domainName, version); if (domainType == null) - throw new AmqpTypeMappingException("Domain type \"" + domainName + "\" not found in C++ typemap."); + 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 protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method, AmqpField field) @@ -270,9 +154,115 @@ public class CppGenerator extends Generator replaceToken(sb, "${FIELD}", field.name); return sb.toString(); } + + @Override + protected void processTemplate(String[] template) + throws IOException, AmqpTemplateException, AmqpTypeMappingException, + IllegalAccessException, InvocationTargetException + { + processTemplate(template, null, null, null); + } + + @Override + protected void processTemplate(String[] template, AmqpClass thisClass) + throws IOException, AmqpTemplateException, AmqpTypeMappingException, + IllegalAccessException, InvocationTargetException + { + processTemplate(template, thisClass, null, null); + } + + @Override + protected void processTemplate(String[] template, AmqpClass thisClass, + AmqpMethod method) + throws IOException, AmqpTemplateException, AmqpTypeMappingException, + IllegalAccessException, InvocationTargetException + { + StringBuffer sb = new StringBuffer(template[templateStringIndex]); + String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, null); + boolean templateProcessedFlag = false; + + // If method is not version consistent, create a namespace for each version + // i.e. copy the bit between the versionNamespaceStartToken and versionNamespaceEndToken + // once for each namespace. + if (method != null) + { + if (!method.isVersionConsistent(globalVersionSet)) + { + int namespaceStartIndex = sb.indexOf(versionNamespaceStartToken); + int namespaceEndIndex = sb.indexOf(versionNamespaceEndToken) + + versionNamespaceEndToken.length(); + if (namespaceStartIndex >= 0 && namespaceEndIndex >= 0 && + namespaceStartIndex <= namespaceEndIndex) + { + String namespaceSpan = sb.substring(namespaceStartIndex, namespaceEndIndex) + cr; + sb.delete(namespaceStartIndex, namespaceEndIndex); + Iterator<AmqpVersion> vItr = method.versionSet.iterator(); + while (vItr.hasNext()) + { + AmqpVersion version = vItr.next(); + StringBuffer nssb = new StringBuffer(namespaceSpan); + processTemplate(nssb, thisClass, method, null, template[templateFileNameIndex], + version); + sb.insert(namespaceStartIndex, nssb); + } + } + templateProcessedFlag = true; + } + } + // Remove any remaining namespace tags + int nsTokenIndex = sb.indexOf(versionNamespaceStartToken); + while (nsTokenIndex > 0) + { + sb.delete(nsTokenIndex, nsTokenIndex + versionNamespaceStartToken.length()); + nsTokenIndex = sb.indexOf(versionNamespaceStartToken); + } + nsTokenIndex = sb.indexOf(versionNamespaceEndToken); + while (nsTokenIndex > 0) + { + sb.delete(nsTokenIndex, nsTokenIndex + versionNamespaceEndToken.length()); + nsTokenIndex = sb.indexOf(versionNamespaceEndToken); + } + + if (!templateProcessedFlag) + { + processTemplate(sb, thisClass, method, null, template[templateFileNameIndex], null); + } + writeTargetFile(sb, new File(genDir + Utils.fileSeparator + filename)); + generatedFileCounter ++; + } + + @Override + protected void processTemplate(String[] template, AmqpClass thisClass, AmqpMethod method, + AmqpField field) + throws IOException, AmqpTemplateException, AmqpTypeMappingException, IllegalAccessException, + InvocationTargetException + { + StringBuffer sb = new StringBuffer(template[templateStringIndex]); + String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field); + processTemplate(sb, thisClass, method, field, template[templateFileNameIndex], null); + writeTargetFile(sb, new File(genDir + Utils.fileSeparator + filename)); + generatedFileCounter ++; + } + + protected void processTemplate(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, + AmqpField field, String templateFileName, AmqpVersion version) + throws InvocationTargetException, IllegalAccessException, AmqpTypeMappingException + { + try { processAllLists(sb, thisClass, method, version); } + catch (AmqpTemplateException e) + { + System.out.println("WARNING: " + templateFileName + ": " + e.getMessage()); + } + try { processAllTokens(sb, thisClass, method, field, version); } + catch (AmqpTemplateException e) + { + System.out.println("WARNING: " + templateFileName + ": " + e.getMessage()); + } + } @Override - protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field) + protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field, + AmqpVersion version) throws AmqpTemplateException { if (token.compareTo("${GENERATOR}") == 0) @@ -280,16 +270,26 @@ public class CppGenerator extends Generator 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 (version == null) + return String.valueOf(thisClass.indexMap.firstKey()); + return getIndex(thisClass.indexMap, version); + } 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 (version == null) + return String.valueOf(method.indexMap.firstKey()); + return getIndex(method.indexMap, version); + } if (token.compareTo("${FIELD}") == 0 && field != null) return field.name; + if (token.compareTo(versionNamespaceStartToken) == 0 && version != null) + return "namespace ver_" + version.getMajor() + "_" + version.getMinor() + cr + "{"; + if (token.compareTo(versionNamespaceEndToken) == 0 && version != null) + return "} // namespace ver_" + version.getMajor() + "_" + version.getMinor(); -// if (token.compareTo("${mb_get_class_id}") == 0 || token.compareTo("${mb_get_method_id}") == 0) -// return("/* === TODO === */"); throw new AmqpTemplateException("Template token " + token + " unknown."); } @@ -309,7 +309,7 @@ public class CppGenerator extends Generator @Override protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpFieldMap fieldMap) + AmqpFieldMap fieldMap, AmqpVersion version) throws AmqpTypeMappingException, AmqpTemplateException, IllegalAccessException, InvocationTargetException { @@ -323,48 +323,39 @@ public class CppGenerator extends Generator // Field declarations - common to MethodBody and PropertyContentHeader classes if (token.compareTo("${mb_field_declaration}") == 0) { - codeSnippet = fieldMap.parseFieldMap(declarationGenerateMethod, - mangledDeclarationGenerateMethod, 4, 4, this); + codeSnippet = generateFieldDeclarations(fieldMap, version, 4); } else if (token.compareTo("${mb_field_get_method}") == 0) { - codeSnippet = fieldMap.parseFieldMap(mbGetGenerateMethod, - mbMangledGetGenerateMethod, 4, 4, this); + codeSnippet = generateFieldGetMethods(fieldMap, version, 4); } else if (token.compareTo("${mb_field_print}") == 0) { - codeSnippet = fieldMap.parseFieldMapOrdinally(mbPrintGenerateMethod, - mbBitPrintGenerateMethod, 8, 4, this); + codeSnippet = generatePrintMethodContents(fieldMap, version, 8); } else if (token.compareTo("${mb_body_size}") == 0) { - codeSnippet = fieldMap.parseFieldMapOrdinally(mbSizeGenerateMethod, - mbBitSizeGenerateMethod, 8, 4, this); + codeSnippet = generateBodySizeMethodContents(fieldMap, version, 8); } else if (token.compareTo("${mb_encode}") == 0) { - codeSnippet = fieldMap.parseFieldMapOrdinally(mbEncodeGenerateMethod, - mbBitEncodeGenerateMethod, 8, 4, this); + codeSnippet = generateEncodeMethodContents(fieldMap, version, 8); } else if (token.compareTo("${mb_decode}") == 0) { - codeSnippet = fieldMap.parseFieldMapOrdinally(mbDecodeGenerateMethod, - mbBitDecodeGenerateMethod, 8, 4, this); + codeSnippet = generateDecodeMethodContents(fieldMap, version, 8); } else if (token.compareTo("${mb_field_list}") == 0) { - codeSnippet = fieldMap.parseFieldMap(mbParamListGenerateMethod, - mbMangledParamListGenerateMethod, 8, 4, this); + codeSnippet = generateFieldList(fieldMap, version, false, false, 8); } else if (token.compareTo("${mb_field_list_initializer}") == 0) { - codeSnippet = fieldMap.parseFieldMap(mbParamInitListGenerateMethod, - mbMangledParamInitListGenerateMethod, 8, 4, this); + codeSnippet = generateFieldList(fieldMap, version, false, true, 8); } else if (token.compareTo("${mb_field_list_declare}") == 0) { - codeSnippet = fieldMap.parseFieldMap(mbParamDeclareListGenerateMethod, - mbMangledParamDeclareListGenerateMethod, 8, 4, this); + codeSnippet = generateFieldList(fieldMap, version, true, false, 8); } else // Oops! @@ -380,224 +371,219 @@ public class CppGenerator extends Generator // Common methods - protected String generateIndexInitializer(String mapName, AmqpOrdinalVersionMap indexMap, - int indentSize) + protected String getIndex(AmqpOrdinalVersionMap indexMap, AmqpVersion version) + throws AmqpTemplateException { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - Iterator<Integer> iItr = indexMap.keySet().iterator(); while (iItr.hasNext()) { int index = iItr.next(); AmqpVersionSet versionSet = indexMap.get(index); - Iterator<AmqpVersion> vItr = versionSet.iterator(); - while (vItr.hasNext()) - { - AmqpVersion version = vItr.next(); - sb.append(indent + mapName + "[\"" + version.toString() + "\"] = " + - index + ";" + cr); - } + if (versionSet.contains(version)) + return String.valueOf(index); } - 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; + throw new AmqpTemplateException("Unable to find index for version " + version); } - - protected String generateMangledFieldDeclaration(AmqpField field, int indentSize, - int tabSize, boolean nextFlag) - throws AmqpTypeMappingException + + protected String generateFieldDeclarations(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) + throws AmqpTypeMappingException { String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); - Iterator<String> dItr = field.domainMap.keySet().iterator(); - int domainCntr = 0; - while (dItr.hasNext()) + Iterator<String> fItr = fieldMap.keySet().iterator(); + while(fItr.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); + AmqpField fieldDetails = fieldMap.get(fItr.next()); + if (version == null) // Version consistent - there *should* be only one domain + { + String domainName = fieldDetails.domainMap.firstKey(); + String codeType = getGeneratedType(domainName, globalVersionSet.first()); + sb.append(indent + codeType + " " + fieldDetails.name + ";" + cr); + } + else + { + Iterator<String> dItr = fieldDetails.domainMap.keySet().iterator(); + while (dItr.hasNext()) + { + String domainName = dItr.next(); + AmqpVersionSet versionSet = fieldDetails.domainMap.get(domainName); + if (versionSet.contains(version)) + { + String codeType = getGeneratedType(domainName, version); + sb.append(indent + codeType + " " + fieldDetails.name + ";" + cr); + } + } + } } - return sb.toString(); + 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) + protected String generateFieldGetMethods(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) throws AmqpTypeMappingException { String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); - Iterator<String> 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) + Iterator<String> fItr = fieldMap.keySet().iterator(); + while(fItr.hasNext()) { - return Utils.createSpaces(indentSize) + (defineFlag ? codeType + " " : "") + - (initializerFlag ? "this." : "") + field.name + - (initializerFlag ? "(" + field.name + ")" : "") + - (nextFlag ? "," : "") + " /* AMQP version(s): " + versionSet + " */" + cr; + AmqpField fieldDetails = fieldMap.get(fItr.next()); + if (version == null) // Version consistent - there *should* be only one domain + { + String domainName = fieldDetails.domainMap.firstKey(); + String codeType = getGeneratedType(domainName, globalVersionSet.first()); + sb.append(indent + "inline " + setRef(codeType) + " get" + + Utils.firstUpper(fieldDetails.name) + "() { return " + + fieldDetails.name + "; }" + cr); + } + else + { + Iterator<String> dItr = fieldDetails.domainMap.keySet().iterator(); + while (dItr.hasNext()) + { + String domainName = dItr.next(); + AmqpVersionSet versionSet = fieldDetails.domainMap.get(domainName); + if (versionSet.contains(version)) + { + String codeType = getGeneratedType(domainName, version); + sb.append(indent + "inline " + setRef(codeType) + " get" + + Utils.firstUpper(fieldDetails.name) + "() { return " + + fieldDetails.name + "; }" + cr); + } + } + } } + return sb.toString(); + } - protected String mbMangledParamList(AmqpField field, int indentSize, - boolean nextFlag, boolean defineFlag, boolean initializerFlag) - throws AmqpTypeMappingException + protected String generatePrintMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) { + String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); - Iterator<String> 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++; + Iterator<String> fItr = fieldMap.keySet().iterator(); + boolean firstFlag = true; + while(fItr.hasNext()) + { + String fieldName = fItr.next(); + AmqpField fieldDetails = fieldMap.get(fieldName); + if (version == null || fieldDetails.versionSet.contains(version)) + { + sb.append(indent + "out << \""); + if (!firstFlag) + sb.append("; "); + sb.append(fieldName + "=\" << " + fieldName + ";" + cr); + firstFlag = false; + } } 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<String> bitFieldList, - int ordinal, int indentSize, int tabSize) + protected String generateBodySizeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, + int indentSize) + throws AmqpTypeMappingException { String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); - for (int i=0; i<bitFieldList.size(); i++) + ArrayList<String> bitFieldList = new ArrayList<String>(); + AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version); + Iterator<Integer> oItr = ordinalFieldMap.keySet().iterator(); + int ordinal = 0; + while (oItr.hasNext()) { - String bitFieldName = bitFieldList.get(i); - sb.append(indent + "out << \""); - if (ordinal-bitFieldList.size()+i == 0) - sb.append(": \""); + ordinal = oItr.next(); + String[] fieldDomainPair = ordinalFieldMap.get(ordinal); + AmqpVersion thisVersion = version == null ? globalVersionSet.first() : version; + String domainType = getDomainType(fieldDomainPair[FIELD_DOMAIN], thisVersion); + + // Defer bit types by adding them to an array. When the first non-bit type is + // encountered, then handle the bits. This allows consecutive bits to be placed + // into the same byte(s) - 8 bits to the byte. + if (domainType.compareTo("bit") == 0) + { + bitFieldList.add(fieldDomainPair[FIELD_NAME]); + } else - sb.append("; \""); - sb.append(" << \"" + bitFieldName + "=\" << (" + bitFieldName + - " ? \"T\" : \"F\");" + cr); - } - return sb.toString(); + { + if (bitFieldList.size() > 0) // Handle accumulated bit types (if any) + { + sb.append(generateBitArrayBodySizeMethodContents(bitFieldList, ordinal, indentSize)); + } + sb.append(indent + "size += " + + typeMap.get(domainType).size.replaceAll("#", fieldDomainPair[FIELD_NAME]) + + "; /* " + fieldDomainPair[FIELD_NAME] + ": " + + domainType + " */" + cr); + } + } + if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types + { + sb.append(generateBitArrayBodySizeMethodContents(bitFieldList, ordinal, indentSize)); + } + return sb.toString(); } - protected String generateMbFieldSize(String domainType, String fieldName, - int ordinal, int indentSize, int tabSize) - { - StringBuffer sb = new StringBuffer(); - sb.append(Utils.createSpaces(indentSize) + "size += " + - typeMap.get(domainType).size.replaceAll("#", fieldName) + - "; /* " + fieldName + ": " + domainType + " */" + cr); - return sb.toString(); - } - - protected String generateMbBitArrayFieldSize(ArrayList<String> bitFieldList, - int ordinal, int indentSize, int tabSize) + protected String generateBitArrayBodySizeMethodContents(ArrayList<String> bitFieldList, + int ordinal, int indentSize) { - StringBuffer sb = new StringBuffer(); int numBytes = ((bitFieldList.size() - 1) / 8) + 1; + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); String comment = bitFieldList.size() == 1 ? bitFieldList.get(0) + ": bit" : "Combinded bits: " + bitFieldList; - sb.append(Utils.createSpaces(indentSize) + "size += " + + sb.append(indent + "size += " + typeMap.get("bit").size.replaceAll("~", String.valueOf(numBytes)) + "; /* " + comment + " */" + cr); - return sb.toString(); + bitFieldList.clear(); + return sb.toString(); } - - protected String generateMbFieldEncode(String domain, String fieldName, - int ordinal, int indentSize, int tabSize) + + protected String generateEncodeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, + int indentSize) + throws AmqpTypeMappingException { + String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); - sb.append(Utils.createSpaces(indentSize) + - typeMap.get(domain).encodeExpression.replaceAll("#", fieldName) + - "; /* " + fieldName + ": " + domain + " */" + cr); - return sb.toString(); + ArrayList<String> bitFieldList = new ArrayList<String>(); + AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version); + Iterator<Integer> oItr = ordinalFieldMap.keySet().iterator(); + int ordinal = 0; + while (oItr.hasNext()) + { + ordinal = oItr.next(); + String[] fieldDomainPair = ordinalFieldMap.get(ordinal); + AmqpVersion thisVersion = version == null ? globalVersionSet.first() : version; + String domainType = getDomainType(fieldDomainPair[FIELD_DOMAIN], thisVersion); + + // Defer bit types by adding them to an array. When the first non-bit type is + // encountered, then handle the bits. This allows consecutive bits to be placed + // into the same byte(s) - 8 bits to the byte. + if (domainType.compareTo("bit") == 0) + { + bitFieldList.add(fieldDomainPair[FIELD_NAME]); + } + else + { + if (bitFieldList.size() > 0) // Handle accumulated bit types (if any) + { + sb.append(generateBitEncodeMethodContents(bitFieldList, ordinal, indentSize)); + } + sb.append(indent + + typeMap.get(domainType).encodeExpression.replaceAll("#", fieldDomainPair[FIELD_NAME]) + + "; /* " + fieldDomainPair[FIELD_NAME] + ": " + domainType + " */"+ cr); + } + } + if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types + { + sb.append(generateBitEncodeMethodContents(bitFieldList, ordinal, indentSize)); + } + + return sb.toString(); } - - protected String generateMbBitFieldEncode(ArrayList<String> bitFieldList, - int ordinal, int indentSize, int tabSize) + + protected String generateBitEncodeMethodContents(ArrayList<String> bitFieldList, int ordinal, + int indentSize) { + int numBytes = ((bitFieldList.size() - 1) / 8) + 1; 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};" + @@ -613,28 +599,62 @@ public class CppGenerator extends Generator for (int i=0; i<numBytes; i++) { sb.append(indent + "buffer.putOctet(" + bitArrayName + "[" + i + "]);" + cr); - } - return sb.toString(); + } + bitFieldList.clear(); + return sb.toString(); } - protected String generateMbFieldDecode(String domain, String fieldName, - int ordinal, int indentSize, int tabSize) + protected String generateDecodeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, + int indentSize) + throws AmqpTypeMappingException { + String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); - sb.append(Utils.createSpaces(indentSize) + - typeMap.get(domain).decodeExpression.replaceAll("#", fieldName) + - "; /* " + fieldName + ": " + domain + " */" + cr); - return sb.toString(); + ArrayList<String> bitFieldList = new ArrayList<String>(); + AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version); + Iterator<Integer> oItr = ordinalFieldMap.keySet().iterator(); + int ordinal = 0; + while (oItr.hasNext()) + { + ordinal = oItr.next(); + String[] fieldDomainPair = ordinalFieldMap.get(ordinal); + AmqpVersion thisVersion = version == null ? globalVersionSet.first() : version; + String domainType = getDomainType(fieldDomainPair[FIELD_DOMAIN], thisVersion); + + // Defer bit types by adding them to an array. When the first non-bit type is + // encountered, then handle the bits. This allows consecutive bits to be placed + // into the same byte(s) - 8 bits to the byte. + if (domainType.compareTo("bit") == 0) + { + bitFieldList.add(fieldDomainPair[FIELD_NAME]); + } + else + { + if (bitFieldList.size() > 0) // Handle accumulated bit types (if any) + { + sb.append(generateBitDecodeMethodContents(bitFieldList, ordinal, indentSize)); + } + sb.append(indent + + typeMap.get(domainType).decodeExpression.replaceAll("#", fieldDomainPair[FIELD_NAME]) + + "; /* " + fieldDomainPair[FIELD_NAME] + ": " + domainType + " */" + cr); + } + } + if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types + { + sb.append(generateBitDecodeMethodContents(bitFieldList, ordinal, indentSize)); + } + + return sb.toString(); } - - protected String generateMbBitFieldDecode(ArrayList<String> bitFieldList, - int ordinal, int indentSize, int tabSize) + + protected String generateBitDecodeMethodContents(ArrayList<String> bitFieldList, int ordinal, + int indentSize) { + int numBytes = ((bitFieldList.size() - 1) / 8) + 1; 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); + bitArrayName + ";" + cr); for (int i=0; i<numBytes; i++) { sb.append(indent + "buffer.getOctet(" + bitArrayName + "[" + i + "]);" + cr); @@ -647,9 +667,99 @@ public class CppGenerator extends Generator bitArrayName + "[" + byteIndex + "]; /* " + bitFieldList.get(i) + ": bit */" + cr); } - return sb.toString(); + bitFieldList.clear(); + return sb.toString(); } + protected String generateFieldList(AmqpFieldMap fieldMap, AmqpVersion version, boolean defineFlag, + boolean initializerFlag, int indentSize) + throws AmqpTypeMappingException + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version); + Iterator<Integer> oItr = ordinalFieldMap.keySet().iterator(); + int ordinal = 0; + while (oItr.hasNext()) + { + ordinal = oItr.next(); + String[] fieldDomainPair = ordinalFieldMap.get(ordinal); + AmqpVersion thisVersion = version == null ? globalVersionSet.first() : version; + String codeType = getGeneratedType(fieldDomainPair[FIELD_DOMAIN], thisVersion); + sb.append(indent + (defineFlag ? codeType + " " : "") + + fieldDomainPair[FIELD_NAME] + (initializerFlag ? "(" + fieldDomainPair[FIELD_NAME] + ")" : "") + + (oItr.hasNext() ? "," : "") + 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 + " " : "") + +// 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<String> 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 + " " : "") + +// field.name + "_" + domainCntr + +// (initializerFlag ? "(" + field.name + "_" + domainCntr + ")" : "") + +// (nextFlag ? "," : "") + " /* AMQP version(s): " + versionSet + " */" + cr); +// domainCntr++; +// } +// return sb.toString(); +// } + private String setRef(String codeType) { if (codeType.compareTo("string") == 0 || diff --git a/qpid/gentools/org/apache/qpid/gentools/Generator.java b/qpid/gentools/org/apache/qpid/gentools/Generator.java index c7d9606d3b..23f019283b 100644 --- a/qpid/gentools/org/apache/qpid/gentools/Generator.java +++ b/qpid/gentools/org/apache/qpid/gentools/Generator.java @@ -26,13 +26,14 @@ import java.io.LineNumberReader; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Iterator; -import java.util.Set; public abstract class Generator implements LanguageConverter { // This string is reproduced in every generated file as a comment // TODO: Tie the version info into the build system. protected static final String generatorInfo = "Qpid Gentools v.0.1"; + protected static final int templateFileNameIndex = 0; + protected static final int templateStringIndex = 1; protected ArrayList<String[]> modelTemplateList; protected ArrayList<String[]> classTemplateList; @@ -126,6 +127,25 @@ public abstract class Generator implements LanguageConverter } } } + + abstract protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method, + AmqpField field); + + abstract protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, + AmqpField field, AmqpVersion version) + throws AmqpTemplateException; + + abstract protected void processClassList(StringBuffer sb, int tokStart, int tokEnd, AmqpModel model) + throws AmqpTemplateException; + + abstract protected void processMethodList(StringBuffer sb, int tokStart, int tokEnd, AmqpClass thisClass) + throws AmqpTemplateException; + + abstract protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpFieldMap fieldMap, AmqpVersion version) + throws AmqpTypeMappingException, AmqpTemplateException, IllegalAccessException, + InvocationTargetException; + public void generate(File genDir) throws TargetDirectoryException, IOException, AmqpTypeMappingException, @@ -138,12 +158,11 @@ public abstract class Generator implements LanguageConverter // Use all model-level templates for (int t = 0; t < modelTemplateList.size(); t++) { - processTemplate(modelTemplateList.get(t), null, null, null); + processTemplate(modelTemplateList.get(t)); } // Cycle through classes - Set<String> ckeys = model.classMap.keySet(); - Iterator<String> citr = ckeys.iterator(); + Iterator<String> citr = model.classMap.keySet().iterator(); while (citr.hasNext()) { String className = citr.next(); @@ -152,12 +171,11 @@ public abstract class Generator implements LanguageConverter // Use all class-level templates for (int c = 0; c < classTemplateList.size(); c++) { - processTemplate(classTemplateList.get(c), thisClass, null, null); + processTemplate(classTemplateList.get(c), thisClass); } // Cycle through all methods - Set<String> mkeys = thisClass.methodMap.keySet(); - Iterator<String> mitr = mkeys.iterator(); + Iterator<String> mitr = thisClass.methodMap.keySet().iterator(); while (mitr.hasNext()) { String methodName = mitr.next(); @@ -166,12 +184,11 @@ public abstract class Generator implements LanguageConverter // Use all method-level templates for (int m = 0; m < methodTemplateList.size(); m++) { - processTemplate(methodTemplateList.get(m), thisClass, method, null); + processTemplate(methodTemplateList.get(m), thisClass, method); } // Cycle through all fields - Set<String> fkeys = method.fieldMap.keySet(); - Iterator<String> fitr = fkeys.iterator(); + Iterator<String> fitr = method.fieldMap.keySet().iterator(); while (fitr.hasNext()) { String fieldName = fitr.next(); @@ -186,23 +203,6 @@ public abstract class Generator implements LanguageConverter } } } - - abstract protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method, - AmqpField field); - - abstract protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field) - throws AmqpTemplateException; - - abstract protected void processClassList(StringBuffer sb, int tokStart, int tokEnd, AmqpModel model) - throws AmqpTemplateException; - - abstract protected void processMethodList(StringBuffer sb, int tokStart, int tokEnd, AmqpClass thisClass) - throws AmqpTemplateException; - - abstract protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpFieldMap fieldMap) - throws AmqpTypeMappingException, AmqpTemplateException, IllegalAccessException, - InvocationTargetException; protected void processVersionList(StringBuffer sb, int tokStart, int tokEnd) throws AmqpTypeMappingException @@ -223,27 +223,27 @@ public abstract class Generator implements LanguageConverter } } - // TODO: This could be a little more elegant - overload this for the various combinations - // of call instead of passing nulls. - protected void processTemplate(String[] template, AmqpClass thisClass, AmqpMethod method, AmqpField field) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, IllegalAccessException, - InvocationTargetException - { - StringBuffer sb = new StringBuffer(template[1]); - String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field); - try { processAllLists(sb, thisClass, method); } - catch (AmqpTemplateException e) - { - System.out.println("WARNING: " + template[0] + ": " + e.getMessage()); - } - try { processAllTokens(sb, thisClass, method, field); } - catch (AmqpTemplateException e) - { - System.out.println("WARNING: " + template[0] + ": " + e.getMessage()); - } - writeTargetFile(sb, new File(genDir + Utils.fileSeparator + filename)); - generatedFileCounter ++; - } + // Model-level template processing + abstract protected void processTemplate(String[] template) + throws IOException, AmqpTemplateException, AmqpTypeMappingException, + IllegalAccessException, InvocationTargetException; + + // Class-level template processing + abstract protected void processTemplate(String[] template, AmqpClass thisClass) + throws IOException, AmqpTemplateException, AmqpTypeMappingException, + IllegalAccessException, InvocationTargetException; + + // Method-level template processing + abstract protected void processTemplate(String[] template, AmqpClass thisClass, + AmqpMethod method) + throws IOException, AmqpTemplateException, AmqpTypeMappingException, + IllegalAccessException, InvocationTargetException; + + // Field-level template processing + abstract protected void processTemplate(String[] template, AmqpClass thisClass, + AmqpMethod method, AmqpField field) + throws IOException, AmqpTemplateException, AmqpTypeMappingException, + IllegalAccessException, InvocationTargetException; // Helper functions common to all generators @@ -268,7 +268,7 @@ public abstract class Generator implements LanguageConverter } - protected void processAllLists(StringBuffer sb, AmqpClass thisClass, AmqpMethod method) + protected void processAllLists(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpVersion version) throws AmqpTemplateException, AmqpTypeMappingException, IllegalAccessException, InvocationTargetException { @@ -297,7 +297,8 @@ public abstract class Generator implements LanguageConverter // If this is called from a class-level template, we assume that the // class field list is required. In this case, method will be null. processFieldList(sb, lstart, lend + 1, - (method == null ? thisClass.fieldMap : method.fieldMap)); + (method == null ? thisClass.fieldMap : method.fieldMap), + version); } else { @@ -309,7 +310,8 @@ public abstract class Generator implements LanguageConverter } } - protected void processAllTokens(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpField field) + protected void processAllTokens(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpField field, + AmqpVersion version) throws AmqpTemplateException { int lstart = sb.indexOf("${"); @@ -319,7 +321,7 @@ public abstract class Generator implements LanguageConverter if (lend > 0) { String token = sb.substring(lstart, lend + 1); - replaceToken(sb, lstart, token, processToken(token, thisClass, method, field)); + replaceToken(sb, lstart, token, processToken(token, thisClass, method, field, version)); } lstart = sb.indexOf("${", lstart); } diff --git a/qpid/gentools/org/apache/qpid/gentools/JavaGenerator.java b/qpid/gentools/org/apache/qpid/gentools/JavaGenerator.java index 48cd51f1c6..5d92a66671 100644 --- a/qpid/gentools/org/apache/qpid/gentools/JavaGenerator.java +++ b/qpid/gentools/org/apache/qpid/gentools/JavaGenerator.java @@ -17,6 +17,8 @@ */ package org.apache.qpid.gentools; +import java.io.File; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; @@ -358,7 +360,7 @@ public class JavaGenerator extends Generator // === Abstract methods from class Generator - Java-specific implementations === - + @Override protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method, AmqpField field) @@ -372,9 +374,64 @@ public class JavaGenerator extends Generator replaceToken(sb, "${FIELD}", field.name); return sb.toString(); } + + @Override + protected void processTemplate(String[] template) + throws IOException, AmqpTemplateException, AmqpTypeMappingException, + IllegalAccessException, InvocationTargetException + { + processTemplate(template, null, null, null); + } + + @Override + protected void processTemplate(String[] template, AmqpClass thisClass) + throws IOException, AmqpTemplateException, AmqpTypeMappingException, + IllegalAccessException, InvocationTargetException + { + processTemplate(template, thisClass, null, null); + } + + @Override + protected void processTemplate(String[] template, AmqpClass thisClass, + AmqpMethod method) + throws IOException, AmqpTemplateException, AmqpTypeMappingException, + IllegalAccessException, InvocationTargetException + { + processTemplate(template, thisClass, method, null); + } + + @Override + protected void processTemplate(String[] template, AmqpClass thisClass, + AmqpMethod method, AmqpField field) + throws IOException, AmqpTemplateException, AmqpTypeMappingException, + IllegalAccessException, InvocationTargetException + { + StringBuffer sb = new StringBuffer(template[1]); + String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field); + processTemplate(sb, thisClass, method, field, template[templateFileNameIndex], null); + writeTargetFile(sb, new File(genDir + Utils.fileSeparator + filename)); + generatedFileCounter ++; + } + + protected void processTemplate(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, + AmqpField field, String templateFileName, AmqpVersion version) + throws InvocationTargetException, IllegalAccessException, AmqpTypeMappingException + { + try { processAllLists(sb, thisClass, method, version); } + catch (AmqpTemplateException e) + { + System.out.println("WARNING: " + templateFileName + ": " + e.getMessage()); + } + try { processAllTokens(sb, thisClass, method, field, version); } + catch (AmqpTemplateException e) + { + System.out.println("WARNING: " + templateFileName + ": " + e.getMessage()); + } + } @Override - protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field) + protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field, + AmqpVersion version) throws AmqpTemplateException { if (token.compareTo("${GENERATOR}") == 0) @@ -463,7 +520,7 @@ public class JavaGenerator extends Generator @Override protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpFieldMap fieldMap) + AmqpFieldMap fieldMap, AmqpVersion version) throws AmqpTypeMappingException, AmqpTemplateException, IllegalAccessException, InvocationTargetException { diff --git a/qpid/gentools/org/apache/qpid/gentools/VersionConsistencyCheck.java b/qpid/gentools/org/apache/qpid/gentools/VersionConsistencyCheck.java new file mode 100644 index 0000000000..0943fbde48 --- /dev/null +++ b/qpid/gentools/org/apache/qpid/gentools/VersionConsistencyCheck.java @@ -0,0 +1,6 @@ +package org.apache.qpid.gentools; + +public interface VersionConsistencyCheck +{ + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet); +} diff --git a/qpid/gentools/templ.cpp/MethodBodyClass.h.tmpl b/qpid/gentools/templ.cpp/MethodBodyClass.h.tmpl index b89f7c5c3d..06b701338b 100644 --- a/qpid/gentools/templ.cpp/MethodBodyClass.h.tmpl +++ b/qpid/gentools/templ.cpp/MethodBodyClass.h.tmpl @@ -36,26 +36,18 @@ #ifndef _${CLASS}${METHOD}Body_ #define _${CLASS}${METHOD}Body_ -namespace qpid { -namespace framing { +namespace qpid +{ +namespace framing +{ +${version_namespace_start} class ${CLASS}${METHOD}Body : virtual public AMQMethodBody { - static std::map<std::string, int> classIdMap; - static std::map<std::string, int> methodIdMap; - static void initMaps() - { - if (classIdMap.empty()) - { -${CLASS_ID_INIT} - } - if (methodIdMap.empty()) - { -${METHOD_ID_INIT} - } - } + const int classId = ${CLASS_ID_INIT}; + const int methodId = ${METHOD_ID_INIT}; - /* Method field declarations */ + // Method field declarations %{FLIST} ${mb_field_declaration} @@ -63,33 +55,40 @@ ${METHOD_ID_INIT} 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(); - } + // Constructors and destructors + + inline ${CLASS}${METHOD}Body( +%{FLIST} ${mb_field_list_declare} + ) : +%{FLIST} ${mb_field_list_initializer} + {} + + inline ${CLASS}${METHOD}Body() {} + + ${CLASS}${METHOD}Body() {} + virtual ~${CLASS}${METHOD}Body() {} + + // Attribute get methods %{FLIST} ${mb_field_get_method} + // Helper methods + inline void print(std::ostream& out) const { - out << "${CLASS}${METHOD}"; + out << "${CLASS}${METHOD}: "; %{FLIST} ${mb_field_print} } inline u_int16_t amqpClassId() const { - std::stringstream ss; - ss << major << "-" << minor; - return classIdMap[ss.str()]; + return classId; } inline u_int16_t amqpMethodId() const { - std::stringstream ss; - ss << major << "-" << minor; - return methodIdMap[ss.str()]; + return methodId; } inline u_int32_t bodySize() const @@ -115,25 +114,11 @@ public: %{FLIST} ${mb_field_list} ); } +}; // class ${CLASS}${METHOD}Body - inline BasicConsumeBody( -%{FLIST} ${mb_field_list_declare} - ) : -%{FLIST} ${mb_field_list_initializer} - { - } - - inline BasicConsumeBody() - { - } -}; /* class ${CLASS}${METHOD}Body */ - -// Static member declarations -std::map<string, int> ${CLASS}${METHOD}Body::classIdMap; -std::map<string, int> ${CLASS}${METHOD}Body::methodIdMap; - -} /* namespace framing */ -} /* namespace qpid */ +${version_namespace_end} +} // namespace framing +} // namespace qpid #endif |