Class: Qpid::Proton::Codec::Data

Inherits:
Object
  • Object
show all
Includes:
Util::Wrapper
Defined in:
lib/codec/data.rb

Overview

Raises TypeError for invalid conversions

Constant Summary collapse

PROTON_METHOD_PREFIX =
"pn_data"

Instance Attribute Summary

Attributes included from Util::Wrapper

#impl

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Util::Wrapper

included, #inspect, registry, #to_s

Constructor Details

#initialize(capacity) ⇒ Data #instance(impl) ⇒ Data

Returns a new instance of Data.

Overloads:

  • #initialize(capacity) ⇒ Data

    Parameters:

    • capacity (Integer)

      capacity for the new data instance.

  • #instance(impl) ⇒ Data

    Parameters:

    • impl (SWIG::pn_data_t*)

      wrap the C impl pointer.



66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/codec/data.rb', line 66

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

  # destructor
  ObjectSpace.define_finalizer(self, self.class.finalize!(@impl, @free))
end

Class Method Details

.finalize!(impl, free) ⇒ Object



81
82
83
84
85
# File 'lib/codec/data.rb', line 81

def self.finalize!(impl, free)
  proc {
    Cproton.pn_data_free(impl) if free
  }
end

.from_object(impl, x) ⇒ Object

Clear a pn_data_t* and convert a ruby object into it. If x==nil leave it empty.



55
56
57
58
59
60
# File 'lib/codec/data.rb', line 55

def self.from_object(impl, x)
  d = Data.new(impl)
  d.clear
  d.object = x if x
  nil
end

.to_multiple(impl) ⇒ Array?

Convert a pn_data_t* containing an AMQP “multiple” field to an Array or nil. A “multiple” field can be encoded as an array or a single value - always return Array.

Returns:

  • (Array, nil)

    The ruby Array extracted from impl or nil if impl is empty



48
49
50
51
# File 'lib/codec/data.rb', line 48

def self.to_multiple(impl)
  o = self.to_object(impl)
  Array(o) if o
end

.to_object(impl) ⇒ Object?

Convert a pn_data_t* containing a single value to a ruby object.

Returns:

  • (Object, nil)

    The ruby value extracted from impl or nil if impl is empty



36
37
38
39
40
41
42
# File 'lib/codec/data.rb', line 36

def self.to_object(impl)
  if (Cproton.pn_data_size(impl) > 0)
    d = Data.new(impl)
    d.rewind
    d.next_object
  end
end

Instance Method Details

#<<(x) ⇒ Object

Add an arbitrary data value using object=, return self



228
# File 'lib/codec/data.rb', line 228

def <<(x) self.object=x; self; end

#arrayObject



165
166
167
168
169
170
171
172
173
174
# File 'lib/codec/data.rb', line 165

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

#array=(a) ⇒ Object

Raises:

  • (TypeError)


176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/codec/data.rb', line 176

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

#binaryString

If the current node is binary, returns its value. Otherwise, it returns an empty string (“”).

Returns:

  • (String)

    The binary string.

See Also:



606
607
608
# File 'lib/codec/data.rb', line 606

def binary
  Qpid::Proton::Types::BinaryString.new(Cproton.pn_data_get_binary(@impl))
end

#binary=(value) ⇒ Object

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.

Parameters:

  • value (String)

    An arbitrary string value.

See Also:



595
596
597
# File 'lib/codec/data.rb', line 595

def binary=(value)
  check(Cproton.pn_data_put_binary(@impl, value))
end

#boolBoolean

If the current node is a boolean, then it returns the value. Otherwise, it returns false.

Returns:

  • (Boolean)

    The boolean value.



265
266
267
# File 'lib/codec/data.rb', line 265

def bool
  Cproton.pn_data_get_bool(@impl)
end

#bool=(value) ⇒ Object

Puts a boolean value.

Parameters:

  • value (Boolean)

    The boolean value.



256
257
258
# File 'lib/codec/data.rb', line 256

def bool=(value)
  check(Cproton.pn_data_put_bool(@impl, value))
end

#byteInteger

If the current node is an byte, returns its value. Otherwise, it returns 0.

Returns:

  • (Integer)

    The byte value.



299
300
301
# File 'lib/codec/data.rb', line 299

def byte
  Cproton.pn_data_get_byte(@impl)
end

#byte=(value) ⇒ Object

Puts a byte value.

Parameters:

  • value (Integer)

    The byte value.



290
291
292
# File 'lib/codec/data.rb', line 290

def byte=(value)
  check(Cproton.pn_data_put_byte(@impl, value))
end

#charInteger

If the current node is a character, returns its value. Otherwise, returns 0.

Returns:

  • (Integer)

    The character value.



387
388
389
# File 'lib/codec/data.rb', line 387

def char
  Cproton.pn_data_get_char(@impl)
end

#char=(value) ⇒ Object

Puts a character value.

Parameters:

  • value (Integer)

    The character value.



378
379
380
# File 'lib/codec/data.rb', line 378

def char=(value)
  check(Cproton.pn_data_put_char(@impl, value))
end

#codeObject



96
# File 'lib/codec/data.rb', line 96

def code() Cproton.pn_data_type(@impl); end

#decimal128Integer

If the current node is a decimal128, returns its value. Otherwise, returns 0.

Returns:

  • (Integer)

    The decimal128 value.



528
529
530
531
532
# File 'lib/codec/data.rb', line 528

def decimal128
  value = ""
  Cproton.pn_data_get_decimal128(@impl).each{|val| value += ("%02x" % val)}
  value.to_i(16)
end

#decimal128=(value) ⇒ Object

Puts a decimal128 value.

Parameters:

  • value (Integer)

    The decimal128 value.

Raises:

  • (TypeError)


515
516
517
518
519
520
521
# File 'lib/codec/data.rb', line 515

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

#decimal32Integer

If the current node is a decimal32, returns its value. Otherwise, returns 0.

Returns:

  • (Integer)

    The decimal32 value.



490
491
492
# File 'lib/codec/data.rb', line 490

def decimal32
  Cproton.pn_data_get_decimal32(@impl)
end

#decimal32=(value) ⇒ Object

Puts a decimal32 value.

Parameters:

  • value (Integer)

    The decimal32 value.



481
482
483
# File 'lib/codec/data.rb', line 481

def decimal32=(value)
  check(Cproton.pn_data_put_decimal32(@impl, value))
end

#decimal64Integer

If the current node is a decimal64, returns its value. Otherwise, it returns 0.

Returns:

  • (Integer)

    The decimal64 value.



507
508
509
# File 'lib/codec/data.rb', line 507

def decimal64
  Cproton.pn_data_get_decimal64(@impl)
end

#decimal64=(value) ⇒ Object

Puts a decimal64 value.

Parameters:

  • value (Integer)

    The decimal64 value.



498
499
500
# File 'lib/codec/data.rb', line 498

def decimal64=(value)
  check(Cproton.pn_data_put_decimal64(@impl, value))
end

#decode(encoded) ⇒ Object

Decodes the first value from supplied AMQP data and returns the number of bytes consumed.

Parameters:

  • encoded (String)

    The encoded data.



119
120
121
# File 'lib/codec/data.rb', line 119

def decode(encoded)
  check(Cproton.pn_data_decode(@impl, encoded, encoded.length))
end

#describedObject



136
137
138
139
# File 'lib/codec/data.rb', line 136

def described
  expect Cproton::PN_DESCRIBED
  enter_exit { Types::Described.new(self.next_object, self.next_object) }
end

#described=(d) ⇒ Object



141
142
143
144
# File 'lib/codec/data.rb', line 141

def described= d
  put_described
  enter_exit { self << d.descriptor << d.value }
end

#doubleFloat

If the current node is a double, returns its value. Otherwise, returns 0.

Returns:

  • (Float)

    The double precision floating point value.



473
474
475
# File 'lib/codec/data.rb', line 473

def double
  Cproton.pn_data_get_double(@impl)
end

#double=(value) ⇒ Object

Puts a double value.

Parameters:

  • value (Float)

    The double precision floating point value.



464
465
466
# File 'lib/codec/data.rb', line 464

def double=(value)
  check(Cproton.pn_data_put_double(@impl, value))
end

#encodeObject

Returns a representation of the data encoded in AMQP format.



101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/codec/data.rb', line 101

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

#enter_exitObject



89
90
91
92
93
94
# File 'lib/codec/data.rb', line 89

def enter_exit()
  enter
  yield self
ensure
  exit
end

#expect(code) ⇒ Object



130
131
132
133
134
# File 'lib/codec/data.rb', line 130

def expect(code)
  unless code == self.code
    raise TypeError, "expected #{Cproton.pn_type_name(code)}, got #{Cproton.pn_type_name(self.code)}"
  end
end

#fill(a, count, what) ⇒ Object

Raises:

  • (TypeError)


146
147
148
149
150
# File 'lib/codec/data.rb', line 146

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

#floatFloat

If the current node is a float, returns its value. Otherwise, returns 0.

Returns:

  • (Float)

    The floating point value.



456
457
458
# File 'lib/codec/data.rb', line 456

def float
  Cproton.pn_data_get_float(@impl)
end

#float=(value) ⇒ Object

Puts a float value.

Parameters:

  • value (Float)

    The floating point value.



447
448
449
# File 'lib/codec/data.rb', line 447

def float=(value)
  check(Cproton.pn_data_put_float(@impl, value))
end

#getObject

Get the current value as a single object.

Returns:

  • (Object)

    The current node’s object.

See Also:



657
658
659
# File 'lib/codec/data.rb', line 657

def get
  type.get(self);
end

#get_arrayObject



128
# File 'lib/codec/data.rb', line 128

def get_array() [Cproton.pn_data_get_array(@impl), array_described?, array_type]; end

#intInteger

If the current node is an integer, returns its value. Otherwise, returns 0.

Returns:

  • (Integer)

    The integer value.



370
371
372
# File 'lib/codec/data.rb', line 370

def int
  Cproton.pn_data_get_int(@impl)
end

#int=(value) ⇒ Object

Puts an integer value.

Options

  • value - the integer value



361
362
363
# File 'lib/codec/data.rb', line 361

def int=(value)
  check(Cproton.pn_data_put_int(@impl, value))
end

#listObject



152
153
154
155
156
157
158
# File 'lib/codec/data.rb', line 152

def list
  return array if code == Cproton::PN_ARRAY
  expect Cproton::PN_LIST
  count = get_list
  a = []
  enter_exit { fill(a, count, __method__) }
end

#list=(a) ⇒ Object



160
161
162
163
# File 'lib/codec/data.rb', line 160

def list=(a)
  put_list
  enter_exit { a.each { |x| self << x } }
end

#longInteger

If the current node is a long, returns its value. Otherwise, returns 0.

Returns:

  • (Integer)

    The long value.



421
422
423
# File 'lib/codec/data.rb', line 421

def long
  Cproton.pn_data_get_long(@impl)
end

#long=(value) ⇒ Object

Puts a long value.

Parameters:

  • value (Integer)

    The long value.



414
415
416
# File 'lib/codec/data.rb', line 414

def long=(value)
  check(Cproton.pn_data_put_long(@impl, value))
end

#mapObject

Raises:

  • (TypeError)


192
193
194
195
196
197
198
199
200
201
202
# File 'lib/codec/data.rb', line 192

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

#map=(m) ⇒ Object



204
205
206
207
# File 'lib/codec/data.rb', line 204

def map= m
  put_map
  enter_exit { m.each_pair { |k,v| self << k << v } }
end

#next_objectObject

Move forward to the next value and return it



231
232
233
234
# File 'lib/codec/data.rb', line 231

def next_object
  self.next or raise TypeError, "not enough data"
  self.object
end

#nullObject

Return nil if vallue is null, raise exception otherwise.

Raises:

  • (TypeError)


210
# File 'lib/codec/data.rb', line 210

def null() raise TypeError, "expected null, got #{type || 'empty'}" unless null?; end

#null=(dummy = nil) ⇒ Object

Set the current value to null



213
# File 'lib/codec/data.rb', line 213

def null=(dummy=nil) check(Cproton.pn_data_put_null(@impl)); end

#null?Boolean

Checks if the current node is null.

Returns:

  • (Boolean)

    True if the node is null.



248
249
250
# File 'lib/codec/data.rb', line 248

def null?
  Cproton.pn_data_is_null(@impl)
end

#objectObject

Gets the current node, based on how it was encoded.

Returns:

  • (Object)

    The current node.



240
241
242
# File 'lib/codec/data.rb', line 240

def object
  self.type.get(self) if self.type
end

#object=(object) ⇒ Object

Puts an arbitrary object type.

The Data instance will determine which AMQP type is appropriate and will use that to encode the object.

Parameters:

  • object (Object)

    The value.



222
223
224
225
# File 'lib/codec/data.rb', line 222

def object=(object)
  Mapping.for_class(object.class).put(self, object)
  object
end

#put(value, type_code) ⇒ Object

Puts a new value with the given type into the current node.

Parameters:

  • value (Object)

    The value.

  • type_code (Mapping)

    The value’s type.



668
669
670
# File 'lib/codec/data.rb', line 668

def put(value, type_code);
  type_code.put(self, value);
end

#shortInteger

If the current node is a short, returns its value. Otherwise, returns a 0.

Returns:

  • (Integer)

    The short value.



333
334
335
# File 'lib/codec/data.rb', line 333

def short
  Cproton.pn_data_get_short(@impl)
end

#short=(value) ⇒ Object

Puts a short value.

Parameters:

  • value (Integer)

    The short value.



324
325
326
# File 'lib/codec/data.rb', line 324

def short=(value)
  check(Cproton.pn_data_put_short(@impl, value))
end

#stringString

If the current node is a string, returns its value. Otherwise, it returns an empty string (“”).

Returns:

  • (String)

    The UTF-8 encoded string.

See Also:



629
630
631
# File 'lib/codec/data.rb', line 629

def string
  Qpid::Proton::Types::UTFString.new(Cproton.pn_data_get_string(@impl))
end

#string=(value) ⇒ Object

Puts a UTF-8 encoded string value.

NOTE: A nil value is stored as an empty string rather than as a nil.

Parameters:

  • value (String)

    The UTF-8 encoded string value.

See Also:



618
619
620
# File 'lib/codec/data.rb', line 618

def string=(value)
  check(Cproton.pn_data_put_string(@impl, value))
end

#symbolSymbol

If the current node is a symbol, returns its value. Otherwise, it returns an empty string (“”).

Returns:

  • (Symbol)

    The symbol value.



646
647
648
# File 'lib/codec/data.rb', line 646

def symbol
  Cproton.pn_data_get_symbol(@impl).to_sym
end

#symbol=(value) ⇒ Object

Puts a symbolic value.

Parameters:

  • value (String|Symbol)

    The symbolic string value.



637
638
639
# File 'lib/codec/data.rb', line 637

def symbol=(value)
  check(Cproton.pn_data_put_symbol(@impl, value.to_s))
end

#timestampInteger

If the current node is a timestamp, returns its value. Otherwise, returns 0.

Returns:

  • (Integer)

    The timestamp value.



439
440
441
# File 'lib/codec/data.rb', line 439

def timestamp
  Cproton.pn_data_get_timestamp(@impl)
end

#timestamp=(value) ⇒ Object

Puts a timestamp value.

Parameters:

  • value (Integer)

    The timestamp value.



429
430
431
432
# File 'lib/codec/data.rb', line 429

def timestamp=(value)
  value = value.to_i if (!value.nil? && value.is_a?(Time))
  check(Cproton.pn_data_put_timestamp(@impl, value))
end

#typeObject



98
# File 'lib/codec/data.rb', line 98

def type() Mapping.for_code(Cproton.pn_data_type(@impl)); end

#ubyteInteger

If the current node is an unsigned byte, returns its value. Otherwise, it returns 0.

Returns:

  • (Integer)

    The unsigned byte value.



282
283
284
# File 'lib/codec/data.rb', line 282

def ubyte
  Cproton.pn_data_get_ubyte(@impl)
end

#ubyte=(value) ⇒ Object

Puts an unsigned byte value.

Parameters:

  • value (Integer)

    The unsigned byte value.



273
274
275
# File 'lib/codec/data.rb', line 273

def ubyte=(value)
  check(Cproton.pn_data_put_ubyte(@impl, value))
end

#uintInteger

If the current node is an unsigned int, returns its value. Otherwise, returns 0.

Returns:

  • (Integer)

    The unsigned integer value.



352
353
354
# File 'lib/codec/data.rb', line 352

def uint
  Cproton.pn_data_get_uint(@impl)
end

#uint=(value) ⇒ Object

Puts an unsigned integer value.

Parameters:

  • value (Integer)

    the unsigned integer value

Raises:

  • (TypeError)


341
342
343
344
345
# File 'lib/codec/data.rb', line 341

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

#ulongInteger

If the current node is an unsigned long, returns its value. Otherwise, returns 0.

Returns:

  • (Integer)

    The unsigned long value.



406
407
408
# File 'lib/codec/data.rb', line 406

def ulong
  Cproton.pn_data_get_ulong(@impl)
end

#ulong=(value) ⇒ Object

Puts an unsigned long value.

Parameters:

  • value (Integer)

    The unsigned long value.

Raises:

  • (TypeError)


395
396
397
398
399
# File 'lib/codec/data.rb', line 395

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

#ushortInteger

If the current node is an unsigned short, returns its value. Otherwise, it returns 0.

Returns:

  • (Integer)

    The unsigned short value.



316
317
318
# File 'lib/codec/data.rb', line 316

def ushort
  Cproton.pn_data_get_ushort(@impl)
end

#ushort=(value) ⇒ Object

Puts an unsigned short value.

Parameters:

  • value (Integer)

    The unsigned short value



307
308
309
# File 'lib/codec/data.rb', line 307

def ushort=(value)
  check(Cproton.pn_data_put_ushort(@impl, value))
end

#uuidString

If the current value is a UUID, returns its value. Otherwise, it returns nil.

Returns:

  • (String)

    The string representation of the UUID.



580
581
582
583
584
# File 'lib/codec/data.rb', line 580

def uuid
  value = ""
  Cproton.pn_data_get_uuid(@impl).each{|val| value += ("%02x" % val)}
  value.insert(8, "-").insert(13, "-").insert(18, "-").insert(23, "-")
end

#uuid=(value) ⇒ Object

Puts a UUID value.

The UUID is expected to be in the format of a string or else a 128-bit integer value.

Examples:


# 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

Parameters:

  • value (String, Numeric)

    A string or numeric representation of the UUID.

Raises:

  • (::ArgumentError)


553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
# File 'lib/codec/data.rb', line 553

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(@impl, bytes))
end