bunny 0.6.3.rc2 → 0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/.gitignore +8 -0
  2. data/.rspec +3 -0
  3. data/.travis.yml +15 -0
  4. data/.yardopts +9 -0
  5. data/CHANGELOG +3 -0
  6. data/Gemfile +39 -0
  7. data/Gemfile.lock +34 -0
  8. data/LICENSE +5 -4
  9. data/README.textile +54 -0
  10. data/Rakefile +15 -13
  11. data/bunny.gemspec +42 -61
  12. data/examples/simple_08.rb +4 -2
  13. data/examples/simple_09.rb +4 -2
  14. data/examples/simple_ack_08.rb +3 -1
  15. data/examples/simple_ack_09.rb +3 -1
  16. data/examples/simple_consumer_08.rb +4 -2
  17. data/examples/simple_consumer_09.rb +4 -2
  18. data/examples/simple_fanout_08.rb +3 -1
  19. data/examples/simple_fanout_09.rb +3 -1
  20. data/examples/simple_headers_08.rb +5 -3
  21. data/examples/simple_headers_09.rb +5 -3
  22. data/examples/simple_publisher_08.rb +3 -1
  23. data/examples/simple_publisher_09.rb +3 -1
  24. data/examples/simple_topic_08.rb +5 -3
  25. data/examples/simple_topic_09.rb +5 -3
  26. data/ext/amqp-0.8.json +616 -0
  27. data/ext/amqp-0.9.1.json +388 -0
  28. data/ext/config.yml +4 -0
  29. data/ext/qparser.rb +463 -0
  30. data/lib/bunny.rb +88 -66
  31. data/lib/bunny/channel08.rb +38 -38
  32. data/lib/bunny/channel09.rb +37 -37
  33. data/lib/bunny/client08.rb +184 -206
  34. data/lib/bunny/client09.rb +277 -363
  35. data/lib/bunny/consumer.rb +35 -0
  36. data/lib/bunny/exchange08.rb +37 -41
  37. data/lib/bunny/exchange09.rb +106 -124
  38. data/lib/bunny/queue08.rb +216 -202
  39. data/lib/bunny/queue09.rb +256 -326
  40. data/lib/bunny/subscription08.rb +30 -29
  41. data/lib/bunny/subscription09.rb +84 -83
  42. data/lib/bunny/version.rb +5 -0
  43. data/lib/qrack/amq-client-url.rb +165 -0
  44. data/lib/qrack/channel.rb +19 -17
  45. data/lib/qrack/client.rb +152 -151
  46. data/lib/qrack/errors.rb +5 -0
  47. data/lib/qrack/protocol/protocol08.rb +132 -130
  48. data/lib/qrack/protocol/protocol09.rb +133 -131
  49. data/lib/qrack/protocol/spec08.rb +2 -0
  50. data/lib/qrack/protocol/spec09.rb +2 -0
  51. data/lib/qrack/qrack08.rb +7 -10
  52. data/lib/qrack/qrack09.rb +7 -10
  53. data/lib/qrack/queue.rb +27 -40
  54. data/lib/qrack/subscription.rb +102 -101
  55. data/lib/qrack/transport/buffer08.rb +266 -264
  56. data/lib/qrack/transport/buffer09.rb +268 -264
  57. data/lib/qrack/transport/frame08.rb +13 -11
  58. data/lib/qrack/transport/frame09.rb +9 -7
  59. data/spec/spec_08/bunny_spec.rb +48 -45
  60. data/spec/spec_08/connection_spec.rb +10 -7
  61. data/spec/spec_08/exchange_spec.rb +145 -143
  62. data/spec/spec_08/queue_spec.rb +161 -161
  63. data/spec/spec_09/bunny_spec.rb +46 -44
  64. data/spec/spec_09/connection_spec.rb +15 -8
  65. data/spec/spec_09/exchange_spec.rb +147 -145
  66. data/spec/spec_09/queue_spec.rb +182 -184
  67. metadata +60 -41
  68. data/README.rdoc +0 -66
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  if [].map.respond_to? :with_index
2
4
  class Array #:nodoc:
3
5
  def enum_with_index
@@ -9,268 +11,270 @@ else
9
11
  end
10
12
 
11
13
  module Qrack
12
- module Transport09 #:nodoc: all
13
- class Buffer
14
-
15
- def initialize data = ''
16
- @data = data
17
- @pos = 0
18
- end
19
-
20
- attr_reader :pos
21
-
22
- def data
23
- @data.clone
24
- end
25
- alias :contents :data
26
- alias :to_s :data
27
-
28
- def << data
29
- @data << data.to_s
30
- self
31
- end
32
-
33
- def length
34
- @data.bytesize
35
- end
36
-
37
- def empty?
38
- pos == length
39
- end
40
-
41
- def rewind
42
- @pos = 0
43
- end
44
-
45
- def read_properties *types
46
- types.shift if types.first == :properties
47
-
48
- i = 0
49
- values = []
50
-
51
- while props = read(:short)
52
- (0..14).each do |n|
53
- # no more property types
54
- break unless types[i]
55
-
56
- # if flag is set
57
- if props & (1<<(15-n)) != 0
58
- if types[i] == :bit
59
- # bit values exist in flags only
60
- values << true
61
- else
62
- # save type name for later reading
63
- values << types[i]
64
- end
65
- else
66
- # property not set or is false bit
67
- values << (types[i] == :bit ? false : nil)
68
- end
69
-
70
- i+=1
71
- end
72
-
73
- # bit(0) == 0 means no more property flags
74
- break unless props & 1 == 1
75
- end
76
-
77
- values.map do |value|
78
- value.is_a?(Symbol) ? read(value) : value
79
- end
80
- end
81
-
82
- def read *types
83
- if types.first == :properties
84
- return read_properties(*types)
85
- end
86
-
87
- values = types.map do |type|
88
- case type
89
- when :octet
90
- _read(1, 'C')
91
- when :short
92
- _read(2, 'n')
93
- when :long
94
- _read(4, 'N')
95
- when :longlong
96
- upper, lower = _read(8, 'NN')
97
- upper << 32 | lower
98
- when :shortstr
99
- _read read(:octet)
100
- when :longstr
101
- _read read(:long)
102
- when :timestamp
103
- Time.at read(:longlong)
104
- when :table
105
- t = Hash.new
106
-
107
- table = Buffer.new(read(:longstr))
108
- until table.empty?
109
- key, type = table.read(:shortstr, :octet)
110
- key = key.intern
111
- t[key] ||= case type
112
- when 83 # 'S'
113
- table.read(:longstr)
114
- when 73 # 'I'
115
- table.read(:long)
116
- when 68 # 'D'
117
- exp = table.read(:octet)
118
- num = table.read(:long)
119
- num / 10.0**exp
120
- when 84 # 'T'
121
- table.read(:timestamp)
122
- when 70 # 'F'
123
- table.read(:table)
124
- end
125
- end
126
-
127
- t
128
- when :bit
129
- if (@bits ||= []).empty?
130
- val = read(:octet)
131
- @bits = (0..7).map{|i| (val & 1<<i) != 0 }
132
- end
133
-
134
- @bits.shift
135
- else
136
- raise Qrack::InvalidTypeError, "Cannot read data of type #{type}"
137
- end
138
- end
139
-
140
- types.size == 1 ? values.first : values
141
- end
142
-
143
- def write type, data
144
- case type
145
- when :octet
146
- _write(data, 'C')
147
- when :short
148
- _write(data, 'n')
149
- when :long
150
- _write(data, 'N')
151
- when :longlong
152
- lower = data & 0xffffffff
153
- upper = (data & ~0xffffffff) >> 32
154
- _write([upper, lower], 'NN')
155
- when :shortstr
156
- data = (data || '').to_s
157
- _write([data.bytesize, data], 'Ca*')
158
- when :longstr
159
- if data.is_a? Hash
160
- write(:table, data)
161
- else
162
- data = (data || '').to_s
163
- _write([data.bytesize, data], 'Na*')
164
- end
165
- when :timestamp
166
- write(:longlong, data.to_i)
167
- when :table
168
- data ||= {}
169
- write :longstr, (data.inject(Buffer.new) do |table, (key, value)|
170
- table.write(:shortstr, key.to_s)
171
-
172
- case value
173
- when String
174
- table.write(:octet, 83) # 'S'
175
- table.write(:longstr, value.to_s)
176
- when Fixnum
177
- table.write(:octet, 73) # 'I'
178
- table.write(:long, value)
179
- when Float
180
- table.write(:octet, 68) # 'D'
181
- # XXX there's gotta be a better way to do this..
182
- exp = value.to_s.split('.').last.bytesize
183
- num = value * 10**exp
184
- table.write(:octet, exp)
185
- table.write(:long, num)
186
- when Time
187
- table.write(:octet, 84) # 'T'
188
- table.write(:timestamp, value)
189
- when Hash
190
- table.write(:octet, 70) # 'F'
191
- table.write(:table, value)
192
- end
193
-
194
- table
195
- end)
196
- when :bit
197
- [*data].to_enum(:each_slice, 8).each{|bits|
198
- write(:octet, bits.enum_with_index.inject(0){ |byte, (bit, i)|
199
- byte |= 1<<i if bit
200
- byte
201
- })
202
- }
203
- when :properties
204
- values = []
205
- data.enum_with_index.inject(0) do |short, ((type, value), i)|
206
- n = i % 15
207
- last = i+1 == data.size
208
-
209
- if (n == 0 and i != 0) or last
210
- if data.size > i+1
211
- short |= 1<<0
212
- elsif last and value
213
- values << [type,value]
214
- short |= 1<<(15-n)
215
- end
216
-
217
- write(:short, short)
218
- short = 0
219
- end
220
-
221
- if value and !last
222
- values << [type,value]
223
- short |= 1<<(15-n)
224
- end
225
-
226
- short
227
- end
228
-
229
- values.each do |type, value|
230
- write(type, value) unless type == :bit
231
- end
232
- else
233
- raise Qrack::InvalidTypeError, "Cannot write data of type #{type}"
234
- end
235
-
236
- self
237
- end
238
-
239
- def extract
240
- begin
241
- cur_data, cur_pos = @data.clone, @pos
242
- yield self
243
- rescue Qrack::BufferOverflowError
244
- @data, @pos = cur_data, cur_pos
245
- nil
246
- end
247
- end
248
-
249
- def _read(size, pack = nil)
250
- if @data.is_a?(Qrack::Client)
251
- raw = @data.read(size)
252
- return raw if raw.nil? or pack.nil?
253
- return raw.unpack(pack).first
254
- end
255
-
256
- if @pos + size > length
257
- raise Qrack::BufferOverflowError
258
- else
259
- data = @data[@pos,size]
260
- @data[@pos,size] = ''
261
- if pack
262
- data = data.unpack(pack)
263
- data = data.pop if data.size == 1
264
- end
265
- data
266
- end
267
- end
268
-
269
- def _write data, pack = nil
270
- data = [*data].pack(pack) if pack
271
- @data[@pos,0] = data
272
- @pos += data.bytesize
273
- end
274
- end
275
- end
14
+ module Transport09 #:nodoc: all
15
+ class Buffer
16
+
17
+ def initialize data = ''
18
+ @data = data
19
+ @pos = 0
20
+ end
21
+
22
+ attr_reader :pos
23
+
24
+ def data
25
+ @data.clone
26
+ end
27
+ alias :contents :data
28
+ alias :to_s :data
29
+
30
+ def << data
31
+ @data << data.to_s
32
+ self
33
+ end
34
+
35
+ def length
36
+ @data.bytesize
37
+ end
38
+
39
+ def empty?
40
+ pos == length
41
+ end
42
+
43
+ def rewind
44
+ @pos = 0
45
+ end
46
+
47
+ def read_properties *types
48
+ types.shift if types.first == :properties
49
+
50
+ i = 0
51
+ values = []
52
+
53
+ while props = read(:short)
54
+ (0..14).each do |n|
55
+ # no more property types
56
+ break unless types[i]
57
+
58
+ # if flag is set
59
+ if props & (1<<(15-n)) != 0
60
+ if types[i] == :bit
61
+ # bit values exist in flags only
62
+ values << true
63
+ else
64
+ # save type name for later reading
65
+ values << types[i]
66
+ end
67
+ else
68
+ # property not set or is false bit
69
+ values << (types[i] == :bit ? false : nil)
70
+ end
71
+
72
+ i+=1
73
+ end
74
+
75
+ # bit(0) == 0 means no more property flags
76
+ break unless props & 1 == 1
77
+ end
78
+
79
+ values.map do |value|
80
+ value.is_a?(Symbol) ? read(value) : value
81
+ end
82
+ end
83
+
84
+ def read *types
85
+ if types.first == :properties
86
+ return read_properties(*types)
87
+ end
88
+
89
+ values = types.map do |type|
90
+ case type
91
+ when :octet
92
+ _read(1, 'C')
93
+ when :short
94
+ _read(2, 'n')
95
+ when :long
96
+ _read(4, 'N')
97
+ when :longlong
98
+ upper, lower = _read(8, 'NN')
99
+ upper << 32 | lower
100
+ when :shortstr
101
+ _read read(:octet)
102
+ when :longstr
103
+ _read read(:long)
104
+ when :timestamp
105
+ Time.at read(:longlong)
106
+ when :table
107
+ t = Hash.new
108
+
109
+ table = Buffer.new(read(:longstr))
110
+ until table.empty?
111
+ key, type = table.read(:shortstr, :octet)
112
+ key = key.intern
113
+ t[key] ||= case type
114
+ when 83 # 'S'
115
+ table.read(:longstr)
116
+ when 73 # 'I'
117
+ table.read(:long)
118
+ when 68 # 'D'
119
+ exp = table.read(:octet)
120
+ num = table.read(:long)
121
+ num / 10.0**exp
122
+ when 84 # 'T'
123
+ table.read(:timestamp)
124
+ when 70 # 'F'
125
+ table.read(:table)
126
+ when 116 # 't'
127
+ table.read(:octet)
128
+ end
129
+ end
130
+
131
+ t
132
+ when :bit
133
+ if (@bits ||= []).empty?
134
+ val = read(:octet)
135
+ @bits = (0..7).map{|i| (val & (1 << i)) != 0 }
136
+ end
137
+
138
+ @bits.shift
139
+ else
140
+ raise Qrack::InvalidTypeError, "Cannot read data of type #{type}"
141
+ end
142
+ end
143
+
144
+ types.size == 1 ? values.first : values
145
+ end
146
+
147
+ def write type, data
148
+ case type
149
+ when :octet
150
+ _write(data, 'C')
151
+ when :short
152
+ _write(data, 'n')
153
+ when :long
154
+ _write(data, 'N')
155
+ when :longlong
156
+ lower = data & 0xffffffff
157
+ upper = (data & ~0xffffffff) >> 32
158
+ _write([upper, lower], 'NN')
159
+ when :shortstr
160
+ data = (data || '').to_s
161
+ _write([data.bytesize, data], 'Ca*')
162
+ when :longstr
163
+ if data.is_a? Hash
164
+ write(:table, data)
165
+ else
166
+ data = (data || '').to_s
167
+ _write([data.bytesize, data], 'Na*')
168
+ end
169
+ when :timestamp
170
+ write(:longlong, data.to_i)
171
+ when :table
172
+ data ||= {}
173
+ write :longstr, (data.inject(Buffer.new) do |table, (key, value)|
174
+ table.write(:shortstr, key.to_s)
175
+
176
+ case value
177
+ when String
178
+ table.write(:octet, 83) # 'S'
179
+ table.write(:longstr, value.to_s)
180
+ when Fixnum
181
+ table.write(:octet, 73) # 'I'
182
+ table.write(:long, value)
183
+ when Float
184
+ table.write(:octet, 68) # 'D'
185
+ # XXX there's gotta be a better way to do this..
186
+ exp = value.to_s.split('.').last.bytesize
187
+ num = value * 10**exp
188
+ table.write(:octet, exp)
189
+ table.write(:long, num)
190
+ when Time
191
+ table.write(:octet, 84) # 'T'
192
+ table.write(:timestamp, value)
193
+ when Hash
194
+ table.write(:octet, 70) # 'F'
195
+ table.write(:table, value)
196
+ end
197
+
198
+ table
199
+ end)
200
+ when :bit
201
+ [*data].to_enum(:each_slice, 8).each{|bits|
202
+ write(:octet, bits.enum_with_index.inject(0){ |byte, (bit, i)|
203
+ byte |= (1 << i) if bit
204
+ byte
205
+ })
206
+ }
207
+ when :properties
208
+ values = []
209
+ data.enum_with_index.inject(0) do |short, ((type, value), i)|
210
+ n = i % 15
211
+ last = i+1 == data.size
212
+
213
+ if (n == 0 and i != 0) or last
214
+ if data.size > i+1
215
+ short |= (1 << 0)
216
+ elsif last and value
217
+ values << [type,value]
218
+ short |= 1<<(15-n)
219
+ end
220
+
221
+ write(:short, short)
222
+ short = 0
223
+ end
224
+
225
+ if value and !last
226
+ values << [type,value]
227
+ short |= 1<<(15-n)
228
+ end
229
+
230
+ short
231
+ end
232
+
233
+ values.each do |type, value|
234
+ write(type, value) unless type == :bit
235
+ end
236
+ else
237
+ raise Qrack::InvalidTypeError, "Cannot write data of type #{type}"
238
+ end
239
+
240
+ self
241
+ end
242
+
243
+ def extract
244
+ begin
245
+ cur_data, cur_pos = @data.clone, @pos
246
+ yield self
247
+ rescue Qrack::BufferOverflowError
248
+ @data, @pos = cur_data, cur_pos
249
+ nil
250
+ end
251
+ end
252
+
253
+ def _read(size, pack = nil)
254
+ if @data.is_a?(Qrack::Client)
255
+ raw = @data.read(size)
256
+ return raw if raw.nil? or pack.nil?
257
+ return raw.unpack(pack).first
258
+ end
259
+
260
+ if @pos + size > length
261
+ raise Qrack::BufferOverflowError
262
+ else
263
+ data = @data[@pos,size]
264
+ @data[@pos,size] = ''
265
+ if pack
266
+ data = data.unpack(pack)
267
+ data = data.pop if data.size == 1
268
+ end
269
+ data
270
+ end
271
+ end
272
+
273
+ def _write data, pack = nil
274
+ data = [*data].pack(pack) if pack
275
+ @data[@pos,0] = data
276
+ @pos += data.bytesize
277
+ end
278
+ end
279
+ end
276
280
  end