You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2017/12/13 20:37:01 UTC

[2/9] qpid-proton git commit: PROTON-1537: [ruby] Simplified SWIG wrappers, use pn_inspect

PROTON-1537: [ruby] Simplified SWIG wrappers, use pn_inspect

Use pn_inspect as default inspect/to_s for all wrapped proton types.
Removed existing special case code to do the same thing.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/889c0c6d
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/889c0c6d
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/889c0c6d

Branch: refs/heads/master
Commit: 889c0c6d1a3dec98a2d6e908392d6b6e20582c85
Parents: 3649b60
Author: Alan Conway <ac...@redhat.com>
Authored: Wed Dec 6 16:30:39 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Wed Dec 13 13:16:47 2017 -0500

----------------------------------------------------------------------
 proton-c/bindings/ruby/lib/codec/data.rb       | 1637 +++++++++----------
 proton-c/bindings/ruby/lib/codec/mapping.rb    |    7 +-
 proton-c/bindings/ruby/lib/core/connection.rb  |   16 +-
 proton-c/bindings/ruby/lib/core/disposition.rb |   20 +-
 proton-c/bindings/ruby/lib/core/event.rb       |    3 +-
 proton-c/bindings/ruby/lib/core/link.rb        |   20 +-
 proton-c/bindings/ruby/lib/core/message.rb     |   28 +-
 proton-c/bindings/ruby/lib/core/receiver.rb    |    7 +-
 proton-c/bindings/ruby/lib/core/sasl.rb        |    6 +-
 proton-c/bindings/ruby/lib/core/session.rb     |   12 +-
 proton-c/bindings/ruby/lib/core/ssl.rb         |    6 +-
 proton-c/bindings/ruby/lib/core/terminus.rb    |   19 +-
 proton-c/bindings/ruby/lib/core/transfer.rb    |    6 +-
 proton-c/bindings/ruby/lib/core/transport.rb   |   26 +-
 proton-c/bindings/ruby/lib/qpid_proton.rb      |    1 -
 proton-c/bindings/ruby/lib/util/swig_helper.rb |  113 --
 proton-c/bindings/ruby/lib/util/wrapper.rb     |   95 +-
 17 files changed, 947 insertions(+), 1075 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/codec/data.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/codec/data.rb b/proton-c/bindings/ruby/lib/codec/data.rb
index f287d64..9814836 100644
--- a/proton-c/bindings/ruby/lib/codec/data.rb
+++ b/proton-c/bindings/ruby/lib/codec/data.rb
@@ -16,905 +16,898 @@
 # under the License.
 
 
-module Qpid::Proton::Codec
-
-  # +DataError+ is raised when an error occurs while encoding
-  # or decoding data.
-  class DataError < Exception; end
-
-  # The +Data+ class provides an interface for decoding, extracting,
-  # creating, and encoding arbitrary AMQP data. A +Data+ object
-  # contains a tree of AMQP values. Leaf nodes in this tree correspond
-  # to scalars in the AMQP type system such as INT or STRING. Interior
-  # nodes in this tree correspond to compound values in the AMQP type
-  # system such as *LIST*,*MAP*, *ARRAY*, or *DESCRIBED*. The root node
-  # of the tree is the +Data+ object itself and can have an arbitrary
-  # number of children.
-  #
-  # A +Data+ object maintains the notion of the current sibling node
-  # and a current parent node. Siblings are ordered within their parent.
-  # Values are accessed and/or added by using the #next, #prev,
-  # #enter, and #exit methods to navigate to the desired location in
-  # the tree and using the supplied variety of mutator and accessor
-  # methods to access or add a value of the desired type.
-  #
-  # The mutator methods will always add a value _after_ the current node
-  # in the tree. If the current node has a next sibling the mutator method
-  # will overwrite the value on this node. If there is no current node
-  # or the current node has no next sibling then one will be added. The
-  # accessor methods always set the added/modified node to the current
-  # node. The accessor methods read the value of the current node and do
-  # not change which node is current.
-  #
-  # The following types of scalar values are supported:
-  #
-  # * NULL
-  # * BOOL
-  # * UBYTE
-  # * BYTE
-  # * USHORT
-  # * SHORT
-  # * UINT
-  # * INT
-  # * CHAR
-  # * ULONG
-  # * LONG
-  # * TIMESTAMP
-  # * FLOAT
-  # * DOUBLE
-  # * DECIMAL32
-  # * DECIMAL64
-  # * DECIMAL128
-  # * UUID
-  # * BINARY
-  # * STRING
-  # * SYMBOL
-  #
-  # The following types of compound values are supported:
-  #
-  # * DESCRIBED
-  # * ARRAY
-  # * LIST
-  # * MAP
-  #
-  class Data
-
-    private
-
-    # Rewind and convert a pn_data_t* containing a single value to a ruby object.
-    def self.to_object(impl) Data.new(impl).rewind.object; end
-    # Clear a pn_data_t* and convert a ruby object into it.
-    def self.from_object(impl, x) Data.new(impl).clear.object = x; end
-
-    public
-
-    # TODO aconway 2017-12-05: confusing: use Data.new(cap) for making a
-    # brand new data object only, add Data.wrap(impl) to wrap existing data object.
-
-    # Creates a new instance.
-    # @param capacity [Integer] capacity for the new data instance.
-    def initialize(capacity = 16)
-      if capacity.is_a?(Integer)
-        @data = Cproton.pn_data(capacity.to_i)
-        @free = true
-      else
-        # Assume non-integer capacity is a SWIG::pn_data_t*
-        @data = capacity
-        @free = false
-      end
-
-      # destructor
-      ObjectSpace.define_finalizer(self, self.class.finalize!(@data, @free))
-    end
+module Qpid::Proton module Codec
+
+    # +DataError+ is raised when an error occurs while encoding
+    # or decoding data.
+    class DataError < Exception; end
+
+    # The +Data+ class provides an interface for decoding, extracting,
+    # creating, and encoding arbitrary AMQP data. A +Data+ object
+    # contains a tree of AMQP values. Leaf nodes in this tree correspond
+    # to scalars in the AMQP type system such as INT or STRING. Interior
+    # nodes in this tree correspond to compound values in the AMQP type
+    # system such as *LIST*,*MAP*, *ARRAY*, or *DESCRIBED*. The root node
+    # of the tree is the +Data+ object itself and can have an arbitrary
+    # number of children.
+    #
+    # A +Data+ object maintains the notion of the current sibling node
+    # and a current parent node. Siblings are ordered within their parent.
+    # Values are accessed and/or added by using the #next, #prev,
+    # #enter, and #exit methods to navigate to the desired location in
+    # the tree and using the supplied variety of mutator and accessor
+    # methods to access or add a value of the desired type.
+    #
+    # The mutator methods will always add a value _after_ the current node
+    # in the tree. If the current node has a next sibling the mutator method
+    # will overwrite the value on this node. If there is no current node
+    # or the current node has no next sibling then one will be added. The
+    # accessor methods always set the added/modified node to the current
+    # node. The accessor methods read the value of the current node and do
+    # not change which node is current.
+    #
+    # The following types of scalar values are supported:
+    #
+    # * NULL
+    # * BOOL
+    # * UBYTE
+    # * BYTE
+    # * USHORT
+    # * SHORT
+    # * UINT
+    # * INT
+    # * CHAR
+    # * ULONG
+    # * LONG
+    # * TIMESTAMP
+    # * FLOAT
+    # * DOUBLE
+    # * DECIMAL32
+    # * DECIMAL64
+    # * DECIMAL128
+    # * UUID
+    # * BINARY
+    # * STRING
+    # * SYMBOL
+    #
+    # The following types of compound values are supported:
+    #
+    # * DESCRIBED
+    # * ARRAY
+    # * LIST
+    # * MAP
+    #
+    class Data
+
+      # @private
+      PROTON_METHOD_PREFIX = "pn_disposition"
+      # @private
+      include Util::Wrapper
+
+      # Rewind and convert a pn_data_t* containing a single value to a ruby object.
+      def self.to_object(impl) Data.new(impl).rewind.object; end
+
+      # Clear a pn_data_t* and convert a ruby object into it.
+      def self.from_object(impl, x) Data.new(impl).clear.object = x; end
+
+      # @overload initialize(capacity)
+      #   @param capacity [Integer] capacity for the new data instance.
+      # @overload instance(impl)
+      #    @param impl [SWIG::pn_data_t*] wrap the C impl pointer.
+      def initialize(capacity = 16)
+        if capacity.is_a?(Integer)
+          @impl = Cproton.pn_data(capacity.to_i)
+          @free = true
+        else
+          # Assume non-integer capacity is a SWIG::pn_data_t*
+          @impl = capacity
+          @free = false
+        end
 
-    # @private
-    def self.finalize!(data, free)
-      proc {
-        Cproton.pn_data_free(data) if free
-      }
-    end
+        # destructor
+        ObjectSpace.define_finalizer(self, self.class.finalize!(@impl, @free))
+      end
 
-    # @private
-    def to_s
-      tmp = Cproton.pn_string("")
-      Cproton.pn_inspect(@data, tmp)
-      result = Cproton.pn_string_get(tmp)
-      Cproton.pn_free(tmp)
-      return result
-    end
+      # @private
+      def self.finalize!(impl, free)
+        proc {
+          Cproton.pn_data_free(impl) if free
+        }
+      end
 
-    # Clears the object.
-    #
-    def clear
-      Cproton.pn_data_clear(@data)
-      self
-    end
+      # Clears the object.
+      #
+      def clear
+        Cproton.pn_data_clear(@impl)
+        self
+      end
 
-    # Clears the current node and sets the parent to the root node.
-    #
-    # Clearing the current node sets it *before* the first node, calling
-    # #next will advance to the first node.
-    #
-    # @return self
-    def rewind
-      Cproton.pn_data_rewind(@data)
-      self
-    end
+      # Clears the current node and sets the parent to the root node.
+      #
+      # Clearing the current node sets it *before* the first node, calling
+      # #next will advance to the first node.
+      #
+      # @return self
+      def rewind
+        Cproton.pn_data_rewind(@impl)
+        self
+      end
 
-    # Advances the current node to its next sibling and returns its types.
-    #
-    # If there is no next sibling the current node remains unchanged
-    # and nil is returned.
-    #
-    def next
-      Cproton.pn_data_next(@data)
-    end
+      # Advances the current node to its next sibling and returns its types.
+      #
+      # If there is no next sibling the current node remains unchanged
+      # and nil is returned.
+      #
+      def next
+        Cproton.pn_data_next(@impl)
+      end
 
-    # Advances the current node to its previous sibling and returns its type.
-    #
-    # If there is no previous sibling then the current node remains unchanged
-    # and nil is return.
-    #
-    def prev
-      return Cproton.pn_data_prev(@data) ? type : nil
-    end
+      # Advances the current node to its previous sibling and returns its type.
+      #
+      # If there is no previous sibling then the current node remains unchanged
+      # and nil is return.
+      #
+      def prev
+        return Cproton.pn_data_prev(@impl) ? type : nil
+      end
 
-    # Sets the parent node to the current node and clears the current node.
-    #
-    # Clearing the current node sets it _before_ the first child.
-    #
-    def enter
-      Cproton.pn_data_enter(@data)
-    end
+      # Sets the parent node to the current node and clears the current node.
+      #
+      # Clearing the current node sets it _before_ the first child.
+      #
+      def enter
+        Cproton.pn_data_enter(@impl)
+      end
 
-    # Sets the current node to the parent node and the parent node to its own
-    # parent.
-    #
-    def exit
-      Cproton.pn_data_exit(@data)
-    end
+      # Sets the current node to the parent node and the parent node to its own
+      # parent.
+      #
+      def exit
+        Cproton.pn_data_exit(@impl)
+      end
 
-    # Returns the numeric type code of the current node.
-    #
-    # @return [Integer] The current node type.
-    # @return [nil] If there is no current node.
-    #
-    def type_code
-      dtype = Cproton.pn_data_type(@data)
-      return (dtype == -1) ? nil : dtype
-    end
+      # Returns the numeric type code of the current node.
+      #
+      # @return [Integer] The current node type.
+      # @return [nil] If there is no current node.
+      #
+      def type_code
+        dtype = Cproton.pn_data_type(@impl)
+        return (dtype == -1) ? nil : dtype
+      end
 
-    # @return [Integer] The type object for the current node.
-    # @see #type_code
-    #
-    def type
-      Mapping.for_code(type_code)
-    end
+      # @return [Integer] The type object for the current node.
+      # @see #type_code
+      #
+      def type
+        Mapping.for_code(type_code)
+      end
 
-    # Returns a representation of the data encoded in AMQP format.
-    #
-    # @return [String] The context of the Data as an AMQP data string.
-    #
-    # @example
-    #
-    #   @data.string = "This is a test."
-    #   @encoded = @data.encode
-    #
-    #   # @encoded now contains the text "This is a test." encoded for
-    #   # AMQP transport.
-    #
-    def encode
-      buffer = "\0"*1024
-      loop do
-        cd = Cproton.pn_data_encode(@data, buffer, buffer.length)
-        if cd == Cproton::PN_OVERFLOW
-          buffer *= 2
-        elsif cd >= 0
-          return buffer[0...cd]
-        else
-          check(cd)
+      # Returns a representation of the data encoded in AMQP format.
+      #
+      # @return [String] The context of the Data as an AMQP data string.
+      #
+      # @example
+      #
+      #   @impl.string = "This is a test."
+      #   @encoded = @impl.encode
+      #
+      #   # @encoded now contains the text "This is a test." encoded for
+      #   # AMQP transport.
+      #
+      def encode
+        buffer = "\0"*1024
+        loop do
+          cd = Cproton.pn_data_encode(@impl, buffer, buffer.length)
+          if cd == Cproton::PN_OVERFLOW
+            buffer *= 2
+          elsif cd >= 0
+            return buffer[0...cd]
+          else
+            check(cd)
+          end
         end
       end
-    end
 
-    # Decodes the first value from supplied AMQP data and returns the number
-    # of bytes consumed.
-    #
-    # @param encoded [String] The encoded data.
-    #
-    # @example
-    #
-    #   # SCENARIO: A string of encoded data, @encoded, contains the text
-    #   #           of "This is a test." and is passed to an instance of Data
-    #   #           for decoding.
-    #
-    #   @data.decode(@encoded)
-    #   @data.string #=> "This is a test."
-    #
-    def decode(encoded)
-      check(Cproton.pn_data_decode(@data, encoded, encoded.length))
-    end
+      # Decodes the first value from supplied AMQP data and returns the number
+      # of bytes consumed.
+      #
+      # @param encoded [String] The encoded data.
+      #
+      # @example
+      #
+      #   # SCENARIO: A string of encoded data, @encoded, contains the text
+      #   #           of "This is a test." and is passed to an instance of Data
+      #   #           for decoding.
+      #
+      #   @impl.decode(@encoded)
+      #   @impl.string #=> "This is a test."
+      #
+      def decode(encoded)
+        check(Cproton.pn_data_decode(@impl, encoded, encoded.length))
+      end
 
-    # Puts a list value.
-    #
-    # Elements may be filled by entering the list node and putting element
-    # values.
-    #
-    # @example
-    #
-    #   data = Qpid::Proton::Codec::Data.new
-    #   data.put_list
-    #   data.enter
-    #   data.int = 1
-    #   data.int = 2
-    #   data.int = 3
-    #   data.exit
-    #
-    def put_list
-      check(Cproton.pn_data_put_list(@data))
-    end
+      # Puts a list value.
+      #
+      # Elements may be filled by entering the list node and putting element
+      # values.
+      #
+      # @example
+      #
+      #   data = Qpid::Proton::Codec::Data.new
+      #   data.put_list
+      #   data.enter
+      #   data.int = 1
+      #   data.int = 2
+      #   data.int = 3
+      #   data.exit
+      #
+      def put_list
+        check(Cproton.pn_data_put_list(@impl))
+      end
 
-    # If the current node is a list, this returns the number of elements.
-    # Otherwise, it returns zero.
-    #
-    # List elements can be accessed by entering the list.
-    #
-    # @example
-    #
-    #   count = @data.list
-    #   @data.enter
-    #   (0...count).each
-    #     type = @data.next
-    #     puts "Value: #{@data.string}" if type == STRING
-    #     # ... process other node types
-    #   end
-    def list
-      Cproton.pn_data_get_list(@data)
-    end
+      # If the current node is a list, this returns the number of elements.
+      # Otherwise, it returns zero.
+      #
+      # List elements can be accessed by entering the list.
+      #
+      # @example
+      #
+      #   count = @impl.list
+      #   @impl.enter
+      #   (0...count).each
+      #     type = @impl.next
+      #     puts "Value: #{@impl.string}" if type == STRING
+      #     # ... process other node types
+      #   end
+      def list
+        Cproton.pn_data_get_list(@impl)
+      end
 
-    # Puts a map value.
-    #
-    # Elements may be filled by entering the map node and putting alternating
-    # key/value pairs.
-    #
-    # @example
-    #
-    #   data = Qpid::Proton::Codec::Data.new
-    #   data.put_map
-    #   data.enter
-    #   data.string = "key"
-    #   data.string = "value"
-    #   data.exit
-    #
-    def put_map
-      check(Cproton.pn_data_put_map(@data))
-    end
+      # Puts a map value.
+      #
+      # Elements may be filled by entering the map node and putting alternating
+      # key/value pairs.
+      #
+      # @example
+      #
+      #   data = Qpid::Proton::Codec::Data.new
+      #   data.put_map
+      #   data.enter
+      #   data.string = "key"
+      #   data.string = "value"
+      #   data.exit
+      #
+      def put_map
+        check(Cproton.pn_data_put_map(@impl))
+      end
 
-    # If the  current node is a map, this returns the number of child
-    # elements. Otherwise, it returns zero.
-    #
-    # Key/value pairs can be accessed by entering the map.
-    #
-    # @example
-    #
-    #   count = @data.map
-    #   @data.enter
-    #   (0...count).each do
-    #     type = @data.next
-    #     puts "Key=#{@data.string}" if type == STRING
-    #     # ... process other key types
-    #     type = @data.next
-    #     puts "Value=#{@data.string}" if type == STRING
-    #     # ... process other value types
-    #   end
-    #   @data.exit
-    def map
-      Cproton.pn_data_get_map(@data)
-    end
+      # If the  current node is a map, this returns the number of child
+      # elements. Otherwise, it returns zero.
+      #
+      # Key/value pairs can be accessed by entering the map.
+      #
+      # @example
+      #
+      #   count = @impl.map
+      #   @impl.enter
+      #   (0...count).each do
+      #     type = @impl.next
+      #     puts "Key=#{@impl.string}" if type == STRING
+      #     # ... process other key types
+      #     type = @impl.next
+      #     puts "Value=#{@impl.string}" if type == STRING
+      #     # ... process other value types
+      #   end
+      #   @impl.exit
+      def map
+        Cproton.pn_data_get_map(@impl)
+      end
 
-    # @private
-    def get_map
-      ::Hash.proton_data_get(self)
-    end
+      # @private
+      def get_map
+        ::Hash.proton_data_get(self)
+      end
 
-    # Puts an array value.
-    #
-    # Elements may be filled by entering the array node and putting the
-    # element values. The values must all be of the specified array element
-    # type.
-    #
-    # If an array is *described* then the first child value of the array
-    # is the descriptor and may be of any type.
-    #
-    # @param described [Boolean] True if the array is described.
-    # @param element_type [Integer] The AMQP type for each element of the array.
-    #
-    # @example
-    #
-    #   # create an array of integer values
-    #   data = Qpid::Proton::Codec::Data.new
-    #   data.put_array(false, INT)
-    #   data.enter
-    #   data.int = 1
-    #   data.int = 2
-    #   data.int = 3
-    #   data.exit
-    #
-    #   # create a described  array of double values
-    #   data.put_array(true, DOUBLE)
-    #   data.enter
-    #   data.symbol = "array-descriptor"
-    #   data.double = 1.1
-    #   data.double = 1.2
-    #   data.double = 1.3
-    #   data.exit
-    #
-    def put_array(described, element_type)
-      check(Cproton.pn_data_put_array(@data, described, element_type.code))
-    end
+      # Puts an array value.
+      #
+      # Elements may be filled by entering the array node and putting the
+      # element values. The values must all be of the specified array element
+      # type.
+      #
+      # If an array is *described* then the first child value of the array
+      # is the descriptor and may be of any type.
+      #
+      # @param described [Boolean] True if the array is described.
+      # @param element_type [Integer] The AMQP type for each element of the array.
+      #
+      # @example
+      #
+      #   # create an array of integer values
+      #   data = Qpid::Proton::Codec::Data.new
+      #   data.put_array(false, INT)
+      #   data.enter
+      #   data.int = 1
+      #   data.int = 2
+      #   data.int = 3
+      #   data.exit
+      #
+      #   # create a described  array of double values
+      #   data.put_array(true, DOUBLE)
+      #   data.enter
+      #   data.symbol = "array-descriptor"
+      #   data.double = 1.1
+      #   data.double = 1.2
+      #   data.double = 1.3
+      #   data.exit
+      #
+      def put_array(described, element_type)
+        check(Cproton.pn_data_put_array(@impl, described, element_type.code))
+      end
 
-    # If the current node is an array, returns a tuple of the element count, a
-    # boolean indicating whether the array is described, and the type of each
-    # element. Otherwise it returns +(0, false, nil).
-    #
-    # Array data can be accessed by entering the array.
-    #
-    # @example
-    #
-    #   # get the details of thecurrent array
-    #   count, described, array_type = @data.array
-    #
-    #   # enter the node
-    #   data.enter
-    #
-    #   # get the next node
-    #   data.next
-    #   puts "Descriptor: #{data.symbol}" if described
-    #   (0...count).each do
-    #     @data.next
-    #     puts "Element: #{@data.string}"
-    #   end
-    def array
-      count = Cproton.pn_data_get_array(@data)
-      described = Cproton.pn_data_is_array_described(@data)
-      array_type = Cproton.pn_data_get_array_type(@data)
-      return nil if array_type == -1
-      [count, described, Mapping.for_code(array_type) ]
-    end
+      # If the current node is an array, returns a tuple of the element count, a
+      # boolean indicating whether the array is described, and the type of each
+      # element. Otherwise it returns +(0, false, nil).
+      #
+      # Array data can be accessed by entering the array.
+      #
+      # @example
+      #
+      #   # get the details of thecurrent array
+      #   count, described, array_type = @impl.array
+      #
+      #   # enter the node
+      #   data.enter
+      #
+      #   # get the next node
+      #   data.next
+      #   puts "Descriptor: #{data.symbol}" if described
+      #   (0...count).each do
+      #     @impl.next
+      #     puts "Element: #{@impl.string}"
+      #   end
+      def array
+        count = Cproton.pn_data_get_array(@impl)
+        described = Cproton.pn_data_is_array_described(@impl)
+        array_type = Cproton.pn_data_get_array_type(@impl)
+        return nil if array_type == -1
+        [count, described, Mapping.for_code(array_type) ]
+      end
 
-    # @private
-    def get_array
-      ::Array.proton_get(self)
-    end
+      # @private
+      def get_array
+        ::Array.proton_get(self)
+      end
 
-    # Puts a described value.
-    #
-    # A described node has two children, the descriptor and the value.
-    # These are specified by entering the node and putting the
-    # desired values.
-    #
-    # @example
-    #
-    #   data = Qpid::Proton::Codec::Data.new
-    #   data.put_described
-    #   data.enter
-    #   data.symbol = "value-descriptor"
-    #   data.string = "the value"
-    #   data.exit
-    #
-    def put_described
-      check(Cproton.pn_data_put_described(@data))
-    end
+      # Puts a described value.
+      #
+      # A described node has two children, the descriptor and the value.
+      # These are specified by entering the node and putting the
+      # desired values.
+      #
+      # @example
+      #
+      #   data = Qpid::Proton::Codec::Data.new
+      #   data.put_described
+      #   data.enter
+      #   data.symbol = "value-descriptor"
+      #   data.string = "the value"
+      #   data.exit
+      #
+      def put_described
+        check(Cproton.pn_data_put_described(@impl))
+      end
 
-    # @private
-    def get_described
-      raise TypeError, "not a described type" unless self.described?
-      self.enter
-      self.next
-      type = self.type
-      descriptor = type.get(self)
-      self.next
-      type = self.type
-      value = type.get(self)
-      self.exit
-      Qpid::Proton::Types::Described.new(descriptor, value)
-    end
+      # @private
+      def get_described
+        raise TypeError, "not a described type" unless self.described?
+        self.enter
+        self.next
+        type = self.type
+        descriptor = type.get(self)
+        self.next
+        type = self.type
+        value = type.get(self)
+        self.exit
+        Qpid::Proton::Types::Described.new(descriptor, value)
+      end
 
-    # Checks if the current node is a described value.
-    #
-    # The described and value may be accessed by entering the described value.
-    #
-    # @example
-    #
-    #   if @data.described?
-    #     @data.enter
-    #     puts "The symbol is #{@data.symbol}"
-    #     puts "The value is #{@data.string}"
-    #   end
-    def described?
-      Cproton.pn_data_is_described(@data)
-    end
+      # Checks if the current node is a described value.
+      #
+      # The described and value may be accessed by entering the described value.
+      #
+      # @example
+      #
+      #   if @impl.described?
+      #     @impl.enter
+      #     puts "The symbol is #{@impl.symbol}"
+      #     puts "The value is #{@impl.string}"
+      #   end
+      def described?
+        Cproton.pn_data_is_described(@impl)
+      end
 
-    # Puts a null value.
-    #
-    def null
-      check(Cproton.pn_data_put_null(@data))
-    end
+      # Puts a null value.
+      #
+      def null
+        check(Cproton.pn_data_put_null(@impl))
+      end
 
-    # Utility method for Qpid::Proton::Codec::Mapping
-    #
-    # @private
-    #
-    def null=(value)
-      null
-    end
+      # Utility method for Qpid::Proton::Codec::Mapping
+      #
+      # @private
+      #
+      def null=(value)
+        null
+      end
 
-    # Puts an arbitrary object type.
-    #
-    # The Data instance will determine which AMQP type is appropriate and will
-    # use that to encode the object.
-    #
-    # @param object [Object] The value.
-    #
-    def object=(object)
-      Mapping.for_class(object.class).put(self, object)
-    end
+      # Puts an arbitrary object type.
+      #
+      # The Data instance will determine which AMQP type is appropriate and will
+      # use that to encode the object.
+      #
+      # @param object [Object] The value.
+      #
+      def object=(object)
+        Mapping.for_class(object.class).put(self, object)
+      end
 
-    # Gets the current node, based on how it was encoded.
-    #
-    # @return [Object] The current node.
-    #
-    def object
-      type = self.type
-      return nil if type.nil?
-      type.get(data)
-    end
+      # Gets the current node, based on how it was encoded.
+      #
+      # @return [Object] The current node.
+      #
+      def object
+        type = self.type
+        return nil if type.nil?
+        type.get(data)
+      end
 
-    # Checks if the current node is null.
-    #
-    # @return [Boolean] True if the node is null.
-    #
-    def null?
-      Cproton.pn_data_is_null(@data)
-    end
+      # Checks if the current node is null.
+      #
+      # @return [Boolean] True if the node is null.
+      #
+      def null?
+        Cproton.pn_data_is_null(@impl)
+      end
 
-    # Puts a boolean value.
-    #
-    # @param value [Boolean] The boolean value.
-    #
-    def bool=(value)
-      check(Cproton.pn_data_put_bool(@data, value))
-    end
+      # Puts a boolean value.
+      #
+      # @param value [Boolean] The boolean value.
+      #
+      def bool=(value)
+        check(Cproton.pn_data_put_bool(@impl, value))
+      end
 
-    # If the current node is a boolean, then it returns the value. Otherwise,
-    # it returns false.
-    #
-    # @return [Boolean] The boolean value.
-    #
-    def bool
-      Cproton.pn_data_get_bool(@data)
-    end
+      # If the current node is a boolean, then it returns the value. Otherwise,
+      # it returns false.
+      #
+      # @return [Boolean] The boolean value.
+      #
+      def bool
+        Cproton.pn_data_get_bool(@impl)
+      end
 
-    # Puts an unsigned byte value.
-    #
-    # @param value [Integer] The unsigned byte value.
-    #
-    def ubyte=(value)
-      check(Cproton.pn_data_put_ubyte(@data, value))
-    end
+      # Puts an unsigned byte value.
+      #
+      # @param value [Integer] The unsigned byte value.
+      #
+      def ubyte=(value)
+        check(Cproton.pn_data_put_ubyte(@impl, value))
+      end
 
-    # If the current node is an unsigned byte, returns its value. Otherwise,
-    # it returns 0.
-    #
-    # @return [Integer] The unsigned byte value.
-    #
-    def ubyte
-      Cproton.pn_data_get_ubyte(@data)
-    end
+      # If the current node is an unsigned byte, returns its value. Otherwise,
+      # it returns 0.
+      #
+      # @return [Integer] The unsigned byte value.
+      #
+      def ubyte
+        Cproton.pn_data_get_ubyte(@impl)
+      end
 
-    # Puts a byte value.
-    #
-    # @param value [Integer] The byte value.
-    #
-    def byte=(value)
-      check(Cproton.pn_data_put_byte(@data, value))
-    end
+      # Puts a byte value.
+      #
+      # @param value [Integer] The byte value.
+      #
+      def byte=(value)
+        check(Cproton.pn_data_put_byte(@impl, value))
+      end
 
-    # If the current node is an byte, returns its value. Otherwise,
-    # it returns 0.
-    #
-    # @return [Integer] The byte value.
-    #
-    def byte
-      Cproton.pn_data_get_byte(@data)
-    end
+      # If the current node is an byte, returns its value. Otherwise,
+      # it returns 0.
+      #
+      # @return [Integer] The byte value.
+      #
+      def byte
+        Cproton.pn_data_get_byte(@impl)
+      end
 
-    # Puts an unsigned short value.
-    #
-    # @param value [Integer] The unsigned short value
-    #
-    def ushort=(value)
-      check(Cproton.pn_data_put_ushort(@data, value))
-    end
+      # Puts an unsigned short value.
+      #
+      # @param value [Integer] The unsigned short value
+      #
+      def ushort=(value)
+        check(Cproton.pn_data_put_ushort(@impl, value))
+      end
 
-    # If the current node is an unsigned short, returns its value. Otherwise,
-    # it returns 0.
-    #
-    # @return [Integer] The unsigned short value.
-    #
-    def ushort
-      Cproton.pn_data_get_ushort(@data)
-    end
+      # If the current node is an unsigned short, returns its value. Otherwise,
+      # it returns 0.
+      #
+      # @return [Integer] The unsigned short value.
+      #
+      def ushort
+        Cproton.pn_data_get_ushort(@impl)
+      end
 
-    # Puts a short value.
-    #
-    # @param value [Integer] The short value.
-    #
-    def short=(value)
-      check(Cproton.pn_data_put_short(@data, value))
-    end
+      # Puts a short value.
+      #
+      # @param value [Integer] The short value.
+      #
+      def short=(value)
+        check(Cproton.pn_data_put_short(@impl, value))
+      end
 
-    # If the current node is a short, returns its value. Otherwise,
-    # returns a 0.
-    #
-    # @return [Integer] The short value.
-    #
-    def short
-      Cproton.pn_data_get_short(@data)
-    end
+      # If the current node is a short, returns its value. Otherwise,
+      # returns a 0.
+      #
+      # @return [Integer] The short value.
+      #
+      def short
+        Cproton.pn_data_get_short(@impl)
+      end
 
-    # Puts an unsigned integer value.
-    #
-    # @param value [Integer] the unsigned integer value
-    #
-    def uint=(value)
-      raise TypeError if value.nil?
-      raise RangeError, "invalid uint: #{value}" if value < 0
-      check(Cproton.pn_data_put_uint(@data, value))
-    end
+      # Puts an unsigned integer value.
+      #
+      # @param value [Integer] the unsigned integer value
+      #
+      def uint=(value)
+        raise TypeError if value.nil?
+        raise RangeError, "invalid uint: #{value}" if value < 0
+        check(Cproton.pn_data_put_uint(@impl, value))
+      end
 
-    # If the current node is an unsigned int, returns its value. Otherwise,
-    # returns 0.
-    #
-    # @return [Integer] The unsigned integer value.
-    #
-    def uint
-      Cproton.pn_data_get_uint(@data)
-    end
+      # If the current node is an unsigned int, returns its value. Otherwise,
+      # returns 0.
+      #
+      # @return [Integer] The unsigned integer value.
+      #
+      def uint
+        Cproton.pn_data_get_uint(@impl)
+      end
 
-    # Puts an integer value.
-    #
-    # ==== Options
-    #
-    # * value - the integer value
-    def int=(value)
-      check(Cproton.pn_data_put_int(@data, value))
-    end
+      # Puts an integer value.
+      #
+      # ==== Options
+      #
+      # * value - the integer value
+      def int=(value)
+        check(Cproton.pn_data_put_int(@impl, value))
+      end
 
-    # If the current node is an integer, returns its value. Otherwise,
-    # returns 0.
-    #
-    # @return [Integer] The integer value.
-    #
-    def int
-      Cproton.pn_data_get_int(@data)
-    end
+      # If the current node is an integer, returns its value. Otherwise,
+      # returns 0.
+      #
+      # @return [Integer] The integer value.
+      #
+      def int
+        Cproton.pn_data_get_int(@impl)
+      end
 
-    # Puts a character value.
-    #
-    # @param value [Integer] The character value.
-    #
-    def char=(value)
-      check(Cproton.pn_data_put_char(@data, value))
-    end
+      # Puts a character value.
+      #
+      # @param value [Integer] The character value.
+      #
+      def char=(value)
+        check(Cproton.pn_data_put_char(@impl, value))
+      end
 
-    # If the current node is a character, returns its value. Otherwise,
-    # returns 0.
-    #
-    # @return [Integer] The character value.
-    #
-    def char
-      Cproton.pn_data_get_char(@data)
-    end
+      # If the current node is a character, returns its value. Otherwise,
+      # returns 0.
+      #
+      # @return [Integer] The character value.
+      #
+      def char
+        Cproton.pn_data_get_char(@impl)
+      end
 
-    # Puts an unsigned long value.
-    #
-    # @param value [Integer] The unsigned long value.
-    #
-    def ulong=(value)
-      raise TypeError if value.nil?
-      raise RangeError, "invalid ulong: #{value}" if value < 0
-      check(Cproton.pn_data_put_ulong(@data, value))
-    end
+      # Puts an unsigned long value.
+      #
+      # @param value [Integer] The unsigned long value.
+      #
+      def ulong=(value)
+        raise TypeError if value.nil?
+        raise RangeError, "invalid ulong: #{value}" if value < 0
+        check(Cproton.pn_data_put_ulong(@impl, value))
+      end
 
-    # If the current node is an unsigned long, returns its value. Otherwise,
-    # returns 0.
-    #
-    # @return [Integer] The unsigned long value.
-    #
-    def ulong
-      Cproton.pn_data_get_ulong(@data)
-    end
+      # If the current node is an unsigned long, returns its value. Otherwise,
+      # returns 0.
+      #
+      # @return [Integer] The unsigned long value.
+      #
+      def ulong
+        Cproton.pn_data_get_ulong(@impl)
+      end
 
-    # Puts a long value.
-    #
-    # @param value [Integer] The long value.
-    #
-    def long=(value)
-      check(Cproton.pn_data_put_long(@data, value))
-    end
+      # Puts a long value.
+      #
+      # @param value [Integer] The long value.
+      #
+      def long=(value)
+        check(Cproton.pn_data_put_long(@impl, value))
+      end
 
-    # If the current node is a long, returns its value. Otherwise, returns 0.
-    #
-    # @return [Integer] The long value.
-    def long
-      Cproton.pn_data_get_long(@data)
-    end
+      # If the current node is a long, returns its value. Otherwise, returns 0.
+      #
+      # @return [Integer] The long value.
+      def long
+        Cproton.pn_data_get_long(@impl)
+      end
 
-    # Puts a timestamp value.
-    #
-    # @param value [Integer] The timestamp value.
-    #
-    def timestamp=(value)
-      value = value.to_i if (!value.nil? && value.is_a?(Time))
-      check(Cproton.pn_data_put_timestamp(@data, value))
-    end
+      # Puts a timestamp value.
+      #
+      # @param value [Integer] The timestamp value.
+      #
+      def timestamp=(value)
+        value = value.to_i if (!value.nil? && value.is_a?(Time))
+        check(Cproton.pn_data_put_timestamp(@impl, value))
+      end
 
-    # If the current node is a timestamp, returns its value. Otherwise,
-    # returns 0.
-    #
-    # @return [Integer] The timestamp value.
-    #
-    def timestamp
-      Cproton.pn_data_get_timestamp(@data)
-    end
+      # If the current node is a timestamp, returns its value. Otherwise,
+      # returns 0.
+      #
+      # @return [Integer] The timestamp value.
+      #
+      def timestamp
+        Cproton.pn_data_get_timestamp(@impl)
+      end
 
-    # Puts a float value.
-    #
-    # @param value [Float] The floating point value.
-    #
-    def float=(value)
-      check(Cproton.pn_data_put_float(@data, value))
-    end
+      # Puts a float value.
+      #
+      # @param value [Float] The floating point value.
+      #
+      def float=(value)
+        check(Cproton.pn_data_put_float(@impl, value))
+      end
 
-    # If the current node is a float, returns its value. Otherwise,
-    # returns 0.
-    #
-    # @return [Float] The floating point value.
-    #
-    def float
-      Cproton.pn_data_get_float(@data)
-    end
+      # If the current node is a float, returns its value. Otherwise,
+      # returns 0.
+      #
+      # @return [Float] The floating point value.
+      #
+      def float
+        Cproton.pn_data_get_float(@impl)
+      end
 
-    # Puts a double value.
-    #
-    # @param value [Float] The double precision floating point value.
-    #
-    def double=(value)
-      check(Cproton.pn_data_put_double(@data, value))
-    end
+      # Puts a double value.
+      #
+      # @param value [Float] The double precision floating point value.
+      #
+      def double=(value)
+        check(Cproton.pn_data_put_double(@impl, value))
+      end
 
-    # If the current node is a double, returns its value. Otherwise,
-    # returns 0.
-    #
-    # @return [Float] The double precision floating point value.
-    #
-    def double
-      Cproton.pn_data_get_double(@data)
-    end
+      # If the current node is a double, returns its value. Otherwise,
+      # returns 0.
+      #
+      # @return [Float] The double precision floating point value.
+      #
+      def double
+        Cproton.pn_data_get_double(@impl)
+      end
 
-    # Puts a decimal32 value.
-    #
-    # @param value [Integer] The decimal32 value.
-    #
-    def decimal32=(value)
-      check(Cproton.pn_data_put_decimal32(@data, value))
-    end
+      # Puts a decimal32 value.
+      #
+      # @param value [Integer] The decimal32 value.
+      #
+      def decimal32=(value)
+        check(Cproton.pn_data_put_decimal32(@impl, value))
+      end
 
-    # If the current node is a decimal32, returns its value. Otherwise,
-    # returns 0.
-    #
-    # @return [Integer] The decimal32 value.
-    #
-    def decimal32
-      Cproton.pn_data_get_decimal32(@data)
-    end
+      # If the current node is a decimal32, returns its value. Otherwise,
+      # returns 0.
+      #
+      # @return [Integer] The decimal32 value.
+      #
+      def decimal32
+        Cproton.pn_data_get_decimal32(@impl)
+      end
 
-    # Puts a decimal64 value.
-    #
-    # @param value [Integer] The decimal64 value.
-    #
-    def decimal64=(value)
-      check(Cproton.pn_data_put_decimal64(@data, value))
-    end
+      # Puts a decimal64 value.
+      #
+      # @param value [Integer] The decimal64 value.
+      #
+      def decimal64=(value)
+        check(Cproton.pn_data_put_decimal64(@impl, value))
+      end
 
-    # If the current node is a decimal64, returns its value. Otherwise,
-    # it returns 0.
-    #
-    # @return [Integer] The decimal64 value.
-    #
-    def decimal64
-      Cproton.pn_data_get_decimal64(@data)
-    end
+      # If the current node is a decimal64, returns its value. Otherwise,
+      # it returns 0.
+      #
+      # @return [Integer] The decimal64 value.
+      #
+      def decimal64
+        Cproton.pn_data_get_decimal64(@impl)
+      end
 
-    # Puts a decimal128 value.
-    #
-    # @param value [Integer] The decimal128 value.
-    #
-    def decimal128=(value)
-      raise TypeError, "invalid decimal128 value: #{value}" if value.nil?
-      value = value.to_s(16).rjust(32, "0")
-      bytes = []
-      value.scan(/(..)/) {|v| bytes << v[0].to_i(16)}
-      check(Cproton.pn_data_put_decimal128(@data, bytes))
-    end
+      # Puts a decimal128 value.
+      #
+      # @param value [Integer] The decimal128 value.
+      #
+      def decimal128=(value)
+        raise TypeError, "invalid decimal128 value: #{value}" if value.nil?
+        value = value.to_s(16).rjust(32, "0")
+        bytes = []
+        value.scan(/(..)/) {|v| bytes << v[0].to_i(16)}
+        check(Cproton.pn_data_put_decimal128(@impl, bytes))
+      end
 
-    # If the current node is a decimal128, returns its value. Otherwise,
-    # returns 0.
-    #
-    # @return [Integer] The decimal128 value.
-    #
-    def decimal128
-      value = ""
-      Cproton.pn_data_get_decimal128(@data).each{|val| value += ("%02x" % val)}
-      value.to_i(16)
-    end
+      # If the current node is a decimal128, returns its value. Otherwise,
+      # returns 0.
+      #
+      # @return [Integer] The decimal128 value.
+      #
+      def decimal128
+        value = ""
+        Cproton.pn_data_get_decimal128(@impl).each{|val| value += ("%02x" % val)}
+        value.to_i(16)
+      end
 
-    # Puts a +UUID+ value.
-    #
-    # The UUID is expected to be in the format of a string or else a 128-bit
-    # integer value.
-    #
-    # @param value [String, Numeric] A string or numeric representation of the UUID.
-    #
-    # @example
-    #
-    #   # set a uuid value from a string value
-    #   require 'securerandom'
-    #   @data.uuid = SecureRandom.uuid
-    #
-    #   # or
-    #   @data.uuid = "fd0289a5-8eec-4a08-9283-81d02c9d2fff"
-    #
-    #   # set a uuid value from a 128-bit value
-    #   @data.uuid = 0 # sets to 00000000-0000-0000-0000-000000000000
-    #
-    def uuid=(value)
-      raise ::ArgumentError, "invalid uuid: #{value}" if value.nil?
-
-      # if the uuid that was submitted was numeric value, then translated
-      # it into a hex string, otherwise assume it was a string represtation
-      # and attempt to decode it
-      if value.is_a? Numeric
-        value = "%032x" % value
-      else
-        raise ::ArgumentError, "invalid uuid: #{value}" if !valid_uuid?(value)
-
-        value = (value[0, 8]  +
-                 value[9, 4]  +
-                 value[14, 4] +
-                 value[19, 4] +
-                 value[24, 12])
-      end
-      bytes = []
-      value.scan(/(..)/) {|v| bytes << v[0].to_i(16)}
-      check(Cproton.pn_data_put_uuid(@data, bytes))
-    end
+      # Puts a +UUID+ value.
+      #
+      # The UUID is expected to be in the format of a string or else a 128-bit
+      # integer value.
+      #
+      # @param value [String, Numeric] A string or numeric representation of the UUID.
+      #
+      # @example
+      #
+      #   # set a uuid value from a string value
+      #   require 'securerandom'
+      #   @impl.uuid = SecureRandom.uuid
+      #
+      #   # or
+      #   @impl.uuid = "fd0289a5-8eec-4a08-9283-81d02c9d2fff"
+      #
+      #   # set a uuid value from a 128-bit value
+      #   @impl.uuid = 0 # sets to 00000000-0000-0000-0000-000000000000
+      #
+      def uuid=(value)
+        raise ::ArgumentError, "invalid uuid: #{value}" if value.nil?
+
+        # if the uuid that was submitted was numeric value, then translated
+        # it into a hex string, otherwise assume it was a string represtation
+        # and attempt to decode it
+        if value.is_a? Numeric
+          value = "%032x" % value
+        else
+          raise ::ArgumentError, "invalid uuid: #{value}" if !valid_uuid?(value)
 
-    # If the current value is a +UUID+, returns its value. Otherwise,
-    # it returns nil.
-    #
-    # @return [String] The string representation of the UUID.
-    #
-    def uuid
-      value = ""
-      Cproton.pn_data_get_uuid(@data).each{|val| value += ("%02x" % val)}
-      value.insert(8, "-").insert(13, "-").insert(18, "-").insert(23, "-")
-    end
+          value = (value[0, 8]  +
+                   value[9, 4]  +
+                   value[14, 4] +
+                   value[19, 4] +
+                   value[24, 12])
+        end
+        bytes = []
+        value.scan(/(..)/) {|v| bytes << v[0].to_i(16)}
+        check(Cproton.pn_data_put_uuid(@impl, bytes))
+      end
 
-    # Puts a binary value.
-    #
-    # A binary string is encoded as an ASCII 8-bit string value. This is in
-    # contranst to other strings, which are treated as UTF-8 encoded.
-    #
-    # @param value [String] An arbitrary string value.
-    #
-    # @see #string=
-    #
-    def binary=(value)
-      check(Cproton.pn_data_put_binary(@data, value))
-    end
+      # If the current value is a +UUID+, returns its value. Otherwise,
+      # it returns nil.
+      #
+      # @return [String] The string representation of the UUID.
+      #
+      def uuid
+        value = ""
+        Cproton.pn_data_get_uuid(@impl).each{|val| value += ("%02x" % val)}
+        value.insert(8, "-").insert(13, "-").insert(18, "-").insert(23, "-")
+      end
 
-    # If the current node is binary, returns its value. Otherwise, it returns
-    # an empty string ("").
-    #
-    # @return [String] The binary string.
-    #
-    # @see #string
-    #
-    def binary
-      Qpid::Proton::Types::BinaryString.new(Cproton.pn_data_get_binary(@data))
-    end
+      # Puts a binary value.
+      #
+      # A binary string is encoded as an ASCII 8-bit string value. This is in
+      # contranst to other strings, which are treated as UTF-8 encoded.
+      #
+      # @param value [String] An arbitrary string value.
+      #
+      # @see #string=
+      #
+      def binary=(value)
+        check(Cproton.pn_data_put_binary(@impl, value))
+      end
 
-    # Puts a UTF-8 encoded string value.
-    #
-    # *NOTE:* A nil value is stored as an empty string rather than as a nil.
-    #
-    # @param value [String] The UTF-8 encoded string value.
-    #
-    # @see #binary=
-    #
-    def string=(value)
-      check(Cproton.pn_data_put_string(@data, value))
-    end
+      # If the current node is binary, returns its value. Otherwise, it returns
+      # an empty string ("").
+      #
+      # @return [String] The binary string.
+      #
+      # @see #string
+      #
+      def binary
+        Qpid::Proton::Types::BinaryString.new(Cproton.pn_data_get_binary(@impl))
+      end
 
-    # If the current node is a string, returns its value. Otherwise, it
-    # returns an empty string ("").
-    #
-    # @return [String] The UTF-8 encoded string.
-    #
-    # @see #binary
-    #
-    def string
-      Qpid::Proton::Types::UTFString.new(Cproton.pn_data_get_string(@data))
-    end
+      # Puts a UTF-8 encoded string value.
+      #
+      # *NOTE:* A nil value is stored as an empty string rather than as a nil.
+      #
+      # @param value [String] The UTF-8 encoded string value.
+      #
+      # @see #binary=
+      #
+      def string=(value)
+        check(Cproton.pn_data_put_string(@impl, value))
+      end
 
-    # Puts a symbolic value.
-    #
-    # @param value [String|Symbol] The symbolic string value.
-    #
-    def symbol=(value)
-      check(Cproton.pn_data_put_symbol(@data, value.to_s))
-    end
+      # If the current node is a string, returns its value. Otherwise, it
+      # returns an empty string ("").
+      #
+      # @return [String] The UTF-8 encoded string.
+      #
+      # @see #binary
+      #
+      def string
+        Qpid::Proton::Types::UTFString.new(Cproton.pn_data_get_string(@impl))
+      end
 
-    # If the current node is a symbol, returns its value. Otherwise, it
-    # returns an empty string ("").
-    #
-    # @return [String] The symbolic string value.
-    #
-    def symbol
-      Cproton.pn_data_get_symbol(@data)
-    end
+      # Puts a symbolic value.
+      #
+      # @param value [String|Symbol] The symbolic string value.
+      #
+      def symbol=(value)
+        check(Cproton.pn_data_put_symbol(@impl, value.to_s))
+      end
 
-    # Get the current value as a single object.
-    #
-    # @return [Object] The current node's object.
-    #
-    # @see #type_code
-    # @see #type
-    #
-    def get
-      type.get(self);
-    end
+      # If the current node is a symbol, returns its value. Otherwise, it
+      # returns an empty string ("").
+      #
+      # @return [String] The symbolic string value.
+      #
+      def symbol
+        Cproton.pn_data_get_symbol(@impl)
+      end
 
-    # Puts a new value with the given type into the current node.
-    #
-    # @param value [Object] The value.
-    # @param type_code [Mapping] The value's type.
-    #
-    # @private
-    #
-    def put(value, type_code);
-      type_code.put(self, value);
-    end
+      # Get the current value as a single object.
+      #
+      # @return [Object] The current node's object.
+      #
+      # @see #type_code
+      # @see #type
+      #
+      def get
+        type.get(self);
+      end
 
-    private
+      # Puts a new value with the given type into the current node.
+      #
+      # @param value [Object] The value.
+      # @param type_code [Mapping] The value's type.
+      #
+      # @private
+      #
+      def put(value, type_code);
+        type_code.put(self, value);
+      end
 
-    def valid_uuid?(value)
-      # ensure that the UUID is in the right format
-      # xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
-      value =~ /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/
-    end
+      private
 
-    # @private
-    def check(err)
-      if err < 0
-        raise DataError, "[#{err}]: #{Cproton.pn_data_error(@data)}"
-      else
-        return err
+      def valid_uuid?(value)
+        # ensure that the UUID is in the right format
+        # xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
+        value =~ /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/
       end
+
+      # @private
+      def check(err)
+        if err < 0
+          raise DataError, "[#{err}]: #{Cproton.pn_data_error(@impl)}"
+        else
+          return err
+        end
+      end
+
     end
 
   end
-
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/codec/mapping.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/codec/mapping.rb b/proton-c/bindings/ruby/lib/codec/mapping.rb
index fbebb57..92d0858 100644
--- a/proton-c/bindings/ruby/lib/codec/mapping.rb
+++ b/proton-c/bindings/ruby/lib/codec/mapping.rb
@@ -75,8 +75,11 @@ module Qpid::Proton::Codec
       data.__send__(@get_method)
     end
 
-    def self.for_class(klass) # :nodoc:
-      klass and (@@by_class[klass] or self.for_class(klass.superclass))
+    def self.for_class(klass)
+      c = klass
+      c = c.superclass while c && (x = @@by_class[c]).nil?
+      raise DataError, "no mapping for #{klass.inspect}" unless x
+      x
     end
 
     def self.for_code(code)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/core/connection.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/connection.rb b/proton-c/bindings/ruby/lib/core/connection.rb
index 96fd211..ed82dc8 100644
--- a/proton-c/bindings/ruby/lib/core/connection.rb
+++ b/proton-c/bindings/ruby/lib/core/connection.rb
@@ -21,26 +21,24 @@ module Qpid::Proton
   # An AMQP connection.
   class Connection < Endpoint
 
-    protected
-    include Util::SwigHelper
+    # @private
     PROTON_METHOD_PREFIX = "pn_connection"
-
-    public
+    # @private
+    include Util::Wrapper
 
     # @!attribute hostname
     #   @return [String] The AMQP hostname for the connection.
-    proton_accessor :hostname
+    proton_set_get :hostname
 
     # @!attribute user
     #   @return [String] User name used for authentication (outgoing connection) or the authenticated user name (incoming connection)
-    proton_accessor :user
+    proton_set_get :user
 
     private
 
-    proton_writer :password
+    proton_set :password
     attr_accessor :overrides
     attr_accessor :session_policy
-    include Util::Wrapper
 
     def self.wrap(impl)
       return nil if impl.nil?
@@ -271,6 +269,6 @@ module Qpid::Proton
       Cproton.pn_connection_remote_condition(@impl)
     end
 
-    proton_reader :attachments
+    proton_get :attachments
   end
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/core/disposition.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/disposition.rb b/proton-c/bindings/ruby/lib/core/disposition.rb
index 71a4593..9cecf69 100644
--- a/proton-c/bindings/ruby/lib/core/disposition.rb
+++ b/proton-c/bindings/ruby/lib/core/disposition.rb
@@ -20,6 +20,11 @@ module Qpid::Proton
 
   # @deprecated use {Delivery}
   class Disposition
+    # @private
+    PROTON_METHOD_PREFIX = "pn_disposition"
+    # @private
+    include Util::Wrapper
+
 
     ACCEPTED = Cproton::PN_ACCEPTED
     REJECTED = Cproton::PN_REJECTED
@@ -39,36 +44,29 @@ module Qpid::Proton
       @annotations = nil
     end
 
-    # @private
-    include Util::SwigHelper
-
-
-    # @private
-    PROTON_METHOD_PREFIX = "pn_disposition"
-
     # @!attribute section_number
     #
     # @return [Integer] The section number of the disposition.
     #
-    proton_accessor :section_number
+    proton_set_get :section_number
 
     # @!attribute section_offset
     #
     #  @return [Integer] The section offset of the disposition.
     #
-    proton_accessor :section_offset
+    proton_set_get :section_offset
 
     # @!attribute failed?
     #
     # @return [Boolean] The failed flag.
     #
-    proton_accessor :failed, :is_or_get => :is
+    proton_set_is :failed
 
     # @!attribute undeliverable?
     #
     # @return [Boolean] The undeliverable flag.
     #
-    proton_accessor :undeliverable, :is_or_get => :is
+    proton_set_is :undeliverable
 
     # Sets the data for the disposition.
     #

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/core/event.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/event.rb b/proton-c/bindings/ruby/lib/core/event.rb
index 37a089b..a5aa08e 100644
--- a/proton-c/bindings/ruby/lib/core/event.rb
+++ b/proton-c/bindings/ruby/lib/core/event.rb
@@ -24,7 +24,8 @@ module Qpid::Proton
   class Event
     private
 
-    include Qpid::Proton::Util::Wrapper
+    PROTON_METHOD_PREFIX = "pn_disposition"
+    include Util::Wrapper
 
     EVENT_TYPE_NAMES = [:PN_EVENT_NONE,
                         :PN_CONNECTION_INIT,

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/core/link.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/link.rb b/proton-c/bindings/ruby/lib/core/link.rb
index f8999cd..209d018 100644
--- a/proton-c/bindings/ruby/lib/core/link.rb
+++ b/proton-c/bindings/ruby/lib/core/link.rb
@@ -25,6 +25,11 @@ module Qpid::Proton
   #
   class Link < Endpoint
 
+    # @private
+    PROTON_METHOD_PREFIX = "pn_link"
+    # @private
+    include Util::Wrapper
+
     # The sender will send all deliveries initially unsettled.
     SND_UNSETTLED = Cproton::PN_SND_UNSETTLED
     # The sender will send all deliveries settled to the receiver.
@@ -37,12 +42,6 @@ module Qpid::Proton
     # The receiver will only settle deliveries after the sender settles.
     RCV_SECOND = Cproton::PN_RCV_SECOND
 
-    # @private
-    include Util::SwigHelper
-
-    # @private
-    PROTON_METHOD_PREFIX = "pn_link"
-
     # @!attribute [r] state
     #
     # Returns the endpoint state flags.
@@ -171,7 +170,7 @@ module Qpid::Proton
     #
     # @return [Boolean] True if the link is a sender.
     #
-    proton_reader  :sender, :is_or_get => :is
+    proton_is  :sender
 
     # @!attribute [r] receiver?
     #
@@ -179,10 +178,10 @@ module Qpid::Proton
     #
     # @return [Boolean] True if the link is a receiver.
     #
-    proton_reader  :receiver, :is_or_get => :is
+    proton_is  :receiver
 
     # @private
-    proton_reader :attachments
+    proton_get :attachments
 
     # Drains excess credit.
     #
@@ -203,9 +202,6 @@ module Qpid::Proton
     proton_caller :drained
 
     # @private
-    include Util::Wrapper
-
-    # @private
     def self.wrap(impl)
       return unless impl
       return fetch_instance(impl, :pn_link_attachments) ||

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/core/message.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/message.rb b/proton-c/bindings/ruby/lib/core/message.rb
index 0f0c072..8f4f67c 100644
--- a/proton-c/bindings/ruby/lib/core/message.rb
+++ b/proton-c/bindings/ruby/lib/core/message.rb
@@ -32,6 +32,11 @@ module Qpid::Proton
   #
   class Message
 
+    # @private
+    PROTON_METHOD_PREFIX = "pn_message"
+    # @private
+    include Util::Wrapper
+
     # Decodes a message from AMQP binary data.
     # @param encoded [String] the encoded bytes
     # @return[Integer] the number of bytes consumed
@@ -40,7 +45,8 @@ module Qpid::Proton
       post_decode
     end
 
-    def post_decode # :nodoc:
+    # @private
+    def post_decode
       # decode elements from the message
       @properties = {}
       props = Codec::Data.new(Cproton::pn_message_properties(@impl))
@@ -79,7 +85,8 @@ module Qpid::Proton
       end
     end
 
-    def pre_encode # :nodoc:
+    # @private
+    def pre_encode
       # encode elements from the message
       props = Codec::Data.new(Cproton::pn_message_properties(@impl))
       props.clear
@@ -106,30 +113,22 @@ module Qpid::Proton
 
     # Creates a new +Message+ instance.
     # @param body the body of the message, equivalent to calling m.body=(body)
-    # @param set [Hash] additional settings, equivalent to m.key=value for each key=>value in settings
-    def initialize(body = nil, settings={})
+    # @param opts [Hash] additional options, equivalent to +Message#key=value+ for each +key=>value+
+    def initialize(body = nil, opts={})
       @impl = Cproton.pn_message
       ObjectSpace.define_finalizer(self, self.class.finalize!(@impl))
       @properties = {}
       @instructions = {}
       @annotations = {}
       self.body = body unless body.nil?
-      if !settings.nil? then
-        settings.each do |k, v|
+      if !opts.nil? then
+        opts.each do |k, v|
           setter = (k.to_s+"=").to_sym()
           self.send setter, v
         end
       end
     end
 
-    def to_s
-      tmp = Cproton.pn_string("")
-      Cproton.pn_inspect(@impl, tmp)
-      result = Cproton.pn_string_get(tmp)
-      Cproton.pn_free(tmp)
-      return result
-    end
-
     # Invoked by garbage collection to clean up resources used
     # by the underlying message implementation.
     def self.finalize!(impl) # :nodoc:
@@ -587,6 +586,7 @@ module Qpid::Proton
     # Assigns a new value to the body of the message.
     #
     def body=(body)
+      Qpid::Proton::Codec::Mapping.for_class(body.class) unless body.nil? # Fail now if not convertible
       @body = body
     end
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/core/receiver.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/receiver.rb b/proton-c/bindings/ruby/lib/core/receiver.rb
index a78e5b5..791e891 100644
--- a/proton-c/bindings/ruby/lib/core/receiver.rb
+++ b/proton-c/bindings/ruby/lib/core/receiver.rb
@@ -25,10 +25,9 @@ module Qpid::Proton
   class Receiver < Link
 
     # @private
-    include Util::SwigHelper
-
-    # @private
     PROTON_METHOD_PREFIX = "pn_link"
+    # @private
+    include Util::Wrapper
 
     # @!attribute drain
     #
@@ -42,7 +41,7 @@ module Qpid::Proton
     #
     # @return [Boolean] True if drain mode is set.
     #
-    proton_accessor :drain
+    proton_set_get :drain
 
     # @!attribute [r] draining?
     #

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/core/sasl.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/sasl.rb b/proton-c/bindings/ruby/lib/core/sasl.rb
index 3787637..08b5e4e 100644
--- a/proton-c/bindings/ruby/lib/core/sasl.rb
+++ b/proton-c/bindings/ruby/lib/core/sasl.rb
@@ -39,7 +39,7 @@ module Qpid::Proton
 
     private
 
-    include Util::SwigHelper
+    include Util::Wrapper
     PROTON_METHOD_PREFIX = "pn_sasl"
 
     public
@@ -52,11 +52,11 @@ module Qpid::Proton
 
     # @!attribute allow_insecure_mechs
     #   @return [Bool] true if clear text authentication is allowed on insecure connections.
-    proton_accessor :allow_insecure_mechs
+    proton_set_get :allow_insecure_mechs
 
     # @!attribute user [r]
     #   @return [String] the authenticated user name
-    proton_reader :user
+    proton_get :user
 
     # Set the mechanisms allowed for SASL negotation
     # @param mechanisms [String] space-delimited list of allowed mechanisms

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/core/session.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/session.rb b/proton-c/bindings/ruby/lib/core/session.rb
index bdc128f..26a7a2f 100644
--- a/proton-c/bindings/ruby/lib/core/session.rb
+++ b/proton-c/bindings/ruby/lib/core/session.rb
@@ -25,13 +25,9 @@ module Qpid::Proton
   class Session < Endpoint
 
     # @private
-    include Util::Wrapper
-
-    # @private
-    include Util::SwigHelper
-
-    # @private
     PROTON_METHOD_PREFIX = "pn_session"
+    # @private
+    include Util::Wrapper
 
     # @!attribute incoming_capacity
     #
@@ -42,10 +38,10 @@ module Qpid::Proton
     #
     # @return [Integer] The incoing capacity of the session, measured in bytes.
     #
-    proton_accessor :incoming_capacity
+    proton_set_get :incoming_capacity
 
     # @private
-    proton_reader :attachments
+    proton_get :attachments
 
     # @!attribute [r] outgoing_bytes
     #

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/core/ssl.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/ssl.rb b/proton-c/bindings/ruby/lib/core/ssl.rb
index 2db1c1c..11db54d 100644
--- a/proton-c/bindings/ruby/lib/core/ssl.rb
+++ b/proton-c/bindings/ruby/lib/core/ssl.rb
@@ -60,11 +60,9 @@ module Qpid::Proton
     RESUME_REUSED = Cproton::PN_SSL_RESUME_REUSED
 
     # @private
-    include Util::SwigHelper
-
-    # @private
     PROTON_METHOD_PREFIX = "pn_ssl"
-
+    # @private
+    include Util::Wrapper
     # @private
     include Util::ErrorHandler
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/core/terminus.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/terminus.rb b/proton-c/bindings/ruby/lib/core/terminus.rb
index b3d7c05..82ac9f7 100644
--- a/proton-c/bindings/ruby/lib/core/terminus.rb
+++ b/proton-c/bindings/ruby/lib/core/terminus.rb
@@ -65,10 +65,9 @@ module Qpid::Proton
     DIST_MODE_MOVE = Cproton::PN_DIST_MODE_MOVE
 
     # @private
-    include Util::SwigHelper
-
-    # @private
     PROTON_METHOD_PREFIX = "pn_terminus"
+    # @private
+    include Util::Wrapper
 
     # @!attribute type
     #
@@ -78,13 +77,13 @@ module Qpid::Proton
     # @see TARGET
     # @see COORDINATOR
     #
-    proton_accessor :type
+    proton_set_get :type
 
     # @!attribute address
     #
     # @return [String] The terminus address.
     #
-    proton_accessor :address
+    proton_set_get :address
 
     # @!attribute durability
     #
@@ -94,7 +93,7 @@ module Qpid::Proton
     # @see CONFIGURATION
     # @see DELIVERIES
     #
-    proton_accessor :durability
+    proton_set_get :durability
 
     # @!attribute expiry_policy
     #
@@ -105,19 +104,19 @@ module Qpid::Proton
     # @see EXPIRE_WITH_CONNECTION
     # @see EXPIRE_NEVER
     #
-    proton_accessor :expiry_policy
+    proton_set_get :expiry_policy
 
     # @!attribute timeout
     #
     # @return [Integer] The timeout period.
     #
-    proton_accessor :timeout
+    proton_set_get :timeout
 
     # @!attribute dynamic?
     #
     # @return [Boolean] True if the terminus is dynamic.
     #
-    proton_accessor :dynamic, :is_or_get => :is
+    proton_set_is :dynamic
 
     # @!attribute distribution_mode
     #
@@ -127,7 +126,7 @@ module Qpid::Proton
     # @see DIST_MODE_COPY
     # @see DIST_MODE_MOVE
     #
-    proton_accessor :distribution_mode
+    proton_set_get :distribution_mode
 
     # @private
     include Util::ErrorHandler

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/core/transfer.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/transfer.rb b/proton-c/bindings/ruby/lib/core/transfer.rb
index 7c3a502..57e8b55 100644
--- a/proton-c/bindings/ruby/lib/core/transfer.rb
+++ b/proton-c/bindings/ruby/lib/core/transfer.rb
@@ -24,9 +24,8 @@ module Qpid::Proton
 
     private
 
-    include Util::Wrapper
-    include Util::SwigHelper
     PROTON_METHOD_PREFIX = "pn_delivery"
+    include Util::Wrapper
 
     protected
 
@@ -77,9 +76,6 @@ module Qpid::Proton
     # @return [Integer] Remote state of the transfer, one of the values in {State}
     def state() Cproton.pn_delivery_remote_state(@impl); end
 
-    def to_s() Cproton.pn_delivery_dump(@impl); end
-    alias inspect to_s
-
     # @return [Link] The parent link.
     def link() Link.wrap(Cproton.pn_delivery_link(@impl)); end
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/core/transport.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/transport.rb b/proton-c/bindings/ruby/lib/core/transport.rb
index 4398966..c1593a0 100644
--- a/proton-c/bindings/ruby/lib/core/transport.rb
+++ b/proton-c/bindings/ruby/lib/core/transport.rb
@@ -62,6 +62,10 @@ module Qpid::Proton
   #   PN_TRACE_FRM=1 ruby my_proton_app.rb
   #
   class Transport
+    # @private
+    PROTON_METHOD_PREFIX = "pn_transport"
+    # @private
+    include Util::Wrapper
 
     # Turn logging off entirely.
     TRACE_OFF = Cproton::PN_TRACE_OFF
@@ -72,17 +76,12 @@ module Qpid::Proton
     # Log driver related events; i.e., initialization, end of stream, etc.
     TRACE_DRV = Cproton::PN_TRACE_DRV
 
-    # @private
-    include Util::SwigHelper
-
-    # @private
-    PROTON_METHOD_PREFIX = "pn_transport"
 
     # @!attribute channel_max
     #
     # @return [Integer] The maximum allowed channel.
     #
-    proton_accessor :channel_max
+    proton_set_get :channel_max
 
     # @!attribute [r] remote_channel_max
     #
@@ -94,25 +93,25 @@ module Qpid::Proton
     #
     # @return [Integer] The maximum frame size.
     #
-    proton_accessor :max_frame_size
+    proton_set_get :max_frame_size
 
     # @!attribute [r] remote_max_frame_size
     #
     # @return [Integer] The maximum frame size of the transport's remote peer.
     #
-    proton_reader :remote_max_frame_size
+    proton_get :remote_max_frame_size
 
     # @!attribute idle_timeout
     #
     # @return [Integer] The idle timeout.
     #
-    proton_accessor :idle_timeout
+    proton_set_get :idle_timeout
 
     # @!attribute [r] remote_idle_timeout
     #
     # @return [Integer] The idle timeout for the transport's remote peer.
     #
-    proton_accessor :remote_idle_timeout
+    proton_set_get :remote_idle_timeout
 
     # @!attribute [r] capacity
     #
@@ -181,13 +180,13 @@ module Qpid::Proton
     #
     # @return [Integer] The number of frames output by a transport.
     #
-    proton_reader :frames_output
+    proton_get :frames_output
 
     # @!attribute [r] frames_input
     #
     # @return [Integer] The number of frames input by a transport.
     #
-    proton_reader :frames_input
+    proton_get :frames_input
 
     # @private
     include Util::ErrorHandler
@@ -198,9 +197,6 @@ module Qpid::Proton
     can_raise_error :close_head, :error_class => TransportError
 
     # @private
-    include Util::Wrapper
-
-    # @private
     def self.wrap(impl)
       return nil if impl.nil?
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/qpid_proton.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/qpid_proton.rb b/proton-c/bindings/ruby/lib/qpid_proton.rb
index 6164fde..a226838 100644
--- a/proton-c/bindings/ruby/lib/qpid_proton.rb
+++ b/proton-c/bindings/ruby/lib/qpid_proton.rb
@@ -47,7 +47,6 @@ require "core/exceptions"
 # Utility classes
 require "util/version"
 require "util/error_handler"
-require "util/swig_helper"
 require "util/wrapper"
 require "util/timeout"
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/util/swig_helper.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/util/swig_helper.rb b/proton-c/bindings/ruby/lib/util/swig_helper.rb
deleted file mode 100644
index 1013df8..0000000
--- a/proton-c/bindings/ruby/lib/util/swig_helper.rb
+++ /dev/null
@@ -1,113 +0,0 @@
-# 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.
-
-
-module Qpid::Proton::Util
-
-  # Provides helper functions for writing wrapper functions for the
-  # underlying C APIs.
-  #
-  # Before defining any mutators the class must define the name of the
-  # prefix for methods with the constant PROTON_METOD_PREFIX.
-  #
-  # == Mutators, Setters And Getters
-  #
-  # There are three types of wrappers that are supported:
-  #
-  # [proton_writer] Defines a set-only method for the named attribute.
-  # [proton_reader] Defines a get-only method for the named attribute.
-  # [proton_accessor] Defines both a set- and a get-method for the named
-  #                  attribute.
-  # [proton_caller] A simple wrapper for calling an underlying method,
-  #                  avoids repetitive boiler plate coding.
-  #
-  # == Arguments
-  #
-  # [:is_or_get => {:is, :get}] For both the getter and the mutator types
-  # you can also declare that the method uses "is" instead of "get" in the
-  # underlying API. Such methods are then defined with "?"
-  #
-  # @example
-  #   class Terminus
-  #
-  #     include WrapperHelper
-  #
-  #     PROTON_METHOD_PREFIX = "pn_terminus"
-  #
-  #     # add methods "type" and "type=" that call "pn_terminus_{get,set}_type"
-  #     proton_accessor :type
-  #
-  #     # adds the method "dynamic?" that calls "pn_terminus_is_dynamic"
-  #     proton_accessor :dynamic, :is_or_get => :is
-  #
-  #     # adds a method named "foo" that calls "pn_terminus_foo"
-  #     proton_caller :foo
-  #
-  #   end
-  #
-  # @private
-  module SwigHelper
-
-    def self.included(base)
-      base.extend ClassMethods
-    end
-
-    module ClassMethods # :nodoc:
-
-      def create_wrapper_method(name, proton_method, with_arg = false)
-        if with_arg
-          define_method "#{name}" do |arg|
-            Cproton.__send__(proton_method.to_sym, @impl, arg)
-          end
-        else
-          define_method "#{name}" do
-            Cproton.__send__(proton_method.to_sym, @impl)
-          end
-        end
-      end
-
-      # Defines a method that calls an underlying C library function.
-      def proton_caller(name, options = {})
-        proton_method = "#{self::PROTON_METHOD_PREFIX}_#{name}"
-        # drop the trailing '?' if this is a property method
-        proton_method = proton_method[0..-2] if proton_method.end_with? "?"
-        create_wrapper_method(name, proton_method, options[:arg])
-      end
-
-      def proton_writer(name, options = {})
-        proton_method = "#{self::PROTON_METHOD_PREFIX}_set_#{name}"
-        create_wrapper_method("#{name}=", proton_method, true)
-      end
-
-      def proton_reader(name, options = {})
-        an_is_method = options[:is_or_get] == :is
-        prefix = (an_is_method) ? "is" : "get"
-        proton_method = "#{self::PROTON_METHOD_PREFIX}_#{prefix}_#{name}"
-        name = "#{name}?" if an_is_method
-        create_wrapper_method(name, proton_method)
-      end
-
-      def proton_accessor(name, options = {})
-        proton_writer(name, options)
-        proton_reader(name, options)
-      end
-
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/889c0c6d/proton-c/bindings/ruby/lib/util/wrapper.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/util/wrapper.rb b/proton-c/bindings/ruby/lib/util/wrapper.rb
index c6e0e72..39cd7b4 100644
--- a/proton-c/bindings/ruby/lib/util/wrapper.rb
+++ b/proton-c/bindings/ruby/lib/util/wrapper.rb
@@ -16,47 +16,46 @@
 # under the License.
 
 
-module Qpid::Proton::Util
-
-  # @private
-  module Wrapper
+module Qpid::Proton
+  module Util
 
     # @private
-    def impl=(impl)
-      @impl = impl
-    end
+    # Class methods to help wrapper classes define forwarding methods to proton-C functions
+    #
+    # The extending class must define PROTON_METHOD_PREFIX, the functions here
+    # make it easy to define ruby methods to forward calls to C functions.
+    #
+    module SWIGClassHelper
+      # Define ruby method +name+ to forward arguments to
+      # CProton.PROTON_METHOD_PREFIX_+pn_name+(@impl, ...)
+      def proton_forward(name, pn_name)
+        pn_name = pn_name[0..-2] if pn_name.to_s.end_with? "?" # Drop trailing ? for ruby bool methods
+        pn_name = "#{self::PROTON_METHOD_PREFIX}_#{pn_name}".to_sym
+        define_method(name.to_sym) { |*args| Cproton.__send__(pn_name, @impl, *args) }
+      end
 
-    # @private
-    def impl
-      @impl
-    end
+      def proton_caller(*names) names.each { |name| proton_forward(name, name) }; end
+      def proton_set(*names) names.each { |name| proton_forward("#{name}=", "set_#{name}") }; end
+      def proton_get(*names) names.each { |name| proton_forward(name, "get_#{name}") }; end
+      def proton_is(*names) names.each { |name| proton_forward("#{name}?", "is_#{name}") }; end
+      def proton_set_get(*names) names.each { |name| proton_get(name); proton_set(name) }; end
+      def proton_set_is(*names) names.each { |name| proton_is(name); proton_set(name) }; end
 
-    def self.registry
-      @registry ||= {}
-    end
+      # Store ruby wrappers as attachments so they can be retrieved from the C pointer.
+      #
+      # Wrappers are stored in a registry using a key. The key is then attached to
+      # the Proton structure as a record. That record lives for as long as the
+      # Proton structure lives, and when the structure is released the record acts
+      # as hook to also delete the Ruby wrapper object from the registry.
 
-    def self.included(base)
-      base.extend(ClassMethods)
-    end
-
-    # Adds methods to the target class for storing and retrieving pure Ruby
-    # wrappers to underlying Proton structures.
-    #
-    # Such wrappers are stored in a registry using a key. The key is then
-    # attached to the Proton structure as a record. That record lives for as
-    # long as the Proton structure lives, and when the structure is released
-    # the record acts as hook to also delete the Ruby wrapper object from the
-    # registry.
-    #
-    # @private
-    #
-    module ClassMethods
+      @@registry = {}
 
       # @private
       def get_key(impl)
         ("%032x" % Cproton.pni_address_of(impl))
       end
 
+      # @private
       # Stores the given object for later retrieval.
       #
       # @param object [Object] The object.
@@ -75,7 +74,7 @@ module Qpid::Proton::Util
           Cproton.pn_record_def(record, RBCTX, Cproton.Pn_rbkey__class());
           Cproton.pn_record_set(record, RBCTX, rbkey)
         end
-        Qpid::Proton::Util::Wrapper.registry[registry_key] = object
+        @@registry[registry_key] = object
       end
 
       # Retrieves the wrapper object with the supplied Proton struct.
@@ -100,9 +99,9 @@ module Qpid::Proton::Util
           registry_key = get_key(impl)
         end
         # if the object's not in the registry then return
-        return nil unless Qpid::Proton::Util::Wrapper.registry.has_key?(registry_key)
+        return nil unless @@registry.has_key?(registry_key)
 
-        result = Qpid::Proton::Util::Wrapper.registry[registry_key]
+        result = @@registry[registry_key]
         # result = nil unless result.weakref_alive?
         if result.nil?
           raise Qpid::Proton::ProtonError.new("missing object for key=#{registry_key}")
@@ -112,18 +111,32 @@ module Qpid::Proton::Util
         end
         return result
       end
-
+      RBCTX = self.hash.to_i
     end
+    # @private
+    module Wrapper
 
-    # Hash/equality of wrappers is based on their @impl pointers, not object_id
+      def self.included(base)
+        base.extend(SWIGClassHelper)
+      end
 
-    def hash() @impl.hash; end
-    def ==(x)  @impl == x.impl; end
-    alias eql? ==
+      attr_accessor :impl
 
-  end
+      def inspect
+        pstr = Cproton.pn_string("")
+        begin
+          Cproton.pn_inspect(@impl, pstr)
+          return Cproton.pn_string_get(pstr)
+        ensure
+          Cproton.pn_free(pstr)
+        end
+      end
 
-  # @private
-  RBCTX = Wrapper.hash.to_i
+      alias to_s inspect
 
+      def self.registry
+        @registry ||= {}
+      end
+    end
+  end
 end


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org