fl-thrift 0.0.1

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 (83) hide show
  1. data/CHANGELOG +4 -0
  2. data/Manifest +81 -0
  3. data/README +43 -0
  4. data/Rakefile +102 -0
  5. data/benchmark/Benchmark.thrift +24 -0
  6. data/benchmark/benchmark.rb +271 -0
  7. data/benchmark/client.rb +74 -0
  8. data/benchmark/server.rb +82 -0
  9. data/benchmark/thin_server.rb +44 -0
  10. data/ext/binary_protocol_accelerated.c +474 -0
  11. data/ext/binary_protocol_accelerated.h +20 -0
  12. data/ext/compact_protocol.c +665 -0
  13. data/ext/compact_protocol.h +20 -0
  14. data/ext/constants.h +95 -0
  15. data/ext/extconf.rb +26 -0
  16. data/ext/macros.h +41 -0
  17. data/ext/memory_buffer.c +76 -0
  18. data/ext/memory_buffer.h +20 -0
  19. data/ext/protocol.c +185 -0
  20. data/ext/protocol.h +20 -0
  21. data/ext/struct.c +606 -0
  22. data/ext/struct.h +67 -0
  23. data/ext/thrift_native.c +194 -0
  24. data/lib/thrift.rb +59 -0
  25. data/lib/thrift/client.rb +62 -0
  26. data/lib/thrift/core_ext.rb +23 -0
  27. data/lib/thrift/core_ext/fixnum.rb +29 -0
  28. data/lib/thrift/exceptions.rb +82 -0
  29. data/lib/thrift/processor.rb +57 -0
  30. data/lib/thrift/protocol/base_protocol.rb +290 -0
  31. data/lib/thrift/protocol/binary_protocol.rb +225 -0
  32. data/lib/thrift/protocol/binary_protocol_accelerated.rb +35 -0
  33. data/lib/thrift/protocol/compact_protocol.rb +422 -0
  34. data/lib/thrift/serializer/deserializer.rb +33 -0
  35. data/lib/thrift/serializer/serializer.rb +34 -0
  36. data/lib/thrift/server/base_server.rb +31 -0
  37. data/lib/thrift/server/mongrel_http_server.rb +58 -0
  38. data/lib/thrift/server/nonblocking_server.rb +296 -0
  39. data/lib/thrift/server/simple_server.rb +43 -0
  40. data/lib/thrift/server/thread_pool_server.rb +75 -0
  41. data/lib/thrift/server/threaded_server.rb +47 -0
  42. data/lib/thrift/struct.rb +298 -0
  43. data/lib/thrift/thrift_native.rb +24 -0
  44. data/lib/thrift/transport/base_server_transport.rb +37 -0
  45. data/lib/thrift/transport/base_transport.rb +70 -0
  46. data/lib/thrift/transport/buffered_transport.rb +77 -0
  47. data/lib/thrift/transport/framed_transport.rb +90 -0
  48. data/lib/thrift/transport/http_client_transport.rb +45 -0
  49. data/lib/thrift/transport/io_stream_transport.rb +39 -0
  50. data/lib/thrift/transport/memory_buffer_transport.rb +96 -0
  51. data/lib/thrift/transport/server_socket.rb +63 -0
  52. data/lib/thrift/transport/socket.rb +136 -0
  53. data/lib/thrift/transport/unix_server_socket.rb +60 -0
  54. data/lib/thrift/transport/unix_socket.rb +40 -0
  55. data/lib/thrift/types.rb +101 -0
  56. data/script/proto_benchmark.rb +121 -0
  57. data/script/read_struct.rb +43 -0
  58. data/script/write_struct.rb +30 -0
  59. data/setup.rb +1585 -0
  60. data/spec/ThriftSpec.thrift +84 -0
  61. data/spec/base_protocol_spec.rb +160 -0
  62. data/spec/base_transport_spec.rb +351 -0
  63. data/spec/binary_protocol_accelerated_spec.rb +41 -0
  64. data/spec/binary_protocol_spec.rb +63 -0
  65. data/spec/binary_protocol_spec_shared.rb +375 -0
  66. data/spec/client_spec.rb +100 -0
  67. data/spec/compact_protocol_spec.rb +117 -0
  68. data/spec/exception_spec.rb +142 -0
  69. data/spec/http_client_spec.rb +49 -0
  70. data/spec/mongrel_http_server_spec.rb +117 -0
  71. data/spec/nonblocking_server_spec.rb +265 -0
  72. data/spec/processor_spec.rb +83 -0
  73. data/spec/serializer_spec.rb +69 -0
  74. data/spec/server_socket_spec.rb +80 -0
  75. data/spec/server_spec.rb +160 -0
  76. data/spec/socket_spec.rb +61 -0
  77. data/spec/socket_spec_shared.rb +104 -0
  78. data/spec/spec_helper.rb +60 -0
  79. data/spec/struct_spec.rb +252 -0
  80. data/spec/types_spec.rb +116 -0
  81. data/spec/unix_socket_spec.rb +108 -0
  82. data/thrift.gemspec +32 -0
  83. metadata +202 -0
@@ -0,0 +1,57 @@
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 Thrift
21
+ module Processor
22
+ def initialize(handler)
23
+ @handler = handler
24
+ end
25
+
26
+ def process(iprot, oprot)
27
+ name, type, seqid = iprot.read_message_begin
28
+ if respond_to?("process_#{name}")
29
+ send("process_#{name}", seqid, iprot, oprot)
30
+ true
31
+ else
32
+ iprot.skip(Types::STRUCT)
33
+ iprot.read_message_end
34
+ x = ApplicationException.new(ApplicationException::UNKNOWN_METHOD, 'Unknown function '+name)
35
+ oprot.write_message_begin(name, MessageTypes::EXCEPTION, seqid)
36
+ x.write(oprot)
37
+ oprot.write_message_end
38
+ oprot.trans.flush
39
+ false
40
+ end
41
+ end
42
+
43
+ def read_args(iprot, args_class)
44
+ args = args_class.new
45
+ args.read(iprot)
46
+ iprot.read_message_end
47
+ args
48
+ end
49
+
50
+ def write_result(result, oprot, name, seqid)
51
+ oprot.write_message_begin(name, MessageTypes::REPLY, seqid)
52
+ result.write(oprot)
53
+ oprot.write_message_end
54
+ oprot.trans.flush
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,290 @@
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
+ # this require is to make generated struct definitions happy
21
+ require 'set'
22
+
23
+ module Thrift
24
+ class ProtocolException < Exception
25
+
26
+ UNKNOWN = 0
27
+ INVALID_DATA = 1
28
+ NEGATIVE_SIZE = 2
29
+ SIZE_LIMIT = 3
30
+ BAD_VERSION = 4
31
+
32
+ attr_reader :type
33
+
34
+ def initialize(type=UNKNOWN, message=nil)
35
+ super(message)
36
+ @type = type
37
+ end
38
+ end
39
+
40
+ class BaseProtocol
41
+
42
+ attr_reader :trans
43
+
44
+ def initialize(trans)
45
+ @trans = trans
46
+ end
47
+
48
+ def native?
49
+ puts "wrong method is being called!"
50
+ false
51
+ end
52
+
53
+ def write_message_begin(name, type, seqid)
54
+ raise NotImplementedError
55
+ end
56
+
57
+ def write_message_end; nil; end
58
+
59
+ def write_struct_begin(name)
60
+ raise NotImplementedError
61
+ end
62
+
63
+ def write_struct_end; nil; end
64
+
65
+ def write_field_begin(name, type, id)
66
+ raise NotImplementedError
67
+ end
68
+
69
+ def write_field_end; nil; end
70
+
71
+ def write_field_stop
72
+ raise NotImplementedError
73
+ end
74
+
75
+ def write_map_begin(ktype, vtype, size)
76
+ raise NotImplementedError
77
+ end
78
+
79
+ def write_map_end; nil; end
80
+
81
+ def write_list_begin(etype, size)
82
+ raise NotImplementedError
83
+ end
84
+
85
+ def write_list_end; nil; end
86
+
87
+ def write_set_begin(etype, size)
88
+ raise NotImplementedError
89
+ end
90
+
91
+ def write_set_end; nil; end
92
+
93
+ def write_bool(bool)
94
+ raise NotImplementedError
95
+ end
96
+
97
+ def write_byte(byte)
98
+ raise NotImplementedError
99
+ end
100
+
101
+ def write_i16(i16)
102
+ raise NotImplementedError
103
+ end
104
+
105
+ def write_i32(i32)
106
+ raise NotImplementedError
107
+ end
108
+
109
+ def write_i64(i64)
110
+ raise NotImplementedError
111
+ end
112
+
113
+ def write_double(dub)
114
+ raise NotImplementedError
115
+ end
116
+
117
+ def write_string(str)
118
+ raise NotImplementedError
119
+ end
120
+
121
+ def read_message_begin
122
+ raise NotImplementedError
123
+ end
124
+
125
+ def read_message_end; nil; end
126
+
127
+ def read_struct_begin
128
+ raise NotImplementedError
129
+ end
130
+
131
+ def read_struct_end; nil; end
132
+
133
+ def read_field_begin
134
+ raise NotImplementedError
135
+ end
136
+
137
+ def read_field_end; nil; end
138
+
139
+ def read_map_begin
140
+ raise NotImplementedError
141
+ end
142
+
143
+ def read_map_end; nil; end
144
+
145
+ def read_list_begin
146
+ raise NotImplementedError
147
+ end
148
+
149
+ def read_list_end; nil; end
150
+
151
+ def read_set_begin
152
+ raise NotImplementedError
153
+ end
154
+
155
+ def read_set_end; nil; end
156
+
157
+ def read_bool
158
+ raise NotImplementedError
159
+ end
160
+
161
+ def read_byte
162
+ raise NotImplementedError
163
+ end
164
+
165
+ def read_i16
166
+ raise NotImplementedError
167
+ end
168
+
169
+ def read_i32
170
+ raise NotImplementedError
171
+ end
172
+
173
+ def read_i64
174
+ raise NotImplementedError
175
+ end
176
+
177
+ def read_double
178
+ raise NotImplementedError
179
+ end
180
+
181
+ def read_string
182
+ raise NotImplementedError
183
+ end
184
+
185
+ def write_field(name, type, fid, value)
186
+ write_field_begin(name, type, fid)
187
+ write_type(type, value)
188
+ write_field_end
189
+ end
190
+
191
+ def write_type(type, value)
192
+ case type
193
+ when Types::BOOL
194
+ write_bool(value)
195
+ when Types::BYTE
196
+ write_byte(value)
197
+ when Types::DOUBLE
198
+ write_double(value)
199
+ when Types::I16
200
+ write_i16(value)
201
+ when Types::I32
202
+ write_i32(value)
203
+ when Types::I64
204
+ write_i64(value)
205
+ when Types::STRING
206
+ write_string(value)
207
+ when Types::STRUCT
208
+ value.write(self)
209
+ else
210
+ raise NotImplementedError
211
+ end
212
+ end
213
+
214
+ def read_type(type)
215
+ case type
216
+ when Types::BOOL
217
+ read_bool
218
+ when Types::BYTE
219
+ read_byte
220
+ when Types::DOUBLE
221
+ read_double
222
+ when Types::I16
223
+ read_i16
224
+ when Types::I32
225
+ read_i32
226
+ when Types::I64
227
+ read_i64
228
+ when Types::STRING
229
+ read_string
230
+ else
231
+ raise NotImplementedError
232
+ end
233
+ end
234
+
235
+ def skip(type)
236
+ case type
237
+ when Types::STOP
238
+ nil
239
+ when Types::BOOL
240
+ read_bool
241
+ when Types::BYTE
242
+ read_byte
243
+ when Types::I16
244
+ read_i16
245
+ when Types::I32
246
+ read_i32
247
+ when Types::I64
248
+ read_i64
249
+ when Types::DOUBLE
250
+ read_double
251
+ when Types::STRING
252
+ read_string
253
+ when Types::STRUCT
254
+ read_struct_begin
255
+ while true
256
+ name, type, id = read_field_begin
257
+ break if type == Types::STOP
258
+ skip(type)
259
+ read_field_end
260
+ end
261
+ read_struct_end
262
+ when Types::MAP
263
+ ktype, vtype, size = read_map_begin
264
+ size.times do
265
+ skip(ktype)
266
+ skip(vtype)
267
+ end
268
+ read_map_end
269
+ when Types::SET
270
+ etype, size = read_set_begin
271
+ size.times do
272
+ skip(etype)
273
+ end
274
+ read_set_end
275
+ when Types::LIST
276
+ etype, size = read_list_begin
277
+ size.times do
278
+ skip(etype)
279
+ end
280
+ read_list_end
281
+ end
282
+ end
283
+ end
284
+
285
+ class BaseProtocolFactory
286
+ def get_protocol(trans)
287
+ raise NotImplementedError
288
+ end
289
+ end
290
+ end
@@ -0,0 +1,225 @@
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 Thrift
21
+ class BinaryProtocol < BaseProtocol
22
+ VERSION_MASK = 0xffff0000
23
+ VERSION_1 = 0x80010000
24
+ TYPE_MASK = 0x000000ff
25
+
26
+ attr_reader :strict_read, :strict_write
27
+
28
+ def initialize(trans, strict_read=true, strict_write=true)
29
+ super(trans)
30
+ @strict_read = strict_read
31
+ @strict_write = strict_write
32
+ end
33
+
34
+ def write_message_begin(name, type, seqid)
35
+ # this is necessary because we added (needed) bounds checking to
36
+ # write_i32, and 0x80010000 is too big for that.
37
+ if strict_write
38
+ write_i16(VERSION_1 >> 16)
39
+ write_i16(type)
40
+ write_string(name)
41
+ write_i32(seqid)
42
+ else
43
+ write_string(name)
44
+ write_byte(type)
45
+ write_i32(seqid)
46
+ end
47
+ end
48
+
49
+ def write_struct_begin(name); nil; end
50
+
51
+ def write_field_begin(name, type, id)
52
+ write_byte(type)
53
+ write_i16(id)
54
+ end
55
+
56
+ def write_field_stop
57
+ write_byte(Thrift::Types::STOP)
58
+ end
59
+
60
+ def write_map_begin(ktype, vtype, size)
61
+ write_byte(ktype)
62
+ write_byte(vtype)
63
+ write_i32(size)
64
+ end
65
+
66
+ def write_list_begin(etype, size)
67
+ write_byte(etype)
68
+ write_i32(size)
69
+ end
70
+
71
+ def write_set_begin(etype, size)
72
+ write_byte(etype)
73
+ write_i32(size)
74
+ end
75
+
76
+ def write_bool(bool)
77
+ write_byte(bool ? 1 : 0)
78
+ end
79
+
80
+ def write_byte(byte)
81
+ raise RangeError if byte < -2**31 || byte >= 2**32
82
+ trans.write([byte].pack('c'))
83
+ end
84
+
85
+ def write_i16(i16)
86
+ trans.write([i16].pack('n'))
87
+ end
88
+
89
+ def write_i32(i32)
90
+ raise RangeError if i32 < -2**31 || i32 >= 2**31
91
+ trans.write([i32].pack('N'))
92
+ end
93
+
94
+ def write_i64(i64)
95
+ raise RangeError if i64 < -2**63 || i64 >= 2**64
96
+ hi = i64 >> 32
97
+ lo = i64 & 0xffffffff
98
+ trans.write([hi, lo].pack('N2'))
99
+ end
100
+
101
+ def write_double(dub)
102
+ trans.write([dub].pack('G'))
103
+ end
104
+
105
+ def write_string(str)
106
+ write_i32(str.length)
107
+ trans.write(str)
108
+ end
109
+
110
+ def read_message_begin
111
+ version = read_i32
112
+ if version < 0
113
+ if (version & VERSION_MASK != VERSION_1)
114
+ raise ProtocolException.new(ProtocolException::BAD_VERSION, 'Missing version identifier')
115
+ end
116
+ type = version & TYPE_MASK
117
+ name = read_string
118
+ seqid = read_i32
119
+ [name, type, seqid]
120
+ else
121
+ if strict_read
122
+ raise ProtocolException.new(ProtocolException::BAD_VERSION, 'No version identifier, old protocol client?')
123
+ end
124
+ name = trans.read_all(version)
125
+ type = read_byte
126
+ seqid = read_i32
127
+ [name, type, seqid]
128
+ end
129
+ end
130
+
131
+ def read_struct_begin; nil; end
132
+
133
+ def read_field_begin
134
+ type = read_byte
135
+ if (type == Types::STOP)
136
+ [nil, type, 0]
137
+ else
138
+ id = read_i16
139
+ [nil, type, id]
140
+ end
141
+ end
142
+
143
+ def read_map_begin
144
+ ktype = read_byte
145
+ vtype = read_byte
146
+ size = read_i32
147
+ [ktype, vtype, size]
148
+ end
149
+
150
+ def read_list_begin
151
+ etype = read_byte
152
+ size = read_i32
153
+ [etype, size]
154
+ end
155
+
156
+ def read_set_begin
157
+ etype = read_byte
158
+ size = read_i32
159
+ [etype, size]
160
+ end
161
+
162
+ def read_bool
163
+ byte = read_byte
164
+ byte != 0
165
+ end
166
+
167
+ def read_byte
168
+ dat = trans.read_all(1)
169
+ val = dat[0].ord
170
+ if (val > 0x7f)
171
+ val = 0 - ((val - 1) ^ 0xff)
172
+ end
173
+ val
174
+ end
175
+
176
+ def read_i16
177
+ dat = trans.read_all(2)
178
+ val, = dat.unpack('n')
179
+ if (val > 0x7fff)
180
+ val = 0 - ((val - 1) ^ 0xffff)
181
+ end
182
+ val
183
+ end
184
+
185
+ def read_i32
186
+ dat = trans.read_all(4)
187
+ val, = dat.unpack('N')
188
+ if (val > 0x7fffffff)
189
+ val = 0 - ((val - 1) ^ 0xffffffff)
190
+ end
191
+ val
192
+ end
193
+
194
+ def read_i64
195
+ dat = trans.read_all(8)
196
+ hi, lo = dat.unpack('N2')
197
+ if (hi > 0x7fffffff)
198
+ hi ^= 0xffffffff
199
+ lo ^= 0xffffffff
200
+ 0 - (hi << 32) - lo - 1
201
+ else
202
+ (hi << 32) + lo
203
+ end
204
+ end
205
+
206
+ def read_double
207
+ dat = trans.read_all(8)
208
+ val = dat.unpack('G').first
209
+ val
210
+ end
211
+
212
+ def read_string
213
+ sz = read_i32
214
+ dat = trans.read_all(sz)
215
+ dat
216
+ end
217
+
218
+ end
219
+
220
+ class BinaryProtocolFactory < BaseProtocolFactory
221
+ def get_protocol(trans)
222
+ return Thrift::BinaryProtocol.new(trans)
223
+ end
224
+ end
225
+ end