qpid_proton 0.9.0 → 0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codec/data.rb +912 -0
  3. data/lib/codec/mapping.rb +169 -0
  4. data/lib/{qpid_proton/tracker.rb → core/base_handler.rb} +4 -15
  5. data/lib/core/connection.rb +328 -0
  6. data/lib/core/delivery.rb +271 -0
  7. data/lib/core/disposition.rb +158 -0
  8. data/lib/core/endpoint.rb +140 -0
  9. data/lib/{qpid_proton → core}/exceptions.rb +43 -2
  10. data/lib/core/link.rb +387 -0
  11. data/lib/core/message.rb +633 -0
  12. data/lib/core/receiver.rb +95 -0
  13. data/lib/core/sasl.rb +94 -0
  14. data/lib/core/selectable.rb +130 -0
  15. data/lib/core/sender.rb +76 -0
  16. data/lib/core/session.rb +163 -0
  17. data/lib/core/ssl.rb +164 -0
  18. data/lib/{qpid_proton/version.rb → core/ssl_details.rb} +7 -6
  19. data/lib/core/ssl_domain.rb +156 -0
  20. data/lib/core/terminus.rb +218 -0
  21. data/lib/core/transport.rb +411 -0
  22. data/lib/core/url.rb +77 -0
  23. data/lib/event/collector.rb +148 -0
  24. data/lib/event/event.rb +318 -0
  25. data/lib/event/event_base.rb +91 -0
  26. data/lib/event/event_type.rb +71 -0
  27. data/lib/handler/acking.rb +70 -0
  28. data/lib/handler/c_adaptor.rb +47 -0
  29. data/lib/handler/c_flow_controller.rb +33 -0
  30. data/lib/handler/endpoint_state_handler.rb +217 -0
  31. data/lib/handler/incoming_message_handler.rb +74 -0
  32. data/lib/handler/messaging_handler.rb +218 -0
  33. data/lib/handler/outgoing_message_handler.rb +98 -0
  34. data/lib/handler/wrapped_handler.rb +76 -0
  35. data/lib/messenger/messenger.rb +702 -0
  36. data/lib/messenger/subscription.rb +37 -0
  37. data/lib/messenger/tracker.rb +38 -0
  38. data/lib/messenger/tracker_status.rb +69 -0
  39. data/lib/qpid_proton.rb +106 -16
  40. data/lib/reactor/acceptor.rb +41 -0
  41. data/lib/reactor/backoff.rb +41 -0
  42. data/lib/reactor/connector.rb +98 -0
  43. data/lib/reactor/container.rb +272 -0
  44. data/lib/reactor/global_overrides.rb +44 -0
  45. data/lib/reactor/link_option.rb +90 -0
  46. data/lib/reactor/reactor.rb +198 -0
  47. data/lib/reactor/session_per_connection.rb +45 -0
  48. data/lib/reactor/ssl_config.rb +41 -0
  49. data/lib/reactor/task.rb +39 -0
  50. data/lib/{qpid_proton/subscription.rb → reactor/urls.rb} +12 -13
  51. data/lib/{qpid_proton → types}/array.rb +28 -29
  52. data/lib/types/described.rb +63 -0
  53. data/lib/{qpid_proton → types}/hash.rb +4 -3
  54. data/lib/types/strings.rb +62 -0
  55. data/lib/util/class_wrapper.rb +54 -0
  56. data/lib/util/condition.rb +45 -0
  57. data/lib/util/constants.rb +85 -0
  58. data/lib/util/engine.rb +82 -0
  59. data/lib/util/error_handler.rb +127 -0
  60. data/lib/util/handler.rb +41 -0
  61. data/lib/util/reactor.rb +32 -0
  62. data/lib/util/swig_helper.rb +114 -0
  63. data/lib/util/timeout.rb +50 -0
  64. data/lib/util/uuid.rb +32 -0
  65. data/lib/util/version.rb +30 -0
  66. data/lib/util/wrapper.rb +124 -0
  67. metadata +67 -21
  68. data/ext/cproton/cproton.c +0 -22196
  69. data/lib/qpid_proton/data.rb +0 -788
  70. data/lib/qpid_proton/described.rb +0 -66
  71. data/lib/qpid_proton/exception_handling.rb +0 -127
  72. data/lib/qpid_proton/filters.rb +0 -67
  73. data/lib/qpid_proton/mapping.rb +0 -170
  74. data/lib/qpid_proton/message.rb +0 -621
  75. data/lib/qpid_proton/messenger.rb +0 -702
  76. data/lib/qpid_proton/selectable.rb +0 -126
  77. data/lib/qpid_proton/strings.rb +0 -65
  78. data/lib/qpid_proton/tracker_status.rb +0 -73
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5dbf22a62de6b722e102f1710d7f8cad7ec11e2d
4
- data.tar.gz: ff15263f67cf7bc052460b46c91092d8fdd41b87
3
+ metadata.gz: 1aad7a8ec19a28dfa1504e304f1d3c8f9f888410
4
+ data.tar.gz: 4b1002f7e67c7a79227ec8276841b3e0388b5e3b
5
5
  SHA512:
6
- metadata.gz: 4cd79aedd6f8bbaab2f4fa84ccd5b30c414ef5723bd0493c1715d6ec19692792628f87ece82c2f0f6154ce938987091377e1641bf79b0329d39dccb67b952a75
7
- data.tar.gz: d027ebd9765b72f550117600270f7921778684bc4ac1a19878a394457ae670e6c0e474546d2910b03da0c144221ae72dc384e92b7e25972fb4bb1f0139eac1ca
6
+ metadata.gz: 7237f196d2af8a1fd2b8ded6b28458597e872f17e87a4ee9b9fff884b3743df62db930e305bc05905638157d21f8fc26ee2b21630114ac517e8559042944cf52
7
+ data.tar.gz: ffc00e8b5b5136322f1c8e2fe757160e5c5b0fc5d1197819928b6da0977015cb5a50abe2b06d6158dbfe1eb24223c6a12a219545ff4d74c6fab84273dddca6ef
data/lib/codec/data.rb ADDED
@@ -0,0 +1,912 @@
1
+ #--
2
+ # Licensed to the Apache Software Foundation (ASF) under one
3
+ # or more contributor license agreements. See the NOTICE file
4
+ # distributed with this work for additional information
5
+ # regarding copyright ownership. The ASF licenses this file
6
+ # to you under the Apache License, Version 2.0 (the
7
+ # "License"); you may not use this file except in compliance
8
+ # with the License. You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing,
13
+ # software distributed under the License is distributed on an
14
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ # KIND, either express or implied. See the License for the
16
+ # specific language governing permissions and limitations
17
+ # under the License.
18
+ #++
19
+
20
+ module Qpid::Proton::Codec
21
+
22
+ # +DataError+ is raised when an error occurs while encoding
23
+ # or decoding data.
24
+ class DataError < Exception; end
25
+
26
+ # The +Data+ class provides an interface for decoding, extracting,
27
+ # creating, and encoding arbitrary AMQP data. A +Data+ object
28
+ # contains a tree of AMQP values. Leaf nodes in this tree correspond
29
+ # to scalars in the AMQP type system such as INT or STRING. Interior
30
+ # nodes in this tree correspond to compound values in the AMQP type
31
+ # system such as *LIST*,*MAP*, *ARRAY*, or *DESCRIBED*. The root node
32
+ # of the tree is the +Data+ object itself and can have an arbitrary
33
+ # number of children.
34
+ #
35
+ # A +Data+ object maintains the notion of the current sibling node
36
+ # and a current parent node. Siblings are ordered within their parent.
37
+ # Values are accessed and/or added by using the #next, #prev,
38
+ # #enter, and #exit methods to navigate to the desired location in
39
+ # the tree and using the supplied variety of mutator and accessor
40
+ # methods to access or add a value of the desired type.
41
+ #
42
+ # The mutator methods will always add a value _after_ the current node
43
+ # in the tree. If the current node has a next sibling the mutator method
44
+ # will overwrite the value on this node. If there is no current node
45
+ # or the current node has no next sibling then one will be added. The
46
+ # accessor methods always set the added/modified node to the current
47
+ # node. The accessor methods read the value of the current node and do
48
+ # not change which node is current.
49
+ #
50
+ # The following types of scalar values are supported:
51
+ #
52
+ # * NULL
53
+ # * BOOL
54
+ # * UBYTE
55
+ # * BYTE
56
+ # * USHORT
57
+ # * SHORT
58
+ # * UINT
59
+ # * INT
60
+ # * CHAR
61
+ # * ULONG
62
+ # * LONG
63
+ # * TIMESTAMP
64
+ # * FLOAT
65
+ # * DOUBLE
66
+ # * DECIMAL32
67
+ # * DECIMAL64
68
+ # * DECIMAL128
69
+ # * UUID
70
+ # * BINARY
71
+ # * STRING
72
+ # * SYMBOL
73
+ #
74
+ # The following types of compound values are supported:
75
+ #
76
+ # * DESCRIBED
77
+ # * ARRAY
78
+ # * LIST
79
+ # * MAP
80
+ #
81
+ class Data
82
+
83
+ # Creates a new instance with the specified capacity.
84
+ #
85
+ # @param capacity [Fixnum, Object] The initial capacity or content.
86
+ #
87
+ def initialize(capacity = 16)
88
+ if (!capacity.nil?) &&
89
+ (capacity.is_a?(Fixnum) ||
90
+ capacity.is_a?(Bignum))
91
+ @data = Cproton.pn_data(capacity)
92
+ @free = true
93
+ else
94
+ @data = capacity
95
+ @free = false
96
+ end
97
+
98
+ # destructor
99
+ ObjectSpace.define_finalizer(self, self.class.finalize!(@data, @free))
100
+ end
101
+
102
+ # @private
103
+ def self.finalize!(data, free)
104
+ proc {
105
+ Cproton.pn_data_free(data) if free
106
+ }
107
+ end
108
+
109
+ # @private
110
+ def to_s
111
+ tmp = Cproton.pn_string("")
112
+ Cproton.pn_inspect(@data, tmp)
113
+ result = Cproton.pn_string_get(tmp)
114
+ Cproton.pn_free(tmp)
115
+ return result
116
+ end
117
+
118
+ # Clears the object.
119
+ #
120
+ def clear
121
+ Cproton.pn_data_clear(@data)
122
+ end
123
+
124
+ # Clears the current node and sets the parent to the root node.
125
+ #
126
+ # Clearing the current node sets it *before* the first node, calling
127
+ # #next will advance to the first node.
128
+ #
129
+ def rewind
130
+ Cproton.pn_data_rewind(@data)
131
+ end
132
+
133
+ # Advances the current node to its next sibling and returns its types.
134
+ #
135
+ # If there is no next sibling the current node remains unchanged
136
+ # and nil is returned.
137
+ #
138
+ def next
139
+ Cproton.pn_data_next(@data)
140
+ end
141
+
142
+ # Advances the current node to its previous sibling and returns its type.
143
+ #
144
+ # If there is no previous sibling then the current node remains unchanged
145
+ # and nil is return.
146
+ #
147
+ def prev
148
+ return Cproton.pn_data_prev(@data) ? type : nil
149
+ end
150
+
151
+ # Sets the parent node to the current node and clears the current node.
152
+ #
153
+ # Clearing the current node sets it _before_ the first child.
154
+ #
155
+ def enter
156
+ Cproton.pn_data_enter(@data)
157
+ end
158
+
159
+ # Sets the current node to the parent node and the parent node to its own
160
+ # parent.
161
+ #
162
+ def exit
163
+ Cproton.pn_data_exit(@data)
164
+ end
165
+
166
+ # Returns the numeric type code of the current node.
167
+ #
168
+ # @return [Fixnum] The current node type.
169
+ # @return [nil] If there is no current node.
170
+ #
171
+ def type_code
172
+ dtype = Cproton.pn_data_type(@data)
173
+ return (dtype == -1) ? nil : dtype
174
+ end
175
+
176
+ # Return the type object for the current node
177
+ #
178
+ # @param [Fixnum] The object type.
179
+ #
180
+ # @see #type_code
181
+ #
182
+ def type
183
+ Mapping.for_code(type_code)
184
+ end
185
+
186
+ # Returns a representation of the data encoded in AMQP format.
187
+ #
188
+ # @return [String] The context of the Data as an AMQP data string.
189
+ #
190
+ # @example
191
+ #
192
+ # @data.string = "This is a test."
193
+ # @encoded = @data.encode
194
+ #
195
+ # # @encoded now contains the text "This is a test." encoded for
196
+ # # AMQP transport.
197
+ #
198
+ def encode
199
+ buffer = "\0"*1024
200
+ loop do
201
+ cd = Cproton.pn_data_encode(@data, buffer, buffer.length)
202
+ if cd == Cproton::PN_OVERFLOW
203
+ buffer *= 2
204
+ elsif cd >= 0
205
+ return buffer[0...cd]
206
+ else
207
+ check(cd)
208
+ end
209
+ end
210
+ end
211
+
212
+ # Decodes the first value from supplied AMQP data and returns the number
213
+ # of bytes consumed.
214
+ #
215
+ # @param encoded [String] The encoded data.
216
+ #
217
+ # @example
218
+ #
219
+ # # SCENARIO: A string of encoded data, @encoded, contains the text
220
+ # # of "This is a test." and is passed to an instance of Data
221
+ # # for decoding.
222
+ #
223
+ # @data.decode(@encoded)
224
+ # @data.string #=> "This is a test."
225
+ #
226
+ def decode(encoded)
227
+ check(Cproton.pn_data_decode(@data, encoded, encoded.length))
228
+ end
229
+
230
+ # Puts a list value.
231
+ #
232
+ # Elements may be filled by entering the list node and putting element
233
+ # values.
234
+ #
235
+ # @example
236
+ #
237
+ # data = Qpid::Proton::Codec::Data.new
238
+ # data.put_list
239
+ # data.enter
240
+ # data.int = 1
241
+ # data.int = 2
242
+ # data.int = 3
243
+ # data.exit
244
+ #
245
+ def put_list
246
+ check(Cproton.pn_data_put_list(@data))
247
+ end
248
+
249
+ # If the current node is a list, this returns the number of elements.
250
+ # Otherwise, it returns zero.
251
+ #
252
+ # List elements can be accessed by entering the list.
253
+ #
254
+ # @example
255
+ #
256
+ # count = @data.list
257
+ # @data.enter
258
+ # (0...count).each
259
+ # type = @data.next
260
+ # puts "Value: #{@data.string}" if type == STRING
261
+ # # ... process other node types
262
+ # end
263
+ def list
264
+ Cproton.pn_data_get_list(@data)
265
+ end
266
+
267
+ # Puts a map value.
268
+ #
269
+ # Elements may be filled by entering the map node and putting alternating
270
+ # key/value pairs.
271
+ #
272
+ # @example
273
+ #
274
+ # data = Qpid::Proton::Codec::Data.new
275
+ # data.put_map
276
+ # data.enter
277
+ # data.string = "key"
278
+ # data.string = "value"
279
+ # data.exit
280
+ #
281
+ def put_map
282
+ check(Cproton.pn_data_put_map(@data))
283
+ end
284
+
285
+ # If the current node is a map, this returns the number of child
286
+ # elements. Otherwise, it returns zero.
287
+ #
288
+ # Key/value pairs can be accessed by entering the map.
289
+ #
290
+ # @example
291
+ #
292
+ # count = @data.map
293
+ # @data.enter
294
+ # (0...count).each do
295
+ # type = @data.next
296
+ # puts "Key=#{@data.string}" if type == STRING
297
+ # # ... process other key types
298
+ # type = @data.next
299
+ # puts "Value=#{@data.string}" if type == STRING
300
+ # # ... process other value types
301
+ # end
302
+ # @data.exit
303
+ def map
304
+ Cproton.pn_data_get_map(@data)
305
+ end
306
+
307
+ # @private
308
+ def get_map
309
+ ::Hash.proton_data_get(self)
310
+ end
311
+
312
+ # Puts an array value.
313
+ #
314
+ # Elements may be filled by entering the array node and putting the
315
+ # element values. The values must all be of the specified array element
316
+ # type.
317
+ #
318
+ # If an array is *described* then the first child value of the array
319
+ # is the descriptor and may be of any type.
320
+ #
321
+ # @param described [Boolean] True if the array is described.
322
+ # @param element_type [Fixnum] The AMQP type for each element of the array.
323
+ #
324
+ # @example
325
+ #
326
+ # # create an array of integer values
327
+ # data = Qpid::Proton::Codec::Data.new
328
+ # data.put_array(false, INT)
329
+ # data.enter
330
+ # data.int = 1
331
+ # data.int = 2
332
+ # data.int = 3
333
+ # data.exit
334
+ #
335
+ # # create a described array of double values
336
+ # data.put_array(true, DOUBLE)
337
+ # data.enter
338
+ # data.symbol = "array-descriptor"
339
+ # data.double = 1.1
340
+ # data.double = 1.2
341
+ # data.double = 1.3
342
+ # data.exit
343
+ #
344
+ def put_array(described, element_type)
345
+ check(Cproton.pn_data_put_array(@data, described, element_type.code))
346
+ end
347
+
348
+ # If the current node is an array, returns a tuple of the element count, a
349
+ # boolean indicating whether the array is described, and the type of each
350
+ # element. Otherwise it returns +(0, false, nil).
351
+ #
352
+ # Array data can be accessed by entering the array.
353
+ #
354
+ # @example
355
+ #
356
+ # # get the details of thecurrent array
357
+ # count, described, array_type = @data.array
358
+ #
359
+ # # enter the node
360
+ # data.enter
361
+ #
362
+ # # get the next node
363
+ # data.next
364
+ # puts "Descriptor: #{data.symbol}" if described
365
+ # (0...count).each do
366
+ # @data.next
367
+ # puts "Element: #{@data.string}"
368
+ # end
369
+ def array
370
+ count = Cproton.pn_data_get_array(@data)
371
+ described = Cproton.pn_data_is_array_described(@data)
372
+ array_type = Cproton.pn_data_get_array_type(@data)
373
+ return nil if array_type == -1
374
+ [count, described, Mapping.for_code(array_type) ]
375
+ end
376
+
377
+ # @private
378
+ def get_array
379
+ ::Array.proton_get(self)
380
+ end
381
+
382
+ # Puts a described value.
383
+ #
384
+ # A described node has two children, the descriptor and the value.
385
+ # These are specified by entering the node and putting the
386
+ # desired values.
387
+ #
388
+ # @example
389
+ #
390
+ # data = Qpid::Proton::Codec::Data.new
391
+ # data.put_described
392
+ # data.enter
393
+ # data.symbol = "value-descriptor"
394
+ # data.string = "the value"
395
+ # data.exit
396
+ #
397
+ def put_described
398
+ check(Cproton.pn_data_put_described(@data))
399
+ end
400
+
401
+ # @private
402
+ def get_described
403
+ raise TypeError, "not a described type" unless self.described?
404
+ self.enter
405
+ self.next
406
+ type = self.type
407
+ descriptor = type.get(self)
408
+ self.next
409
+ type = self.type
410
+ value = type.get(self)
411
+ self.exit
412
+ Qpid::Proton::Types::Described.new(descriptor, value)
413
+ end
414
+
415
+ # Checks if the current node is a described value.
416
+ #
417
+ # The described and value may be accessed by entering the described value.
418
+ #
419
+ # @example
420
+ #
421
+ # if @data.described?
422
+ # @data.enter
423
+ # puts "The symbol is #{@data.symbol}"
424
+ # puts "The value is #{@data.string}"
425
+ # end
426
+ def described?
427
+ Cproton.pn_data_is_described(@data)
428
+ end
429
+
430
+ # Puts a null value.
431
+ #
432
+ def null
433
+ check(Cproton.pn_data_put_null(@data))
434
+ end
435
+
436
+ # Utility method for Qpid::Proton::Codec::Mapping
437
+ #
438
+ # @private
439
+ #
440
+ def null=(value)
441
+ null
442
+ end
443
+
444
+ # Puts an arbitrary object type.
445
+ #
446
+ # The Data instance will determine which AMQP type is appropriate and will
447
+ # use that to encode the object.
448
+ #
449
+ # @param object [Object] The value.
450
+ #
451
+ def object=(object)
452
+ Mapping.for_class(object.class).put(self, object)
453
+ end
454
+
455
+ # Gets the current node, based on how it was encoded.
456
+ #
457
+ # @return [Object] The current node.
458
+ #
459
+ def object
460
+ type = self.type
461
+ return nil if type.nil?
462
+ type.get(data)
463
+ end
464
+
465
+ # Checks if the current node is null.
466
+ #
467
+ # @return [Boolean] True if the node is null.
468
+ #
469
+ def null?
470
+ Cproton.pn_data_is_null(@data)
471
+ end
472
+
473
+ # Puts a boolean value.
474
+ #
475
+ # @param value [Boolean] The boolean value.
476
+ #
477
+ def bool=(value)
478
+ check(Cproton.pn_data_put_bool(@data, value))
479
+ end
480
+
481
+ # If the current node is a boolean, then it returns the value. Otherwise,
482
+ # it returns false.
483
+ #
484
+ # @return [Boolean] The boolean value.
485
+ #
486
+ def bool
487
+ Cproton.pn_data_get_bool(@data)
488
+ end
489
+
490
+ # Puts an unsigned byte value.
491
+ #
492
+ # @param value [Fixnum] The unsigned byte value.
493
+ #
494
+ def ubyte=(value)
495
+ check(Cproton.pn_data_put_ubyte(@data, value))
496
+ end
497
+
498
+ # If the current node is an unsigned byte, returns its value. Otherwise,
499
+ # it returns 0.
500
+ #
501
+ # @return [Fixnum] The unsigned byte value.
502
+ #
503
+ def ubyte
504
+ Cproton.pn_data_get_ubyte(@data)
505
+ end
506
+
507
+ # Puts a byte value.
508
+ #
509
+ # @param value [Fixnum] The byte value.
510
+ #
511
+ def byte=(value)
512
+ check(Cproton.pn_data_put_byte(@data, value))
513
+ end
514
+
515
+ # If the current node is an byte, returns its value. Otherwise,
516
+ # it returns 0.
517
+ #
518
+ # @return [Fixnum] The byte value.
519
+ #
520
+ def byte
521
+ Cproton.pn_data_get_byte(@data)
522
+ end
523
+
524
+ # Puts an unsigned short value.
525
+ #
526
+ # @param value [Fixnum] The unsigned short value
527
+ #
528
+ def ushort=(value)
529
+ check(Cproton.pn_data_put_ushort(@data, value))
530
+ end
531
+
532
+ # If the current node is an unsigned short, returns its value. Otherwise,
533
+ # it returns 0.
534
+ #
535
+ # @return [Fixnum] The unsigned short value.
536
+ #
537
+ def ushort
538
+ Cproton.pn_data_get_ushort(@data)
539
+ end
540
+
541
+ # Puts a short value.
542
+ #
543
+ # @param value [Fixnum] The short value.
544
+ #
545
+ def short=(value)
546
+ check(Cproton.pn_data_put_short(@data, value))
547
+ end
548
+
549
+ # If the current node is a short, returns its value. Otherwise,
550
+ # returns a 0.
551
+ #
552
+ # @return [Fixnum] The short value.
553
+ #
554
+ def short
555
+ Cproton.pn_data_get_short(@data)
556
+ end
557
+
558
+ # Puts an unsigned integer value.
559
+ #
560
+ # @param value [Fixnum] the unsigned integer value
561
+ #
562
+ def uint=(value)
563
+ raise TypeError if value.nil?
564
+ raise RangeError, "invalid uint: #{value}" if value < 0
565
+ check(Cproton.pn_data_put_uint(@data, value))
566
+ end
567
+
568
+ # If the current node is an unsigned int, returns its value. Otherwise,
569
+ # returns 0.
570
+ #
571
+ # @return [Fixnum] The unsigned integer value.
572
+ #
573
+ def uint
574
+ Cproton.pn_data_get_uint(@data)
575
+ end
576
+
577
+ # Puts an integer value.
578
+ #
579
+ # ==== Options
580
+ #
581
+ # * value - the integer value
582
+ def int=(value)
583
+ check(Cproton.pn_data_put_int(@data, value))
584
+ end
585
+
586
+ # If the current node is an integer, returns its value. Otherwise,
587
+ # returns 0.
588
+ #
589
+ # @return [Fixnum] The integer value.
590
+ #
591
+ def int
592
+ Cproton.pn_data_get_int(@data)
593
+ end
594
+
595
+ # Puts a character value.
596
+ #
597
+ # @param value [Fixnum] The character value.
598
+ #
599
+ def char=(value)
600
+ check(Cproton.pn_data_put_char(@data, value))
601
+ end
602
+
603
+ # If the current node is a character, returns its value. Otherwise,
604
+ # returns 0.
605
+ #
606
+ # @return [Fixnum] The character value.
607
+ #
608
+ def char
609
+ Cproton.pn_data_get_char(@data)
610
+ end
611
+
612
+ # Puts an unsigned long value.
613
+ #
614
+ # @param value [Fixnum] The unsigned long value.
615
+ #
616
+ def ulong=(value)
617
+ raise TypeError if value.nil?
618
+ raise RangeError, "invalid ulong: #{value}" if value < 0
619
+ check(Cproton.pn_data_put_ulong(@data, value))
620
+ end
621
+
622
+ # If the current node is an unsigned long, returns its value. Otherwise,
623
+ # returns 0.
624
+ #
625
+ # @return [Fixnum] The unsigned long value.
626
+ #
627
+ def ulong
628
+ Cproton.pn_data_get_ulong(@data)
629
+ end
630
+
631
+ # Puts a long value.
632
+ #
633
+ # @param value [Fixnum] The long value.
634
+ #
635
+ def long=(value)
636
+ check(Cproton.pn_data_put_long(@data, value))
637
+ end
638
+
639
+ # If the current node is a long, returns its value. Otherwise, returns 0.
640
+ #
641
+ # @return [Fixnum] The long value.
642
+ def long
643
+ Cproton.pn_data_get_long(@data)
644
+ end
645
+
646
+ # Puts a timestamp value.
647
+ #
648
+ # @param value [Fixnum] The timestamp value.
649
+ #
650
+ def timestamp=(value)
651
+ value = value.to_i if (!value.nil? && value.is_a?(Time))
652
+ check(Cproton.pn_data_put_timestamp(@data, value))
653
+ end
654
+
655
+ # If the current node is a timestamp, returns its value. Otherwise,
656
+ # returns 0.
657
+ #
658
+ # @return [Fixnum] The timestamp value.
659
+ #
660
+ def timestamp
661
+ Cproton.pn_data_get_timestamp(@data)
662
+ end
663
+
664
+ # Puts a float value.
665
+ #
666
+ # @param value [Float] The floating point value.
667
+ #
668
+ def float=(value)
669
+ check(Cproton.pn_data_put_float(@data, value))
670
+ end
671
+
672
+ # If the current node is a float, returns its value. Otherwise,
673
+ # returns 0.
674
+ #
675
+ # @return [Float] The floating point value.
676
+ #
677
+ def float
678
+ Cproton.pn_data_get_float(@data)
679
+ end
680
+
681
+ # Puts a double value.
682
+ #
683
+ # @param value [Float] The double precision floating point value.
684
+ #
685
+ def double=(value)
686
+ check(Cproton.pn_data_put_double(@data, value))
687
+ end
688
+
689
+ # If the current node is a double, returns its value. Otherwise,
690
+ # returns 0.
691
+ #
692
+ # @return [Float] The double precision floating point value.
693
+ #
694
+ def double
695
+ Cproton.pn_data_get_double(@data)
696
+ end
697
+
698
+ # Puts a decimal32 value.
699
+ #
700
+ # @param value [Fixnum] The decimal32 value.
701
+ #
702
+ def decimal32=(value)
703
+ check(Cproton.pn_data_put_decimal32(@data, value))
704
+ end
705
+
706
+ # If the current node is a decimal32, returns its value. Otherwise,
707
+ # returns 0.
708
+ #
709
+ # @return [Fixnum] The decimal32 value.
710
+ #
711
+ def decimal32
712
+ Cproton.pn_data_get_decimal32(@data)
713
+ end
714
+
715
+ # Puts a decimal64 value.
716
+ #
717
+ # @param value [Fixnum] The decimal64 value.
718
+ #
719
+ def decimal64=(value)
720
+ check(Cproton.pn_data_put_decimal64(@data, value))
721
+ end
722
+
723
+ # If the current node is a decimal64, returns its value. Otherwise,
724
+ # it returns 0.
725
+ #
726
+ # @return [Fixnum] The decimal64 value.
727
+ #
728
+ def decimal64
729
+ Cproton.pn_data_get_decimal64(@data)
730
+ end
731
+
732
+ # Puts a decimal128 value.
733
+ #
734
+ # @param value [Fixnum] The decimal128 value.
735
+ #
736
+ def decimal128=(value)
737
+ raise TypeError, "invalid decimal128 value: #{value}" if value.nil?
738
+ value = value.to_s(16).rjust(32, "0")
739
+ bytes = []
740
+ value.scan(/(..)/) {|v| bytes << v[0].to_i(16)}
741
+ check(Cproton.pn_data_put_decimal128(@data, bytes))
742
+ end
743
+
744
+ # If the current node is a decimal128, returns its value. Otherwise,
745
+ # returns 0.
746
+ #
747
+ # @return [Fixnum] The decimal128 value.
748
+ #
749
+ def decimal128
750
+ value = ""
751
+ Cproton.pn_data_get_decimal128(@data).each{|val| value += ("%02x" % val)}
752
+ value.to_i(16)
753
+ end
754
+
755
+ # Puts a +UUID+ value.
756
+ #
757
+ # The UUID is expected to be in the format of a string or else a 128-bit
758
+ # integer value.
759
+ #
760
+ # @param value [String, Numeric] A string or numeric representation of the UUID.
761
+ #
762
+ # @example
763
+ #
764
+ # # set a uuid value from a string value
765
+ # require 'securerandom'
766
+ # @data.uuid = SecureRandom.uuid
767
+ #
768
+ # # or
769
+ # @data.uuid = "fd0289a5-8eec-4a08-9283-81d02c9d2fff"
770
+ #
771
+ # # set a uuid value from a 128-bit value
772
+ # @data.uuid = 0 # sets to 00000000-0000-0000-0000-000000000000
773
+ #
774
+ def uuid=(value)
775
+ raise ::ArgumentError, "invalid uuid: #{value}" if value.nil?
776
+
777
+ # if the uuid that was submitted was numeric value, then translated
778
+ # it into a hex string, otherwise assume it was a string represtation
779
+ # and attempt to decode it
780
+ if value.is_a? Numeric
781
+ value = "%032x" % value
782
+ else
783
+ raise ::ArgumentError, "invalid uuid: #{value}" if !valid_uuid?(value)
784
+
785
+ value = (value[0, 8] +
786
+ value[9, 4] +
787
+ value[14, 4] +
788
+ value[19, 4] +
789
+ value[24, 12])
790
+ end
791
+ bytes = []
792
+ value.scan(/(..)/) {|v| bytes << v[0].to_i(16)}
793
+ check(Cproton.pn_data_put_uuid(@data, bytes))
794
+ end
795
+
796
+ # If the current value is a +UUID+, returns its value. Otherwise,
797
+ # it returns nil.
798
+ #
799
+ # @return [String] The string representation of the UUID.
800
+ #
801
+ def uuid
802
+ value = ""
803
+ Cproton.pn_data_get_uuid(@data).each{|val| value += ("%02x" % val)}
804
+ value.insert(8, "-").insert(13, "-").insert(18, "-").insert(23, "-")
805
+ end
806
+
807
+ # Puts a binary value.
808
+ #
809
+ # A binary string is encoded as an ASCII 8-bit string value. This is in
810
+ # contranst to other strings, which are treated as UTF-8 encoded.
811
+ #
812
+ # @param value [String] An arbitrary string value.
813
+ #
814
+ # @see #string=
815
+ #
816
+ def binary=(value)
817
+ check(Cproton.pn_data_put_binary(@data, value))
818
+ end
819
+
820
+ # If the current node is binary, returns its value. Otherwise, it returns
821
+ # an empty string ("").
822
+ #
823
+ # @return [String] The binary string.
824
+ #
825
+ # @see #string
826
+ #
827
+ def binary
828
+ Qpid::Proton::Types::BinaryString.new(Cproton.pn_data_get_binary(@data))
829
+ end
830
+
831
+ # Puts a UTF-8 encoded string value.
832
+ #
833
+ # *NOTE:* A nil value is stored as an empty string rather than as a nil.
834
+ #
835
+ # @param value [String] The UTF-8 encoded string value.
836
+ #
837
+ # @see #binary=
838
+ #
839
+ def string=(value)
840
+ check(Cproton.pn_data_put_string(@data, value))
841
+ end
842
+
843
+ # If the current node is a string, returns its value. Otherwise, it
844
+ # returns an empty string ("").
845
+ #
846
+ # @return [String] The UTF-8 encoded string.
847
+ #
848
+ # @see #binary
849
+ #
850
+ def string
851
+ Qpid::Proton::Types::UTFString.new(Cproton.pn_data_get_string(@data))
852
+ end
853
+
854
+ # Puts a symbolic value.
855
+ #
856
+ # @param value [String] The symbolic string value.
857
+ #
858
+ def symbol=(value)
859
+ check(Cproton.pn_data_put_symbol(@data, value))
860
+ end
861
+
862
+ # If the current node is a symbol, returns its value. Otherwise, it
863
+ # returns an empty string ("").
864
+ #
865
+ # @return [String] The symbolic string value.
866
+ #
867
+ def symbol
868
+ Cproton.pn_data_get_symbol(@data)
869
+ end
870
+
871
+ # Get the current value as a single object.
872
+ #
873
+ # @return [Object] The current node's object.
874
+ #
875
+ # @see #type_code
876
+ # @see #type
877
+ #
878
+ def get
879
+ type.get(self);
880
+ end
881
+
882
+ # Puts a new value with the given type into the current node.
883
+ #
884
+ # @param value [Object] The value.
885
+ # @param type_code [Mapping] The value's type.
886
+ #
887
+ # @private
888
+ #
889
+ def put(value, type_code);
890
+ type_code.put(self, value);
891
+ end
892
+
893
+ private
894
+
895
+ def valid_uuid?(value)
896
+ # ensure that the UUID is in the right format
897
+ # xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
898
+ 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}/
899
+ end
900
+
901
+ # @private
902
+ def check(err)
903
+ if err < 0
904
+ raise DataError, "[#{err}]: #{Cproton.pn_data_error(@data)}"
905
+ else
906
+ return err
907
+ end
908
+ end
909
+
910
+ end
911
+
912
+ end