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