diff options
Diffstat (limited to 'cpp/rubygen')
-rwxr-xr-x | cpp/rubygen/cppgen.rb | 17 | ||||
-rw-r--r-- | cpp/rubygen/templates/Session.rb | 80 |
2 files changed, 82 insertions, 15 deletions
diff --git a/cpp/rubygen/cppgen.rb b/cpp/rubygen/cppgen.rb index c6f06e80c7..0de448869d 100755 --- a/cpp/rubygen/cppgen.rb +++ b/cpp/rubygen/cppgen.rb @@ -68,6 +68,7 @@ class CppType def retcref() @ret="const #{name}&"; self; end def passcref() @param="const #{name}&"; self; end def code(str) @code=str; self; end + def defval(str) @defval=str; self; end def encode(value, buffer) @code ? "#{buffer}.put#{@code}(#{value});" : "#{value}.encode(#{buffer});" @@ -85,6 +86,10 @@ class CppType end end + def default_value() + return @defval ||= "#{name}()" + end + def to_s() name; end; end @@ -107,12 +112,12 @@ end class AmqpDomain @@typemap = { - "bit"=> CppType.new("bool").code("Octet"), - "octet"=>CppType.new("uint8_t").code("Octet"), - "short"=>CppType.new("uint16_t").code("Short"), - "long"=>CppType.new("uint32_t").code("Long"), - "longlong"=>CppType.new("uint64_t").code("LongLong"), - "timestamp"=>CppType.new("uint64_t").code("LongLong"), + "bit"=> CppType.new("bool").code("Octet").defval("false"), + "octet"=>CppType.new("uint8_t").code("Octet").defval("0"), + "short"=>CppType.new("uint16_t").code("Short").defval("0"), + "long"=>CppType.new("uint32_t").code("Long").defval("0"), + "longlong"=>CppType.new("uint64_t").code("LongLong").defval("0"), + "timestamp"=>CppType.new("uint64_t").code("LongLong").defval("0"), "longstr"=>CppType.new("string").passcref.retcref.code("LongString"), "shortstr"=>CppType.new("string").passcref.retcref.code("ShortString"), "table"=>CppType.new("FieldTable").passcref.retcref.code("FieldTable"), diff --git a/cpp/rubygen/templates/Session.rb b/cpp/rubygen/templates/Session.rb index 4cea9f9665..b2932f9a2b 100644 --- a/cpp/rubygen/templates/Session.rb +++ b/cpp/rubygen/templates/Session.rb @@ -23,29 +23,71 @@ class SessionGen < CppGen end def declare_method (m) - gen "#{return_type(m)} #{m.parent.name.lcaps}#{m.name.caps}(" + param_unpackers = m.fields.collect { |f| "args[#{f.cppname}|#{f.cpptype.default_value}]" } if (m.content()) + param_names = m.param_names + ["content"] + param_unpackers << "args[content|DefaultContent(\"\")]" params=m.signature + ["const MethodContent& content"] else + param_names = m.param_names params=m.signature end - indent { gen params.join(",\n") } - gen ");\n\n" - end - def declare_class(c) - c.methods_on(@chassis).each { |m| declare_method(m) } + if (params.empty?) + gen "#{return_type(m)} #{m.parent.name.lcaps}#{m.name.caps}();\n\n" + else + genl "template <class ArgumentPack> #{return_type(m)} #{m.parent.name.lcaps}#{m.name.caps}(ArgumentPack const& args)" + genl "{" + indent { + genl "return #{m.parent.name.lcaps}#{m.name.caps}(#{param_unpackers.join(",\n")});" + } + genl "}" + + #generate the 'real' methods signature + gen "#{return_type(m)} #{m.parent.name.lcaps}#{m.name.caps}(" + indent { gen params.join(",\n") } + gen ");\n\n" + + #generate some overloaded methods to handle keyword args + boost_max_arity = 8 + if param_names.length > boost_max_arity + keywords = param_names[1..boost_max_arity].collect { |p| "keyword::#{p}" } + else + keywords = param_names.collect { |p| "keyword::#{p}" } + end + genl "typedef boost::parameter::parameters< #{keywords.join(",")} > #{m.parent.name.caps}#{m.name.caps}Params;\n" + + j = 1 + while j <= params.length && j <= boost_max_arity + dummy_args = Array.new(j) { |i| "P#{i} const& p#{i}"} + dummy_names = Array.new(j) { |i| "p#{i}"} + dummy_types = Array.new(j) { |i| "class P#{i}"} + + genl "template <#{dummy_types.join(',')}> #{return_type(m)} #{m.parent.name.lcaps}#{m.name.caps}_(#{dummy_args.join(',')})" + genl "{" + indent { + genl "return #{m.parent.name.lcaps}#{m.name.caps}(#{m.parent.name.caps}#{m.name.caps}Params()(#{dummy_names.join(',')}));" + } + genl "}" + j = j + 1 + end + end + end def define_method (m) - gen "#{return_type(m)} Session::#{m.parent.name.lcaps}#{m.name.caps}(" if (m.content()) params=m.signature + ["const MethodContent& content"] else params=m.signature end - indent { gen params.join(",\n") } - gen "){\n\n" + if (params.empty?) + gen "#{return_type(m)} Session::#{m.parent.name.lcaps}#{m.name.caps}(){\n\n" + else + gen "#{return_type(m)} Session::#{m.parent.name.lcaps}#{m.name.caps}(" + indent { gen params.join(",\n") } + gen "){\n\n" + end indent (2) { gen "return #{return_type(m)}(impl()->send(#{m.body_name}(" params = ["version"] + m.param_names @@ -60,6 +102,17 @@ class SessionGen < CppGen gen "}\n\n" end + def declare_keywords(classes) + #need to assemble a listof all the field names + keywords = classes.collect { |c| c.methods_on(@chassis).collect { |m| m.param_names } }.flatten().uniq() + keywords.each { |k| genl "BOOST_PARAMETER_KEYWORD(keyword, #{k})" } + genl "BOOST_PARAMETER_KEYWORD(keyword, content)" + end + + def declare_class(c) + c.methods_on(@chassis).each { |m| declare_method(m) } + end + def define_class(c) c.methods_on(@chassis).each { |m| define_method(m) } end @@ -68,12 +121,16 @@ class SessionGen < CppGen excludes = ["channel", "connection", "session", "execution"] h_file("qpid/client/#{@classname}.h") { + genl "#define BOOST_PARAMETER_MAX_ARITY 8" + gen <<EOS #include <sstream> +#include <boost/parameter.hpp> #include "qpid/framing/amqp_framing.h" #include "qpid/framing/amqp_structs.h" #include "qpid/framing/ProtocolVersion.h" #include "qpid/framing/MethodContent.h" +#include "qpid/framing/TransferContent.h" #include "qpid/client/ConnectionImpl.h" #include "qpid/client/Response.h" #include "qpid/client/ScopedAssociation.h" @@ -88,6 +145,10 @@ using framing::FieldTable; using framing::MethodContent; using framing::SequenceNumberSet; +EOS + declare_keywords(@amqp.classes.select { |c| !excludes.include?(c.name) }) + genl + gen <<EOS class #{@classname} { ScopedAssociation::shared_ptr assoc; framing::ProtocolVersion version; @@ -103,6 +164,7 @@ public: void close(); Execution& execution() { return impl()->getExecution(); } + typedef framing::TransferContent DefaultContent; EOS indent { @amqp.classes.each { |c| declare_class(c) if !excludes.include?(c.name) } } gen <<EOS |