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:03 UTC
[4/9] qpid-proton git commit: PROTON-1537: [ruby] Fixed encoding
problems, simplified Codec::Data.
PROTON-1537: [ruby] Fixed encoding problems, simplified Codec::Data.
Code::Data decodes/encodes all specific AMQP types with methods named type/type=
General encoding of any ruby object with Data#object=, Data#<<
General decoding with Data#object, decodes as ruby object for the type.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/c172383d
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/c172383d
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/c172383d
Branch: refs/heads/master
Commit: c172383d4439f0c47a094e403134a7d226b85fa7
Parents: 889c0c6
Author: Alan Conway <ac...@redhat.com>
Authored: Thu Dec 7 14:26:05 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Wed Dec 13 13:16:48 2017 -0500
----------------------------------------------------------------------
proton-c/bindings/ruby/lib/codec/data.rb | 465 ++++++---------------
proton-c/bindings/ruby/lib/codec/mapping.rb | 273 ++++++------
proton-c/bindings/ruby/lib/core/container.rb | 2 +-
proton-c/bindings/ruby/lib/core/event.rb | 1 -
proton-c/bindings/ruby/lib/core/exceptions.rb | 3 +-
proton-c/bindings/ruby/lib/core/message.rb | 139 ++----
proton-c/bindings/ruby/lib/qpid_proton.rb | 1 +
proton-c/bindings/ruby/lib/types/array.rb | 188 +++------
proton-c/bindings/ruby/lib/types/described.rb | 43 +-
proton-c/bindings/ruby/lib/types/hash.rb | 63 +--
proton-c/bindings/ruby/lib/types/type.rb | 68 +++
proton-c/bindings/ruby/lib/util/wrapper.rb | 1 +
proton-c/bindings/ruby/spec/array_spec.rb | 17 +-
proton-c/bindings/ruby/spec/data_spec.rb | 22 +-
proton-c/bindings/ruby/spec/hash_spec.rb | 12 -
proton-c/bindings/ruby/tests/test_data.rb | 66 +++
proton-c/bindings/ruby/tests/test_interop.rb | 76 ++--
17 files changed, 541 insertions(+), 899 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c172383d/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 9814836..86af3a1 100644
--- a/proton-c/bindings/ruby/lib/codec/data.rb
+++ b/proton-c/bindings/ruby/lib/codec/data.rb
@@ -15,80 +15,40 @@
# specific language governing permissions and limitations
# under the License.
+module Qpid::Proton
+ # @private
+ module Codec
-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
- #
+ DataError = ::TypeError
+
+ # @private wrapper for pn_data_t*
+ # Raises TypeError for invalid conversions
class Data
# @private
- PROTON_METHOD_PREFIX = "pn_disposition"
+ PROTON_METHOD_PREFIX = "pn_data"
# @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
+ # @private
+ # Convert a pn_data_t* containing a single value to a ruby object.
+ # @return [Object, nil] The ruby value extracted from +impl+ or nil if impl is empty
+ def self.to_object(impl)
+ if (Cproton.pn_data_size(impl) > 0)
+ d = Data.new(impl)
+ d.rewind
+ d.next_object
+ end
+ 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
+ # @private
+ # Clear a pn_data_t* and convert a ruby object into it. If x==nil leave it empty.
+ def self.from_object(impl, x)
+ d = Data.new(impl)
+ d.clear
+ d.object = x if x
+ nil
+ end
# @overload initialize(capacity)
# @param capacity [Integer] capacity for the new data instance.
@@ -115,86 +75,20 @@ module Qpid::Proton module Codec
}
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(@impl)
- self
- end
+ proton_caller :clear, :rewind, :next, :prev, :enter, :exit, :type
- # 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)
+ def enter_exit()
+ enter
+ yield self
+ ensure
+ exit
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(@impl)
- 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(@impl)
- return (dtype == -1) ? nil : dtype
- end
+ def code() Cproton.pn_data_type(@impl); end
- # @return [Integer] The type object for the current node.
- # @see #type_code
- #
- def type
- Mapping.for_code(type_code)
- end
+ def type() Mapping.for_code(Cproton.pn_data_type(@impl)); end
# 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
@@ -213,233 +107,101 @@ module Qpid::Proton module Codec
# 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(@impl))
- end
+ proton_is :described, :array_described
+ proton_caller :put_described
+ proton_caller :put_list, :get_list, :put_map, :get_map
+ proton_get :array_type
+ proton_caller :put_array
+ def get_array() [Cproton.pn_data_get_array(@impl), array_described?, array_type]; 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)
+ def expect(code)
+ unless code == self.code
+ raise TypeError, "expected #{Cproton.pn_type_name(code)}, got #{Cproton.pn_type_name(code)}"
+ end
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))
+ def described
+ expect Cproton::PN_DESCRIBED
+ enter_exit { Types::Described.new(self.next_object, self.next_object) }
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)
+ def described= d
+ put_described
+ enter_exit { self << d.descriptor << d.value }
end
- # @private
- def get_map
- ::Hash.proton_data_get(self)
+ def fill(a, count, what)
+ a << self.object while self.next
+ raise TypeError, "#{what} expected #{count} elements, got #{a.size}" unless a.size == count
+ a
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))
+ def list
+ return array if code == Cproton::PN_ARRAY
+ expect Cproton::PN_LIST
+ count = get_list
+ a = []
+ enter_exit { fill(a, count, __method__) }
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) ]
+ def list=(a)
+ put_list
+ enter_exit { a.each { |x| self << x } }
end
- # @private
- def get_array
- ::Array.proton_get(self)
+ def array
+ return list if code == Cproton::PN_LIST
+ expect Cproton::PN_ARRAY
+ count, d, t = get_array
+ enter_exit do
+ desc = next_object if d
+ a = Types::UniformArray.new(t, nil, desc)
+ fill(a, count, "array")
+ end
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))
+ def array=(a)
+ t = a.type if a.respond_to? :type
+ d = a.descriptor if a.respond_to? :descriptor
+ if (h = a.instance_variable_get(:@proton_array_header))
+ t ||= h.type
+ d ||= h.descriptor
+ end
+ raise TypeError, "no type when converting #{a.class} to an array" unless t
+ put_array(!d.nil?, t.code)
+ m = Mapping[t]
+ enter_exit do
+ self << d unless d.nil?
+ a.each { |e| m.put(self, e); }
+ end
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)
+ def map
+ expect Cproton::PN_MAP
+ count = self.get_map
+ raise TypeError, "invalid map, total of keys and values is odd" if count.odd?
+ enter_exit do
+ m = {}
+ m[object] = next_object while self.next
+ raise TypeError, "map expected #{count/2} entries, got #{m.size}" unless m.size == count/2
+ m
+ end
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)
+ def map= m
+ put_map
+ enter_exit { m.each_pair { |k,v| self << k << v } }
end
- # Puts a null value.
- #
- def null
- check(Cproton.pn_data_put_null(@impl))
- end
+ # Return nil if vallue is null, raise exception otherwise.
+ def null() raise TypeError, "expected null, got #{type || 'empty'}" unless null?; end
- # Utility method for Qpid::Proton::Codec::Mapping
- #
- # @private
- #
- def null=(value)
- null
- end
+ # Set the current value to null
+ def null=(dummy=nil) check(Cproton.pn_data_put_null(@impl)); end
# Puts an arbitrary object type.
#
@@ -450,6 +212,16 @@ module Qpid::Proton module Codec
#
def object=(object)
Mapping.for_class(object.class).put(self, object)
+ object
+ end
+
+ # Add an arbitrary data value using object=, return self
+ def <<(x) self.object=x; self; end
+
+ # Move forward to the next value and return it
+ def next_object
+ self.next or raise TypeError, "not enough data"
+ self.object
end
# Gets the current node, based on how it was encoded.
@@ -457,9 +229,7 @@ module Qpid::Proton module Codec
# @return [Object] The current node.
#
def object
- type = self.type
- return nil if type.nil?
- type.get(data)
+ self.type.get(self) if self.type
end
# Checks if the current node is null.
@@ -862,10 +632,10 @@ module Qpid::Proton module Codec
# If the current node is a symbol, returns its value. Otherwise, it
# returns an empty string ("").
#
- # @return [String] The symbolic string value.
+ # @return [Symbol] The symbol value.
#
def symbol
- Cproton.pn_data_get_symbol(@impl)
+ Cproton.pn_data_get_symbol(@impl).to_sym
end
# Get the current value as a single object.
@@ -901,13 +671,12 @@ module Qpid::Proton module Codec
# @private
def check(err)
if err < 0
- raise DataError, "[#{err}]: #{Cproton.pn_data_error(@impl)}"
+ raise TypeError, "[#{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/c172383d/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 92d0858..1b8df6e 100644
--- a/proton-c/bindings/ruby/lib/codec/mapping.rb
+++ b/proton-c/bindings/ruby/lib/codec/mapping.rb
@@ -16,165 +16,170 @@
# under the License.
-module Qpid::Proton::Codec
+module Qpid::Proton
+ module Codec
- # Maps between Proton types and their Ruby native language counterparts.
- #
- # @private
- class Mapping
+ # Maps between Proton types and their Ruby native language counterparts.
+ #
+ # @private
+ class Mapping
+
+ attr_reader :code
+ attr_reader :put_method
+ attr_reader :get_method
+
+ @@by_code = {}
+ @@by_class = {}
+
+ # Creates a new mapping.
+ #
+ # ==== Arguments
+ #
+ # * code - the AMQP code for this type
+ # * name - the AMQP name for this type
+ # * klasses - native Ruby classes that are mapped to this AMQP type
+ # * getter - overrides the get method for the type
+ def initialize(code, name, klasses = nil, getter = nil)
+
+ @code = code
+ @name = name
+
+ @@by_code[code] = self
+
+ unless klasses.nil?
+ klasses.each do |klass|
+ raise "entry exists for #{klass}" if @@by_class.keys.include? klass
+ @@by_class[klass] = self unless klass.nil?
+ end
+ end
- attr_reader :code
- attr_reader :put_method
- attr_reader :get_method
+ @put_method = (name + "=").intern
- # Creates a new mapping.
- #
- # ==== Arguments
- #
- # * code - the AMQP code for this type
- # * name - the AMQP name for this type
- # * klasses - native Ruby classes that are mapped to this AMQP type
- # * getter - overrides the get method for the type
- def initialize(code, name, klasses = nil, getter = nil)
-
- @debug = (name == "bool")
-
- @code = code
- @name = name
-
- @@by_preferred ||= {}
- @@by_code ||= {}
- @@by_code["#{code}"] = self
- @@by_name ||= {}
- @@by_name[name] = self
- @@by_class ||= {}
-
- unless klasses.nil?
- klasses.each do |klass|
- raise "entry exists for #{klass}" if @@by_class.keys.include? klass
- @@by_class[klass] = self unless klass.nil?
+ if getter.nil?
+ @get_method = name.intern
+ else
+ @get_method = getter.intern
end
end
- @put_method = (name + "=").intern
+ def to_s; @name; end
- if getter.nil?
- @get_method = name.intern
- else
- @get_method = getter.intern
+ def put(data, value)
+ data.__send__(@put_method, value)
end
- end
- def to_s; @name; end
+ def get(data)
+ data.__send__(@get_method)
+ end
- def put(data, value)
- data.__send__(@put_method, value)
- end
+ def self.for_class(klass)
+ c = klass
+ c = c.superclass while c && (x = @@by_class[c]).nil?
+ raise TypeError, "#{klass} cannot be converted to AMQP" unless x
+ x
+ end
- def get(data)
- data.__send__(@get_method)
- end
+ def self.for_code(code)
+ @@by_code[code]
+ end
- 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
+ # Convert x to a Mapping
+ def self.[](x)
+ case x
+ when Mapping then x
+ when Integer then @@by_code[x]
+ when Types::Type then @@by_code[x.code]
+ end
+ end
- def self.for_code(code)
- @@by_code["#{code}"]
end
- end
-
- NULL = Mapping.new(Cproton::PN_NULL, "null", [NilClass], "nil?")
- BOOL = Mapping.new(Cproton::PN_BOOL, "bool", [TrueClass, FalseClass], "bool")
- UBYTE = Mapping.new(Cproton::PN_UBYTE, "ubyte")
- BYTE = Mapping.new(Cproton::PN_BYTE, "byte")
- USHORT = Mapping.new(Cproton::PN_USHORT, "ushort")
- SHORT = Mapping.new(Cproton::PN_SHORT, "short")
- UINT = Mapping.new(Cproton::PN_UINT, "uint")
- INT = Mapping.new(Cproton::PN_INT, "int")
- CHAR = Mapping.new(Cproton::PN_CHAR, "char")
- ULONG = Mapping.new(Cproton::PN_ULONG, "ulong")
- LONG = Mapping.new(Cproton::PN_LONG, "long", [Integer])
- TIMESTAMP = Mapping.new(Cproton::PN_TIMESTAMP, "timestamp", [Date, Time])
- FLOAT = Mapping.new(Cproton::PN_FLOAT, "float")
- DOUBLE = Mapping.new(Cproton::PN_DOUBLE, "double", [Float])
- DECIMAL32 = Mapping.new(Cproton::PN_DECIMAL32, "decimal32")
- DECIMAL64 = Mapping.new(Cproton::PN_DECIMAL64, "decimal64")
- DECIMAL128 = Mapping.new(Cproton::PN_DECIMAL128, "decimal128")
- UUID = Mapping.new(Cproton::PN_UUID, "uuid")
- BINARY = Mapping.new(Cproton::PN_BINARY, "binary")
- STRING = Mapping.new(Cproton::PN_STRING, "string", [::String,
- Qpid::Proton::Types::UTFString,
- Qpid::Proton::Types::BinaryString])
- SYMBOL = Mapping.new(Cproton::PN_SYMBOL, "symbol", [::Symbol])
- DESCRIBED = Mapping.new(Cproton::PN_DESCRIBED, "described", [Qpid::Proton::Types::Described], "get_described")
- ARRAY = Mapping.new(Cproton::PN_ARRAY, "array", nil, "get_array")
- LIST = Mapping.new(Cproton::PN_LIST, "list", [::Array], "get_array")
- MAP = Mapping.new(Cproton::PN_MAP, "map", [::Hash], "get_map")
-
-
- private
-
- class << STRING
- def put(data, value)
- # if we have a symbol then convert it to a string
- value = value.to_s if value.is_a?(Symbol)
-
- isutf = false
-
- if value.is_a?(Qpid::Proton::Types::UTFString)
- isutf = true
- else
- # For Ruby 1.8 we will just treat all strings as binary.
- # For Ruby 1.9+ we can check the encoding first to see what it is
- if RUBY_VERSION >= "1.9"
- # If the string is ASCII-8BIT then treat is as binary. Otherwise,
- # try to convert it to UTF-8 and, if successful, send as that.
- if value.encoding != Encoding::ASCII_8BIT &&
- value.encode(Encoding::UTF_8).valid_encoding?
- isutf = true
+ NULL = Mapping.new(Cproton::PN_NULL, "null", [NilClass])
+ BOOL = Mapping.new(Cproton::PN_BOOL, "bool", [TrueClass, FalseClass])
+ UBYTE = Mapping.new(Cproton::PN_UBYTE, "ubyte")
+ BYTE = Mapping.new(Cproton::PN_BYTE, "byte")
+ USHORT = Mapping.new(Cproton::PN_USHORT, "ushort")
+ SHORT = Mapping.new(Cproton::PN_SHORT, "short")
+ UINT = Mapping.new(Cproton::PN_UINT, "uint")
+ INT = Mapping.new(Cproton::PN_INT, "int")
+ CHAR = Mapping.new(Cproton::PN_CHAR, "char")
+ ULONG = Mapping.new(Cproton::PN_ULONG, "ulong")
+ LONG = Mapping.new(Cproton::PN_LONG, "long", [Integer])
+ TIMESTAMP = Mapping.new(Cproton::PN_TIMESTAMP, "timestamp", [Date, Time])
+ FLOAT = Mapping.new(Cproton::PN_FLOAT, "float")
+ DOUBLE = Mapping.new(Cproton::PN_DOUBLE, "double", [Float])
+ DECIMAL32 = Mapping.new(Cproton::PN_DECIMAL32, "decimal32")
+ DECIMAL64 = Mapping.new(Cproton::PN_DECIMAL64, "decimal64")
+ DECIMAL128 = Mapping.new(Cproton::PN_DECIMAL128, "decimal128")
+ UUID = Mapping.new(Cproton::PN_UUID, "uuid")
+ BINARY = Mapping.new(Cproton::PN_BINARY, "binary")
+ STRING = Mapping.new(Cproton::PN_STRING, "string", [::String,
+ Types::UTFString,
+ Types::BinaryString])
+ SYMBOL = Mapping.new(Cproton::PN_SYMBOL, "symbol", [::Symbol])
+ DESCRIBED = Mapping.new(Cproton::PN_DESCRIBED, "described", [Types::Described])
+ ARRAY = Mapping.new(Cproton::PN_ARRAY, "array", [Types::UniformArray])
+ LIST = Mapping.new(Cproton::PN_LIST, "list", [::Array])
+ MAP = Mapping.new(Cproton::PN_MAP, "map", [::Hash])
+
+ private
+
+ class << STRING
+ def put(data, value)
+ # if we have a symbol then convert it to a string
+ value = value.to_s if value.is_a?(Symbol)
+
+ isutf = false
+
+ if value.is_a?(Types::UTFString)
+ isutf = true
+ else
+ # For Ruby 1.8 we will just treat all strings as binary.
+ # For Ruby 1.9+ we can check the encoding first to see what it is
+ if RUBY_VERSION >= "1.9"
+ # If the string is ASCII-8BIT then treat is as binary. Otherwise,
+ # try to convert it to UTF-8 and, if successful, send as that.
+ if value.encoding != Encoding::ASCII_8BIT &&
+ value.encode(Encoding::UTF_8).valid_encoding?
+ isutf = true
+ end
end
end
- end
- data.string = value if isutf
- data.binary = value if !isutf
+ data.string = value if isutf
+ data.binary = value if !isutf
+ end
end
- end
- class << MAP
- def put(data, map, options = {})
- data.put_map
- data.enter
- map.each_pair do |key, value|
- if options[:keys] == :SYMBOL
- SYMBOL.put(data, key)
- else
- Mapping.for_class(key.class).put(data, key)
- end
+ class << MAP
+ def put(data, map, options = {})
+ data.put_map
+ data.enter
+ map.each_pair do |key, value|
+ if options[:keys] == :SYMBOL
+ SYMBOL.put(data, key)
+ else
+ data.object = key
+ end
- if value.nil?
- data.null
- else
- Mapping.for_class(value.class).put(data, value)
+ if value.nil?
+ data.null
+ else
+ data.object = value
+ end
end
+ data.exit
end
- data.exit
end
- end
- class << DESCRIBED
- def put(data, described)
- data.put_described
- data.enter
- data.object = described.descriptor
- data.object = described.value
- data.exit
+ class << DESCRIBED
+ def put(data, described)
+ data.put_described
+ data.enter
+ data.object = described.descriptor
+ data.object = described.value
+ data.exit
+ end
end
end
-
end
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c172383d/proton-c/bindings/ruby/lib/core/container.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/container.rb b/proton-c/bindings/ruby/lib/core/container.rb
index 91a3d2a..dddde03 100644
--- a/proton-c/bindings/ruby/lib/core/container.rb
+++ b/proton-c/bindings/ruby/lib/core/container.rb
@@ -105,7 +105,7 @@ module Qpid::Proton
def initialize(handler = nil, id = nil)
# Allow ID as sole argument
(handler, id = nil, handler.to_str) if (id.nil? && handler.respond_to?(:to_str))
- # Allow multiple handlers for backwards compatibility
+ # Allow multiple handlers ofor backwards compatibility
a = Array(handler)
@handler = a.size > 1 ? MessagingHandlers.new(a) : handler
@id = ((id && id.to_s) || SecureRandom.uuid).freeze
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c172383d/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 a5aa08e..88fdbaf 100644
--- a/proton-c/bindings/ruby/lib/core/event.rb
+++ b/proton-c/bindings/ruby/lib/core/event.rb
@@ -84,7 +84,6 @@ module Qpid::Proton
when Cproton::CID_pn_session then Session.wrap(Cproton.pn_cast_pn_session(x))
when Cproton::CID_pn_link then Link.wrap(Cproton.pn_cast_pn_link(x))
when Cproton::CID_pn_delivery then Delivery.wrap(Cproton.pn_cast_pn_delivery(x))
- else raise TypeError, "bad class-id #{pn_class_id(Cproton.pn_event_class(impl))}"
end
end
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c172383d/proton-c/bindings/ruby/lib/core/exceptions.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/exceptions.rb b/proton-c/bindings/ruby/lib/core/exceptions.rb
index f88b3c8..34a3e60 100644
--- a/proton-c/bindings/ruby/lib/core/exceptions.rb
+++ b/proton-c/bindings/ruby/lib/core/exceptions.rb
@@ -18,8 +18,8 @@
module Qpid::Proton
+ # @private
module Error
-
NONE = 0
EOS = Cproton::PN_EOS
ERROR = Cproton::PN_ERR
@@ -30,7 +30,6 @@ module Qpid::Proton
TIMEOUT = Cproton::PN_TIMEOUT
INTERRUPTED = Cproton::PN_INTR
INPROGRESS = Cproton::PN_INPROGRESS
-
end
# Represents a generic error at the messaging level.
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c172383d/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 8f4f67c..7041d04 100644
--- a/proton-c/bindings/ruby/lib/core/message.rb
+++ b/proton-c/bindings/ruby/lib/core/message.rb
@@ -48,26 +48,10 @@ module Qpid::Proton
# @private
def post_decode
# decode elements from the message
- @properties = {}
- props = Codec::Data.new(Cproton::pn_message_properties(@impl))
- if props.next
- @properties = props.type.get(props)
- end
- @instructions = nil
- insts = Codec::Data.new(Cproton::pn_message_instructions(@impl))
- if insts.next
- @instructions = insts.type.get(insts)
- end
- @annotations = nil
- annts = Codec::Data.new(Cproton::pn_message_annotations(@impl))
- if annts.next
- @annotations = annts.type.get(annts)
- end
- @body = nil
- body = Codec::Data.new(Cproton::pn_message_body(@impl))
- if body.next
- @body = body.type.get(body)
- end
+ @properties = Codec::Data.to_object(Cproton::pn_message_properties(@impl)) || {}
+ @instructions = Codec:: Data.to_object(Cproton::pn_message_instructions(@impl)) || {}
+ @annotations = Codec::Data.to_object(Cproton::pn_message_annotations(@impl)) || {}
+ @body = Codec::Data.to_object(Cproton::pn_message_body(@impl))
end
# Encodes the message.
@@ -88,27 +72,15 @@ module Qpid::Proton
# @private
def pre_encode
# encode elements from the message
- props = Codec::Data.new(Cproton::pn_message_properties(@impl))
- props.clear
- Codec::Mapping.for_class(@properties.class).put(props, @properties) unless @properties.empty?
- insts = Codec::Data.new(Cproton::pn_message_instructions(@impl))
- insts.clear
- if !@instructions.nil?
- mapping = Codec::Mapping.for_class(@instructions.class)
- mapping.put(insts, @instructions)
- end
- annts = Codec::Data.new(Cproton::pn_message_annotations(@impl))
- annts.clear
- if !@annotations.nil?
- mapping = Codec::Mapping.for_class(@annotations.class)
- mapping.put(annts, @annotations, :keys => :SYMBOL)
- end
- body = Codec::Data.new(Cproton::pn_message_body(@impl))
- body.clear
- if !@body.nil?
- mapping = Codec::Mapping.for_class(@body.class)
- mapping.put(body, @body)
+ Codec::Data.from_object(Cproton::pn_message_properties(@impl), !@properties.empty? && @properties)
+ Codec::Data.from_object(Cproton::pn_message_instructions(@impl), !@instructions.empty? && @instructions)
+ if @annotations # Make sure keys are symbols
+ @annotations.keys.each do |k|
+ @annotations[k.to_sym] = @annotations.delete(k) unless k.is_a? Symbol
+ end
end
+ Codec::Data.from_object(Cproton::pn_message_annotations(@impl), !@annotations.empty? && @annotations)
+ Codec::Data.from_object(Cproton::pn_message_body(@impl), @body)
end
# Creates a new +Message+ instance.
@@ -512,89 +484,32 @@ module Qpid::Proton
Cproton.pn_message_get_reply_to_group_id(@impl)
end
- # Returns the list of property names for associated with this message.
- #
- # ==== Examples
- #
- # msg.properties.each do |name|
- # end
- #
- def properties
- @properties
- end
+ # @return [Hash] Application properties for the message
+ attr_accessor :properties
- # Use +properties+ as the message properties.
- # @param properties [Hash] new properties
- def properties=(properties)
- @properties = properties
- end
+ # Equivalent to +{#properties}[name] = value+
+ def []=(name, value) @properties[name] = value; end
- # Assigns the value given to the named property.
- #
- # ==== Arguments
- #
- # * name - the property name
- # * value - the property value
- #
- def []=(name, value)
- @properties[name] = value
- end
+ # Equivalent to +{#properties}[name]+
+ def [](name) @properties[name]; end
- # Retrieves the value for the specified property name. If not found, then
- # it returns nil.
- #
- def [](name)
- @properties[name]
- end
+ # Equivalent to +{#properties}.delete(name)+
+ def delete_property(name) @properties.delete(name); end
- # Deletes the named property.
- #
- def delete_property(name)
- @properties.delete(name)
- end
-
- # Returns the instructions for this message.
- #
- def instructions
- @instructions
- end
+ # @return [Hash] Delivery instructions for this message.
+ attr_accessor :instructions
- # Assigns instructions to this message.
- #
- def instructions=(instr)
- @instructions = instr
- end
+ # @return [Hash] Delivery annotations for this message.
+ attr_accessor :annotations
- # Returns the annotations for this message.
- #
- def annotations
- @annotations
- end
-
- # Assigns annotations to this message.
- #
- def annotations=(annotations)
- @annotations = annotations
- end
-
- # Returns the body property of the message.
- #
- def body
- @body
- end
-
- # 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
+ # @return [Object] body of the message.
+ attr_accessor :body
private
def check(err) # :nodoc:
if err < 0
- raise DataError, "[#{err}]: #{Cproton.pn_message_error(@data)}"
+ raise TypeError, "[#{err}]: #{Cproton.pn_message_error(@data)}"
else
return err
end
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c172383d/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 a226838..3af6d39 100644
--- a/proton-c/bindings/ruby/lib/qpid_proton.rb
+++ b/proton-c/bindings/ruby/lib/qpid_proton.rb
@@ -51,6 +51,7 @@ require "util/wrapper"
require "util/timeout"
# Types
+require "types/type"
require "types/strings"
require "types/hash"
require "types/array"
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c172383d/proton-c/bindings/ruby/lib/types/array.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/types/array.rb b/proton-c/bindings/ruby/lib/types/array.rb
index 88eb26b..3051f31 100644
--- a/proton-c/bindings/ruby/lib/types/array.rb
+++ b/proton-c/bindings/ruby/lib/types/array.rb
@@ -21,151 +21,83 @@
# to a Qpid::Proton::Data instance.
#++
-module Qpid::Proton::Types
+module Qpid::Proton
+ module Types
+
+ # @deprecated use {UniformArray}
+ class ArrayHeader
+ def initialize(type, descriptor = nil) @type, @descriptor = Codec::Mapping[type], descriptor; end
+ attr_reader :type, :descriptor
+ def described?() !@descriptor.nil?; end
+ def <=>(x) [@type, @descriptor] <=> [x.type, x.descriptor]; end
+ include Comparable
+ end
- # Holds the information for an AMQP Array compound type.
- #
- # It holds the type for the array and the descriptor if the
- # array is described.
- #
- # @private
- #
- class ArrayHeader
- attr_reader :type
- attr_reader :descriptor
+ # *Unsettled API* - An array that is converted to/from an AMQP array of uniform element type.
+ # A plain ruby +::Array+ is converted to/from an AMQP list, which can contain mixed type elements.
+ # If invalid elements are included, then {TypeError} will be raised when encoding to AMQP.
+ class UniformArray < ::Array
+
+ # Construct a uniform array, which will be converted to an AMQP array.
+ # A plain ruby +::Array+ is converted to/from an AMQP list, containing mixed type elements.
+ #
+ # @param type [Type] Elements must be convertible to this AMQP type.
+ # @param elements [Enumerator] Initial elements for the array
+ # @param descriptor [Object] Optional array descriptor
+ def initialize(type, elements=nil, descriptor=nil)
+ @type, @descriptor = type, descriptor
+ raise ArgumentError, "no type specified for array" if @type.nil?
+ super elements if elements
+ @proton_array_header = ArrayHeader.new(@type, @descriptor) # Deprecated
+ end
- def initialize(type, descriptor = nil)
- @type = type
- @descriptor = descriptor
- end
+ # @return [Type] Array elements must be convertible to this AMQP type
+ attr_reader :type
- # Returns true if the array is described.
- def described?
- !@descriptor.nil?
- end
+ # @return [Object] Optional descriptor.
+ def attr_reader() descriptor; end
- def ==(that)
- ((@type == that.type) && (@descriptor == that.descriptor))
+ def inspect() "#{self.class.name}<#{type}>#{super}"; end
end
end
-
end
-# @private
-class Array # :nodoc:
+# {Array} is converted to/from an AMQP list, which is allowed to hold mixed-type elements.
+# Use {UniformArray} to convert/from an AMQP array with uniform element type.
+class ::Array
+ # @deprecated use {UniformArray}
+ def proton_array_header
+ Qpid.deprecated __method__, "UniformArray"
+ @proton_array_header
+ end
- # Used to declare an array as an AMQP array.
- #
- # The value, if defined, is an instance of Qpid::Proton::Types::ArrayHeader
- attr_accessor :proton_array_header
+ # @deprecated use {UniformArray}
+ def proton_array_header=(h)
+ Qpid.deprecated __method__, "UniformArray"
+ @proton_array_header= h
+ end
- # Returns true if the array is the a Proton described type.
- def proton_described?
- !@proton_array_header.nil? && @proton_array_header.described?
+ # @deprecated use {UniformArray}
+ def proton_described?()
+ Qpid.deprecated __method__, "UniformArray"
+ @proton_array_header && @proton_array_header.described?
end
- # Puts the elements of the array into the specified Qpid::Proton::Data object.
+ # @deprecated
def proton_put(data)
- raise TypeError, "data object cannot be nil" if data.nil?
-
- if @proton_array_header.nil?
- proton_put_list(data)
+ Qpid.deprecated __method__, "Codec::Data#array=, Codec::Data#list="
+ raise TypeError, "nil data" unless data
+ if @proton_array_header && @proton_array_header.type
+ data.array = self
else
- proton_put_array(data)
+ data.list = self
end
end
- private
-
- def proton_put_list(data)
- # create a list, then enter it and add each element
- data.put_list
- data.enter
- each do |element|
- # get the proton type for the element
- mapping = Qpid::Proton::Codec::Mapping.for_class(element.class)
- # add the element
- mapping.put(data, element)
- end
- # exit the list
- data.exit
+ # @deprecated
+ def self.proton_get(data)
+ Qpid.deprecated __method__, "Codec::Data#list"
+ data.list
end
-
- def proton_put_array(data)
- data.put_array(@proton_array_header.described?, @proton_array_header.type)
- data.enter
- if @proton_array_header.described?
- data.symbol = @proton_array_header.descriptor
- end
-
- each do |element|
- @proton_array_header.type.put(data, element)
- end
-
- data.exit
- end
-
- class << self
-
- # Gets the elements of an array or list out of the specified
- # Qpid::Proton::Data object.
- def proton_get(data)
- raise TypeError, "can't convert nil into Qpid::Proton::Data" if data.nil?
-
- type = data.type
-
- if type == Qpid::Proton::Codec::LIST
- result = proton_get_list(data)
- elsif type == Qpid::Proton::Codec::ARRAY
- result = proton_get_array(data)
- else
- raise TypeError, "element is not a list and not an array"
- end
- end
-
- private
-
- def proton_get_list(data)
- size = data.list
- raise TypeError, "not a list" unless data.enter
- elements = []
- (0...size).each do
- data.next
- type = data.type
- raise TypeError, "missing next element in list" unless type
- elements << type.get(data)
- end
- data.exit
- return elements
- end
-
- def proton_get_array(data)
- count, described, type = data.array
-
- raise TypeError, "not an array" unless data.enter
- elements = []
-
- descriptor = nil
-
- if described
- data.next
- descriptor = data.symbol
- end
-
- elements.proton_array_header = Qpid::Proton::Types::ArrayHeader.new(type, descriptor)
- (0...count).each do |which|
- if data.next
- etype = data.type
- raise TypeError, "missing next element in array" unless etype
- raise TypeError, "invalid array element: #{etype}" unless etype == type
- elements << type.get(data)
- end
- end
- data.exit
- return elements
- end
-
- end
-
end
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c172383d/proton-c/bindings/ruby/lib/types/described.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/types/described.rb b/proton-c/bindings/ruby/lib/types/described.rb
index fb880ba..41d7ed2 100644
--- a/proton-c/bindings/ruby/lib/types/described.rb
+++ b/proton-c/bindings/ruby/lib/types/described.rb
@@ -17,46 +17,5 @@
module Qpid::Proton::Types
-
- # @private
- class Described
-
- attr_reader :descriptor
- attr_reader :value
-
- def initialize(descriptor, value)
- @descriptor = descriptor
- @value = value
- end
-
- # Puts the description into the Data object.
- #
- # ==== Arguments
- #
- # * data - the Qpid::Proton::Data instance
- #
- # ==== Examples
- #
- # described = Qpid::Proton::Described.new("my-descriptor", "the value")
- # data = Qpid::Proton::Data.new
- # ...
- # described.put(data)
- #
- def put(data)
- data.symbol = @descriptor
- data.string = @value
- end
-
- def ==(that) # :nodoc:
- (that.is_a?(Qpid::Proton::Types::Described) &&
- (self.descriptor == that.descriptor) &&
- (self.value == that.value))
- end
-
- def to_s # :nodoc:
- "descriptor=#{descriptor} value=#{value}"
- end
-
- end
-
+ Described = Struct.new(:descriptor, :value)
end
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c172383d/proton-c/bindings/ruby/lib/types/hash.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/types/hash.rb b/proton-c/bindings/ruby/lib/types/hash.rb
index 9415f86..736bb8f 100644
--- a/proton-c/bindings/ruby/lib/types/hash.rb
+++ b/proton-c/bindings/ruby/lib/types/hash.rb
@@ -23,64 +23,15 @@
# @private
class Hash # :nodoc:
-
- # Places the contents of the hash into the specified data object.
- #
- # ==== Arguments
- #
- # * data - the Qpid::Proton::Data instance
- #
- # ==== Examples
- #
- # data = Qpid::Proton::Data.new
- # values = {:foo => :bar}
- # values.proton_data_put(data)
- #
+ # @deprecated
def proton_data_put(data)
- raise TypeError, "data object cannot be nil" if data.nil?
-
- data.put_map
- data.enter
-
- each_pair do |key, value|
- type = Qpid::Proton::Codec::Mapping.for_class(key.class)
- type.put(data, key)
- type = Qpid::Proton::Codec::Mapping.for_class(value.class)
- type.put(data, value)
- end
-
- data.exit
+ Qpid.deprecated(__method__, "Codec::Data#map=")
+ data.map = self
end
- class << self
-
- def proton_data_get(data)
- raise TypeError, "data object cannot be nil" if data.nil?
-
- type = data.type
-
- raise TypeError, "element is not a map" unless type == Qpid::Proton::Codec::MAP
-
- count = data.map
- result = {}
-
- data.enter
-
- (0...(count/2)).each do
- data.next
- type = data.type
- key = type.get(data)
- data.next
- type = data.type
- value = type.get(data)
- result[key] = value
- end
-
- data.exit
-
- return result
- end
-
+ # @deprecated
+ def self.proton_data_get(data)
+ Qpid.deprecated(__method__, "Codec::Data#map")
+ data.map
end
-
end
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c172383d/proton-c/bindings/ruby/lib/types/type.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/types/type.rb b/proton-c/bindings/ruby/lib/types/type.rb
new file mode 100644
index 0000000..8defa42
--- /dev/null
+++ b/proton-c/bindings/ruby/lib/types/type.rb
@@ -0,0 +1,68 @@
+#--
+# 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
+ module Types
+
+ # Represents an AMQP Type
+ class Type
+ private
+ @@builtin = {}
+ def initialize(code) @code = code; @@builtin[code] = self; end
+
+ public
+ def self.try_convert(code) code.is_a?(Type) ? code : @@builtin[code]; end
+ def self.[](code) try_convert(code) or raise IndexError, "unknown type code #{code}"; end
+
+ attr_reader :code
+ def name() Cproton.pn_type_name(@code); end
+ alias to_s name
+ def <=>(x) @code <=> x; end
+ def hash() @code.hash; end
+ end
+
+ # @!group
+ NULL = Type.new(Cproton::PN_NULL)
+ BOOL = Type.new(Cproton::PN_BOOL)
+ UBYTE = Type.new(Cproton::PN_UBYTE)
+ BYTE = Type.new(Cproton::PN_BYTE)
+ USHORT = Type.new(Cproton::PN_USHORT)
+ SHORT = Type.new(Cproton::PN_SHORT)
+ UINT = Type.new(Cproton::PN_UINT)
+ INT = Type.new(Cproton::PN_INT)
+ CHAR = Type.new(Cproton::PN_CHAR)
+ ULONG = Type.new(Cproton::PN_ULONG)
+ LONG = Type.new(Cproton::PN_LONG)
+ TIMESTAMP = Type.new(Cproton::PN_TIMESTAMP)
+ FLOAT = Type.new(Cproton::PN_FLOAT)
+ DOUBLE = Type.new(Cproton::PN_DOUBLE)
+ DECIMAL32 = Type.new(Cproton::PN_DECIMAL32)
+ DECIMAL64 = Type.new(Cproton::PN_DECIMAL64)
+ DECIMAL128 = Type.new(Cproton::PN_DECIMAL128)
+ UUID = Type.new(Cproton::PN_UUID)
+ BINARY = Type.new(Cproton::PN_BINARY)
+ STRING = Type.new(Cproton::PN_STRING)
+ SYMBOL = Type.new(Cproton::PN_SYMBOL)
+ DESCRIBED = Type.new(Cproton::PN_DESCRIBED)
+ ARRAY = Type.new(Cproton::PN_ARRAY)
+ LIST = Type.new(Cproton::PN_LIST)
+ MAP = Type.new(Cproton::PN_MAP)
+ #@!endgroup
+ end
+end
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c172383d/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 39cd7b4..347a9a5 100644
--- a/proton-c/bindings/ruby/lib/util/wrapper.rb
+++ b/proton-c/bindings/ruby/lib/util/wrapper.rb
@@ -113,6 +113,7 @@ module Qpid::Proton
end
RBCTX = self.hash.to_i
end
+
# @private
module Wrapper
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c172383d/proton-c/bindings/ruby/spec/array_spec.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/spec/array_spec.rb b/proton-c/bindings/ruby/spec/array_spec.rb
index 3bfe559..e760877 100644
--- a/proton-c/bindings/ruby/spec/array_spec.rb
+++ b/proton-c/bindings/ruby/spec/array_spec.rb
@@ -38,20 +38,10 @@ describe "The extended array type" do
expect(value).respond_to? :proton_described?
end
- it "raises an error when putting into a nil Data object" do
- expect { @list.proton_put(nil) }.must_raise(TypeError)
- end
-
it "raises an error when getting from a nil Data object" do
expect {
Array.proton_get(nil)
- }.must_raise(TypeError)
- end
-
- it "raises an error when the data object is empty" do
- expect {
- Array.proton_get(@data)
- }.must_raise(TypeError)
+ }.must_raise
end
it "raises an error when the current object is not a list" do
@@ -92,6 +82,7 @@ describe "The extended array type" do
it "can be put into a Data object as an undescribed array" do
@undescribed.proton_put(@data)
result = Array.proton_get(@data)
+ expect(result).is_a? Qpid::Proton::Types::UniformArray
expect(@undescribed).must_equal(result)
expect(result.proton_array_header).wont_be_nil
expect(result.proton_array_header).must_equal(@undescribed.proton_array_header)
@@ -101,8 +92,8 @@ describe "The extended array type" do
it "can be put into a Data object as a described array" do
@described.proton_put(@data)
result = Array.proton_get(@data)
- expect(@described) == result
-
+ expect(@described).must_equal(result)
+ expect(result).is_a? Qpid::Proton::Types::UniformArray
expect(result.proton_array_header).wont_be_nil
expect(result.proton_array_header).must_equal(@described.proton_array_header)
expect(result.proton_array_header.described?).must_equal(true)
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c172383d/proton-c/bindings/ruby/spec/data_spec.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/spec/data_spec.rb b/proton-c/bindings/ruby/spec/data_spec.rb
index f4041e4..d5c92fb 100644
--- a/proton-c/bindings/ruby/spec/data_spec.rb
+++ b/proton-c/bindings/ruby/spec/data_spec.rb
@@ -34,7 +34,7 @@ module Qpid
end
it "can hold a null" do
- @data.null
+ @data.null = nil
expect(@data.null?).must_equal(true)
end
@@ -385,17 +385,17 @@ module Qpid
it "can hold a null symbol" do
@data.symbol = nil
- expect(@data.symbol).must_equal("")
+ expect(@data.symbol).must_equal(:"")
end
it "can hold a symbol" do
- value = random_string(128)
+ value = random_string(128).to_sym
@data.symbol = value
expect(@data.symbol).must_equal(value)
end
it "can hold a described value" do
- name = random_string(16)
+ name = random_string(16).to_sym
value = random_string(16)
@data.put_described
@data.enter
@@ -411,12 +411,16 @@ module Qpid
expect(@data.string).must_equal(value)
end
- it "raises an error when setting the wrong type in an array"
+ it "raises an error when setting the wrong type in an array" do
+ expect {
+ @data << Qpid::Proton::Types::UniformArray.new(Qpid::Proton::Types::INT, [1, 2.0, :a, "b"])
+ }.must_raise(TypeError)
+ end
it "can hold an array" do
values = []
(1..(rand(100) + 5)).each { values << rand(2**16) }
- @data.put_array false, Qpid::Proton::Codec::INT
+ @data.put_array false, Qpid::Proton::Codec::INT.code
@data.enter
values.each { |value| @data.int = value }
@data.exit
@@ -431,14 +435,14 @@ module Qpid
it "can hold a described array" do
values = []
(1..(rand(100) + 5)).each { values << random_string(64) }
- descriptor = random_string(32)
- @data.put_array true, Qpid::Proton::Codec::STRING
+ descriptor = random_string(32).to_sym
+ @data.put_array true, Qpid::Proton::Codec::STRING.code
@data.enter
@data.symbol = descriptor
values.each { |value| @data.string = value }
@data.exit
- expect(@data.array).must_equal([values.size, true, Qpid::Proton::Codec::STRING])
+ expect(@data.get_array).must_equal([values.size, true, Qpid::Proton::Codec::STRING.code])
@data.enter
@data.next
expect(@data.symbol).must_equal(descriptor)
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c172383d/proton-c/bindings/ruby/spec/hash_spec.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/spec/hash_spec.rb b/proton-c/bindings/ruby/spec/hash_spec.rb
index cd661c2..92acd0a 100644
--- a/proton-c/bindings/ruby/spec/hash_spec.rb
+++ b/proton-c/bindings/ruby/spec/hash_spec.rb
@@ -26,12 +26,6 @@ describe "The extended hash type" do
@hash = random_hash(rand(128) + 64)
end
- it "raises an error when put into a nil Data instance" do
- expect {
- @hash.proton_data_put(nil)
- }.must_raise(TypeError)
- end
-
it "can be put into an instance of Data" do
@hash.proton_data_put(@data)
result = Hash.proton_data_get(@data)
@@ -39,12 +33,6 @@ describe "The extended hash type" do
expect(result.values).must_equal(@hash.values)
end
- it "raises an error when retrieved from a nil Data instance" do
- expect {
- Hash.proton_data_get(nil)
- }.must_raise(TypeError)
- end
-
it "raises an error when trying to get what is not a Hash" do
@data.string = random_string(128)
@data.rewind
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c172383d/proton-c/bindings/ruby/tests/test_data.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/tests/test_data.rb b/proton-c/bindings/ruby/tests/test_data.rb
new file mode 100644
index 0000000..b1ae2d9
--- /dev/null
+++ b/proton-c/bindings/ruby/tests/test_data.rb
@@ -0,0 +1,66 @@
+# 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.
+
+
+require 'minitest/autorun'
+require "securerandom"
+require 'qpid_proton'
+
+class TestData < Minitest::Test
+ include Qpid::Proton
+
+ def assert_from_to(*values)
+ d = Codec::Data.new
+ values.each do |x|
+ Codec::Data.from_object(d.impl, x)
+ assert_equal x, Codec::Data.to_object(d.impl)
+ end
+ end
+
+ def test_from_to
+ assert_from_to({ 1 => :one, 2=>:two })
+ assert_from_to([{:a => 1, "b" => 2}, 3, 4.4, :five])
+ assert_from_to(Types::UniformArray.new(Types::INT, [1, 2, 3, 4]))
+ end
+
+ def rnum(*arg) SecureRandom.random_number(*arg); end
+ def rstr(*arg) SecureRandom.base64(*arg); end
+
+ def test_nil()
+ assert_nil((Codec::Data.new << nil).object)
+ end
+
+ def assert_convert(*values)
+ values.each { |x| assert_equal x, ((Codec::Data.new << x).object) }
+ end
+
+ def test_bool()
+ assert_convert(true, false)
+ end
+
+ def test_float()
+ assert_convert(0.0, 1.0, -1.0, 1.23e123, rnum(), rnum(), rnum(), rnum())
+ end
+
+ def test_string()
+ assert_convert("", "foo", rstr(100000), rstr(rnum(1000)), rstr(rnum(1000)))
+ end
+
+ def test_symbol()
+ assert_convert(:"", :foo, rstr(256).to_sym)
+ end
+end
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c172383d/proton-c/bindings/ruby/tests/test_interop.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/tests/test_interop.rb b/proton-c/bindings/ruby/tests/test_interop.rb
index e08ada1..0a13a3d 100755
--- a/proton-c/bindings/ruby/tests/test_interop.rb
+++ b/proton-c/bindings/ruby/tests/test_interop.rb
@@ -14,8 +14,8 @@ if ((RUBY_VERSION.split(".").map {|x| x.to_i} <=> [1, 9]) < 0)
end
class InteropTest < MiniTest::Test
- Data = Qpid::Proton::Codec::Data
- Message = Qpid::Proton::Message
+ include Qpid::Proton
+ Data = Codec::Data
def setup
@data = Data.new
@@ -53,87 +53,81 @@ class InteropTest < MiniTest::Test
def assert_next(type, value)
assert @data.next
assert_equal(type, @data.type)
- assert_equal(value, type.get(@data))
+ assert_equal(value, @data.object)
end
- def assert_array_next(expected, header)
- assert_next(Qpid::Proton::Codec::ARRAY, expected)
- result = @data.type.get(@data)
- assert_equal(result.proton_array_header, header)
+ def assert_array_next(expected)
+ result = @data.next_object
+ assert_equal(expected, result)
end
def test_message
decode_message_file("message")
- assert_next(Qpid::Proton::Codec::STRING, "hello")
+ assert_next(Codec::STRING, "hello")
assert !@data.next
end
def test_primitives
decode_data_file("primitives")
- assert_next(Qpid::Proton::Codec::BOOL, true)
- assert_next(Qpid::Proton::Codec::BOOL, false)
- assert_next(Qpid::Proton::Codec::UBYTE, 42)
- assert_next(Qpid::Proton::Codec::USHORT, 42)
- assert_next(Qpid::Proton::Codec::SHORT, -42)
- assert_next(Qpid::Proton::Codec::UINT, 12345)
- assert_next(Qpid::Proton::Codec::INT, -12345)
- assert_next(Qpid::Proton::Codec::ULONG, 12345)
- assert_next(Qpid::Proton::Codec::LONG, -12345)
- assert_next(Qpid::Proton::Codec::FLOAT, 0.125)
- assert_next(Qpid::Proton::Codec::DOUBLE, 0.125)
+ assert_next(Codec::BOOL, true)
+ assert_next(Codec::BOOL, false)
+ assert_next(Codec::UBYTE, 42)
+ assert_next(Codec::USHORT, 42)
+ assert_next(Codec::SHORT, -42)
+ assert_next(Codec::UINT, 12345)
+ assert_next(Codec::INT, -12345)
+ assert_next(Codec::ULONG, 12345)
+ assert_next(Codec::LONG, -12345)
+ assert_next(Codec::FLOAT, 0.125)
+ assert_next(Codec::DOUBLE, 0.125)
assert !@data.next
end
def test_strings
decode_data_file("strings")
- assert_next(Qpid::Proton::Codec::BINARY, "abc\0defg")
- assert_next(Qpid::Proton::Codec::STRING, "abcdefg")
- assert_next(Qpid::Proton::Codec::SYMBOL, "abcdefg")
- assert_next(Qpid::Proton::Codec::BINARY, "")
- assert_next(Qpid::Proton::Codec::STRING, "")
- assert_next(Qpid::Proton::Codec::SYMBOL, "")
+ assert_next(Codec::BINARY, "abc\0defg")
+ assert_next(Codec::STRING, "abcdefg")
+ assert_next(Codec::SYMBOL, :abcdefg)
+ assert_next(Codec::BINARY, "")
+ assert_next(Codec::STRING, "")
+ assert_next(Codec::SYMBOL, :"")
assert !@data.next
end
def test_described
decode_data_file("described")
- assert_next(Qpid::Proton::Codec::DESCRIBED, Qpid::Proton::Types::Described.new("foo-descriptor", "foo-value"))
+ assert_next(Codec::DESCRIBED, Types::Described.new(:"foo-descriptor", "foo-value"))
assert(@data.described?)
- assert_next(Qpid::Proton::Codec::DESCRIBED, Qpid::Proton::Types::Described.new(12, 13))
+ assert_next(Codec::DESCRIBED, Types::Described.new(12, 13))
assert(@data.described?)
assert !@data.next
end
def test_described_array
decode_data_file("described_array")
- assert_array_next((0...10).to_a,
- Qpid::Proton::Types::ArrayHeader.new(Qpid::Proton::Codec::INT,
- "int-array"))
+ assert_array_next(Types::UniformArray.new(Types::INT, (0...10).to_a, :"int-array"))
end
def test_arrays
decode_data_file("arrays")
- assert_array_next((0...100).to_a,
- Qpid::Proton::Types::ArrayHeader.new(Qpid::Proton::Codec::INT))
- assert_array_next(["a", "b", "c"],
- Qpid::Proton::Types::ArrayHeader.new(Qpid::Proton::Codec::STRING))
- assert_array_next([],
- Qpid::Proton::Types::ArrayHeader.new(Qpid::Proton::Codec::INT))
+ assert_array_next(Types::UniformArray.new(Codec::INT, (0...100).to_a))
+ assert_array_next(Types::UniformArray.new(Codec::STRING, ["a", "b", "c"]))
+ assert_array_next(Types::UniformArray.new(Codec::INT))
assert !@data.next
end
def test_lists
decode_data_file("lists")
- assert_next(Qpid::Proton::Codec::LIST, [32, "foo", true])
- assert_next(Qpid::Proton::Codec::LIST, [])
+ assert_next(Codec::LIST, [32, "foo", true])
+ assert_next(Codec::LIST, [])
assert !@data.next
end
def test_maps
decode_data_file("maps")
- assert_next(Qpid::Proton::Codec::MAP, {"one" => 1, "two" => 2, "three" => 3 })
- assert_next(Qpid::Proton::Codec::MAP, {1 => "one", 2 => "two", 3 => "three"})
- assert_next(Qpid::Proton::Codec::MAP, {})
+ assert_next(Codec::MAP, {"one" => 1, "two" => 2, "three" => 3 })
+ assert_next(Codec::MAP, {1 => "one", 2 => "two", 3 => "three"})
+ assert_next(Codec::MAP, {})
assert !@data.next
end
end
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org