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
data/CHANGELOG CHANGED
@@ -1,13 +1 @@
1
- v0.2.0.4 Support Rubinius properly (tritonrc).
2
-
3
- v0.2.0.3 Support JRuby properly (tritonrc).
4
-
5
- v0.2.0.2 Remove -Werror from compile.
6
-
7
- v0.2.0. Update version to Thrift release 0.2.0. No actual code changes.
8
-
9
- v0.0.820831. Update to Thrift trunk 820831.
10
-
11
- v0.0.810255.1. Fixes for Ruby 1.9.
12
-
13
- v0.0.789419. Initial release
1
+ v0.0.1. Initial release
data/Manifest CHANGED
@@ -1,14 +1,11 @@
1
1
  CHANGELOG
2
- Makefile.am
3
2
  Manifest
4
- README
5
3
  Rakefile
6
- benchmark/Benchmark.thrift
4
+ README
5
+ setup.rb
7
6
  benchmark/benchmark.rb
7
+ benchmark/Benchmark.thrift
8
8
  benchmark/client.rb
9
- benchmark/gen-rb/BenchmarkService.rb
10
- benchmark/gen-rb/Benchmark_constants.rb
11
- benchmark/gen-rb/Benchmark_types.rb
12
9
  benchmark/server.rb
13
10
  benchmark/thin_server.rb
14
11
  ext/binary_protocol_accelerated.c
@@ -28,31 +25,26 @@ ext/thrift_native.c
28
25
  lib/thrift.rb
29
26
  lib/thrift/client.rb
30
27
  lib/thrift/core_ext.rb
31
- lib/thrift/core_ext/fixnum.rb
32
28
  lib/thrift/exceptions.rb
33
29
  lib/thrift/processor.rb
30
+ lib/thrift/struct.rb
31
+ lib/thrift/struct_union.rb
32
+ lib/thrift/union.rb
33
+ lib/thrift/thrift_native.rb
34
+ lib/thrift/types.rb
35
+ lib/thrift/core_ext/fixnum.rb
34
36
  lib/thrift/protocol/base_protocol.rb
35
37
  lib/thrift/protocol/binary_protocol.rb
36
38
  lib/thrift/protocol/binary_protocol_accelerated.rb
37
- lib/thrift/protocol/binaryprotocol.rb
38
- lib/thrift/protocol/binaryprotocolaccelerated.rb
39
39
  lib/thrift/protocol/compact_protocol.rb
40
- lib/thrift/protocol/tbinaryprotocol.rb
41
- lib/thrift/protocol/tprotocol.rb
42
40
  lib/thrift/serializer/deserializer.rb
43
41
  lib/thrift/serializer/serializer.rb
44
42
  lib/thrift/server/base_server.rb
45
- lib/thrift/server/httpserver.rb
46
43
  lib/thrift/server/mongrel_http_server.rb
47
44
  lib/thrift/server/nonblocking_server.rb
48
- lib/thrift/server/nonblockingserver.rb
49
45
  lib/thrift/server/simple_server.rb
50
46
  lib/thrift/server/thread_pool_server.rb
51
47
  lib/thrift/server/threaded_server.rb
52
- lib/thrift/server/thttpserver.rb
53
- lib/thrift/server/tserver.rb
54
- lib/thrift/struct.rb
55
- lib/thrift/thrift_native.rb
56
48
  lib/thrift/transport/base_server_transport.rb
57
49
  lib/thrift/transport/base_transport.rb
58
50
  lib/thrift/transport/buffered_transport.rb
@@ -64,12 +56,9 @@ lib/thrift/transport/server_socket.rb
64
56
  lib/thrift/transport/socket.rb
65
57
  lib/thrift/transport/unix_server_socket.rb
66
58
  lib/thrift/transport/unix_socket.rb
67
- lib/thrift/types.rb
68
59
  script/proto_benchmark.rb
69
60
  script/read_struct.rb
70
61
  script/write_struct.rb
71
- setup.rb
72
- spec/ThriftSpec.thrift
73
62
  spec/base_protocol_spec.rb
74
63
  spec/base_transport_spec.rb
75
64
  spec/binary_protocol_accelerated_spec.rb
@@ -78,9 +67,6 @@ spec/binary_protocol_spec_shared.rb
78
67
  spec/client_spec.rb
79
68
  spec/compact_protocol_spec.rb
80
69
  spec/exception_spec.rb
81
- spec/gen-rb/NonblockingService.rb
82
- spec/gen-rb/ThriftSpec_constants.rb
83
- spec/gen-rb/ThriftSpec_types.rb
84
70
  spec/http_client_spec.rb
85
71
  spec/mongrel_http_server_spec.rb
86
72
  spec/nonblocking_server_spec.rb
@@ -92,5 +78,7 @@ spec/socket_spec.rb
92
78
  spec/socket_spec_shared.rb
93
79
  spec/spec_helper.rb
94
80
  spec/struct_spec.rb
81
+ spec/union_spec.rb
82
+ spec/ThriftSpec.thrift
95
83
  spec/types_spec.rb
96
84
  spec/unix_socket_spec.rb
data/Rakefile CHANGED
@@ -77,20 +77,22 @@ begin
77
77
  require 'echoe'
78
78
 
79
79
  Echoe.new('thrift') do |p|
80
- p.author = ['Kevin Ballard', 'Kevin Clark', 'Mark Slee', 'Evan Weaver']
81
- p.project = "fauna"
80
+ p.author = ['Kevin Ballard', 'Kevin Clark', 'Mark Slee']
81
+ p.email = ['kevin@sb.org', 'kevin.clark@gmail.com', 'mcslee@facebook.com']
82
82
  p.summary = "Ruby libraries for Thrift (a language-agnostic RPC system)"
83
+ p.url = "http://incubator.apache.org/thrift/"
83
84
  p.include_rakefile = true
84
- p.url = "http://blog.evanweaver.com/files/doc/fauna/thrift/"
85
- p.docs_host = "blog.evanweaver.com:~/www/bax/public/files/doc/"
85
+ p.version = "0.4.0"
86
+ p.rubygems_version = ">= 1.2.0"
86
87
  end
87
88
 
88
89
  task :install => [:check_site_lib]
89
90
 
90
91
  require 'rbconfig'
91
92
  task :check_site_lib do
92
- file = File.join(Config::CONFIG['sitelibdir'], 'thrift')
93
- fail "Thrift is already installed in site_ruby: #{file}*\nPlease remove it if you want to continue." if File.exist?(file)
93
+ if File.exist?(File.join(Config::CONFIG['sitelibdir'], 'thrift.rb'))
94
+ fail "thrift is already installed in site_ruby"
95
+ end
94
96
  end
95
97
  rescue LoadError
96
98
  [:install, :package].each do |t|
@@ -374,15 +374,15 @@ VALUE rb_thrift_binary_proto_read_string(VALUE self) {
374
374
 
375
375
  void Init_binary_protocol_accelerated() {
376
376
  VALUE thrift_binary_protocol_class = rb_const_get(thrift_module, rb_intern("BinaryProtocol"));
377
-
377
+
378
378
  VERSION_1 = rb_num2ll(rb_const_get(thrift_binary_protocol_class, rb_intern("VERSION_1")));
379
379
  VERSION_MASK = rb_num2ll(rb_const_get(thrift_binary_protocol_class, rb_intern("VERSION_MASK")));
380
380
  TYPE_MASK = rb_num2ll(rb_const_get(thrift_binary_protocol_class, rb_intern("TYPE_MASK")));
381
-
381
+
382
382
  VALUE bpa_class = rb_define_class_under(thrift_module, "BinaryProtocolAccelerated", thrift_binary_protocol_class);
383
-
383
+
384
384
  rb_define_method(bpa_class, "native?", rb_thrift_binary_proto_native_qmark, 0);
385
-
385
+
386
386
  rb_define_method(bpa_class, "write_message_begin", rb_thrift_binary_proto_write_message_begin, 3);
387
387
  rb_define_method(bpa_class, "write_field_begin", rb_thrift_binary_proto_write_field_begin, 3);
388
388
  rb_define_method(bpa_class, "write_field_stop", rb_thrift_binary_proto_write_field_stop, 0);
@@ -404,8 +404,6 @@ void Init_binary_protocol_accelerated() {
404
404
  rb_define_method(bpa_class, "write_map_end", rb_thrift_binary_proto_write_map_end, 0);
405
405
  rb_define_method(bpa_class, "write_list_end", rb_thrift_binary_proto_write_list_end, 0);
406
406
  rb_define_method(bpa_class, "write_set_end", rb_thrift_binary_proto_write_set_end, 0);
407
-
408
-
409
407
 
410
408
  rb_define_method(bpa_class, "read_message_begin", rb_thrift_binary_proto_read_message_begin, 0);
411
409
  rb_define_method(bpa_class, "read_field_begin", rb_thrift_binary_proto_read_field_begin, 0);
@@ -427,51 +425,4 @@ void Init_binary_protocol_accelerated() {
427
425
  rb_define_method(bpa_class, "read_map_end", rb_thift_binary_proto_read_map_end, 0);
428
426
  rb_define_method(bpa_class, "read_list_end", rb_thift_binary_proto_read_list_end, 0);
429
427
  rb_define_method(bpa_class, "read_set_end", rb_thift_binary_proto_read_set_end, 0);
430
-
431
- // set up native method table
432
- native_proto_method_table *npmt;
433
- npmt = ALLOC(native_proto_method_table);
434
-
435
- npmt->write_field_begin = rb_thrift_binary_proto_write_field_begin;
436
- npmt->write_field_stop = rb_thrift_binary_proto_write_field_stop;
437
- npmt->write_map_begin = rb_thrift_binary_proto_write_map_begin;
438
- npmt->write_list_begin = rb_thrift_binary_proto_write_list_begin;
439
- npmt->write_set_begin = rb_thrift_binary_proto_write_set_begin;
440
- npmt->write_byte = rb_thrift_binary_proto_write_byte;
441
- npmt->write_bool = rb_thrift_binary_proto_write_bool;
442
- npmt->write_i16 = rb_thrift_binary_proto_write_i16;
443
- npmt->write_i32 = rb_thrift_binary_proto_write_i32;
444
- npmt->write_i64 = rb_thrift_binary_proto_write_i64;
445
- npmt->write_double = rb_thrift_binary_proto_write_double;
446
- npmt->write_string = rb_thrift_binary_proto_write_string;
447
- npmt->write_message_end = rb_thrift_binary_proto_write_message_end;
448
- npmt->write_struct_begin = rb_thrift_binary_proto_write_struct_begin;
449
- npmt->write_struct_end = rb_thrift_binary_proto_write_struct_end;
450
- npmt->write_field_end = rb_thrift_binary_proto_write_field_end;
451
- npmt->write_map_end = rb_thrift_binary_proto_write_map_end;
452
- npmt->write_list_end = rb_thrift_binary_proto_write_list_end;
453
- npmt->write_set_end = rb_thrift_binary_proto_write_set_end;
454
-
455
- npmt->read_message_begin = rb_thrift_binary_proto_read_message_begin;
456
- npmt->read_field_begin = rb_thrift_binary_proto_read_field_begin;
457
- npmt->read_map_begin = rb_thrift_binary_proto_read_map_begin;
458
- npmt->read_list_begin = rb_thrift_binary_proto_read_list_begin;
459
- npmt->read_set_begin = rb_thrift_binary_proto_read_set_begin;
460
- npmt->read_byte = rb_thrift_binary_proto_read_byte;
461
- npmt->read_bool = rb_thrift_binary_proto_read_bool;
462
- npmt->read_i16 = rb_thrift_binary_proto_read_i16;
463
- npmt->read_i32 = rb_thrift_binary_proto_read_i32;
464
- npmt->read_i64 = rb_thrift_binary_proto_read_i64;
465
- npmt->read_double = rb_thrift_binary_proto_read_double;
466
- npmt->read_string = rb_thrift_binary_proto_read_string;
467
- npmt->read_message_end = rb_thrift_binary_proto_read_message_end;
468
- npmt->read_struct_begin = rb_thift_binary_proto_read_struct_begin;
469
- npmt->read_struct_end = rb_thift_binary_proto_read_struct_end;
470
- npmt->read_field_end = rb_thift_binary_proto_read_field_end;
471
- npmt->read_map_end = rb_thift_binary_proto_read_map_end;
472
- npmt->read_list_end = rb_thift_binary_proto_read_list_end;
473
- npmt->read_set_end = rb_thift_binary_proto_read_set_end;
474
-
475
- VALUE method_table_object = Data_Wrap_Struct(rb_cObject, 0, free, npmt);
476
- rb_const_set(bpa_class, rb_intern("@native_method_table"), method_table_object);
477
428
  }
@@ -20,8 +20,8 @@
20
20
  #include <ruby.h>
21
21
  #include <stdbool.h>
22
22
  #include <stdint.h>
23
- #include <constants.h>
24
- #include <struct.h>
23
+ #include "constants.h"
24
+ #include "struct.h"
25
25
  #include "macros.h"
26
26
 
27
27
  #define LAST_ID(obj) FIX2INT(rb_ary_pop(rb_ivar_get(obj, last_field_id)))
@@ -458,6 +458,7 @@ VALUE rb_thrift_compact_proto_read_field_begin(VALUE self) {
458
458
 
459
459
  if (modifier == 0) {
460
460
  // not a delta. look ahead for the zigzag varint field id.
461
+ (void) LAST_ID(self);
461
462
  field_id = read_i16(self);
462
463
  } else {
463
464
  // has a delta. add the delta to the last read field id.
@@ -608,58 +609,7 @@ static void Init_rb_methods() {
608
609
  rb_define_method(thrift_compact_protocol_class, "read_set_end", rb_thrift_compact_proto_read_set_end, 0);
609
610
  }
610
611
 
611
- static void Init_npmt() {
612
- native_proto_method_table *npmt;
613
- npmt = ALLOC(native_proto_method_table);
614
-
615
- npmt->write_field_begin = rb_thrift_compact_proto_write_field_begin;
616
- npmt->write_field_stop = rb_thrift_compact_proto_write_field_stop;
617
- npmt->write_map_begin = rb_thrift_compact_proto_write_map_begin;
618
- npmt->write_list_begin = rb_thrift_compact_proto_write_list_begin;
619
- npmt->write_set_begin = rb_thrift_compact_proto_write_set_begin;
620
- npmt->write_byte = rb_thrift_compact_proto_write_byte;
621
- npmt->write_bool = rb_thrift_compact_proto_write_bool;
622
- npmt->write_i16 = rb_thrift_compact_proto_write_i16;
623
- npmt->write_i32 = rb_thrift_compact_proto_write_i32;
624
- npmt->write_i64 = rb_thrift_compact_proto_write_i64;
625
- npmt->write_double = rb_thrift_compact_proto_write_double;
626
- npmt->write_string = rb_thrift_compact_proto_write_string;
627
- npmt->write_message_end = rb_thrift_compact_proto_write_message_end;
628
- npmt->write_struct_begin = rb_thrift_compact_proto_write_struct_begin;
629
- npmt->write_struct_end = rb_thrift_compact_proto_write_struct_end;
630
- npmt->write_field_end = rb_thrift_compact_proto_write_field_end;
631
- npmt->write_map_end = rb_thrift_compact_proto_write_map_end;
632
- npmt->write_list_end = rb_thrift_compact_proto_write_list_end;
633
- npmt->write_set_end = rb_thrift_compact_proto_write_set_end;
634
-
635
- npmt->read_message_begin = rb_thrift_compact_proto_read_message_begin;
636
- npmt->read_field_begin = rb_thrift_compact_proto_read_field_begin;
637
- npmt->read_map_begin = rb_thrift_compact_proto_read_map_begin;
638
- npmt->read_list_begin = rb_thrift_compact_proto_read_list_begin;
639
- npmt->read_set_begin = rb_thrift_compact_proto_read_set_begin;
640
- npmt->read_byte = rb_thrift_compact_proto_read_byte;
641
- npmt->read_bool = rb_thrift_compact_proto_read_bool;
642
- npmt->read_i16 = rb_thrift_compact_proto_read_i16;
643
- npmt->read_i32 = rb_thrift_compact_proto_read_i32;
644
- npmt->read_i64 = rb_thrift_compact_proto_read_i64;
645
- npmt->read_double = rb_thrift_compact_proto_read_double;
646
- npmt->read_string = rb_thrift_compact_proto_read_string;
647
- npmt->read_message_end = rb_thrift_compact_proto_read_message_end;
648
- npmt->read_struct_begin = rb_thrift_compact_proto_read_struct_begin;
649
- npmt->read_struct_end = rb_thrift_compact_proto_read_struct_end;
650
- npmt->read_field_end = rb_thrift_compact_proto_read_field_end;
651
- npmt->read_map_end = rb_thrift_compact_proto_read_map_end;
652
- npmt->read_list_end = rb_thrift_compact_proto_read_list_end;
653
- npmt->read_set_end = rb_thrift_compact_proto_read_set_end;
654
-
655
- VALUE method_table_object = Data_Wrap_Struct(rb_cObject, 0, free, npmt);
656
- rb_const_set(thrift_compact_protocol_class, rb_intern("@native_method_table"), method_table_object);
657
- }
658
-
659
-
660
-
661
612
  void Init_compact_protocol() {
662
613
  Init_constants();
663
614
  Init_rb_methods();
664
- Init_npmt();
665
615
  }
@@ -17,24 +17,10 @@
17
17
  # under the License.
18
18
  #
19
19
 
20
- unless defined?(JRUBY_VERSION)
21
- require 'mkmf'
20
+ require 'mkmf'
22
21
 
23
- $CFLAGS = "-g -O2 -Wall " + $CFLAGS
22
+ $CFLAGS = "-g -O2 -Wall -Werror"
24
23
 
25
- have_func("strlcpy", "string.h")
24
+ have_func("strlcpy", "string.h")
26
25
 
27
- create_makefile 'thrift_native'
28
- else
29
- # RubyGems Gem::Ext::ExtConfBuilder is looking for a Makefile
30
- # so make a dummy Makefile to appease it
31
- File.open(File.expand_path('../Makefile', __FILE__), 'w') do |f|
32
- f.write <<-EOS
33
- all:
34
- static:
35
- clean:
36
- distclean:
37
- install:
38
- EOS
39
- end
40
- end
26
+ create_makefile 'thrift_native'
@@ -17,8 +17,8 @@
17
17
  * under the License.
18
18
  */
19
19
 
20
- #include <struct.h>
21
- #include <constants.h>
20
+ #include "struct.h"
21
+ #include "constants.h"
22
22
  #include "macros.h"
23
23
 
24
24
  #ifndef HAVE_STRLCPY
@@ -40,34 +40,25 @@ strlcpy (char *dst, const char *src, size_t dst_sz)
40
40
  *(dst - 1) = '\0';
41
41
  return n + strlen (src);
42
42
  }
43
-
43
+ #else
44
+ /*
45
+ Ruby 1.9.x includes the OpenBSD implementation of strlcpy.
46
+ See missing/strlcpy.c in Ruby 1.9 source
47
+ */
48
+ extern size_t strlcpy(char *, const char *, size_t);
44
49
  #endif
45
50
 
46
- static native_proto_method_table *mt;
47
- static native_proto_method_table *default_mt;
48
- // static VALUE last_proto_class = Qnil;
51
+ VALUE thrift_union_class;
52
+
53
+ ID setfield_id;
54
+ ID setvalue_id;
55
+
56
+ ID to_s_method_id;
57
+ ID name_to_id_method_id;
49
58
 
50
59
  #define IS_CONTAINER(ttype) ((ttype) == TTYPE_MAP || (ttype) == TTYPE_LIST || (ttype) == TTYPE_SET)
51
60
  #define STRUCT_FIELDS(obj) rb_const_get(CLASS_OF(obj), fields_const_id)
52
61
 
53
- // static void set_native_proto_function_pointers(VALUE protocol) {
54
- // VALUE method_table_object = rb_const_get(CLASS_OF(protocol), rb_intern("@native_method_table"));
55
- // // TODO: check nil?
56
- // Data_Get_Struct(method_table_object, native_proto_method_table, mt);
57
- // }
58
-
59
- // static void check_native_proto_method_table(VALUE protocol) {
60
- // VALUE protoclass = CLASS_OF(protocol);
61
- // if (protoclass != last_proto_class) {
62
- // last_proto_class = protoclass;
63
- // if (rb_funcall(protocol, native_qmark_method_id, 0) == Qtrue) {
64
- // set_native_proto_function_pointers(protocol);
65
- // } else {
66
- // mt = default_mt;
67
- // }
68
- // }
69
- // }
70
-
71
62
  //-------------------------------------------
72
63
  // Writing section
73
64
  //-------------------------------------------
@@ -232,106 +223,65 @@ VALUE default_read_struct_end(VALUE protocol) {
232
223
  return rb_funcall(protocol, read_struct_end_method_id, 0);
233
224
  }
234
225
 
235
- static void set_default_proto_function_pointers() {
236
- default_mt = ALLOC(native_proto_method_table);
237
-
238
- default_mt->write_field_begin = default_write_field_begin;
239
- default_mt->write_field_stop = default_write_field_stop;
240
- default_mt->write_map_begin = default_write_map_begin;
241
- default_mt->write_map_end = default_write_map_end;
242
- default_mt->write_list_begin = default_write_list_begin;
243
- default_mt->write_list_end = default_write_list_end;
244
- default_mt->write_set_begin = default_write_set_begin;
245
- default_mt->write_set_end = default_write_set_end;
246
- default_mt->write_byte = default_write_byte;
247
- default_mt->write_bool = default_write_bool;
248
- default_mt->write_i16 = default_write_i16;
249
- default_mt->write_i32 = default_write_i32;
250
- default_mt->write_i64 = default_write_i64;
251
- default_mt->write_double = default_write_double;
252
- default_mt->write_string = default_write_string;
253
- default_mt->write_struct_begin = default_write_struct_begin;
254
- default_mt->write_struct_end = default_write_struct_end;
255
- default_mt->write_field_end = default_write_field_end;
256
-
257
- default_mt->read_struct_begin = default_read_struct_begin;
258
- default_mt->read_struct_end = default_read_struct_end;
259
- default_mt->read_field_begin = default_read_field_begin;
260
- default_mt->read_field_end = default_read_field_end;
261
- default_mt->read_map_begin = default_read_map_begin;
262
- default_mt->read_map_end = default_read_map_end;
263
- default_mt->read_list_begin = default_read_list_begin;
264
- default_mt->read_list_end = default_read_list_end;
265
- default_mt->read_set_begin = default_read_set_begin;
266
- default_mt->read_set_end = default_read_set_end;
267
- default_mt->read_byte = default_read_byte;
268
- default_mt->read_bool = default_read_bool;
269
- default_mt->read_i16 = default_read_i16;
270
- default_mt->read_i32 = default_read_i32;
271
- default_mt->read_i64 = default_read_i64;
272
- default_mt->read_double = default_read_double;
273
- default_mt->read_string = default_read_string;
274
- }
275
-
276
226
  // end default protocol methods
277
227
 
278
-
228
+ static VALUE rb_thrift_union_write (VALUE self, VALUE protocol);
279
229
  static VALUE rb_thrift_struct_write(VALUE self, VALUE protocol);
280
230
  static void write_anything(int ttype, VALUE value, VALUE protocol, VALUE field_info);
281
231
 
282
232
  VALUE get_field_value(VALUE obj, VALUE field_name) {
283
233
  char name_buf[RSTRING_LEN(field_name) + 1];
284
-
234
+
285
235
  name_buf[0] = '@';
286
236
  strlcpy(&name_buf[1], RSTRING_PTR(field_name), sizeof(name_buf));
287
237
 
288
238
  VALUE value = rb_ivar_get(obj, rb_intern(name_buf));
289
-
239
+
290
240
  return value;
291
241
  }
292
242
 
293
243
  static void write_container(int ttype, VALUE field_info, VALUE value, VALUE protocol) {
294
244
  int sz, i;
295
-
245
+
296
246
  if (ttype == TTYPE_MAP) {
297
247
  VALUE keys;
298
248
  VALUE key;
299
249
  VALUE val;
300
250
 
301
251
  Check_Type(value, T_HASH);
302
-
252
+
303
253
  VALUE key_info = rb_hash_aref(field_info, key_sym);
304
254
  VALUE keytype_value = rb_hash_aref(key_info, type_sym);
305
255
  int keytype = FIX2INT(keytype_value);
306
-
256
+
307
257
  VALUE value_info = rb_hash_aref(field_info, value_sym);
308
258
  VALUE valuetype_value = rb_hash_aref(value_info, type_sym);
309
259
  int valuetype = FIX2INT(valuetype_value);
310
-
260
+
311
261
  keys = rb_funcall(value, keys_method_id, 0);
312
-
262
+
313
263
  sz = RARRAY_LEN(keys);
314
-
315
- mt->write_map_begin(protocol, keytype_value, valuetype_value, INT2FIX(sz));
316
-
264
+
265
+ default_write_map_begin(protocol, keytype_value, valuetype_value, INT2FIX(sz));
266
+
317
267
  for (i = 0; i < sz; i++) {
318
268
  key = rb_ary_entry(keys, i);
319
269
  val = rb_hash_aref(value, key);
320
-
270
+
321
271
  if (IS_CONTAINER(keytype)) {
322
272
  write_container(keytype, key_info, key, protocol);
323
273
  } else {
324
274
  write_anything(keytype, key, protocol, key_info);
325
275
  }
326
-
276
+
327
277
  if (IS_CONTAINER(valuetype)) {
328
278
  write_container(valuetype, value_info, val, protocol);
329
279
  } else {
330
280
  write_anything(valuetype, val, protocol, value_info);
331
281
  }
332
282
  }
333
-
334
- mt->write_map_end(protocol);
283
+
284
+ default_write_map_end(protocol);
335
285
  } else if (ttype == TTYPE_LIST) {
336
286
  Check_Type(value, T_ARRAY);
337
287
 
@@ -340,8 +290,8 @@ static void write_container(int ttype, VALUE field_info, VALUE value, VALUE prot
340
290
  VALUE element_type_info = rb_hash_aref(field_info, element_sym);
341
291
  VALUE element_type_value = rb_hash_aref(element_type_info, type_sym);
342
292
  int element_type = FIX2INT(element_type_value);
343
-
344
- mt->write_list_begin(protocol, element_type_value, INT2FIX(sz));
293
+
294
+ default_write_list_begin(protocol, element_type_value, INT2FIX(sz));
345
295
  for (i = 0; i < sz; ++i) {
346
296
  VALUE val = rb_ary_entry(value, i);
347
297
  if (IS_CONTAINER(element_type)) {
@@ -350,7 +300,7 @@ static void write_container(int ttype, VALUE field_info, VALUE value, VALUE prot
350
300
  write_anything(element_type, val, protocol, element_type_info);
351
301
  }
352
302
  }
353
- mt->write_list_end(protocol);
303
+ default_write_list_end(protocol);
354
304
  } else if (ttype == TTYPE_SET) {
355
305
  VALUE items;
356
306
 
@@ -370,9 +320,9 @@ static void write_container(int ttype, VALUE field_info, VALUE value, VALUE prot
370
320
  VALUE element_type_info = rb_hash_aref(field_info, element_sym);
371
321
  VALUE element_type_value = rb_hash_aref(element_type_info, type_sym);
372
322
  int element_type = FIX2INT(element_type_value);
373
-
374
- mt->write_set_begin(protocol, element_type_value, INT2FIX(sz));
375
-
323
+
324
+ default_write_set_begin(protocol, element_type_value, INT2FIX(sz));
325
+
376
326
  for (i = 0; i < sz; i++) {
377
327
  VALUE val = rb_ary_entry(items, i);
378
328
  if (IS_CONTAINER(element_type)) {
@@ -381,8 +331,8 @@ static void write_container(int ttype, VALUE field_info, VALUE value, VALUE prot
381
331
  write_anything(element_type, val, protocol, element_type_info);
382
332
  }
383
333
  }
384
-
385
- mt->write_set_end(protocol);
334
+
335
+ default_write_set_end(protocol);
386
336
  } else {
387
337
  rb_raise(rb_eNotImpError, "can't write container of type: %d", ttype);
388
338
  }
@@ -390,23 +340,27 @@ static void write_container(int ttype, VALUE field_info, VALUE value, VALUE prot
390
340
 
391
341
  static void write_anything(int ttype, VALUE value, VALUE protocol, VALUE field_info) {
392
342
  if (ttype == TTYPE_BOOL) {
393
- mt->write_bool(protocol, value);
343
+ default_write_bool(protocol, value);
394
344
  } else if (ttype == TTYPE_BYTE) {
395
- mt->write_byte(protocol, value);
345
+ default_write_byte(protocol, value);
396
346
  } else if (ttype == TTYPE_I16) {
397
- mt->write_i16(protocol, value);
347
+ default_write_i16(protocol, value);
398
348
  } else if (ttype == TTYPE_I32) {
399
- mt->write_i32(protocol, value);
349
+ default_write_i32(protocol, value);
400
350
  } else if (ttype == TTYPE_I64) {
401
- mt->write_i64(protocol, value);
351
+ default_write_i64(protocol, value);
402
352
  } else if (ttype == TTYPE_DOUBLE) {
403
- mt->write_double(protocol, value);
353
+ default_write_double(protocol, value);
404
354
  } else if (ttype == TTYPE_STRING) {
405
- mt->write_string(protocol, value);
355
+ default_write_string(protocol, value);
406
356
  } else if (IS_CONTAINER(ttype)) {
407
357
  write_container(ttype, field_info, value, protocol);
408
358
  } else if (ttype == TTYPE_STRUCT) {
409
- rb_thrift_struct_write(value, protocol);
359
+ if (rb_obj_is_kind_of(value, thrift_union_class)) {
360
+ rb_thrift_union_write(value, protocol);
361
+ } else {
362
+ rb_thrift_struct_write(value, protocol);
363
+ }
410
364
  } else {
411
365
  rb_raise(rb_eNotImpError, "Unknown type for binary_encoding: %d", ttype);
412
366
  }
@@ -416,39 +370,40 @@ static VALUE rb_thrift_struct_write(VALUE self, VALUE protocol) {
416
370
  // call validate
417
371
  rb_funcall(self, validate_method_id, 0);
418
372
 
419
- // check_native_proto_method_table(protocol);
420
-
421
373
  // write struct begin
422
- mt->write_struct_begin(protocol, rb_class_name(CLASS_OF(self)));
374
+ default_write_struct_begin(protocol, rb_class_name(CLASS_OF(self)));
423
375
 
424
376
  // iterate through all the fields here
425
377
  VALUE struct_fields = STRUCT_FIELDS(self);
378
+
426
379
  VALUE struct_field_ids_unordered = rb_funcall(struct_fields, keys_method_id, 0);
427
380
  VALUE struct_field_ids_ordered = rb_funcall(struct_field_ids_unordered, sort_method_id, 0);
428
381
 
429
382
  int i = 0;
430
383
  for (i=0; i < RARRAY_LEN(struct_field_ids_ordered); i++) {
431
384
  VALUE field_id = rb_ary_entry(struct_field_ids_ordered, i);
385
+
432
386
  VALUE field_info = rb_hash_aref(struct_fields, field_id);
433
387
 
434
388
  VALUE ttype_value = rb_hash_aref(field_info, type_sym);
435
389
  int ttype = FIX2INT(ttype_value);
436
390
  VALUE field_name = rb_hash_aref(field_info, name_sym);
391
+
437
392
  VALUE field_value = get_field_value(self, field_name);
438
393
 
439
394
  if (!NIL_P(field_value)) {
440
- mt->write_field_begin(protocol, field_name, ttype_value, field_id);
441
-
395
+ default_write_field_begin(protocol, field_name, ttype_value, field_id);
396
+
442
397
  write_anything(ttype, field_value, protocol, field_info);
443
-
444
- mt->write_field_end(protocol);
398
+
399
+ default_write_field_end(protocol);
445
400
  }
446
401
  }
447
402
 
448
- mt->write_field_stop(protocol);
403
+ default_write_field_stop(protocol);
449
404
 
450
405
  // write struct end
451
- mt->write_struct_end(protocol);
406
+ default_write_struct_end(protocol);
452
407
 
453
408
  return Qnil;
454
409
  }
@@ -457,6 +412,7 @@ static VALUE rb_thrift_struct_write(VALUE self, VALUE protocol) {
457
412
  // Reading section
458
413
  //-------------------------------------------
459
414
 
415
+ static VALUE rb_thrift_union_read(VALUE self, VALUE protocol);
460
416
  static VALUE rb_thrift_struct_read(VALUE self, VALUE protocol);
461
417
 
462
418
  static void set_field_value(VALUE obj, VALUE field_name, VALUE value) {
@@ -472,27 +428,32 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
472
428
  VALUE result = Qnil;
473
429
 
474
430
  if (ttype == TTYPE_BOOL) {
475
- result = mt->read_bool(protocol);
431
+ result = default_read_bool(protocol);
476
432
  } else if (ttype == TTYPE_BYTE) {
477
- result = mt->read_byte(protocol);
433
+ result = default_read_byte(protocol);
478
434
  } else if (ttype == TTYPE_I16) {
479
- result = mt->read_i16(protocol);
435
+ result = default_read_i16(protocol);
480
436
  } else if (ttype == TTYPE_I32) {
481
- result = mt->read_i32(protocol);
437
+ result = default_read_i32(protocol);
482
438
  } else if (ttype == TTYPE_I64) {
483
- result = mt->read_i64(protocol);
439
+ result = default_read_i64(protocol);
484
440
  } else if (ttype == TTYPE_STRING) {
485
- result = mt->read_string(protocol);
441
+ result = default_read_string(protocol);
486
442
  } else if (ttype == TTYPE_DOUBLE) {
487
- result = mt->read_double(protocol);
443
+ result = default_read_double(protocol);
488
444
  } else if (ttype == TTYPE_STRUCT) {
489
445
  VALUE klass = rb_hash_aref(field_info, class_sym);
490
446
  result = rb_class_new_instance(0, NULL, klass);
491
- rb_thrift_struct_read(result, protocol);
447
+
448
+ if (rb_obj_is_kind_of(result, thrift_union_class)) {
449
+ rb_thrift_union_read(result, protocol);
450
+ } else {
451
+ rb_thrift_struct_read(result, protocol);
452
+ }
492
453
  } else if (ttype == TTYPE_MAP) {
493
454
  int i;
494
455
 
495
- VALUE map_header = mt->read_map_begin(protocol);
456
+ VALUE map_header = default_read_map_begin(protocol);
496
457
  int key_ttype = FIX2INT(rb_ary_entry(map_header, 0));
497
458
  int value_ttype = FIX2INT(rb_ary_entry(map_header, 1));
498
459
  int num_entries = FIX2INT(rb_ary_entry(map_header, 2));
@@ -511,11 +472,11 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
511
472
  rb_hash_aset(result, key, val);
512
473
  }
513
474
 
514
- mt->read_map_end(protocol);
475
+ default_read_map_end(protocol);
515
476
  } else if (ttype == TTYPE_LIST) {
516
477
  int i;
517
478
 
518
- VALUE list_header = mt->read_list_begin(protocol);
479
+ VALUE list_header = default_read_list_begin(protocol);
519
480
  int element_ttype = FIX2INT(rb_ary_entry(list_header, 0));
520
481
  int num_elements = FIX2INT(rb_ary_entry(list_header, 1));
521
482
  result = rb_ary_new2(num_elements);
@@ -524,13 +485,12 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
524
485
  rb_ary_push(result, read_anything(protocol, element_ttype, rb_hash_aref(field_info, element_sym)));
525
486
  }
526
487
 
527
-
528
- mt->read_list_end(protocol);
488
+ default_read_list_end(protocol);
529
489
  } else if (ttype == TTYPE_SET) {
530
490
  VALUE items;
531
491
  int i;
532
492
 
533
- VALUE set_header = mt->read_set_begin(protocol);
493
+ VALUE set_header = default_read_set_begin(protocol);
534
494
  int element_ttype = FIX2INT(rb_ary_entry(set_header, 0));
535
495
  int num_elements = FIX2INT(rb_ary_entry(set_header, 1));
536
496
  items = rb_ary_new2(num_elements);
@@ -539,8 +499,7 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
539
499
  rb_ary_push(items, read_anything(protocol, element_ttype, rb_hash_aref(field_info, element_sym)));
540
500
  }
541
501
 
542
-
543
- mt->read_set_end(protocol);
502
+ default_read_set_end(protocol);
544
503
 
545
504
  result = rb_class_new_instance(1, &items, rb_cSet);
546
505
  } else {
@@ -551,16 +510,14 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
551
510
  }
552
511
 
553
512
  static VALUE rb_thrift_struct_read(VALUE self, VALUE protocol) {
554
- // check_native_proto_method_table(protocol);
555
-
556
513
  // read struct begin
557
- mt->read_struct_begin(protocol);
514
+ default_read_struct_begin(protocol);
558
515
 
559
516
  VALUE struct_fields = STRUCT_FIELDS(self);
560
517
 
561
518
  // read each field
562
519
  while (true) {
563
- VALUE field_header = mt->read_field_begin(protocol);
520
+ VALUE field_header = default_read_field_begin(protocol);
564
521
  VALUE field_type_value = rb_ary_entry(field_header, 1);
565
522
  int field_type = FIX2INT(field_type_value);
566
523
 
@@ -585,15 +542,102 @@ static VALUE rb_thrift_struct_read(VALUE self, VALUE protocol) {
585
542
  }
586
543
 
587
544
  // read field end
588
- mt->read_field_end(protocol);
545
+ default_read_field_end(protocol);
546
+ }
547
+
548
+ // read struct end
549
+ default_read_struct_end(protocol);
550
+
551
+ // call validate
552
+ rb_funcall(self, validate_method_id, 0);
553
+
554
+ return Qnil;
555
+ }
556
+
557
+
558
+ // --------------------------------
559
+ // Union section
560
+ // --------------------------------
561
+
562
+ static VALUE rb_thrift_union_read(VALUE self, VALUE protocol) {
563
+ // read struct begin
564
+ default_read_struct_begin(protocol);
565
+
566
+ VALUE struct_fields = STRUCT_FIELDS(self);
567
+
568
+ VALUE field_header = default_read_field_begin(protocol);
569
+ VALUE field_type_value = rb_ary_entry(field_header, 1);
570
+ int field_type = FIX2INT(field_type_value);
571
+
572
+ // make sure we got a type we expected
573
+ VALUE field_info = rb_hash_aref(struct_fields, rb_ary_entry(field_header, 2));
574
+
575
+ if (!NIL_P(field_info)) {
576
+ int specified_type = FIX2INT(rb_hash_aref(field_info, type_sym));
577
+ if (field_type == specified_type) {
578
+ // read the value
579
+ VALUE name = rb_hash_aref(field_info, name_sym);
580
+ rb_iv_set(self, "@setfield", ID2SYM(rb_intern(RSTRING_PTR(name))));
581
+ rb_iv_set(self, "@value", read_anything(protocol, field_type, field_info));
582
+ } else {
583
+ rb_funcall(protocol, skip_method_id, 1, field_type_value);
584
+ }
585
+ } else {
586
+ rb_funcall(protocol, skip_method_id, 1, field_type_value);
589
587
  }
590
588
 
589
+ // read field end
590
+ default_read_field_end(protocol);
591
+
592
+ field_header = default_read_field_begin(protocol);
593
+ field_type_value = rb_ary_entry(field_header, 1);
594
+ field_type = FIX2INT(field_type_value);
595
+
596
+ if (field_type != TTYPE_STOP) {
597
+ rb_raise(rb_eRuntimeError, "too many fields in union!");
598
+ }
599
+
600
+ // read field end
601
+ default_read_field_end(protocol);
602
+
591
603
  // read struct end
592
- mt->read_struct_end(protocol);
604
+ default_read_struct_end(protocol);
605
+
606
+ // call validate
607
+ rb_funcall(self, validate_method_id, 0);
608
+
609
+ return Qnil;
610
+ }
593
611
 
612
+ static VALUE rb_thrift_union_write(VALUE self, VALUE protocol) {
594
613
  // call validate
595
614
  rb_funcall(self, validate_method_id, 0);
596
615
 
616
+ // write struct begin
617
+ default_write_struct_begin(protocol, rb_class_name(CLASS_OF(self)));
618
+
619
+ VALUE struct_fields = STRUCT_FIELDS(self);
620
+
621
+ VALUE setfield = rb_ivar_get(self, setfield_id);
622
+ VALUE setvalue = rb_ivar_get(self, setvalue_id);
623
+ VALUE field_id = rb_funcall(self, name_to_id_method_id, 1, rb_funcall(setfield, to_s_method_id, 0));
624
+
625
+ VALUE field_info = rb_hash_aref(struct_fields, field_id);
626
+
627
+ VALUE ttype_value = rb_hash_aref(field_info, type_sym);
628
+ int ttype = FIX2INT(ttype_value);
629
+
630
+ default_write_field_begin(protocol, setfield, ttype_value, field_id);
631
+
632
+ write_anything(ttype, setvalue, protocol, field_info);
633
+
634
+ default_write_field_end(protocol);
635
+
636
+ default_write_field_stop(protocol);
637
+
638
+ // write struct end
639
+ default_write_struct_end(protocol);
640
+
597
641
  return Qnil;
598
642
  }
599
643
 
@@ -603,7 +647,14 @@ void Init_struct() {
603
647
  rb_define_method(struct_module, "write", rb_thrift_struct_write, 1);
604
648
  rb_define_method(struct_module, "read", rb_thrift_struct_read, 1);
605
649
 
606
- set_default_proto_function_pointers();
607
- mt = default_mt;
608
- }
650
+ thrift_union_class = rb_const_get(thrift_module, rb_intern("Union"));
651
+
652
+ rb_define_method(thrift_union_class, "write", rb_thrift_union_write, 1);
653
+ rb_define_method(thrift_union_class, "read", rb_thrift_union_read, 1);
609
654
 
655
+ setfield_id = rb_intern("@setfield");
656
+ setvalue_id = rb_intern("@value");
657
+
658
+ to_s_method_id = rb_intern("to_s");
659
+ name_to_id_method_id = rb_intern("name_to_id");
660
+ }