You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by gs...@apache.org on 2007/09/10 20:37:36 UTC

svn commit: r574323 - in /incubator/qpid/trunk/qpid/cpp: rubygen/cppgen.rb rubygen/templates/Session.rb src/qpid/client/ClientChannel.cpp src/tests/ClientSessionTest.cpp

Author: gsim
Date: Mon Sep 10 11:37:36 2007
New Revision: 574323

URL: http://svn.apache.org/viewvc?rev=574323&view=rev
Log:
Support for keyword args in session interface


Modified:
    incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb
    incubator/qpid/trunk/qpid/cpp/rubygen/templates/Session.rb
    incubator/qpid/trunk/qpid/cpp/src/qpid/client/ClientChannel.cpp
    incubator/qpid/trunk/qpid/cpp/src/tests/ClientSessionTest.cpp

Modified: incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb?rev=574323&r1=574322&r2=574323&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb Mon Sep 10 11:37:36 2007
@@ -68,6 +68,7 @@
   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 @@
     end
   end
 
+  def default_value()
+    return @defval ||= "#{name}()"
+  end
+
   def to_s() name; end;
 end
 
@@ -107,12 +112,12 @@
 
 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"),

Modified: incubator/qpid/trunk/qpid/cpp/rubygen/templates/Session.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/templates/Session.rb?rev=574323&r1=574322&r2=574323&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/templates/Session.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/templates/Session.rb Mon Sep 10 11:37:36 2007
@@ -23,29 +23,71 @@
   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 @@
     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 @@
     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::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 @@
     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

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/client/ClientChannel.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/client/ClientChannel.cpp?rev=574323&r1=574322&r2=574323&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/client/ClientChannel.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/client/ClientChannel.cpp Mon Sep 10 11:37:36 2007
@@ -80,7 +80,7 @@
 }
 
 void Channel::setQos() {
-    session.basicQos(0, getPrefetch(), false);
+    session.basicQos((prefetchCount=getPrefetch(), global=false));
     if(isTransactional()) {
         //I think this is wrong! should only send TxSelect once...
         session.txSelect();
@@ -92,34 +92,32 @@
     setQos();
 }
 
-void Channel::declareExchange(Exchange& exchange, bool synch){
-    FieldTable args;
+void Channel::declareExchange(Exchange& _exchange, bool synch){
     ScopedSync s(session, synch);
-    session.exchangeDeclare(0, exchange.getName(), exchange.getType(), empty, false, false, false, args);
+    session.exchangeDeclare((exchange=_exchange.getName(), type=_exchange.getType()));
 }
 
-void Channel::deleteExchange(Exchange& exchange, bool synch){
+void Channel::deleteExchange(Exchange& _exchange, bool synch){
     ScopedSync s(session, synch);
-    session.exchangeDelete(0, exchange.getName(), false);
+    session.exchangeDelete((exchange=_exchange.getName(), ifUnused=false));
 }
 
-void Channel::declareQueue(Queue& queue, bool synch){
-    if (queue.getName().empty()) {
+void Channel::declareQueue(Queue& _queue, bool synch){
+    if (_queue.getName().empty()) {
         stringstream uniqueName;
         uniqueName << uniqueId << "-queue-" << ++nameCounter;
-        queue.setName(uniqueName.str());
+        _queue.setName(uniqueName.str());
     }
 
-    FieldTable args;
     ScopedSync s(session, synch);
-    session.queueDeclare(0, queue.getName(), empty, false/*passive*/, queue.isDurable(),
-                          queue.isExclusive(), queue.isAutoDelete(), args);
+    session.queueDeclare((queue=_queue.getName(), passive=false/*passive*/, durable=_queue.isDurable(),
+                              exclusive=_queue.isExclusive(), autoDelete=_queue.isAutoDelete()));
     
 }
 
-void Channel::deleteQueue(Queue& queue, bool ifunused, bool ifempty, bool synch){
+void Channel::deleteQueue(Queue& _queue, bool ifunused, bool ifempty, bool synch){
     ScopedSync s(session, synch);
-    session.queueDelete(0, queue.getName(), ifunused, ifempty);
+    session.queueDelete((queue=_queue.getName(), ifUnused=ifunused, ifEmpty=ifempty));
 }
 
 void Channel::bind(const Exchange& exchange, const Queue& queue, const std::string& key, const FieldTable& args, bool synch){

Modified: incubator/qpid/trunk/qpid/cpp/src/tests/ClientSessionTest.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/tests/ClientSessionTest.cpp?rev=574323&r1=574322&r2=574323&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/tests/ClientSessionTest.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/tests/ClientSessionTest.cpp Mon Sep 10 11:37:36 2007
@@ -50,7 +50,7 @@
     {
         std::string name("my-queue");
         std::string alternate("amq.fanout");
-        session.queueDeclare(0, name, alternate, false, false, true, true, FieldTable());
+        session.queueDeclare((queue=name, alternateExchange=alternate, exclusive=true, autoDelete=true));
         TypedResult<QueueQueryResult> result = session.queueQuery(name);
         CPPUNIT_ASSERT_EQUAL(false, result.get().getDurable());
         CPPUNIT_ASSERT_EQUAL(true, result.get().getExclusive());
@@ -59,16 +59,16 @@
 
     void testTransfer()
     {
-        std::string queue("my-queue");
+        std::string queueName("my-queue");
         std::string dest("my-dest");
         std::string data("my message");
-        session.queueDeclare(0, queue, "", false, false, true, true, FieldTable());
+        session.queueDeclare_(queue=queueName, exclusive=true, autoDelete=true);
         //subcribe to the queue with confirm_mode = 1:
-        session.messageSubscribe(0, queue, dest, false, 1, 0, false, FieldTable());
+        session.messageSubscribe_(queue=queueName, destination=dest, acquireMode=1);
         //publish a message:
-        TransferContent content(data);
-        content.getDeliveryProperties().setRoutingKey("my-queue");
-        session.messageTransfer(0, "", 0, 0, content);
+        TransferContent _content(data);
+        _content.getDeliveryProperties().setRoutingKey("my-queue");
+        session.messageTransfer_(content=_content);
         //get & test the message:
         FrameSet::shared_ptr msg = session.get();
         CPPUNIT_ASSERT(msg->isA<MessageTransferBody>());