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
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
+ }