From b7d5fa07d1cc66a2f1495ebc191bb689d7db0b77 Mon Sep 17 00:00:00 2001 From: James Strachan Date: Mon, 27 Feb 2006 19:19:19 +0000 Subject: [PATCH] initial spike of the code generation of the OpenWire marshalling code for C++ git-svn-id: https://svn.apache.org/repos/asf/incubator/activemq/trunk@381410 13f79535-47bb-0310-9956-ffa450edef68 --- .../OpenWireCppMarshallingClassesScript.java | 241 ++++++++++++++++++ .../OpenWireCppMarshallingHeadersScript.java | 38 +++ .../tool/OpenWireJavaMarshallingScript.java | 2 +- .../GenerateCppMarshallingClasses.groovy | 207 +++++++++++++++ .../GenerateCppMarshallingHeaders.groovy | 168 ++++++++++++ 5 files changed, 655 insertions(+), 1 deletion(-) create mode 100644 activemq-core/src/gram/java/org/apache/activemq/openwire/tool/OpenWireCppMarshallingClassesScript.java create mode 100644 activemq-core/src/gram/java/org/apache/activemq/openwire/tool/OpenWireCppMarshallingHeadersScript.java create mode 100755 activemq-core/src/gram/script/GenerateCppMarshallingClasses.groovy create mode 100755 activemq-core/src/gram/script/GenerateCppMarshallingHeaders.groovy diff --git a/activemq-core/src/gram/java/org/apache/activemq/openwire/tool/OpenWireCppMarshallingClassesScript.java b/activemq-core/src/gram/java/org/apache/activemq/openwire/tool/OpenWireCppMarshallingClassesScript.java new file mode 100644 index 0000000000..1a824407c3 --- /dev/null +++ b/activemq-core/src/gram/java/org/apache/activemq/openwire/tool/OpenWireCppMarshallingClassesScript.java @@ -0,0 +1,241 @@ +/** + * + * Copyright 2005-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. + */ +package org.apache.activemq.openwire.tool; + +import org.codehaus.jam.JAnnotation; +import org.codehaus.jam.JAnnotationValue; +import org.codehaus.jam.JClass; +import org.codehaus.jam.JProperty; + +import java.io.PrintWriter; +import java.util.Iterator; +import java.util.List; + +/** + * + * @version $Revision$ + */ +public abstract class OpenWireCppMarshallingClassesScript extends OpenWireCppMarshallingHeadersScript { + + protected String getFilePostFix() { + return ".cpp"; + } + + protected void generateUnmarshalBodyForProperty(PrintWriter out, JProperty property, JAnnotationValue size) { + out.print(" "); + String setter = property.getSetter().getSimpleName(); + String type = property.getType().getSimpleName(); + + if (type.equals("boolean")) { + out.println("info." + setter + "( bs.readBoolean() );"); + } + else if (type.equals("byte")) { + out.println("info." + setter + "( DataStreamMarshaller.readByte(dataIn) );"); + } + else if (type.equals("char")) { + out.println("info." + setter + "( DataStreamMarshaller.readChar(dataIn) );"); + } + else if (type.equals("short")) { + out.println("info." + setter + "( DataStreamMarshaller.readShort(dataIn) );"); + } + else if (type.equals("int")) { + out.println("info." + setter + "( DataStreamMarshaller.readInt(dataIn) );"); + } + else if (type.equals("long")) { + out.println("info." + setter + "( UnmarshalLong(wireFormat, dataIn, bs) );"); + } + else if (type.equals("String")) { + out.println("info." + setter + "( readString(dataIn, bs) );"); + } + else if (type.equals("byte[]") || type.equals("ByteSequence")) { + if (size != null) { + out.println("info." + setter + "( readBytes(dataIn, " + size.asInt() + ") );"); + } + else { + out.println("info." + setter + "( readBytes(dataIn, bs.readBoolean()) );"); + } + } + else if (isThrowable(property.getType())) { + out.println("info." + setter + "( unmarshalBrokerError(wireFormat, dataIn, bs) );"); + } + else if (isCachedProperty(property)) { + out.println("info." + setter + "( (" + type + ") unmarshalCachedObject(wireFormat, dataIn, bs) );"); + } + else { + out.println("info." + setter + "( (" + type + ") unmarshalNestedObject(wireFormat, dataIn, bs) );"); + } + } + + protected void generateUnmarshalBodyForArrayProperty(PrintWriter out, JProperty property, JAnnotationValue size) { + JClass propertyType = property.getType(); + String arrayType = propertyType.getArrayComponentType().getSimpleName(); + String setter = property.getGetter().getSimpleName(); + out.println(); + if (size != null) { + out.println(" {"); + out.println(" " + arrayType + "[] value = new " + arrayType + "[" + size.asInt() + "];"); + out.println(" " + "for( int i=0; i < " + size.asInt() + "; i++ ) {"); + out.println(" value[i] = (" + arrayType + ") unmarshalNestedObject(wireFormat,dataIn, bs);"); + out.println(" }"); + out.println(" info." + setter + "( value );"); + out.println(" }"); + } + else { + out.println(" if (bs.readBoolean()) {"); + out.println(" short size = DataStreamMarshaller.readShort(dataIn);"); + out.println(" " + arrayType + "[] value = new " + arrayType + "[size];"); + out.println(" for( int i=0; i < size; i++ ) {"); + out.println(" value[i] = (" + arrayType + ") unmarshalNestedObject(wireFormat,dataIn, bs);"); + out.println(" }"); + out.println(" info." + setter + "( value );"); + out.println(" }"); + out.println(" else {"); + out.println(" info." + setter + "( null );"); + out.println(" }"); + } + } + + protected int generateMarshal1Body(PrintWriter out) { + List properties = getProperties(); + int baseSize = 0; + for (Iterator iter = properties.iterator(); iter.hasNext();) { + JProperty property = (JProperty) iter.next(); + JAnnotation annotation = property.getAnnotation("openwire:property"); + JAnnotationValue size = annotation.getValue("size"); + JClass propertyType = property.getType(); + String type = propertyType.getSimpleName(); + String getter = "info." + property.getGetter().getSimpleName() + "()"; + + out.print(indent); + if (type.equals("boolean")) { + out.println("bs.writeBoolean(" + getter + ");"); + } + else if (type.equals("byte")) { + baseSize += 1; + } + else if (type.equals("char")) { + baseSize += 1; + } + else if (type.equals("short")) { + baseSize += 1; + } + else if (type.equals("int")) { + baseSize += 1; + } + else if (type.equals("long")) { + out.println("rc += marshal1Long(wireFormat, " + getter + ", bs);"); + } + else if (type.equals("String")) { + out.println("rc += writeString(" + getter + ", bs);"); + } + else if (type.equals("byte[]") || type.equals("ByteSequence")) { + if (size == null) { + out.println("bs.writeBoolean(" + getter + "!=null);"); + out.println(" rc += " + getter + "==null ? 0 : " + getter + ".Length+4;"); + } + else { + baseSize += size.asInt(); + } + } + else if (propertyType.isArrayType()) { + if (size != null) { + out.println("rc += marshalObjectArrayConstSize(wireFormat, " + getter + ", bs, " + size.asInt() + ");"); + } + else { + out.println("rc += marshalObjectArray(wireFormat, " + getter + ", bs);"); + } + } + else if (isThrowable(propertyType)) { + out.println("rc += marshalBrokerError(wireFormat, " + getter + ", bs);"); + } + else { + if (isCachedProperty(property)) { + out.println("rc += marshal1CachedObject(wireFormat, " + getter + ", bs);"); + } + else { + out.println("rc += marshal1NestedObject(wireFormat, " + getter + ", bs);"); + } + } + } + return baseSize; + } + + protected void generateMarshal2Body(PrintWriter out) { + List properties = getProperties(); + for (Iterator iter = properties.iterator(); iter.hasNext();) { + JProperty property = (JProperty) iter.next(); + JAnnotation annotation = property.getAnnotation("openwire:property"); + JAnnotationValue size = annotation.getValue("size"); + JClass propertyType = property.getType(); + String type = propertyType.getSimpleName(); + String getter = "info." + property.getGetter().getSimpleName() + "()"; + + out.print(indent); + if (type.equals("boolean")) { + out.println("bs.readBoolean();"); + } + else if (type.equals("byte")) { + out.println("DataStreamMarshaller.writeByte(" + getter + ", dataOut);"); + } + else if (type.equals("char")) { + out.println("DataStreamMarshaller.writeChar(" + getter + ", dataOut);"); + } + else if (type.equals("short")) { + out.println("DataStreamMarshaller.writeShort(" + getter + ", dataOut);"); + } + else if (type.equals("int")) { + out.println("DataStreamMarshaller.writeInt(" + getter + ", dataOut);"); + } + else if (type.equals("long")) { + out.println("marshal2Long(wireFormat, " + getter + ", dataOut, bs);"); + } + else if (type.equals("String")) { + out.println("writeString(" + getter + ", dataOut, bs);"); + } + else if (type.equals("byte[]") || type.equals("ByteSequence")) { + if (size != null) { + out.println("dataOut.write(" + getter + ", 0, " + size.asInt() + ");"); + } + else { + out.println("if(bs.readBoolean()) {"); + out.println(" DataStreamMarshaller.writeInt(" + getter + ".Length, dataOut);"); + out.println(" dataOut.write(" + getter + ");"); + out.println(" }"); + } + } + else if (propertyType.isArrayType()) { + if (size != null) { + out.println("marshalObjectArrayConstSize(wireFormat, " + getter + ", dataOut, bs, " + size.asInt() + ");"); + } + else { + out.println("marshalObjectArray(wireFormat, " + getter + ", dataOut, bs);"); + } + } + else if (isThrowable(propertyType)) { + out.println("marshalBrokerError(wireFormat, " + getter + ", dataOut, bs);"); + } + else { + if (isCachedProperty(property)) { + out.println("marshal2CachedObject(wireFormat, " + getter + ", dataOut, bs);"); + } + else { + out.println("marshal2NestedObject(wireFormat, " + getter + ", dataOut, bs);"); + } + } + } + } +} diff --git a/activemq-core/src/gram/java/org/apache/activemq/openwire/tool/OpenWireCppMarshallingHeadersScript.java b/activemq-core/src/gram/java/org/apache/activemq/openwire/tool/OpenWireCppMarshallingHeadersScript.java new file mode 100644 index 0000000000..785f64fe3b --- /dev/null +++ b/activemq-core/src/gram/java/org/apache/activemq/openwire/tool/OpenWireCppMarshallingHeadersScript.java @@ -0,0 +1,38 @@ +/** + * + * Copyright 2005-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. + */ +package org.apache.activemq.openwire.tool; + +import java.io.File; + +/** + * + * @version $Revision$ + */ +public abstract class OpenWireCppMarshallingHeadersScript extends OpenWireJavaMarshallingScript { + + public Object run() { + filePostFix = getFilePostFix(); + if (destDir == null) { + destDir = new File("../openwire-cpp/src/marshal"); + } + return super.run(); + } + + protected String getFilePostFix() { + return ".hpp"; + } +} diff --git a/activemq-core/src/gram/java/org/apache/activemq/openwire/tool/OpenWireJavaMarshallingScript.java b/activemq-core/src/gram/java/org/apache/activemq/openwire/tool/OpenWireJavaMarshallingScript.java index cb19d072a1..37a306f03e 100644 --- a/activemq-core/src/gram/java/org/apache/activemq/openwire/tool/OpenWireJavaMarshallingScript.java +++ b/activemq-core/src/gram/java/org/apache/activemq/openwire/tool/OpenWireJavaMarshallingScript.java @@ -32,7 +32,7 @@ public abstract class OpenWireJavaMarshallingScript extends OpenWireClassesScrip protected List concreteClasses = new ArrayList(); protected File factoryFile; protected String factoryFileName = "MarshallerFactory"; - protected String indent = " "; + protected String indent = " "; public Object run() { if (destDir == null) { diff --git a/activemq-core/src/gram/script/GenerateCppMarshallingClasses.groovy b/activemq-core/src/gram/script/GenerateCppMarshallingClasses.groovy new file mode 100755 index 0000000000..ebd8430e1a --- /dev/null +++ b/activemq-core/src/gram/script/GenerateCppMarshallingClasses.groovy @@ -0,0 +1,207 @@ +/** + * + * Copyright 2005-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. + */ +import org.apache.activemq.openwire.tool.OpenWireCppMarshallingClassesScript + +/** + * Generates the C++ marshalling classes for the Open Wire Format + * + * @version $Revision$ + */ +class GenerateCSharpMarshalling extends OpenWireCppMarshallingClassesScript { + + void generateFile(PrintWriter out) { + out << """/* + * Copyright 2006 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "marshal/${className}.hpp" + +using namespace apache::activemq::client::marshal; + +/* + * Marshalling code for Open Wire Format for ${jclass.simpleName} + * + * NOTE!: This file is autogenerated - do not modify! + * if you need to make a change, please see the Groovy scripts in the + * activemq-core module + */ + +${className}::${className}() +{ + // no-op +} + +${className}::~${className}() +{ + // no-op +} + +""" + +if( !abstractClass ) out << """ + +DataStructure* ${className}::createObject() +{ + return new ${jclass.simpleName}(); +} + +byte ${className}::getDataStructureType() +{ + return ${jclass.simpleName}.ID_${jclass.simpleName}; +} +""" + +out << """ + /* + * Un-marshal an object instance from the data input stream + */ +void ${className}::unmarshal(OpenWireFormat& wireFormat, Object o, BinaryReader& dataIn, BooleanStream& bs) +{ + base.unmarshal(wireFormat, o, dataIn, bs); +""" + +if( !properties.isEmpty() || marshallerAware ) out << """ + ${jclass.simpleName}& info = (${jclass.simpleName}&) o; +""" + +if( marshallerAware ) out << """ + info.beforeUnmarshall(wireFormat); + +""" + +generateUnmarshalBody(out) + +if( marshallerAware ) out << """ + info.afterUnmarshall(wireFormat); +""" + +out << """ +} + + +/* + * Write the booleans that this object uses to a BooleanStream + */ +int ${className}::marshal1(OpenWireFormat& wireFormat, Object& o, BooleanStream& bs) { + ${jclass.simpleName}& info = (${jclass.simpleName}&) o; +""" + + +if( marshallerAware ) out << """ + info.beforeMarshall(wireFormat); +""" + +out << """ + int rc = base.marshal1(wireFormat, info, bs); +""" + +def baseSize = generateMarshal1Body(out) + +out << """ + return rc + ${baseSize}; +} + +/* + * Write a object instance to data output stream + */ +void ${className}::marshal2(OpenWireFormat& wireFormat, Object& o, BinaryWriter& dataOut, BooleanStream& bs) { + base.marshal2(wireFormat, o, dataOut, bs); +""" + +if( !properties.isEmpty() || marshallerAware ) out << """ + ${jclass.simpleName}& info = (${jclass.simpleName}&) o; +""" + +generateMarshal2Body(out) + +if( marshallerAware ) out << """ + info.afterMarshall(wireFormat); +""" + +out << """ +} +""" + } + + + void generateFactory(PrintWriter out) { + out << """/* +* Copyright 2006 The Apache Software Foundation or its licensors, as +* applicable. +* +* 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. +*/ + +// Marshalling code for Open Wire Format +// +// +// NOTE!: This file is autogenerated - do not modify! +// if you need to make a change, please see the Groovy scripts in the +// activemq-openwire module +// + +#include "marshal/${className}.hpp" + +""" + + for (jclass in concreteClasses) { + out << """#include "marshal/${jclass.simpleName}Marshaller.hpp" +""" + } + + out << """ + +using namespace apache::activemq::client::marshal; + + +void MarshallerFactory::configure(OpenWireFormat& format) +{ +""" + + for (jclass in concreteClasses) { + out << """ + format.addMarshaller(new ${jclass.simpleName}Marshaller());""" + } + + out << """ +} +""" + } +} + \ No newline at end of file diff --git a/activemq-core/src/gram/script/GenerateCppMarshallingHeaders.groovy b/activemq-core/src/gram/script/GenerateCppMarshallingHeaders.groovy new file mode 100755 index 0000000000..b2a4b9d0ac --- /dev/null +++ b/activemq-core/src/gram/script/GenerateCppMarshallingHeaders.groovy @@ -0,0 +1,168 @@ +/** + * + * Copyright 2005-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. + */ +import org.apache.activemq.openwire.tool.OpenWireCppMarshallingHeadersScript + +/** + * Generates the C++ marshalling headers for the Open Wire Format + * + * @version $Revision$ + */ +class GenerateCppMarshallingHeaders extends OpenWireCppMarshallingHeadersScript { + + void generateFile(PrintWriter out) { + out << """/* +* Copyright 2006 The Apache Software Foundation or its licensors, as +* applicable. +* +* 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. +*/ +#ifndef ${className}_hpp_ +#define ${className}_hpp_ + +#include + +#include "command/DataStructure.hpp" + +/* we could cut this down - for now include all possible headers */ +#include "command/BrokerId.hpp" +#include "command/ConnectionId.hpp" +#include "command/ConsumerId.hpp" +#include "command/ProducerId.hpp" +#include "command/SessionId.hpp" + +#include "io/BinaryReader.hpp" +#include "io/BinaryWriter.hpp" + +#include "command/${baseClass}.hpp" +#include "util/ifr/p" + +namespace apache +{ + namespace activemq + { + namespace client + { + namespace marshal + { + using namespace ifr ; + using namespace apache::activemq::client::command; + using namespace apache::activemq::client::io; + +/* + * + */ +class ${className} : public ${baseClass} +{ +public: + ${className}() ; + virtual ~${className}() ; + + virtual DataStructure* createCommand() ; + virtual byte getDataStructureType() ; + + virtual void unmarshal(OpenWireFormat& wireFormat, Object o, BinaryReader& dataIn, BooleanStream& bs) ; + virtual int marshal1(OpenWireFormat& wireFormat, Object& o, BooleanStream& bs) ; + virtual void marshal2(OpenWireFormat& wireFormat, Object& o, BinaryWriter& dataOut, BooleanStream& bs) ; +} ; + +/* namespace */ + } + } + } +} +#endif /*${className}_hpp_*/ +""" + } + + + void generateFactory(PrintWriter out) { + out << """//* +* Copyright 2006 The Apache Software Foundation or its licensors, as +* applicable. +* +* 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. +*/ + +// Marshalling code for Open Wire Format +// +// +// NOTE!: This file is autogenerated - do not modify! +// if you need to make a change, please see the Groovy scripts in the +// activemq-openwire module +// + +#ifndef MarshallerFactory_hpp_ +#define MarshallerFactory_hpp_ + + +namespace apache +{ + namespace activemq + { + namespace client + { + namespace marshal + { + using namespace ifr ; + using namespace std ; + using namespace apache::activemq::client; + using namespace apache::activemq::client::command; + using namespace apache::activemq::client::io; + +/* + * + */ +class MarshallerFactory +{ +public: + MarshallerFactory() ; + virtual ~MarshallerFactory() ; + + virtual void configure(OpenWireFormat& format) ; +} ; + +/* namespace */ + } + } + } +} + +#endif /*MarshallerFactory_hpp_*/ +""" + } +} + \ No newline at end of file