lib/qpid_proton/data.rb in qpid_proton-0.4 vs lib/qpid_proton/data.rb in qpid_proton-0.5
- old
+ new
@@ -15,10 +15,12 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
+require 'cproton'
+
module Qpid
module Proton
# +DataError+ is raised when an error occurs while encoding
@@ -49,31 +51,38 @@
# 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*
- # * *:USHORT*
- # * *:SHORT*
- # * *:UINT*
- # * *:INT*
- # * *:ULONG*
- # * *:LONG*
- # * *:FLOAT*
- # * *:DOUBLE*
- # * *:BINARY*
- # * *:STRING*
- # * *:SYMBOL*
+ # * *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*
+ # * *DESCRIBED*
+ # * *ARRAY*
+ # * *LIST*
+ # * *MAP*
#
class Data
# Creates a new instance with the specified capacity.
#
@@ -113,26 +122,24 @@
# #next will advance to the first node.
def rewind
Cproton.pn_data_rewind(@data)
end
- # Advances the current node to tits next sibling and returns its types.
+ # 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
- found = Cproton.pn_data_next(@data)
- return found ? found : nil
+ def next(print = false)
+ Cproton.pn_data_next(@data)
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
- found = Cproton.pn_data_prev(@data)
- return found ? found : nil
+ return Cproton.pn_data_prev(@data) ? 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.
@@ -144,25 +151,30 @@
# parent.
def exit
Cproton.pn_data_exit(@data)
end
- # Returns the type of the current node.
- def node_type
+ # Returns the numeric type code of the current node.
+ def type_code
dtype = Cproton.pn_data_type(@data)
return (dtype == -1) ? nil : dtype
end
- # Returns a representation of the data encoded. in AMQP format.
+ # Return the Type object for the current node
+ def type
+ Mapping.for_code(type_code)
+ end
+
+ # Returns a representation of the data encoded in AMQP format.
def encode
- size = 1024
+ buffer = "\0"*1024
loop do
- (cd, enc) = Cproton.pn_data_encode(@data, size)
+ cd = Cproton.pn_data_encode(@data, buffer, buffer.length)
if cd == Cproton::PN_OVERFLOW
- size *= 2
+ buffer *= 2
elsif cd >= 0
- return enc
+ return buffer[0...cd]
else
check(cd)
end
end
end
@@ -173,11 +185,11 @@
# ==== Options
#
# * encoded - the encoded data
#
def decode(encoded)
- check(Cproton.pn_data_decode(@data, encoded))
+ check(Cproton.pn_data_decode(@data, encoded, encoded.length))
end
# Puts a list value.
#
# Elements may be filled by entering the list node and putting element
@@ -206,11 +218,11 @@
#
# count = @data.list
# @data.enter
# (0...count).each
# type = @data.next
- # puts "Value: #{@data.string}" if type == :STRING
+ # puts "Value: #{@data.string}" if type == STRING
# # ... process other node types
# end
def list
Cproton.pn_data_get_list(@data)
end
@@ -242,21 +254,25 @@
#
# count = @data.map
# @data.enter
# (0...count).each do
# type = @data.next
- # puts "Key=#{@data.string}" if type == :STRING
+ # puts "Key=#{@data.string}" if type == STRING
# # ... process other key types
# type = @data.next
- # puts "Value=#{@data.string}" if type == :STRING
+ # puts "Value=#{@data.string}" if type == STRING
# # ... process other value types
# end
# @data.exit
def map
Cproton.pn_data_get_map(@data)
end
+ def get_map # :nodoc:
+ ::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.
@@ -271,29 +287,28 @@
#
# ==== Examples
#
# # create an array of integer values
# data = Qpid::Proton::Data.new
- # data.put_array(false, :INT)
+ # data.put_array(false, INT)
# data.enter
# data.int = 1
# data.int = 2
# data.int = 3
# data.exit
#
# # create an array of double values
- # data.put_array(true, :DOUBLE)
+ # 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,
- Data.type_value(element_type)))
+ check(Cproton.pn_data_put_array(@data, 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).
@@ -317,18 +332,18 @@
# 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)
- if array_type == -1
- array_type = nil
- else
- array_type = Data.type_name(array_type)
- end
- [count, described, array_type]
+ return nil if array_type == -1
+ [count, described, Mapping.for_code(array_type) ]
end
+ def get_array # :nodoc:
+ ::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.
@@ -344,10 +359,23 @@
#
def put_described
check(Cproton.pn_data_put_described(@data))
end
+ def get_described # :nodoc:
+ 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
+ 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.
#
# ==== Examples
@@ -364,10 +392,15 @@
# Puts a null value.
def null
check(Cproton.pn_data_put_null(@data))
end
+ # Utility method for Qpid::Proton::Mapping
+ def null=(value) # :nodoc:
+ null
+ end
+
# Checks if the current node is null.
def null?
Cproton.pn_data_is_null(@data)
end
@@ -717,78 +750,33 @@
# returns an empty string ("").
def symbol
Cproton.pn_data_get_symbol(@data)
end
- def self.add_item(key, value, name) # :nodoc:
- @@type_value ||= {}
- @@type_value[key] = value
-
- @@type_name ||= {}
- @@type_name[value] = key
+ # Get the current value as a single object.
+ def get
+ type.get(self);
end
- # Returns the typename for the specified type.
- #
- # ==== Examples
- # # returns "null"
- # name = Qpid::Proton::Data.type_name(:NULL)
- #
- def self.type_name(key)
- @@type_name[key]
+ # Put value as an object of type type_
+ def put(value, type_);
+ type_.put(self, value);
end
- def self.type_value(key) # :nodoc:
- @@type_value[key]
- end
-
- def self.const_missing(key) # :nodoc:
- @@type_value[key]
- end
-
private
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}/
+ # 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
def check(err) # :nodoc:
if err < 0
raise DataError, "[#{err}]: #{Cproton.pn_data_error(@data)}"
else
return err
end
end
-
- self.add_item(:NULL, Cproton::PN_NULL, "null")
- self.add_item(:BOOL, Cproton::PN_BOOL, "bool")
- self.add_item(:UBYTE, Cproton::PN_UBYTE, "ubyte")
- self.add_item(:BYTE, Cproton::PN_BYTE, "byte")
- self.add_item(:USHORT, Cproton::PN_USHORT, "ushort")
- self.add_item(:SHORT, Cproton::PN_SHORT, "short")
- self.add_item(:UINT, Cproton::PN_UINT, "uint")
- self.add_item(:INT, Cproton::PN_INT, "int")
- self.add_item(:CHAR, Cproton::PN_CHAR, "char")
- self.add_item(:ULONG, Cproton::PN_ULONG, "ulong")
- self.add_item(:LONG, Cproton::PN_LONG, "long")
- self.add_item(:TIMESTAMP, Cproton::PN_TIMESTAMP, "timestamp")
- self.add_item(:FLOAT, Cproton::PN_FLOAT, "float")
- self.add_item(:DOUBLE, Cproton::PN_DOUBLE, "double")
- self.add_item(:DECIMAL32, Cproton::PN_DECIMAL32, "decimal32")
- self.add_item(:DECIMAL64, Cproton::PN_DECIMAL64, "decimal64")
- self.add_item(:DECIMAL128, Cproton::PN_DECIMAL128, "decimal128")
- self.add_item(:UUID, Cproton::PN_UUID, "uuid")
- self.add_item(:BINARY, Cproton::PN_BINARY, "binary")
- self.add_item(:STRING, Cproton::PN_STRING, "string")
- self.add_item(:SYMBOL, Cproton::PN_SYMBOL, "symbol")
- self.add_item(:DESCRIBED, Cproton::PN_DESCRIBED, "described")
- self.add_item(:ARRAY, Cproton::PN_ARRAY, "array")
- self.add_item(:LIST, Cproton::PN_LIST, "list")
- self.add_item(:MAP, Cproton::PN_MAP, "map")
-
end
-
end
-
end