blob: f5c6b50de244d3d7ef0b30cb8fc3ee741b3d4a2a [file] [log] [blame]
#--
# 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.
#++
#--
# Patch the Array class to provide methods for adding its contents
# to a Qpid::Proton::Data instance.
#++
module Qpid::Proton::Types
# 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
def initialize(type, descriptor = nil)
@type = type
@descriptor = descriptor
end
# Returns true if the array is described.
def described?
!@descriptor.nil?
end
def ==(that)
((@type == that.type) && (@descriptor == that.descriptor))
end
end
end
# @private
class Array # :nodoc:
# 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
# Returns true if the array is the a Proton described type.
def proton_described?
!@proton_array_header.nil? && @proton_array_header.described?
end
# Puts the elements of the array into the specified Qpid::Proton::Data object.
def proton_put(data)
raise TypeError, "data object cannot be nil" if data.nil?
if @proton_array_header.nil?
proton_put_list(data)
else
proton_put_array(data)
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
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