sparqcode_bunny 0.0.1

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