From 248f1fe188fe2307b9dcf2c87a83b653eaa1920c Mon Sep 17 00:00:00 2001 From: "Rafael H. Schloming" Date: Sat, 26 Dec 2009 12:42:57 +0000 Subject: synchronized with trunk except for ruby dir git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/qpid.rnr@893970 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/rubygen/0-10/allsegmenttypes.rb | 18 ++ cpp/rubygen/0-10/exceptions.rb | 18 ++ cpp/rubygen/0-10/handlers.rb | 20 +- cpp/rubygen/0-10/specification.rb | 22 ++- cpp/rubygen/0-10/typecode.rb | 18 ++ cpp/rubygen/MethodBodyDefaultVisitor.rb | 19 ++ cpp/rubygen/amqpgen.rb | 83 +++++--- cpp/rubygen/cppgen.rb | 5 +- cpp/rubygen/framing.0-10/MethodBodyConstVisitor.rb | 18 ++ .../framing.0-10/MethodBodyDefaultVisitor.rb | 23 ++- cpp/rubygen/framing.0-10/MethodBodyFactory.rb | 58 ++++++ cpp/rubygen/framing.0-10/MethodHolder.rb | 100 ---------- cpp/rubygen/framing.0-10/Operations.rb | 24 ++- cpp/rubygen/framing.0-10/OperationsInvoker.rb | 27 ++- cpp/rubygen/framing.0-10/Proxy.rb | 30 ++- cpp/rubygen/framing.0-10/Session.rb | 214 +++++++++++++++++++-- cpp/rubygen/framing.0-10/all_method_bodies.rb | 18 ++ cpp/rubygen/framing.0-10/constants.rb | 184 +++++++++++++----- cpp/rubygen/framing.0-10/frame_body_lists.rb | 20 +- cpp/rubygen/framing.0-10/structs.rb | 80 +++++--- cpp/rubygen/generate | 103 +++++++--- 21 files changed, 839 insertions(+), 263 deletions(-) create mode 100644 cpp/rubygen/framing.0-10/MethodBodyFactory.rb mode change 100644 => 100755 cpp/rubygen/framing.0-10/Session.rb mode change 100644 => 100755 cpp/rubygen/framing.0-10/structs.rb (limited to 'cpp/rubygen') diff --git a/cpp/rubygen/0-10/allsegmenttypes.rb b/cpp/rubygen/0-10/allsegmenttypes.rb index c4c4095e02..26363d6a1f 100755 --- a/cpp/rubygen/0-10/allsegmenttypes.rb +++ b/cpp/rubygen/0-10/allsegmenttypes.rb @@ -1,4 +1,22 @@ #!/usr/bin/env ruby +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 .. in load path require 'cppgen' diff --git a/cpp/rubygen/0-10/exceptions.rb b/cpp/rubygen/0-10/exceptions.rb index 2f62b2ccdf..02e3a5d547 100755 --- a/cpp/rubygen/0-10/exceptions.rb +++ b/cpp/rubygen/0-10/exceptions.rb @@ -1,4 +1,22 @@ #!/usr/bin/env ruby +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 .. in load path require 'cppgen' diff --git a/cpp/rubygen/0-10/handlers.rb b/cpp/rubygen/0-10/handlers.rb index c23eb5faf4..981ea890e6 100755 --- a/cpp/rubygen/0-10/handlers.rb +++ b/cpp/rubygen/0-10/handlers.rb @@ -1,4 +1,22 @@ #!/usr/bin/env ruby +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 .. in load path require 'cppgen' @@ -17,7 +35,7 @@ class GenHandlers < CppGen def generate() h_file("#{@dir}/handlers.h") { - include "specification" + include "#{@dir}/specification" namespace("#{@ns}") { action_handler "Command", @amqp.collect_all(AmqpCommand) action_handler "Control", @amqp.collect_all(AmqpControl) diff --git a/cpp/rubygen/0-10/specification.rb b/cpp/rubygen/0-10/specification.rb index a98292ee4e..7366599eba 100755 --- a/cpp/rubygen/0-10/specification.rb +++ b/cpp/rubygen/0-10/specification.rb @@ -1,4 +1,22 @@ #!/usr/bin/env ruby +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 .. in load path require 'cppgen' @@ -324,8 +342,8 @@ class Specification < CppGen } cpp_file("#{@dir}/#{name}") { - include "#{name}" - include "exceptions.h" + include "#{@dir}/#{name}" + include "#{@dir}/exceptions.h" namespace(@ns) { genl "using framing::in_place;" genl diff --git a/cpp/rubygen/0-10/typecode.rb b/cpp/rubygen/0-10/typecode.rb index e36b92c07c..0ab9c4be5d 100755 --- a/cpp/rubygen/0-10/typecode.rb +++ b/cpp/rubygen/0-10/typecode.rb @@ -1,4 +1,22 @@ #!/usr/bin/env ruby +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 .. in load path require 'cppgen' diff --git a/cpp/rubygen/MethodBodyDefaultVisitor.rb b/cpp/rubygen/MethodBodyDefaultVisitor.rb index 1fff1d51db..4f9b369117 100755 --- a/cpp/rubygen/MethodBodyDefaultVisitor.rb +++ b/cpp/rubygen/MethodBodyDefaultVisitor.rb @@ -1,4 +1,23 @@ #!/usr/bin/env ruby +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 .. in load path require 'cppgen' diff --git a/cpp/rubygen/amqpgen.rb b/cpp/rubygen/amqpgen.rb index bfa15bb391..69e65a4056 100755 --- a/cpp/rubygen/amqpgen.rb +++ b/cpp/rubygen/amqpgen.rb @@ -1,7 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. # # Generic AMQP code generation library. # - # TODO aconway 2008-02-21: # # The amqp_attr_reader and amqp_child_reader for each Amqp* class @@ -15,6 +30,7 @@ require 'delegate' require 'rexml/document' require 'pathname' +require 'set' include REXML # Handy String functions for converting names. @@ -150,7 +166,7 @@ class AmqpElement # The root element. def root() @root ||=parent ? parent.root : self; end - def to_s() "#<#{self.class}(#{fqname})>"; end + def to_s() "#<#{self.class}(#{fqname})>"; end def inspect() to_s; end # Text of doc child if there is one. @@ -166,6 +182,21 @@ class AmqpElement return self if is_a? AmqpClass return parent && parent.containing_class end + + # 0-10 array domains are missing element type information, add it here. + ArrayTypes={ + "str16-array" => "str-16", + "amqp-host-array" => "connection.amqp-host-url", + "command-fragments" => "session.command-fragment", + "in-doubt" => "dtx.xid", + "tx-publish" => "str-8", + "queues" => "str-8" + } + + def array_type(name) + return ArrayTypes[name] if ArrayTypes[name] + raise "Missing ArrayType entry for " + name + end end @@ -189,14 +220,6 @@ class AmqpEnum < AmqpElement amqp_child_reader :choice end -# 0-10 array domains are missing element type information, add it here. -ArrayTypes={ - "str16-array" => "str-16", - "amqp-host-array" => "connection.amqp-host-url", - "command-fragments" => "session.command-fragment", - "in-doubt" => "dtx.xid" -} - class AmqpDomain < AmqpElement def initialize(xml, parent) super @@ -295,7 +318,7 @@ class AmqpFakeMethod < AmqpMethod def content() return "1" if @action.is_a? AmqpCommand and @action.segments end def index() @action.code end def code() @action.code end - def synchronous() end # FIXME aconway 2008-04-10: ??? + def synchronous() end def on_chassis?(chassis) @action.received_by?(chassis) end @@ -318,7 +341,14 @@ class AmqpAction < AmqpElement def initialize(xml,amqp) super; end amqp_child_reader :implement, :field, :response amqp_attr_reader :code - def implement?(role) xml.elements["./implement[@role='#{role}']"] end + def implement?(role) + # we can't use xpath for this because it triggers a bug in some + # versions of ruby, including version 1.8.6.110 + xml.elements.each {|el| + return true if el.name == "implement" and el.attributes["role"] == role + } + return false + end def received_by?(client_or_server) return (implement?(client_or_server) or implement?("sender") or implement?("receiver")) end @@ -434,9 +464,12 @@ end # Collect information about generated files. class GenFiles - @@files =[] - def GenFiles.add(f) @@files << f; end + @@files = Set.new + @@public_api = [] + def GenFiles.add(f) @@files.add(f); end def GenFiles.get() @@files; end + def GenFiles.public_api(file) @@public_api << file; end + def GenFiles.public_api?(file) @@public_api.find { |f| f == file }; end end # Base class for code generators. @@ -446,27 +479,27 @@ class Generator # Takes directory for output or "-", meaning print file names that # would be generated. def initialize (outdir, amqp) + @outdir=outdir[0] + @apidir=outdir[1] @amqp=amqp - @outdir=outdir + raise "outdir is not an array" unless outdir.class == Array @prefix=[''] # For indentation or comments. @indentstr=' ' # One indent level. @outdent=2 - Pathname.new(@outdir).mkpath unless @outdir=="-" end + # Declare next file to be public API + def public_api(file) GenFiles.public_api(file); end + # Create a new file, set @out. def file(file, &block) - GenFiles.add file - if (@outdir != "-") - @path=Pathname.new "#{@outdir}/#{file}" + GenFiles.add(file) + dir = GenFiles.public_api?(file) ? @apidir : @outdir + if (dir != "-") + @path=Pathname.new "#{dir}/#{file}" @path.parent.mkpath @out=String.new # Generate in memory first - if block then yield; endfile; end - end - end - - def endfile() - if @outdir != "-" + yield if block if @path.exist? and @path.read == @out puts "Skipped #{@path} - unchanged" # Dont generate if unchanged else diff --git a/cpp/rubygen/cppgen.rb b/cpp/rubygen/cppgen.rb index 3a4228567a..7818e1c4b0 100755 --- a/cpp/rubygen/cppgen.rb +++ b/cpp/rubygen/cppgen.rb @@ -118,6 +118,7 @@ class AmqpRoot # preview; map 0-10 types to preview code generator types @@typemap = { "bit"=> CppType.new("bool").code("Octet").defval("false"), + "boolean"=> CppType.new("bool").code("Octet").defval("false"), "uint8"=>CppType.new("uint8_t").code("Octet").defval("0"), "uint16"=>CppType.new("uint16_t").code("Short").defval("0"), "uint32"=>CppType.new("uint32_t").code("Long").defval("0"), @@ -146,7 +147,7 @@ end class AmqpElement # convert my amqp type_ attribute to a C++ type. def amqp2cpp() - return "ArrayDomain<#{ArrayTypes[name].amqp2cpp}> " if type_=="array" + return "ArrayDomain<#{array_type(name).amqp2cpp}> " if type_=="array" return type_.amqp2cpp end @@ -189,7 +190,7 @@ class AmqpField c=containing_class c.struct(type_) end - def cpptype() lookup_cpptype(type_) or raise "no cpptype #{self}" end + def cpptype() lookup_cpptype(type_) or raise "no cpptype #{type_} for field #{self}" end def cppname() name.lcaps.cppsafe; end def bit?() type_ == "bit"; end def signature() cpptype.param+" "+cppname; end diff --git a/cpp/rubygen/framing.0-10/MethodBodyConstVisitor.rb b/cpp/rubygen/framing.0-10/MethodBodyConstVisitor.rb index f9ef95f5a0..d784e589df 100755 --- a/cpp/rubygen/framing.0-10/MethodBodyConstVisitor.rb +++ b/cpp/rubygen/framing.0-10/MethodBodyConstVisitor.rb @@ -1,4 +1,22 @@ #!/usr/bin/env ruby +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 .. in load path require 'cppgen' diff --git a/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb b/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb index a74b0c06d6..00962de4f9 100755 --- a/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb +++ b/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb @@ -1,4 +1,22 @@ #!/usr/bin/env ruby +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 .. in load path require 'cppgen' @@ -12,18 +30,19 @@ class MethodBodyDefaultVisitorGen < CppGen def generate() h_file(@filename) { include "qpid/framing/MethodBodyConstVisitor" + include "qpid/CommonImportExport.h" namespace(@namespace) { genl "class AMQMethodBody;" cpp_class(@classname, "public MethodBodyConstVisitor") { genl "public:" genl "virtual void defaultVisit(const AMQMethodBody&) = 0;" @amqp.methods_.each { |m| - genl "virtual void visit(const #{m.body_name}&);" } + genl "QPID_COMMON_EXTERN virtual void visit(const #{m.body_name}&);" } }}} cpp_file(@filename) { include(@filename) - include("all_method_bodies.h") + include("qpid/framing/all_method_bodies.h") namespace(@namespace) { @amqp.methods_.each { |m| genl "void #{@classname}::visit(const #{m.body_name}& b) { defaultVisit(b); }" diff --git a/cpp/rubygen/framing.0-10/MethodBodyFactory.rb b/cpp/rubygen/framing.0-10/MethodBodyFactory.rb new file mode 100644 index 0000000000..95c79fd1a4 --- /dev/null +++ b/cpp/rubygen/framing.0-10/MethodBodyFactory.rb @@ -0,0 +1,58 @@ +#!/usr/bin/env ruby +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 .. in load path +require 'cppgen' + +class MethodBodyFactoryGen < CppGen + + def initialize(outdir, amqp) + super(outdir, amqp) + @namespace="qpid::framing" + @classname="MethodBodyFactory" + @filename="qpid/framing/MethodBodyFactory" + end + + def generate() + cpp_file(@filename) { + include @filename + include "qpid/framing/BodyFactory" + @amqp.methods_.each { |m| include "qpid/framing/#{m.body_name}" } + include "qpid/Exception.h" + genl + namespace(@namespace) { + scope("boost::intrusive_ptr #{@classname}::create(ClassId c, MethodId m) {") { + scope("switch (c) {") { + @amqp.classes.each { |c| + scope("case #{c.code}: switch(m) {") { + c.methods_.each { |m| + genl "case #{m.code}: return BodyFactory::create<#{m.body_name}>();" + } + genl "default: throw Exception(QPID_MSG(\"Invalid method id \" << int(m) << \" for class #{c.name} \"));" + } + genl "break;" + } + genl "default: throw Exception(QPID_MSG(\"Invalid class id \" << int(c)));" + } + } + }} + end +end + +MethodBodyFactoryGen.new($outdir, $amqp).generate(); diff --git a/cpp/rubygen/framing.0-10/MethodHolder.rb b/cpp/rubygen/framing.0-10/MethodHolder.rb index 90a9333916..e69de29bb2 100755 --- a/cpp/rubygen/framing.0-10/MethodHolder.rb +++ b/cpp/rubygen/framing.0-10/MethodHolder.rb @@ -1,100 +0,0 @@ -#!/usr/bin/env ruby -$: << ".." # Include .. in load path -require 'cppgen' - -class MethodHolderGen < CppGen - - def initialize(outdir, amqp) - super(outdir, amqp) - @namespace="qpid::framing" - @classname="BodyHolder" - @filename="qpid/framing/BodyHolder" - end - - def gen_max_size() - # Generate program to generate MaxSize.h - cpp_file("generate_MaxMethodBodySize_h") { - include "qpid/framing/AMQHeaderBody" - include "qpid/framing/AMQContentBody" - include "qpid/framing/AMQHeartbeatBody" - @amqp.methods_.each { |m| include "qpid/framing/#{m.body_name}" } - genl - include "" - include "" - genl - genl "using namespace std;" - genl "using namespace qpid::framing;" - genl - scope("int main(int, char** argv) {") { - genl "size_t maxSize=0;" - genl "maxSize=max(maxSize, sizeof(AMQHeaderBody));" - genl "maxSize=max(maxSize, sizeof(AMQContentBody));" - genl "maxSize=max(maxSize, sizeof(AMQHeartbeatBody));" - @amqp.methods_.each { |m| - genl "maxSize=max(maxSize, sizeof(#{m.body_name}));" } - gen <(); break;" - } - genl "default: throw Exception(QPID_MSG(\"Invalid method id \" << int(m) << \" for class #{c.name} \"));" - } - genl "break;" - } - genl "default: throw Exception(QPID_MSG(\"Invalid class id \" << int(c)));" - } - } - - struct("CopyVisitor", "public FrameDefaultVisitor") { - genl "using FrameDefaultVisitor::visit;" - genl "using FrameDefaultVisitor::defaultVisit;" - genl "BodyHolder& holder;" - genl "CopyVisitor(BodyHolder& h) : holder(h) {}" - ["Header", "Content", "Heartbeat"].each { |type| - genl "void visit(const AMQ#{type}Body& x) { holder=x; }" - } - @amqp.methods_.each { |m| - genl "void visit(const #{m.body_name}& x) { holder=x; }" - } - genl "void defaultVisit(const AMQBody&) { assert(0); }" - } - genl - - scope("void BodyHolder::setBody(const AMQBody& b) {") { - genl "CopyVisitor cv(*this); b.accept(cv);" - } - }} - end - - def generate - gen_max_size - gen_construct - end -end - -MethodHolderGen.new($outdir, $amqp).generate(); - diff --git a/cpp/rubygen/framing.0-10/Operations.rb b/cpp/rubygen/framing.0-10/Operations.rb index 4a67df8b92..cd6a363c56 100755 --- a/cpp/rubygen/framing.0-10/Operations.rb +++ b/cpp/rubygen/framing.0-10/Operations.rb @@ -1,4 +1,22 @@ #!/usr/bin/env ruby +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# # Usage: output_directory xml_spec_file [xml_spec_file...] # $: << '..' @@ -97,7 +115,7 @@ EOS end end -OperationsGen.new("client",ARGV[0], $amqp).generate() -OperationsGen.new("server",ARGV[0], $amqp).generate() -OperationsGen.new("all",ARGV[0], $amqp).generate() +OperationsGen.new("client",$outdir, $amqp).generate() +OperationsGen.new("server",$outdir, $amqp).generate() +OperationsGen.new("all",$outdir, $amqp).generate() diff --git a/cpp/rubygen/framing.0-10/OperationsInvoker.rb b/cpp/rubygen/framing.0-10/OperationsInvoker.rb index 44006207ca..f9b6cac76b 100755 --- a/cpp/rubygen/framing.0-10/OperationsInvoker.rb +++ b/cpp/rubygen/framing.0-10/OperationsInvoker.rb @@ -1,4 +1,22 @@ #!/usr/bin/env ruby +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# # Usage: output_directory xml_spec_file [xml_spec_file...] # $: << '..' @@ -56,7 +74,7 @@ class OperationsInvokerGen < CppGen public genl("Invoker(#{target}& target_) : target(target_) {}") genl "using MethodBodyDefaultVisitor::visit;" - methods.each { |m| genl "void visit(const #{m.body_name}& body);" } + methods.each { |m| genl "QPID_COMMON_EXTERN void visit(const #{m.body_name}& body);" } } end @@ -64,6 +82,7 @@ class OperationsInvokerGen < CppGen h_file(@filename) { include "qpid/framing/#{@ops}" include "qpid/framing/Invoker.h" + include "qpid/CommonImportExport.h" namespace("qpid::framing") { # AMQP_*Operations invoker. methods=@amqp.classes.map { |c| visit_methods(c).to_a }.flatten @@ -93,6 +112,6 @@ class OperationsInvokerGen < CppGen end end -OperationsInvokerGen.new("client",ARGV[0], $amqp).generate() -OperationsInvokerGen.new("server",ARGV[0], $amqp).generate() -OperationsInvokerGen.new("all",ARGV[0], $amqp).generate() +OperationsInvokerGen.new("client",$outdir, $amqp).generate() +OperationsInvokerGen.new("server",$outdir, $amqp).generate() +OperationsInvokerGen.new("all",$outdir, $amqp).generate() diff --git a/cpp/rubygen/framing.0-10/Proxy.rb b/cpp/rubygen/framing.0-10/Proxy.rb index 71a6b954c6..6e3cb4fd4d 100755 --- a/cpp/rubygen/framing.0-10/Proxy.rb +++ b/cpp/rubygen/framing.0-10/Proxy.rb @@ -1,4 +1,22 @@ #!/usr/bin/env ruby +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 .. in load path require 'cppgen' @@ -19,14 +37,14 @@ class ProxyGen < CppGen def inner_class_decl(c) cname=c.name.caps - cpp_class(cname, "Proxy") { + cpp_class(cname, "public Proxy") { gen <" - include "#{@classname}.h" + include "qpid/framing/#{@classname}.h" include "qpid/framing/amqp_types_full.h" methods_on(@amqp, @chassis).each { |m| include "qpid/framing/"+m.body_name @@ -74,7 +94,7 @@ EOS genl namespace("qpid::framing") { genl "#{@classname}::#{@classname}(FrameHandler& f) :" - gen " Proxy(f)" + gen " Proxy(f)" @amqp.classes.each { |c| gen ",\n "+proxy_member(c)+"(f)" } genl "{}\n" @amqp.classes.each { |c| inner_class_defn(c) } diff --git a/cpp/rubygen/framing.0-10/Session.rb b/cpp/rubygen/framing.0-10/Session.rb old mode 100644 new mode 100755 index 9f54ad1675..61f0e03a8b --- a/cpp/rubygen/framing.0-10/Session.rb +++ b/cpp/rubygen/framing.0-10/Session.rb @@ -1,17 +1,38 @@ #!/usr/bin/env ruby +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# # Usage: output_directory xml_spec_file [xml_spec_file...] # $: << '..' require 'cppgen' class CppGen - def session_methods + def session_methods(sync_default) excludes = ["connection", "session", "file", "stream"] gen_methods=@amqp.methods_on(@chassis).reject { |m| excludes.include? m.parent.name or m.body_name.include?("010") } + gen_methods.each { |m| m.set_sync_default(sync_default) } end + + # Generates a doxygen comment for AmqpMethod m. def doxygen(m) doxygen_comment { genl m.doc @@ -34,9 +55,9 @@ module SyncAsync def decl_ctor_opeq() genl - genl "#{@classname}();" - genl "#{@classname}(const #{@version_base}& other);" - genl "#{@classname}& operator=(const #{@version_base}& other);" + genl "QPID_CLIENT_EXTERN #{@classname}();" + genl "QPID_CLIENT_EXTERN #{@classname}(const #{@version_base}& other);" + genl "QPID_CLIENT_EXTERN #{@classname}& operator=(const #{@version_base}& other);" end def defn_ctor_opeq(inline="") @@ -50,23 +71,35 @@ module SyncAsync genl "return *this;" } end + + def sync_default() !@async end end class ContentField # For extra content parameters def cppname() "content" end - def signature() "const MethodContent& content" end - def sig_default() signature+"="+"DefaultContent(std::string())" end - def unpack() "p[arg::content|DefaultContent(std::string())]"; end + def signature() "const Message& content" end + def sig_default() signature+"="+"Message(std::string())" end + def unpack() "p[arg::content|Message(std::string())]"; end def doc() "Message content"; end end +class SyncField # For extra sync parameters + def initialize(default_value) @default_value=default_value ? "true" : "false" end + def cppname() "sync" end + def signature() "bool sync" end + def sig_default() signature+"="+@default_value end + def unpack() "p[arg::sync|#{@default_value}]"; end + def doc() "If true the broker will respond with completion status as soon as possible."; end +end + class AmqpField def unpack() "p[arg::#{cppname}|#{default_value}]"; end def sig_default() signature+"="+default_value; end end class AmqpMethod - def fields_c() content ? fields+[ContentField.new] : fields end + def set_sync_default(sync_default) @sync_default=sync_default end + def fields_c() result = fields + (content ? [ContentField.new] : []) + [SyncField.new(@sync_default)] end def param_names_c() fields_c.map { |f| f.cppname} end def signature_c() fields_c.map { |f| f.signature }; end def sig_c_default() fields_c.map { |f| f.sig_default }; end @@ -103,8 +136,10 @@ class SessionNoKeywordGen < CppGen end def generate() + public_api("#{@file}.h") h_file(@file) { include "qpid/client/#{@version_base}.h" + include "qpid/client/ClientImportExport.h" namespace(@namespace) { doxygen_comment { genl "AMQP #{@amqp.version} #{sync_adjective} session API." @@ -114,31 +149,36 @@ class SessionNoKeywordGen < CppGen cpp_class(@classname, "public #{@version_base}") { public decl_ctor_opeq() - session_methods.each { |m| + session_methods(sync_default).each { |m| genl doxygen(m) args=m.sig_c_default.join(", ") - genl "#{m.return_type(@async)} #{m.session_function}(#{args});" + genl "QPID_CLIENT_EXTERN #{m.return_type(@async)} #{m.session_function}(#{args});" } } }} cpp_file(@file) { - include @classname + include "qpid/client/#{@classname}" include "qpid/framing/all_method_bodies.h" + include "qpid/client/SessionImpl.h" + include "qpid/client/MessageImpl.h" + include "qpid/client/PrivateImplRef.h" + include "qpid/client/CompletionImpl.h" + include "" namespace(@namespace) { genl "using namespace framing;" - session_methods.each { |m| + session_methods(sync_default).each { |m| genl sig=m.signature_c.join(", ") func="#{@classname}::#{m.session_function}" scope("#{m.return_type(@async)} #{func}(#{sig}) {") { args=(["ProtocolVersion(#{@amqp.major},#{@amqp.minor})"]+m.param_names).join(", ") genl "#{m.body_name} body(#{args});"; - genl "body.setSync(#{@async ? 'false':'true'});" + genl "body.setSync(sync);" sendargs="body" - sendargs << ", content" if m.content - async_retval="#{m.return_type(true)}(impl->send(#{sendargs}), impl)" + sendargs << ", *MessageImpl::get(content)" if m.content + async_retval="#{m.return_type(true)}(new CompletionImpl(impl->send(#{sendargs}), impl))" if @async then genl "return #{async_retval};" else @@ -180,9 +220,10 @@ class SessionGen < CppGen end def generate() - keyword_methods=session_methods.reject { |m| m.fields_c.empty? } + keyword_methods=session_methods(sync_default).reject { |m| m.fields_c.empty? } max_arity = keyword_methods.map{ |m| m.fields_c.size }.max + public_api("qpid/client/arg.h") h_file("qpid/client/arg.h") { # Generate keyword tag declarations. genl "#define BOOST_PARAMETER_MAX_ARITY #{max_arity}" @@ -192,10 +233,11 @@ class SessionGen < CppGen genl "BOOST_PARAMETER_KEYWORD(keyword_tags, #{k})" }} } - + public_api("#{@fqclass.file}.h") h_file(@fqclass.file) { include @fqbase.file include "qpid/client/arg" + include "qpid/client/ClientImportExport" namespace("qpid::client") { # Doxygen comment. doxygen_comment { @@ -219,6 +261,136 @@ which provides the same set of functions using normal non-keyword declarations. \\ingroup clientapi + + +\\details + +

Publishing Messages

+
    +
  • messageTransfer()

    +
    session.messageTransfer(arg::content=message, arg::destination="amq.topic");
  • +
  • messageTransfer() — asynchronous

    +
    #include <qpid/client/AsyncSession.h>
    +
    +for (int i=0; i<10; i++) {
    +    message.setData(message_data.str());
    +    async(session).messageTransfer(arg::content=message,  arg::destination="amq.direct");        
    +}
    +
    +session.sync();
    +
    +
  • +
+ +

Exchanges

+
    +
  • exchangeBind()

    +
    session.exchangeBind(arg::exchange="amq.topic", arg::queue=queue, arg::bindingKey=routing_key);
    +
  • +
  • exchangeUnbind()

    +
    session.exchangeUnBind(arg::exchange="amq.topic", arg::queue=queue, arg::bindingKey=routing_key);
  • +
  • exchangeBound()

    +
    if (session.exchangeBound(arg::exchange="amq.topic", arg::queue=queue, arg::bindingKey=rk)){...}
    +
    if (session.exchangeBound(arg::exchange="amq.topic", arg::queue=queue)){...}
    +
  • +
  • exchangeDeclare()

    +
    session.exchangeDeclare(arg::exchange="my.topic", arg::type="topic");
    +
    session.exchangeDeclare(arg::exchange="xml", arg::type="xml");
    +
  • +
  • exchangeDelete()

    +
    session.exchangeDeclare(arg::exchange="my.topic");
    +
    session.exchangeDeclare(arg::exchange="xml", arg::ifUnused=true);
    +
  • +
  • exchangeQuery()

    +
    ExchangeQueryResult eqr = session.exchangeQuery(arg::exchange="my.topic");
  • +
+ + +

Configuring exchanges in session.exchangeDeclare

+ +
arg::durable=true
+

Default: false.

+

If durable=true, an exchange remains active even if the server is restarted. If durable=false, an exchange is purged when a server restarts.

+ +
arg::autoDelete=true
+

Default: false.

+

If autoDelete=true, deleting the last binding for an exchange also deletes the exchange.

+ +
arg::alternatExchange="my.exchange"
+

Default: none.

+

If an alternate exchange is specified, messages that can not be delivered to any queue are sent to the alternate exchange.

+ +

Queues

+
    +
  • queueDeclare()

    +
    session.queueDeclare(arg::queue="message_queue");
    +
  • +
  • queueDelete()

    +
    session.queueDelete(arg::queue="message_queue");
  • +
  • queuePurge()

    +
    session.queuePurge(arg::queue="message_queue");
  • +
  • queueQuery()

    +
    QueueQueryResult qqr = session.queueQuery(arg::queue="message_queue");
  • +
+ + +

Configuring queues with session.queueDeclare

+
arg::durable=true
+

Default: false.

+

If durable=true, a queue remains active if the server is restarted. If durable=false, a queue and its contents are lost when a server restarts.

+
+ +
arg::autoDelete=true
+

Default: false.

+

If autoDelete=true, the queue is deleted when the last active Subscription to the Queue is canceled.

+
+ +
arg::exclusive=true
+

Default: false.

+

If exclusive=true, only the Session that created a queue can access it.

+
+ +
arg::alternateExchange="my.exchange"
+

Default: none.

+

If an alternate exchange is specified, messages are routed to it if (1) they are rejected by a client, or (2) they remain on the queue when it is deleted.

+
+ + +

Accepting, Acquiring, Rejecting, or Releasing Messages

+
    +
  • messageAccept() — acknowledges messages

    +
    SequenceSet tobeAccepted; 
    +toAccepted.add(msg.getId()); 
    +session.messageAccept(toBeAccepted);
    +
  • +
  • messageAcquire()

    +
    SequenceSet tobeAcquired;
    +toBeAcquired.add(msg.getId()); 
    +session.messageAcquire(toBeAcquired);
    +
  • +
  • messageReject()

    +
    SequenceSet tobeRejected; 
    +toRejected.add(msg.getId()); 
    +session.messageReject(toBeRejected);
    +
  • +
  • messageRelease()

    +
    SequenceSet tobeReleased; 
    +toReleased.add(msg.getId()); 
    +session.messageRelease(toBeReleased);
  • +
+ +

Transactions

+
    +
  • txSelect()

    +
    session.txSelect();
    +
  • +
  • txCommit()

    +
    session.txSelect();
  • +
  • txRollback()

    +
    session.txRollback();
  • +
+ + EOS } # Session class. @@ -238,8 +410,8 @@ EOS end end -SessionNoKeywordGen.new(ARGV[0], $amqp, true).generate() -SessionNoKeywordGen.new(ARGV[0], $amqp, false).generate() -SessionGen.new(ARGV[0], $amqp, true).generate() -SessionGen.new(ARGV[0], $amqp, false).generate() +SessionNoKeywordGen.new($outdir, $amqp, true).generate() +SessionNoKeywordGen.new($outdir, $amqp, false).generate() +SessionGen.new($outdir, $amqp, true).generate() +SessionGen.new($outdir, $amqp, false).generate() diff --git a/cpp/rubygen/framing.0-10/all_method_bodies.rb b/cpp/rubygen/framing.0-10/all_method_bodies.rb index 5971d49189..4c7fccfff5 100755 --- a/cpp/rubygen/framing.0-10/all_method_bodies.rb +++ b/cpp/rubygen/framing.0-10/all_method_bodies.rb @@ -1,4 +1,22 @@ #!/usr/bin/env ruby +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 .. in load path require 'cppgen' diff --git a/cpp/rubygen/framing.0-10/constants.rb b/cpp/rubygen/framing.0-10/constants.rb index 7f026a3e54..5c1c1047f7 100755 --- a/cpp/rubygen/framing.0-10/constants.rb +++ b/cpp/rubygen/framing.0-10/constants.rb @@ -1,4 +1,22 @@ #!/usr/bin/env ruby +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 .. in load path require 'cppgen' @@ -11,8 +29,10 @@ class ConstantsGen < CppGen end def constants_h() - h_file("#{@dir}/constants") { - namespace(@namespace) { + public_api("#{@dir}/constants.h") + h_file("#{@dir}/constants.h") { + namespace(@namespace) { + # Constants for class/method names. scope("enum AmqpConstant {","};") { l=[] l.concat @amqp.constants.map { |c| "#{c.name.shout}=#{c.value}" } @@ -23,53 +43,137 @@ class ConstantsGen < CppGen } genl l.join(",\n") } - define_constants_for(@amqp.domain("segment-type").enum) - namespace("execution") { - define_constants_for(@amqp.class_("execution").domain("error-code").enum) + } + } + end + + def typecode_enum(t) "TYPE_CODE_#{t.name.shout}" end + + def typecode_h_cpp + path="#{@dir}/TypeCode" + public_api(path+".h") + h_file(path) { + include("") + include("\"qpid/sys/IntegerTypes.h\"") + namespace(@namespace) { + scope("enum TypeCode {", "};") { + genl @amqp.types.map { |t| "#{typecode_enum t} = #{t.code}" if t.code }.compact.join(",\n") } - namespace("connection") { - define_constants_for(@amqp.class_("connection").domain("close-code").enum) + genl <") + namespace(@namespace) { + scope("const char* typeName(TypeCode t) {") { + scope("switch (t) {") { + @amqp.types.each { |t| genl "case #{typecode_enum t}: return \"#{t.name}\";" if t.code } + genl "default: break;" + } + genl "return 0;"; } - namespace("session") { - define_constants_for(@amqp.class_("session").domain("detach-code").enum) + genl <" include "" namespace("qpid::framing") { - scope("void throwExecutionException(int code, const std::string& text) {"){ - genl "sys::ExceptionHolder h;" - genl "setExecutionException(h, code, text);" - genl "h.raise();" - } - scope("void setExecutionException(sys::ExceptionHolder& holder, int code, const std::string& text) {"){ - scope("switch (code) {") { - enum = @amqp.class_("execution").domain("error-code").enum - enum.choices.each { |c| - genl "case #{c.value}: holder = new #{c.name.caps}Exception(text); break;" - } - genl 'default: assert(0);' - genl ' holder = new InvalidArgumentException(QPID_MSG("Bad exception code: " << code << ": " << text));' - } - } + create_exception("execution", "error-code", "SessionException", "InvalidArgumentException") + # FIXME aconway 2008-10-07: there are no good exception codes in 0-10 for an invalid code. + # The following choices are arbitrary. + create_exception("connection", "close-code", "ConnectionException", "FramingErrorException") + create_exception("session", "detach-code", "ChannelException", "NotAttachedException") } } end def generate() constants_h + enum_h reply_exceptions_h reply_exceptions_cpp + typecode_h_cpp end end diff --git a/cpp/rubygen/framing.0-10/frame_body_lists.rb b/cpp/rubygen/framing.0-10/frame_body_lists.rb index b20e4550f3..4f1b976032 100644 --- a/cpp/rubygen/framing.0-10/frame_body_lists.rb +++ b/cpp/rubygen/framing.0-10/frame_body_lists.rb @@ -1,3 +1,21 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 .. in load path require 'cppgen' @@ -26,6 +44,6 @@ EOS end end -FrameBodyListsGen.new(ARGV[0], $amqp).generate; +FrameBodyListsGen.new($outdir, $amqp).generate; diff --git a/cpp/rubygen/framing.0-10/structs.rb b/cpp/rubygen/framing.0-10/structs.rb old mode 100644 new mode 100755 index e4d57ca75d..c3684aea66 --- a/cpp/rubygen/framing.0-10/structs.rb +++ b/cpp/rubygen/framing.0-10/structs.rb @@ -1,4 +1,22 @@ #!/usr/bin/env ruby +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# # Usage: output_directory xml_spec_file [xml_spec_file...] # $: << '..' @@ -26,6 +44,12 @@ class StructGen < CppGen "timestamp"=>8 } + StringSizeMap={ + "LongString"=>4, + "MediumString"=>2, + "ShortString"=>1 + } + SizeType={ 1=>"Octet", 2=>"Short", @@ -153,13 +177,10 @@ class StructGen < CppGen genl "total += #{size};//#{f.cppname}" elsif (f.cpptype.name == "SequenceNumberSet") genl "total += #{f.cppname}.encodedSize();" - else - encoded = f.cpptype.encoded - gen "total += (" - gen "4 + " if encoded == "LongString" - gen "2 + " if encoded == "MediumString" - gen "1 + " if encoded == "ShortString" - genl "#{f.cppname}.size());" + elsif (size = StringSizeMap[f.cpptype.encoded]) + genl "total += #{size} + #{f.cppname}.size();" + else + genl "total += #{f.cppname}.encodedSize();" end end end @@ -212,6 +233,7 @@ class StructGen < CppGen using AMQMethodBody::accept; void accept(MethodBodyConstVisitor& v) const { v.visit(*this); } + boost::intrusive_ptr clone() const { return BodyFactory::copy(*this); } ClassId amqpClassId() const { return CLASS_ID; } MethodId amqpMethodId() const { return METHOD_ID; } @@ -329,15 +351,15 @@ EOS end def declare_packed_accessors(f) - genl "void set#{f.name.caps}(#{f.cpptype.param} _#{f.cppname});"; - genl "#{f.cpptype.ret} get#{f.name.caps}() const;" + genl "QPID_COMMON_EXTERN void set#{f.name.caps}(#{f.cpptype.param} _#{f.cppname});"; + genl "QPID_COMMON_EXTERN #{f.cpptype.ret} get#{f.name.caps}() const;" if (f.cpptype.name == "FieldTable") - genl "#{f.cpptype.name}& get#{f.name.caps}();" + genl "QPID_COMMON_EXTERN #{f.cpptype.name}& get#{f.name.caps}();" end if (f.type_ != "bit") #extra 'accessors' for packed fields: - genl "bool has#{f.name.caps}() const;" - genl "void clear#{f.name.caps}Flag();" + genl "QPID_COMMON_EXTERN bool has#{f.name.caps}() const;" + genl "QPID_COMMON_EXTERN void clear#{f.name.caps}Flag();" end end @@ -359,9 +381,11 @@ EOS else inheritance = ": public AMQMethodBody" end + else + public_api("qpid/framing/#{classname}.h") # Non-method structs are public end - h_file("qpid/framing/#{classname}.h") { + h_file("qpid/framing/#{classname}.h") { if (s.kind_of? AmqpMethod) gen < #include "qpid/framing/amqp_types_full.h" +#include "qpid/CommonImportExport.h" namespace qpid { namespace framing { @@ -416,17 +441,17 @@ EOS methodbody_extra_defs(s) end if (s.kind_of? AmqpStruct) - indent {genl "friend std::ostream& operator<<(std::ostream&, const #{classname}&);" } + indent {genl "QPID_COMMON_EXTERN friend std::ostream& operator<<(std::ostream&, const #{classname}&);" } end gen <