thrift 0.2.0.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/CHANGELOG +1 -13
  2. data/Manifest +11 -23
  3. data/Rakefile +8 -6
  4. data/ext/binary_protocol_accelerated.c +4 -53
  5. data/ext/compact_protocol.c +3 -53
  6. data/ext/extconf.rb +4 -18
  7. data/ext/struct.c +181 -130
  8. data/ext/struct.h +2 -44
  9. data/ext/thrift_native.c +3 -3
  10. data/lib/thrift.rb +6 -1
  11. data/lib/thrift/protocol/binary_protocol_accelerated.rb +5 -1
  12. data/lib/thrift/protocol/compact_protocol.rb +1 -0
  13. data/lib/thrift/server/nonblocking_server.rb +1 -2
  14. data/lib/thrift/struct.rb +46 -112
  15. data/lib/thrift/struct_union.rb +159 -0
  16. data/lib/thrift/transport/http_client_transport.rb +12 -6
  17. data/lib/thrift/transport/memory_buffer_transport.rb +2 -2
  18. data/lib/thrift/types.rb +1 -1
  19. data/lib/thrift/union.rb +179 -0
  20. data/spec/ThriftSpec.thrift +48 -0
  21. data/spec/binary_protocol_accelerated_spec.rb +18 -13
  22. data/spec/binary_protocol_spec_shared.rb +2 -2
  23. data/spec/compact_protocol_spec.rb +19 -3
  24. data/spec/http_client_spec.rb +17 -2
  25. data/spec/struct_spec.rb +34 -0
  26. data/spec/union_spec.rb +193 -0
  27. data/thrift.gemspec +11 -13
  28. metadata +36 -67
  29. data.tar.gz.sig +0 -2
  30. data/Makefile.am +0 -47
  31. data/benchmark/gen-rb/BenchmarkService.rb +0 -81
  32. data/benchmark/gen-rb/Benchmark_constants.rb +0 -11
  33. data/benchmark/gen-rb/Benchmark_types.rb +0 -10
  34. data/lib/thrift/protocol/binaryprotocol.rb +0 -213
  35. data/lib/thrift/protocol/binaryprotocolaccelerated.rb +0 -19
  36. data/lib/thrift/protocol/tbinaryprotocol.rb +0 -2
  37. data/lib/thrift/protocol/tprotocol.rb +0 -2
  38. data/lib/thrift/server/httpserver.rb +0 -44
  39. data/lib/thrift/server/nonblockingserver.rb +0 -278
  40. data/lib/thrift/server/thttpserver.rb +0 -2
  41. data/lib/thrift/server/tserver.rb +0 -2
  42. data/spec/gen-rb/NonblockingService.rb +0 -268
  43. data/spec/gen-rb/ThriftSpec_constants.rb +0 -11
  44. data/spec/gen-rb/ThriftSpec_types.rb +0 -134
  45. metadata.gz.sig +0 -0
@@ -17,51 +17,9 @@
17
17
  * under the License.
18
18
  */
19
19
 
20
+
20
21
  #include <stdbool.h>
21
22
  #include <ruby.h>
22
23
 
23
- typedef struct native_proto_method_table {
24
- VALUE (*write_bool)(VALUE, VALUE);
25
- VALUE (*write_byte)(VALUE, VALUE);
26
- VALUE (*write_i16)(VALUE, VALUE);
27
- VALUE (*write_i32)(VALUE, VALUE);
28
- VALUE (*write_i64)(VALUE, VALUE);
29
- VALUE (*write_double)(VALUE, VALUE);
30
- VALUE (*write_string)(VALUE, VALUE);
31
- VALUE (*write_list_begin)(VALUE, VALUE, VALUE);
32
- VALUE (*write_list_end)(VALUE);
33
- VALUE (*write_set_begin)(VALUE, VALUE, VALUE);
34
- VALUE (*write_set_end)(VALUE);
35
- VALUE (*write_map_begin)(VALUE, VALUE, VALUE, VALUE);
36
- VALUE (*write_map_end)(VALUE);
37
- VALUE (*write_struct_begin)(VALUE, VALUE);
38
- VALUE (*write_struct_end)(VALUE);
39
- VALUE (*write_field_begin)(VALUE, VALUE, VALUE, VALUE);
40
- VALUE (*write_field_end)(VALUE);
41
- VALUE (*write_field_stop)(VALUE);
42
- VALUE (*write_message_begin)(VALUE, VALUE, VALUE, VALUE);
43
- VALUE (*write_message_end)(VALUE);
44
-
45
- VALUE (*read_message_begin)(VALUE);
46
- VALUE (*read_message_end)(VALUE);
47
- VALUE (*read_field_begin)(VALUE);
48
- VALUE (*read_field_end)(VALUE);
49
- VALUE (*read_map_begin)(VALUE);
50
- VALUE (*read_map_end)(VALUE);
51
- VALUE (*read_list_begin)(VALUE);
52
- VALUE (*read_list_end)(VALUE);
53
- VALUE (*read_set_begin)(VALUE);
54
- VALUE (*read_set_end)(VALUE);
55
- VALUE (*read_byte)(VALUE);
56
- VALUE (*read_bool)(VALUE);
57
- VALUE (*read_i16)(VALUE);
58
- VALUE (*read_i32)(VALUE);
59
- VALUE (*read_i64)(VALUE);
60
- VALUE (*read_double)(VALUE);
61
- VALUE (*read_string)(VALUE);
62
- VALUE (*read_struct_begin)(VALUE);
63
- VALUE (*read_struct_end)(VALUE);
64
-
65
- } native_proto_method_table;
66
-
67
24
  void Init_struct();
25
+ void Init_union();
@@ -111,7 +111,7 @@ void Init_thrift_native() {
111
111
  thrift_types_module = rb_const_get(thrift_module, rb_intern("Types"));
112
112
  rb_cSet = rb_const_get(rb_cObject, rb_intern("Set"));
113
113
  protocol_exception_class = rb_const_get(thrift_module, rb_intern("ProtocolException"));
114
-
114
+
115
115
  // Init ttype constants
116
116
  TTYPE_BOOL = FIX2INT(rb_const_get(thrift_types_module, rb_intern("BOOL")));
117
117
  TTYPE_BYTE = FIX2INT(rb_const_get(thrift_types_module, rb_intern("BYTE")));
@@ -171,13 +171,13 @@ void Init_thrift_native() {
171
171
  write_method_id = rb_intern("write");
172
172
  read_all_method_id = rb_intern("read_all");
173
173
  native_qmark_method_id = rb_intern("native?");
174
-
174
+
175
175
  // constant ids
176
176
  fields_const_id = rb_intern("FIELDS");
177
177
  transport_ivar_id = rb_intern("@trans");
178
178
  strict_read_ivar_id = rb_intern("@strict_read");
179
179
  strict_write_ivar_id = rb_intern("@strict_write");
180
-
180
+
181
181
  // cached symbols
182
182
  type_sym = ID2SYM(rb_intern("type"));
183
183
  name_sym = ID2SYM(rb_intern("name"));
@@ -16,6 +16,9 @@
16
16
  # specific language governing permissions and limitations
17
17
  # under the License.
18
18
  #
19
+ # Contains some contributions under the Thrift Software License.
20
+ # Please see doc/old-thrift-license.txt in the Thrift distribution for
21
+ # details.
19
22
 
20
23
  $:.unshift File.dirname(__FILE__)
21
24
 
@@ -25,6 +28,8 @@ require 'thrift/types'
25
28
  require 'thrift/processor'
26
29
  require 'thrift/client'
27
30
  require 'thrift/struct'
31
+ require 'thrift/union'
32
+ require 'thrift/struct_union'
28
33
 
29
34
  # serializer
30
35
  require 'thrift/serializer/serializer'
@@ -56,4 +61,4 @@ require 'thrift/server/simple_server'
56
61
  require 'thrift/server/threaded_server'
57
62
  require 'thrift/server/thread_pool_server'
58
63
 
59
- require 'thrift/thrift_native'
64
+ require 'thrift/thrift_native'
@@ -29,7 +29,11 @@ See MemoryBuffer and BufferedTransport for examples.
29
29
  module Thrift
30
30
  class BinaryProtocolAcceleratedFactory < BaseProtocolFactory
31
31
  def get_protocol(trans)
32
- BinaryProtocolAccelerated.new(trans)
32
+ if (defined? BinaryProtocolAccelerated)
33
+ BinaryProtocolAccelerated.new(trans)
34
+ else
35
+ BinaryProtocol.new(trans)
36
+ end
33
37
  end
34
38
  end
35
39
  end
@@ -252,6 +252,7 @@ module Thrift
252
252
  modifier = (type & 0xf0) >> 4
253
253
  if modifier == 0
254
254
  # not a delta. look ahead for the zigzag varint field id.
255
+ @last_field.pop
255
256
  field_id = read_i16()
256
257
  else
257
258
  # has a delta. add the delta to the last read field id.
@@ -160,8 +160,7 @@ module Thrift
160
160
 
161
161
  def read_connection(fd)
162
162
  @buffers[fd] << fd.read(DEFAULT_BUFFER)
163
- frame = slice_frame!(@buffers[fd])
164
- if frame
163
+ while(frame = slice_frame!(@buffers[fd]))
165
164
  @logger.debug "#{self} is processing a frame"
166
165
  @worker_queue.push [:frame, fd, frame]
167
166
  end
@@ -65,33 +65,14 @@ module Thrift
65
65
  end
66
66
  fields_with_default_values
67
67
  end
68
-
69
- def name_to_id(name)
70
- names_to_ids = self.class.instance_variable_get("@names_to_ids")
71
- unless names_to_ids
72
- names_to_ids = {}
73
- struct_fields.each do |fid, field_def|
74
- names_to_ids[field_def[:name]] = fid
75
- end
76
- self.class.instance_variable_set("@names_to_ids", names_to_ids)
77
- end
78
- names_to_ids[name]
79
- end
80
-
81
- def each_field
82
- struct_fields.keys.sort.each do |fid|
83
- data = struct_fields[fid]
84
- yield fid, data
85
- end
86
- end
87
-
68
+
88
69
  def inspect(skip_optional_nulls = true)
89
70
  fields = []
90
71
  each_field do |fid, field_info|
91
72
  name = field_info[:name]
92
73
  value = instance_variable_get("@#{name}")
93
74
  unless skip_optional_nulls && field_info[:optional] && value.nil?
94
- fields << "#{name}:#{value.inspect}"
75
+ fields << "#{name}:#{inspect_field(value, field_info)}"
95
76
  end
96
77
  end
97
78
  "<#{self.class} #{fields.join(", ")}>"
@@ -115,7 +96,8 @@ module Thrift
115
96
  each_field do |fid, field_info|
116
97
  name = field_info[:name]
117
98
  type = field_info[:type]
118
- if (value = instance_variable_get("@#{name}"))
99
+ value = instance_variable_get("@#{name}")
100
+ unless value.nil?
119
101
  if is_container? type
120
102
  oprot.write_field_begin(name, type, fid)
121
103
  write_container(oprot, value, field_info)
@@ -163,13 +145,49 @@ module Thrift
163
145
  diffs
164
146
  end
165
147
 
166
- def self.field_accessor(klass, *fields)
167
- fields.each do |field|
168
- klass.send :attr_reader, field
169
- klass.send :define_method, "#{field}=" do |value|
170
- Thrift.check_type(value, klass::FIELDS.values.find { |f| f[:name].to_s == field.to_s }, field) if Thrift.type_checking
171
- instance_variable_set("@#{field}", value)
148
+ def self.field_accessor(klass, field_info)
149
+ field_name_sym = field_info[:name].to_sym
150
+ klass.send :attr_reader, field_name_sym
151
+ klass.send :define_method, "#{field_info[:name]}=" do |value|
152
+ Thrift.check_type(value, field_info, field_info[:name]) if Thrift.type_checking
153
+ instance_variable_set("@#{field_name_sym}", value)
154
+ end
155
+ end
156
+
157
+ def self.generate_accessors(klass)
158
+ klass::FIELDS.values.each do |field_info|
159
+ field_accessor(klass, field_info)
160
+ qmark_isset_method(klass, field_info)
161
+ end
162
+ end
163
+
164
+ def self.qmark_isset_method(klass, field_info)
165
+ klass.send :define_method, "#{field_info[:name]}?" do
166
+ !self.send(field_info[:name].to_sym).nil?
167
+ end
168
+ end
169
+
170
+ def <=>(other)
171
+ if self.class == other.class
172
+ each_field do |fid, field_info|
173
+ v1 = self.send(field_info[:name])
174
+ v1_set = !v1.nil?
175
+ v2 = other.send(field_info[:name])
176
+ v2_set = !v2.nil?
177
+ if v1_set && !v2_set
178
+ return -1
179
+ elsif !v1_set && v2_set
180
+ return 1
181
+ elsif v1_set && v2_set
182
+ cmp = v1 <=> v2
183
+ if cmp != 0
184
+ return cmp
185
+ end
186
+ end
172
187
  end
188
+ 0
189
+ else
190
+ self.class <=> other.class
173
191
  end
174
192
  end
175
193
 
@@ -210,89 +228,5 @@ module Thrift
210
228
  iprot.skip(ftype)
211
229
  end
212
230
  end
213
-
214
- def read_field(iprot, field = {})
215
- case field[:type]
216
- when Types::STRUCT
217
- value = field[:class].new
218
- value.read(iprot)
219
- when Types::MAP
220
- key_type, val_type, size = iprot.read_map_begin
221
- value = {}
222
- size.times do
223
- k = read_field(iprot, field_info(field[:key]))
224
- v = read_field(iprot, field_info(field[:value]))
225
- value[k] = v
226
- end
227
- iprot.read_map_end
228
- when Types::LIST
229
- e_type, size = iprot.read_list_begin
230
- value = Array.new(size) do |n|
231
- read_field(iprot, field_info(field[:element]))
232
- end
233
- iprot.read_list_end
234
- when Types::SET
235
- e_type, size = iprot.read_set_begin
236
- value = Set.new
237
- size.times do
238
- element = read_field(iprot, field_info(field[:element]))
239
- value << element
240
- end
241
- iprot.read_set_end
242
- else
243
- value = iprot.read_type(field[:type])
244
- end
245
- value
246
- end
247
-
248
- def write_data(oprot, value, field)
249
- if is_container? field[:type]
250
- write_container(oprot, value, field)
251
- else
252
- oprot.write_type(field[:type], value)
253
- end
254
- end
255
-
256
- def write_container(oprot, value, field = {})
257
- case field[:type]
258
- when Types::MAP
259
- oprot.write_map_begin(field[:key][:type], field[:value][:type], value.size)
260
- value.each do |k, v|
261
- write_data(oprot, k, field[:key])
262
- write_data(oprot, v, field[:value])
263
- end
264
- oprot.write_map_end
265
- when Types::LIST
266
- oprot.write_list_begin(field[:element][:type], value.size)
267
- value.each do |elem|
268
- write_data(oprot, elem, field[:element])
269
- end
270
- oprot.write_list_end
271
- when Types::SET
272
- oprot.write_set_begin(field[:element][:type], value.size)
273
- value.each do |v,| # the , is to preserve compatibility with the old Hash-style sets
274
- write_data(oprot, v, field[:element])
275
- end
276
- oprot.write_set_end
277
- else
278
- raise "Not a container type: #{field[:type]}"
279
- end
280
- end
281
-
282
- CONTAINER_TYPES = []
283
- CONTAINER_TYPES[Types::LIST] = true
284
- CONTAINER_TYPES[Types::MAP] = true
285
- CONTAINER_TYPES[Types::SET] = true
286
- def is_container?(type)
287
- CONTAINER_TYPES[type]
288
- end
289
-
290
- def field_info(field)
291
- { :type => field[:type],
292
- :class => field[:class],
293
- :key => field[:key],
294
- :value => field[:value],
295
- :element => field[:element] }
296
- end
297
231
  end
298
232
  end
@@ -0,0 +1,159 @@
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
+ require 'set'
20
+
21
+ module Thrift
22
+ module Struct_Union
23
+ def name_to_id(name)
24
+ names_to_ids = self.class.instance_variable_get("@names_to_ids")
25
+ unless names_to_ids
26
+ names_to_ids = {}
27
+ struct_fields.each do |fid, field_def|
28
+ names_to_ids[field_def[:name]] = fid
29
+ end
30
+ self.class.instance_variable_set("@names_to_ids", names_to_ids)
31
+ end
32
+ names_to_ids[name]
33
+ end
34
+
35
+ def each_field
36
+ struct_fields.keys.sort.each do |fid|
37
+ data = struct_fields[fid]
38
+ yield fid, data
39
+ end
40
+ end
41
+
42
+ def read_field(iprot, field = {})
43
+ case field[:type]
44
+ when Types::STRUCT
45
+ value = field[:class].new
46
+ value.read(iprot)
47
+ when Types::MAP
48
+ key_type, val_type, size = iprot.read_map_begin
49
+ value = {}
50
+ size.times do
51
+ k = read_field(iprot, field_info(field[:key]))
52
+ v = read_field(iprot, field_info(field[:value]))
53
+ value[k] = v
54
+ end
55
+ iprot.read_map_end
56
+ when Types::LIST
57
+ e_type, size = iprot.read_list_begin
58
+ value = Array.new(size) do |n|
59
+ read_field(iprot, field_info(field[:element]))
60
+ end
61
+ iprot.read_list_end
62
+ when Types::SET
63
+ e_type, size = iprot.read_set_begin
64
+ value = Set.new
65
+ size.times do
66
+ element = read_field(iprot, field_info(field[:element]))
67
+ value << element
68
+ end
69
+ iprot.read_set_end
70
+ else
71
+ value = iprot.read_type(field[:type])
72
+ end
73
+ value
74
+ end
75
+
76
+ def write_data(oprot, value, field)
77
+ if is_container? field[:type]
78
+ write_container(oprot, value, field)
79
+ else
80
+ oprot.write_type(field[:type], value)
81
+ end
82
+ end
83
+
84
+ def write_container(oprot, value, field = {})
85
+ case field[:type]
86
+ when Types::MAP
87
+ oprot.write_map_begin(field[:key][:type], field[:value][:type], value.size)
88
+ value.each do |k, v|
89
+ write_data(oprot, k, field[:key])
90
+ write_data(oprot, v, field[:value])
91
+ end
92
+ oprot.write_map_end
93
+ when Types::LIST
94
+ oprot.write_list_begin(field[:element][:type], value.size)
95
+ value.each do |elem|
96
+ write_data(oprot, elem, field[:element])
97
+ end
98
+ oprot.write_list_end
99
+ when Types::SET
100
+ oprot.write_set_begin(field[:element][:type], value.size)
101
+ value.each do |v,| # the , is to preserve compatibility with the old Hash-style sets
102
+ write_data(oprot, v, field[:element])
103
+ end
104
+ oprot.write_set_end
105
+ else
106
+ raise "Not a container type: #{field[:type]}"
107
+ end
108
+ end
109
+
110
+ CONTAINER_TYPES = []
111
+ CONTAINER_TYPES[Types::LIST] = true
112
+ CONTAINER_TYPES[Types::MAP] = true
113
+ CONTAINER_TYPES[Types::SET] = true
114
+ def is_container?(type)
115
+ CONTAINER_TYPES[type]
116
+ end
117
+
118
+ def field_info(field)
119
+ { :type => field[:type],
120
+ :class => field[:class],
121
+ :key => field[:key],
122
+ :value => field[:value],
123
+ :element => field[:element] }
124
+ end
125
+
126
+ def inspect_field(value, field_info)
127
+ if enum_class = field_info[:enum_class]
128
+ "#{enum_class.const_get(:VALUE_MAP)[value]} (#{value})"
129
+ elsif value.is_a? Hash
130
+ if field_info[:type] == Types::MAP
131
+ map_buf = []
132
+ value.each do |k, v|
133
+ map_buf << inspect_field(k, field_info[:key]) + ": " + inspect_field(v, field_info[:value])
134
+ end
135
+ "{" + map_buf.join(", ") + "}"
136
+ else
137
+ # old-style set
138
+ inspect_collection(value.keys, field_info)
139
+ end
140
+ elsif value.is_a? Array
141
+ inspect_collection(value, field_info)
142
+ elsif value.is_a? Set
143
+ inspect_collection(value, field_info)
144
+ elsif value.is_a?(String) && field_info[:binary]
145
+ value.unpack("H*").first
146
+ else
147
+ value.inspect
148
+ end
149
+ end
150
+
151
+ def inspect_collection(collection, field_info)
152
+ buf = []
153
+ collection.each do |k|
154
+ buf << inspect_field(k, field_info[:element])
155
+ end
156
+ "[" + buf.join(", ") + "]"
157
+ end
158
+ end
159
+ end