qpid_proton 0.9.0 → 0.10

Sign up to get free protection for your applications and to get access to all the features.
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