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/27 18:50:27 UTC

svn commit: r580094 - in /incubator/qpid/trunk/qpid/cpp: rubygen/amqpgen.rb rubygen/cppgen.rb rubygen/templates/structs.rb src/Makefile.am src/qpid/framing/ModelMethod.h

Author: gsim
Date: Thu Sep 27 09:50:25 2007
New Revision: 580094

URL: http://svn.apache.org/viewvc?rev=580094&view=rev
Log:
Some revisions to rubygen for packed structs and execution header (changes not yet enabled)


Added:
    incubator/qpid/trunk/qpid/cpp/src/qpid/framing/ModelMethod.h   (with props)
Modified:
    incubator/qpid/trunk/qpid/cpp/rubygen/amqpgen.rb
    incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb
    incubator/qpid/trunk/qpid/cpp/rubygen/templates/structs.rb
    incubator/qpid/trunk/qpid/cpp/src/Makefile.am

Modified: incubator/qpid/trunk/qpid/cpp/rubygen/amqpgen.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/amqpgen.rb?rev=580094&r1=580093&r2=580094&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/amqpgen.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/amqpgen.rb Thu Sep 27 09:50:25 2007
@@ -151,7 +151,7 @@
 
 class AmqpStruct < AmqpElement
   def initialize(xml, parent) super; end
-  amqp_attr_reader :size, :type
+  amqp_attr_reader :size, :type, :pack
   amqp_child_reader :field
   
   def result?() parent.xml.name == "result"; end
@@ -180,6 +180,10 @@
   def methods_on(chassis)
     @methods_on ||= { }
     @methods_on[chassis] ||= methods_.select { |m| m.on_chassis? chassis }
+  end
+
+  def l4?()
+    !["connection", "session", "execution"].include?(name)
   end
 end
 

Modified: incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb?rev=580094&r1=580093&r2=580094&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb Thu Sep 27 09:50:25 2007
@@ -135,6 +135,10 @@
       CppType.new(d.cppname).passcref.retcref or
       raise "Invalid type #{self}"
   end
+
+  def AmqpDomain.lookup_type(t)
+    @@typemap[t]
+  end
 end
 
 class AmqpResult
@@ -144,6 +148,7 @@
 end
 
 class AmqpStruct
+  def cpp_pack_type() AmqpDomain.lookup_type(pack()) or CppType.new("uint16_t"); end
   def cpptype() parent.cpptype; end
   def cppname() cpptype.name;  end
 end

Modified: incubator/qpid/trunk/qpid/cpp/rubygen/templates/structs.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/templates/structs.rb?rev=580094&r1=580093&r2=580094&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/templates/structs.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/templates/structs.rb Thu Sep 27 09:50:25 2007
@@ -32,6 +32,18 @@
 
   ValueTypes=["octet", "short", "long", "longlong", "timestamp"]
 
+  def is_packed(s)
+    false and s.kind_of? AmqpStruct and s.pack
+  end
+
+  def execution_header?(s)
+    false and s.kind_of? AmqpMethod and s.parent.l4?
+  end
+
+  def has_bitfields_only(s)
+    s.fields.select {|f| f.domain.type_ != "bit"}.empty?
+  end
+
   def default_initialisation(s)
     params = s.fields.select {|f| ValueTypes.include?(f.domain.type_) || f.domain.type_ == "bit"}
     strings = params.collect {|f| "#{f.cppname}(0)"}   
@@ -50,6 +62,57 @@
     end
   end
 
+  def get_flags_impl(s)
+    genl "#{s.cpp_pack_type.name} flags = 0;"
+    process_packed_fields(s) { |f, i| set_field_flag(f, i) }
+    genl "return flags;"
+  end
+
+  def set_field_flag(f, i)
+    if (ValueTypes.include?(f.domain.type_) || f.domain.type_ == "bit")
+      genl "if (#{f.cppname}) flags |= (1 << #{i});"
+    else
+      genl "if (#{f.cppname}.size()) flags |= (1 << #{i});"
+    end
+  end
+
+  def encode_packed_struct(s)
+    genl "#{s.cpp_pack_type.name} flags = getFlags();"
+    genl s.cpp_pack_type.encode('flags', 'buffer')
+    process_packed_fields(s) { |f, i| encode_packed_field(f, i) unless f.domain.type_ == "bit" }
+  end
+
+  def decode_packed_struct(s)
+    genl "#{s.cpp_pack_type.name} #{s.cpp_pack_type.decode('flags', 'buffer')}"
+    process_packed_fields(s) { |f, i| decode_packed_field(f, i) unless f.domain.type_ == "bit" }
+    process_packed_fields(s) { |f, i| set_bitfield(f, i) if f.domain.type_ == "bit" }
+  end
+
+  def size_packed_struct(s)
+    genl "#{s.cpp_pack_type.name} flags = getFlags();" unless has_bitfields_only(s)
+    genl "total += #{SizeMap[s.pack]};"
+    process_packed_fields(s) { |f, i| size_packed_field(f, i) unless f.domain.type_ == "bit" }
+  end
+
+  def encode_packed_field(f, i)
+    genl "if (flags & (1 << #{i}))"
+    indent { genl f.domain.cpptype.encode(f.cppname,"buffer") }
+  end
+
+  def decode_packed_field(f, i)
+    genl "if (flags & (1 << #{i}))"
+    indent { genl f.domain.cpptype.decode(f.cppname,"buffer") }
+  end
+
+  def size_packed_field(f, i)
+      genl "if (flags & (1 << #{i}))"
+      indent { generate_size(f, []) }
+  end
+
+  def set_bitfield(f, i)
+    genl "#{f.cppname} = (flags & (1 << #{i}));"
+  end
+
   def generate_encode(f, combined)
     if (f.domain.type_ == "bit")
       genl "uint8_t #{f.cppname}_bits = #{f.cppname};"
@@ -75,22 +138,27 @@
   def generate_size(f, combined)
     if (f.domain.type_ == "bit")
       names = ([f] + combined).collect {|g| g.cppname}
-      genl "+ 1 //#{names.join(", ")}"
+      genl "total += 1;//#{names.join(", ")}"
     else
       size = SizeMap[f.domain.type_]
       if (size)
-        genl "+ #{size} //#{f.cppname}"
+        genl "total += #{size};//#{f.cppname}"
       elsif (f.cpptype.name == "SequenceNumberSet")
-        genl "+ #{f.cppname}.encodedSize()"
+        genl "total += #{f.cppname}.encodedSize();"
       else 
         encoded = EncodingMap[f.domain.type_]        
-        gen "+ 4 " if encoded == "LongString"
-        gen "+ 1 " if encoded == "ShortString"
-        genl "+ #{f.cppname}.size()"
+        gen "total += ("
+        gen "4 " if encoded == "LongString"
+        gen "1 " if encoded == "ShortString"
+        genl "+ #{f.cppname}.size());"
       end
     end
   end
 
+  def process_packed_fields(s)
+    s.fields.each { |f| yield f, s.fields.index(f) }
+  end
+
   def process_fields(s)
     last = nil
     count = 0  
@@ -162,7 +230,11 @@
     inheritance = ""
     if (s.kind_of? AmqpMethod)
       classname = s.body_name
-      inheritance = ": public AMQMethodBody"
+      if (execution_header?(s))
+        inheritance = ": public ModelMethod"
+      else
+        inheritance = ": public AMQMethodBody"
+      end
     end
 
     h_file("qpid/framing/#{classname}.h") { 
@@ -173,6 +245,7 @@
 #include "qpid/framing/MethodBodyConstVisitor.h"
 EOS
       end
+      include "qpid/framing/ModelMethod.h" if (execution_header?(s))
 
       #need to include any nested struct definitions
       s.fields.each { |f| include f.cpptype.name if f.domain.struct }
@@ -188,6 +261,9 @@
 class #{classname} #{inheritance} {
 EOS
   indent { s.fields.each { |f| genl "#{f.cpptype.name} #{f.cppname};" } }
+  if (is_packed(s))
+    indent { genl "#{s.cpp_pack_type.name} getFlags() const;"}
+  end
   genl "public:"
   if (s.kind_of? AmqpMethod)
     indent { genl "static const ClassId CLASS_ID = #{s.parent.index};" }
@@ -231,7 +307,7 @@
 EOS
     }
     cpp_file("qpid/framing/#{classname}.cpp") { 
-      if (s.fields.size > 0)
+      if (s.fields.size > 0 || execution_header?(s))
         buffer = "buffer"
       else
         buffer = "/*buffer*/"
@@ -241,46 +317,79 @@
 
 using namespace qpid::framing;
 
+EOS
+    
+      if (is_packed(s))
+        genl "#{s.cpp_pack_type.name} #{classname}::getFlags() const"
+        genl "{"
+        indent { get_flags_impl(s) }
+        genl "}"
+      end
+      gen <<EOS
 void #{classname}::encode(Buffer& #{buffer}) const
 {
 EOS
-  indent { process_fields(s) { |f, combined| generate_encode(f, combined) } } 
-  gen <<EOS
+      if (execution_header?(s))
+        genl "ModelMethod::encode(buffer);"
+      end
+
+      if (is_packed(s))
+        indent {encode_packed_struct(s)}
+      else 
+        indent { process_fields(s) { |f, combined| generate_encode(f, combined) } } 
+      end
+      gen <<EOS
 }
 
 void #{classname}::decode(Buffer& #{buffer}, uint32_t /*size*/)
 {
 EOS
-  indent { process_fields(s) { |f, combined| generate_decode(f, combined) } } 
-  gen <<EOS
+      if (execution_header?(s))
+        genl "ModelMethod::decode(buffer);"
+      end
+
+      if (is_packed(s))
+        indent {decode_packed_struct(s)}
+      else 
+        indent { process_fields(s) { |f, combined| generate_decode(f, combined) } } 
+      end
+      gen <<EOS
 }
 
 uint32_t #{classname}::size() const
 {
-    return 0
+    uint32_t total = 0;
 EOS
-  indent { process_fields(s) { |f, combined| generate_size(f, combined) } } 
-  gen <<EOS
-        ;
+      if (execution_header?(s))
+        genl "total += ModelMethod::size();"
+      end
+
+      if (is_packed(s))
+        indent {size_packed_struct(s)}
+      else 
+        indent { process_fields(s) { |f, combined| generate_size(f, combined) } } 
+      end
+      gen <<EOS
+    return total;
 }
 
 void #{classname}::print(std::ostream& out) const
 {
     out << "#{classname}: ";
 EOS
-  copy = Array.new(s.fields)
-  f = copy.shift
+      copy = Array.new(s.fields)
+      f = copy.shift
   
-  indent { 
-    genl "out << \"#{f.name}=\" << #{printable_form(f)};" if f
-    copy.each { |f| genl "out << \"; #{f.name}=\" << #{printable_form(f)};" } 
-  } 
-  gen <<EOS
+      indent { 
+        genl "out << \"#{f.name}=\" << #{printable_form(f)};" if f
+        copy.each { |f| genl "out << \"; #{f.name}=\" << #{printable_form(f)};" } 
+      } 
+      gen <<EOS
 }
 EOS
 
-  if (s.kind_of? AmqpStruct)
-    gen <<EOS
+      if (s.kind_of? AmqpStruct)
+        gen <<EOS
 namespace qpid{
 namespace framing{
 
@@ -293,8 +402,7 @@
 }
 }
 EOS
-  end 
-
+      end 
 }
   end
 

Modified: incubator/qpid/trunk/qpid/cpp/src/Makefile.am
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/Makefile.am?rev=580094&r1=580093&r2=580094&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/Makefile.am (original)
+++ incubator/qpid/trunk/qpid/cpp/src/Makefile.am Thu Sep 27 09:50:25 2007
@@ -343,6 +343,7 @@
   qpid/framing/MethodContent.h \
   qpid/framing/MethodHolder.h \
   qpid/framing/MethodHolderMaxSize.h \
+  qpid/framing/ModelMethod.h \
   qpid/framing/OutputHandler.h \
   qpid/framing/ProtocolInitiation.h \
   qpid/framing/ProtocolVersion.h \

Added: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/ModelMethod.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/framing/ModelMethod.h?rev=580094&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/framing/ModelMethod.h (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/framing/ModelMethod.h Thu Sep 27 09:50:25 2007
@@ -0,0 +1,48 @@
+#ifndef _ModelMethod_
+#define _ModelMethod_
+
+/*
+ *
+ * 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 "AMQMethodBody.h"
+#include "qpid/framing/ExecutionHeader.h"
+
+namespace qpid {
+namespace framing {
+
+
+class ModelMethod : public AMQMethodBody 
+{
+    ExecutionHeader header;
+public:    
+    virtual ~ModelMethod() {}
+    virtual void encode(Buffer& buffer) const { header.encode(buffer); }
+    virtual void decode(Buffer& buffer, uint32_t size=0) { header.decode(buffer, size); }
+    virtual uint32_t size() const { return header.size(); } 
+
+    ExecutionHeader& getHeader() { return header; } 
+    const ExecutionHeader& getHeader()  const { return header; } 
+};
+
+
+}} // namespace qpid::framing
+
+
+#endif

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/ModelMethod.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/ModelMethod.h
------------------------------------------------------------------------------
    svn:keywords = Rev Date