thrift 0.2.0.4 → 0.4.0

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 (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