summaryrefslogtreecommitdiff
path: root/cpp/rubygen
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/rubygen')
-rwxr-xr-xcpp/rubygen/cppgen.rb17
-rw-r--r--cpp/rubygen/templates/Session.rb80
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