thrift 0.24.0 → 0.25.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.
- checksums.yaml +4 -4
- data/README.md +107 -4
- data/ext/binary_protocol_accelerated.c +52 -17
- data/ext/compact_protocol.c +135 -70
- data/ext/constants.h +3 -0
- data/ext/extconf.rb +4 -4
- data/ext/macros.h +11 -0
- data/ext/memory_buffer.c +35 -17
- data/ext/struct.c +185 -64
- data/ext/thrift_native.c +6 -0
- data/lib/thrift/bytes.rb +2 -2
- data/lib/thrift/client.rb +31 -22
- data/lib/thrift/exceptions.rb +10 -8
- data/lib/thrift/multiplexed_processor.rb +5 -6
- data/lib/thrift/processor.rb +24 -3
- data/lib/thrift/protocol/base_protocol.rb +53 -27
- data/lib/thrift/protocol/binary_protocol.rb +54 -40
- data/lib/thrift/protocol/binary_protocol_accelerated.rb +6 -2
- data/lib/thrift/protocol/compact_protocol.rb +193 -88
- data/lib/thrift/protocol/header_protocol.rb +14 -3
- data/lib/thrift/protocol/json_protocol.rb +146 -104
- data/lib/thrift/protocol/multiplexed_protocol.rb +2 -3
- data/lib/thrift/protocol/protocol_decorator.rb +5 -2
- data/lib/thrift/serializer/serializer.rb +6 -0
- data/lib/thrift/server/base_server.rb +10 -2
- data/lib/thrift/server/nonblocking_server.rb +49 -26
- data/lib/thrift/server/rack_application.rb +69 -0
- data/lib/thrift/server/simple_server.rb +27 -23
- data/lib/thrift/server/thin_http_server.rb +20 -44
- data/lib/thrift/server/thread_pool_server.rb +20 -17
- data/lib/thrift/server/threaded_server.rb +22 -26
- data/lib/thrift/struct.rb +33 -18
- data/lib/thrift/struct_union.rb +36 -30
- data/lib/thrift/transport/base_transport.rb +23 -5
- data/lib/thrift/transport/buffered_transport.rb +4 -4
- data/lib/thrift/transport/framed_transport.rb +32 -7
- data/lib/thrift/transport/header_transport.rb +130 -50
- data/lib/thrift/transport/http_client_transport.rb +27 -14
- data/lib/thrift/transport/io_stream_transport.rb +2 -1
- data/lib/thrift/transport/memory_buffer_transport.rb +8 -10
- data/lib/thrift/transport/server_socket.rb +4 -5
- data/lib/thrift/transport/socket.rb +20 -22
- data/lib/thrift/transport/ssl_server_socket.rb +64 -4
- data/lib/thrift/transport/ssl_socket.rb +32 -5
- data/lib/thrift/transport/unix_server_socket.rb +1 -1
- data/lib/thrift/transport/unix_socket.rb +4 -6
- data/lib/thrift/types.rb +22 -22
- data/lib/thrift/union.rb +20 -11
- data/lib/thrift/uuid.rb +8 -8
- data/lib/thrift.rb +39 -39
- metadata +5 -230
- data/benchmark/Benchmark.thrift +0 -24
- data/benchmark/benchmark.rb +0 -286
- data/benchmark/client.rb +0 -118
- data/benchmark/server.rb +0 -121
- data/benchmark/thin_server.rb +0 -46
- data/lib/thrift/server/mongrel_http_server.rb +0 -61
- data/spec/BaseService.thrift +0 -27
- data/spec/ExtendedService.thrift +0 -25
- data/spec/Referenced.thrift +0 -44
- data/spec/ThriftNamespacedSpec.thrift +0 -53
- data/spec/ThriftSpec.thrift +0 -203
- data/spec/base_protocol_spec.rb +0 -244
- data/spec/base_transport_spec.rb +0 -428
- data/spec/binary_protocol_accelerated_spec.rb +0 -47
- data/spec/binary_protocol_spec.rb +0 -73
- data/spec/binary_protocol_spec_shared.rb +0 -509
- data/spec/bytes_spec.rb +0 -117
- data/spec/client_spec.rb +0 -167
- data/spec/compact_protocol_spec.rb +0 -295
- data/spec/constants_demo_spec.rb +0 -102
- data/spec/exception_spec.rb +0 -141
- data/spec/flat_spec.rb +0 -63
- data/spec/header_protocol_spec.rb +0 -476
- data/spec/header_transport_spec.rb +0 -431
- data/spec/http_client_spec.rb +0 -160
- data/spec/json_protocol_spec.rb +0 -574
- data/spec/multiplexed_processor_spec.rb +0 -75
- data/spec/namespaced_spec.rb +0 -67
- data/spec/nonblocking_server_spec.rb +0 -429
- data/spec/processor_spec.rb +0 -80
- data/spec/recursion_depth_spec.rb +0 -223
- data/spec/serializer_spec.rb +0 -67
- data/spec/server_socket_spec.rb +0 -121
- data/spec/server_spec.rb +0 -238
- data/spec/socket_spec.rb +0 -174
- data/spec/socket_spec_shared.rb +0 -168
- data/spec/spec_helper.rb +0 -70
- data/spec/ssl_server_socket_spec.rb +0 -85
- data/spec/ssl_socket_spec.rb +0 -248
- data/spec/struct_nested_containers_spec.rb +0 -191
- data/spec/struct_spec.rb +0 -398
- data/spec/support/header_protocol_helper.rb +0 -55
- data/spec/thin_http_server_spec.rb +0 -127
- data/spec/types_spec.rb +0 -118
- data/spec/union_spec.rb +0 -273
- data/spec/unix_socket_spec.rb +0 -131
- data/spec/uuid_validation_spec.rb +0 -239
- data/test/fuzz/Makefile +0 -779
- data/test/fuzz/Makefile.am +0 -173
- data/test/fuzz/Makefile.in +0 -775
- data/test/fuzz/README.md +0 -149
- data/test/fuzz/fuzz_common.rb +0 -96
- data/test/fuzz/fuzz_parse_binary_protocol.rb +0 -23
- data/test/fuzz/fuzz_parse_binary_protocol_accelerated.rb +0 -23
- data/test/fuzz/fuzz_parse_binary_protocol_accelerated_harness.rb +0 -23
- data/test/fuzz/fuzz_parse_binary_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_parse_compact_protocol.rb +0 -23
- data/test/fuzz/fuzz_parse_compact_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_parse_json_protocol.rb +0 -23
- data/test/fuzz/fuzz_parse_json_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_binary_protocol.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated_harness.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_binary_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_compact_protocol.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_compact_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_json_protocol.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_json_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_tracer.rb +0 -29
data/ext/constants.h
CHANGED
|
@@ -77,14 +77,17 @@ extern ID skip_method_id;
|
|
|
77
77
|
extern ID write_method_id;
|
|
78
78
|
extern ID read_all_method_id;
|
|
79
79
|
extern ID read_into_buffer_method_id;
|
|
80
|
+
extern ID reset_message_size_method_id;
|
|
80
81
|
extern ID force_binary_encoding_id;
|
|
81
82
|
extern ID convert_to_utf8_byte_buffer_id;
|
|
82
83
|
extern ID convert_to_string_id;
|
|
83
84
|
|
|
84
85
|
extern ID fields_const_id;
|
|
85
86
|
extern ID transport_ivar_id;
|
|
87
|
+
extern ID reset_message_size_ivar_id;
|
|
86
88
|
extern ID strict_read_ivar_id;
|
|
87
89
|
extern ID strict_write_ivar_id;
|
|
90
|
+
extern ID max_string_size_ivar_id;
|
|
88
91
|
|
|
89
92
|
extern VALUE type_sym;
|
|
90
93
|
extern VALUE name_sym;
|
data/ext/extconf.rb
CHANGED
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
# under the License.
|
|
19
19
|
#
|
|
20
20
|
|
|
21
|
-
if defined?(RUBY_ENGINE) && RUBY_ENGINE
|
|
22
|
-
File.open(
|
|
21
|
+
if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
|
|
22
|
+
File.open("Makefile", "w") { |f| f.puts "all:\n\ninstall:\n" }
|
|
23
23
|
else
|
|
24
|
-
require
|
|
24
|
+
require "mkmf"
|
|
25
25
|
|
|
26
26
|
append_cflags(["-fsigned-char", "-g", "-O2", "-Wall", "-Werror", "-Werror=old-style-definition"])
|
|
27
27
|
|
|
@@ -39,5 +39,5 @@ else
|
|
|
39
39
|
|
|
40
40
|
have_func("strlcpy", "string.h")
|
|
41
41
|
|
|
42
|
-
create_makefile
|
|
42
|
+
create_makefile "thrift_native"
|
|
43
43
|
end
|
data/ext/macros.h
CHANGED
|
@@ -24,6 +24,17 @@
|
|
|
24
24
|
#define CHECK_NIL(obj) if (NIL_P(obj)) { rb_raise(rb_eStandardError, "nil argument not allowed!");}
|
|
25
25
|
#define READ(obj, length) rb_funcall(GET_TRANSPORT(obj), read_all_method_id, 1, INT2FIX(length))
|
|
26
26
|
|
|
27
|
+
// Refuse a declared string length over the protocol's @max_string_size (nil
|
|
28
|
+
// means no limit) before it becomes a read size.
|
|
29
|
+
#define CHECK_STRING_SIZE(obj, size) \
|
|
30
|
+
do { \
|
|
31
|
+
VALUE max_string_size_ = rb_ivar_get(obj, max_string_size_ivar_id); \
|
|
32
|
+
if (!NIL_P(max_string_size_) && RB_UNLIKELY((long long)(size) > NUM2LL(max_string_size_))) { \
|
|
33
|
+
rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_SIZE_LIMIT), \
|
|
34
|
+
rb_sprintf("String size %lld larger than the maximum %lld", (long long)(size), NUM2LL(max_string_size_)))); \
|
|
35
|
+
} \
|
|
36
|
+
} while (0)
|
|
37
|
+
|
|
27
38
|
#ifndef RFLOAT_VALUE
|
|
28
39
|
# define RFLOAT_VALUE(v) RFLOAT(rb_Float(v))->value
|
|
29
40
|
#endif
|
data/ext/memory_buffer.c
CHANGED
|
@@ -48,23 +48,28 @@ VALUE rb_thrift_memory_buffer_write(VALUE self, VALUE str) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
VALUE rb_thrift_memory_buffer_read(VALUE self, VALUE length_value) {
|
|
51
|
-
|
|
51
|
+
long long length = NUM2LL(length_value);
|
|
52
|
+
|
|
53
|
+
if (RB_UNLIKELY(length < 0)) {
|
|
54
|
+
rb_exc_raise(rb_funcall(transport_exception_class, new_method_id, 2, transport_negative_size, rb_str_new2("Negative size")));
|
|
55
|
+
}
|
|
52
56
|
|
|
53
57
|
VALUE index_value = rb_ivar_get(self, index_ivar_id);
|
|
54
|
-
|
|
58
|
+
long index = NUM2LONG(index_value);
|
|
55
59
|
|
|
56
60
|
VALUE buf = GET_BUF(self);
|
|
57
61
|
VALUE data = rb_funcall(buf, slice_method_id, 2, index_value, length_value);
|
|
58
62
|
|
|
59
|
-
index
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
if (length > RSTRING_LEN(buf) - index) {
|
|
64
|
+
index = RSTRING_LEN(buf);
|
|
65
|
+
} else {
|
|
66
|
+
index += (long)length;
|
|
62
67
|
}
|
|
63
68
|
if (index >= GARBAGE_BUFFER_SIZE) {
|
|
64
|
-
rb_ivar_set(self, buf_ivar_id, rb_funcall(buf, slice_method_id, 2,
|
|
69
|
+
rb_ivar_set(self, buf_ivar_id, rb_funcall(buf, slice_method_id, 2, LONG2NUM(index), LONG2NUM(RSTRING_LEN(buf) - 1)));
|
|
65
70
|
index = 0;
|
|
66
71
|
}
|
|
67
|
-
rb_ivar_set(self, index_ivar_id,
|
|
72
|
+
rb_ivar_set(self, index_ivar_id, LONG2NUM(index));
|
|
68
73
|
|
|
69
74
|
if (RSTRING_LEN(data) < length) {
|
|
70
75
|
rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer");
|
|
@@ -74,28 +79,28 @@ VALUE rb_thrift_memory_buffer_read(VALUE self, VALUE length_value) {
|
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
VALUE rb_thrift_memory_buffer_read_all(VALUE self, VALUE length_value) {
|
|
77
|
-
|
|
82
|
+
long long length = NUM2LL(length_value);
|
|
78
83
|
|
|
79
84
|
if (RB_UNLIKELY(length < 0)) {
|
|
80
85
|
rb_exc_raise(rb_funcall(transport_exception_class, new_method_id, 2, transport_negative_size, rb_str_new2("Negative size")));
|
|
81
86
|
}
|
|
82
87
|
|
|
83
88
|
VALUE index_value = rb_ivar_get(self, index_ivar_id);
|
|
84
|
-
|
|
89
|
+
long index = NUM2LONG(index_value);
|
|
85
90
|
VALUE buf = GET_BUF(self);
|
|
86
91
|
|
|
87
92
|
if (RB_UNLIKELY(length > RSTRING_LEN(buf) - index)) {
|
|
88
93
|
rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer");
|
|
89
94
|
}
|
|
90
95
|
|
|
91
|
-
VALUE data = rb_str_subseq(buf, index, length);
|
|
96
|
+
VALUE data = rb_str_subseq(buf, index, (long)length);
|
|
92
97
|
|
|
93
|
-
index += length;
|
|
98
|
+
index += (long)length;
|
|
94
99
|
if (index >= GARBAGE_BUFFER_SIZE) {
|
|
95
100
|
rb_ivar_set(self, buf_ivar_id, rb_str_subseq(buf, index, RSTRING_LEN(buf) - index));
|
|
96
101
|
index = 0;
|
|
97
102
|
}
|
|
98
|
-
rb_ivar_set(self, index_ivar_id,
|
|
103
|
+
rb_ivar_set(self, index_ivar_id, LONG2NUM(index));
|
|
99
104
|
|
|
100
105
|
return data;
|
|
101
106
|
}
|
|
@@ -108,7 +113,7 @@ VALUE rb_thrift_memory_buffer_read_byte(VALUE self) {
|
|
|
108
113
|
if (index >= RSTRING_LEN(buf)) {
|
|
109
114
|
rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer");
|
|
110
115
|
}
|
|
111
|
-
char byte = RSTRING_PTR(buf)[index++];
|
|
116
|
+
unsigned char byte = (unsigned char)RSTRING_PTR(buf)[index++];
|
|
112
117
|
|
|
113
118
|
if (index >= GARBAGE_BUFFER_SIZE) {
|
|
114
119
|
rb_ivar_set(self, buf_ivar_id, rb_funcall(buf, slice_method_id, 2, INT2FIX(index), INT2FIX(RSTRING_LEN(buf) - 1)));
|
|
@@ -116,8 +121,7 @@ VALUE rb_thrift_memory_buffer_read_byte(VALUE self) {
|
|
|
116
121
|
}
|
|
117
122
|
rb_ivar_set(self, index_ivar_id, INT2FIX(index));
|
|
118
123
|
|
|
119
|
-
|
|
120
|
-
return INT2FIX(result);
|
|
124
|
+
return INT2FIX(byte);
|
|
121
125
|
}
|
|
122
126
|
|
|
123
127
|
VALUE rb_thrift_memory_buffer_read_into_buffer(VALUE self, VALUE buffer_value, VALUE size_value) {
|
|
@@ -127,15 +131,29 @@ VALUE rb_thrift_memory_buffer_read_into_buffer(VALUE self, VALUE buffer_value, V
|
|
|
127
131
|
VALUE buf = GET_BUF(self);
|
|
128
132
|
|
|
129
133
|
index = FIX2INT(rb_ivar_get(self, index_ivar_id));
|
|
130
|
-
|
|
134
|
+
if (size > 0) {
|
|
131
135
|
if (index >= RSTRING_LEN(buf)) {
|
|
136
|
+
rb_ivar_set(self, index_ivar_id, INT2FIX(index));
|
|
132
137
|
rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer");
|
|
133
138
|
}
|
|
134
|
-
|
|
139
|
+
StringValue(buffer_value);
|
|
140
|
+
if (RSTRING_LEN(buffer_value) == 0) {
|
|
141
|
+
rb_ivar_set(self, index_ivar_id, INT2FIX(index));
|
|
142
|
+
rb_raise(rb_eIndexError, "index 0 out of string");
|
|
143
|
+
}
|
|
144
|
+
rb_str_modify(buffer_value);
|
|
145
|
+
}
|
|
135
146
|
|
|
147
|
+
while (i < size) {
|
|
148
|
+
if (index >= RSTRING_LEN(buf)) {
|
|
149
|
+
rb_ivar_set(self, index_ivar_id, INT2FIX(index));
|
|
150
|
+
rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer");
|
|
151
|
+
}
|
|
136
152
|
if (i >= RSTRING_LEN(buffer_value)) {
|
|
153
|
+
rb_ivar_set(self, index_ivar_id, INT2FIX(index));
|
|
137
154
|
rb_raise(rb_eIndexError, "index %d out of string", i);
|
|
138
155
|
}
|
|
156
|
+
char byte = RSTRING_PTR(buf)[index++];
|
|
139
157
|
((char*)RSTRING_PTR(buffer_value))[i] = byte;
|
|
140
158
|
i++;
|
|
141
159
|
}
|
data/ext/struct.c
CHANGED
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
+
#include <stdint.h>
|
|
21
|
+
|
|
20
22
|
#include "struct.h"
|
|
21
23
|
#include "constants.h"
|
|
22
24
|
#include "macros.h"
|
|
@@ -31,23 +33,63 @@ ID setvalue_id;
|
|
|
31
33
|
ID to_s_method_id;
|
|
32
34
|
ID name_to_id_method_id;
|
|
33
35
|
static ID sorted_field_ids_method_id;
|
|
36
|
+
static ID validate_container_size_method_id;
|
|
37
|
+
static VALUE default_sym;
|
|
34
38
|
|
|
35
39
|
#define IS_CONTAINER(ttype) ((ttype) == TTYPE_MAP || (ttype) == TTYPE_LIST || (ttype) == TTYPE_SET)
|
|
36
40
|
#define STRUCT_FIELDS(obj) rb_const_get(CLASS_OF(obj), fields_const_id)
|
|
41
|
+
// Default budget when callers do not provide a remaining depth.
|
|
42
|
+
static int recursion_limit;
|
|
37
43
|
|
|
38
|
-
static void
|
|
39
|
-
if (RB_UNLIKELY(
|
|
44
|
+
static void validate_recursion_depth(int remaining_depth) {
|
|
45
|
+
if (RB_UNLIKELY(remaining_depth <= 0)) {
|
|
40
46
|
rb_exc_raise(
|
|
41
47
|
get_protocol_exception(
|
|
42
|
-
INT2FIX(
|
|
43
|
-
rb_str_new2("
|
|
48
|
+
INT2FIX(PROTOERR_DEPTH_LIMIT),
|
|
49
|
+
rb_str_new2("Maximum recursion depth exceeded")
|
|
44
50
|
)
|
|
45
51
|
);
|
|
46
52
|
}
|
|
47
53
|
}
|
|
48
54
|
|
|
55
|
+
static int parse_recursive_args(int argc, const VALUE *argv, VALUE *protocol) {
|
|
56
|
+
if (RB_UNLIKELY(argc < 1 || argc > 2)) {
|
|
57
|
+
rb_error_arity(argc, 1, 2);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
*protocol = argv[0];
|
|
61
|
+
int remaining_depth = argc == 1 ? recursion_limit : NUM2INT(argv[1]);
|
|
62
|
+
validate_recursion_depth(remaining_depth);
|
|
63
|
+
return remaining_depth;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static int container_size(VALUE protocol, VALUE size) {
|
|
67
|
+
if (RB_LIKELY(FIXNUM_P(size))) {
|
|
68
|
+
long value = FIX2LONG(size);
|
|
69
|
+
if (RB_UNLIKELY(value < 0)) {
|
|
70
|
+
rb_exc_raise(
|
|
71
|
+
get_protocol_exception(
|
|
72
|
+
INT2FIX(PROTOERR_NEGATIVE_SIZE),
|
|
73
|
+
rb_str_new2("Negative size")
|
|
74
|
+
)
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
if (RB_UNLIKELY((unsigned long)value > INT32_MAX)) {
|
|
78
|
+
rb_exc_raise(
|
|
79
|
+
get_protocol_exception(
|
|
80
|
+
INT2FIX(PROTOERR_SIZE_LIMIT),
|
|
81
|
+
rb_str_new2("Container size limit exceeded")
|
|
82
|
+
)
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
return (int)value;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
rb_funcall(protocol, validate_container_size_method_id, 1, size);
|
|
89
|
+
return NUM2INT(size);
|
|
90
|
+
}
|
|
91
|
+
|
|
49
92
|
static VALUE new_container_array(int size) {
|
|
50
|
-
validate_container_size(size);
|
|
51
93
|
return rb_ary_new2(size > 1024 ? 1024 : size);
|
|
52
94
|
}
|
|
53
95
|
|
|
@@ -235,22 +277,24 @@ VALUE default_read_struct_end(VALUE protocol) {
|
|
|
235
277
|
|
|
236
278
|
// end default protocol methods
|
|
237
279
|
|
|
238
|
-
static VALUE
|
|
239
|
-
static VALUE
|
|
240
|
-
static void write_anything(int ttype, VALUE value, VALUE protocol, VALUE field_info);
|
|
280
|
+
static VALUE rb_thrift_struct_write_recursive(VALUE self, VALUE protocol, int remaining_depth);
|
|
281
|
+
static VALUE rb_thrift_union_write_recursive(VALUE self, VALUE protocol, int remaining_depth);
|
|
282
|
+
static void write_anything(int ttype, VALUE value, VALUE protocol, VALUE field_info, int remaining_depth);
|
|
241
283
|
|
|
242
|
-
|
|
284
|
+
static inline ID field_ivar_id(VALUE field_name) {
|
|
243
285
|
char name_buf[RSTRING_LEN(field_name) + 2];
|
|
244
286
|
|
|
245
287
|
name_buf[0] = '@';
|
|
246
288
|
strlcpy(&name_buf[1], RSTRING_PTR(field_name), RSTRING_LEN(field_name) + 1);
|
|
247
289
|
|
|
248
|
-
|
|
290
|
+
return rb_intern(name_buf);
|
|
291
|
+
}
|
|
249
292
|
|
|
250
|
-
|
|
293
|
+
VALUE get_field_value(VALUE obj, VALUE field_name) {
|
|
294
|
+
return rb_ivar_get(obj, field_ivar_id(field_name));
|
|
251
295
|
}
|
|
252
296
|
|
|
253
|
-
static void write_container(int ttype, VALUE field_info, VALUE value, VALUE protocol) {
|
|
297
|
+
static void write_container(int ttype, VALUE field_info, VALUE value, VALUE protocol, int remaining_depth) {
|
|
254
298
|
long sz, i;
|
|
255
299
|
|
|
256
300
|
if (ttype == TTYPE_MAP) {
|
|
@@ -277,15 +321,15 @@ static void write_container(int ttype, VALUE field_info, VALUE value, VALUE prot
|
|
|
277
321
|
VALUE val = rb_hash_aref(value, key);
|
|
278
322
|
|
|
279
323
|
if (IS_CONTAINER(keytype)) {
|
|
280
|
-
write_container(keytype, key_info, key, protocol);
|
|
324
|
+
write_container(keytype, key_info, key, protocol, remaining_depth);
|
|
281
325
|
} else {
|
|
282
|
-
write_anything(keytype, key, protocol, key_info);
|
|
326
|
+
write_anything(keytype, key, protocol, key_info, remaining_depth);
|
|
283
327
|
}
|
|
284
328
|
|
|
285
329
|
if (IS_CONTAINER(valuetype)) {
|
|
286
|
-
write_container(valuetype, value_info, val, protocol);
|
|
330
|
+
write_container(valuetype, value_info, val, protocol, remaining_depth);
|
|
287
331
|
} else {
|
|
288
|
-
write_anything(valuetype, val, protocol, value_info);
|
|
332
|
+
write_anything(valuetype, val, protocol, value_info, remaining_depth);
|
|
289
333
|
}
|
|
290
334
|
}
|
|
291
335
|
|
|
@@ -303,9 +347,9 @@ static void write_container(int ttype, VALUE field_info, VALUE value, VALUE prot
|
|
|
303
347
|
for (i = 0; i < sz; ++i) {
|
|
304
348
|
VALUE val = rb_ary_entry(value, i);
|
|
305
349
|
if (IS_CONTAINER(element_type)) {
|
|
306
|
-
write_container(element_type, element_type_info, val, protocol);
|
|
350
|
+
write_container(element_type, element_type_info, val, protocol, remaining_depth);
|
|
307
351
|
} else {
|
|
308
|
-
write_anything(element_type, val, protocol, element_type_info);
|
|
352
|
+
write_anything(element_type, val, protocol, element_type_info, remaining_depth);
|
|
309
353
|
}
|
|
310
354
|
}
|
|
311
355
|
default_write_list_end(protocol);
|
|
@@ -315,7 +359,7 @@ static void write_container(int ttype, VALUE field_info, VALUE value, VALUE prot
|
|
|
315
359
|
if (TYPE(value) == T_ARRAY) {
|
|
316
360
|
items = value;
|
|
317
361
|
} else {
|
|
318
|
-
if (
|
|
362
|
+
if (rb_obj_is_kind_of(value, rb_cSet)) {
|
|
319
363
|
items = rb_funcall(value, entries_method_id, 0);
|
|
320
364
|
} else {
|
|
321
365
|
Check_Type(value, T_HASH);
|
|
@@ -334,9 +378,9 @@ static void write_container(int ttype, VALUE field_info, VALUE value, VALUE prot
|
|
|
334
378
|
for (i = 0; i < sz; i++) {
|
|
335
379
|
VALUE val = rb_ary_entry(items, i);
|
|
336
380
|
if (IS_CONTAINER(element_type)) {
|
|
337
|
-
write_container(element_type, element_type_info, val, protocol);
|
|
381
|
+
write_container(element_type, element_type_info, val, protocol, remaining_depth);
|
|
338
382
|
} else {
|
|
339
|
-
write_anything(element_type, val, protocol, element_type_info);
|
|
383
|
+
write_anything(element_type, val, protocol, element_type_info, remaining_depth);
|
|
340
384
|
}
|
|
341
385
|
}
|
|
342
386
|
|
|
@@ -346,7 +390,7 @@ static void write_container(int ttype, VALUE field_info, VALUE value, VALUE prot
|
|
|
346
390
|
}
|
|
347
391
|
}
|
|
348
392
|
|
|
349
|
-
static void write_anything(int ttype, VALUE value, VALUE protocol, VALUE field_info) {
|
|
393
|
+
static void write_anything(int ttype, VALUE value, VALUE protocol, VALUE field_info, int remaining_depth) {
|
|
350
394
|
if (ttype == TTYPE_BOOL) {
|
|
351
395
|
default_write_bool(protocol, value);
|
|
352
396
|
} else if (ttype == TTYPE_BYTE) {
|
|
@@ -369,19 +413,21 @@ static void write_anything(int ttype, VALUE value, VALUE protocol, VALUE field_i
|
|
|
369
413
|
} else if (ttype == TTYPE_UUID) {
|
|
370
414
|
default_write_uuid(protocol, value);
|
|
371
415
|
} else if (IS_CONTAINER(ttype)) {
|
|
372
|
-
write_container(ttype, field_info, value, protocol);
|
|
416
|
+
write_container(ttype, field_info, value, protocol, remaining_depth);
|
|
373
417
|
} else if (ttype == TTYPE_STRUCT) {
|
|
418
|
+
remaining_depth--;
|
|
419
|
+
validate_recursion_depth(remaining_depth);
|
|
374
420
|
if (rb_obj_is_kind_of(value, thrift_union_class)) {
|
|
375
|
-
|
|
421
|
+
rb_thrift_union_write_recursive(value, protocol, remaining_depth);
|
|
376
422
|
} else {
|
|
377
|
-
|
|
423
|
+
rb_thrift_struct_write_recursive(value, protocol, remaining_depth);
|
|
378
424
|
}
|
|
379
425
|
} else {
|
|
380
426
|
rb_raise(rb_eNotImpError, "Unknown type for binary_encoding: %d", ttype);
|
|
381
427
|
}
|
|
382
428
|
}
|
|
383
429
|
|
|
384
|
-
static VALUE
|
|
430
|
+
static VALUE rb_thrift_struct_write_recursive(VALUE self, VALUE protocol, int remaining_depth) {
|
|
385
431
|
// call validate
|
|
386
432
|
rb_funcall(self, validate_method_id, 0);
|
|
387
433
|
|
|
@@ -407,7 +453,7 @@ static VALUE rb_thrift_struct_write(VALUE self, VALUE protocol) {
|
|
|
407
453
|
if (!NIL_P(field_value)) {
|
|
408
454
|
default_write_field_begin(protocol, field_name, ttype_value, field_id);
|
|
409
455
|
|
|
410
|
-
write_anything(ttype, field_value, protocol, field_info);
|
|
456
|
+
write_anything(ttype, field_value, protocol, field_info, remaining_depth);
|
|
411
457
|
|
|
412
458
|
default_write_field_end(protocol);
|
|
413
459
|
}
|
|
@@ -421,22 +467,60 @@ static VALUE rb_thrift_struct_write(VALUE self, VALUE protocol) {
|
|
|
421
467
|
return Qnil;
|
|
422
468
|
}
|
|
423
469
|
|
|
470
|
+
// cppcheck-suppress constParameterCallback
|
|
471
|
+
static VALUE rb_thrift_struct_write(int argc, VALUE *argv, VALUE self) {
|
|
472
|
+
VALUE protocol;
|
|
473
|
+
int remaining_depth = parse_recursive_args(argc, argv, &protocol);
|
|
474
|
+
return rb_thrift_struct_write_recursive(self, protocol, remaining_depth);
|
|
475
|
+
}
|
|
476
|
+
|
|
424
477
|
//-------------------------------------------
|
|
425
478
|
// Reading section
|
|
426
479
|
//-------------------------------------------
|
|
427
480
|
|
|
428
|
-
static VALUE
|
|
429
|
-
static VALUE
|
|
481
|
+
static VALUE rb_thrift_union_read_recursive(VALUE self, VALUE protocol, int remaining_depth);
|
|
482
|
+
static VALUE rb_thrift_struct_read_recursive(VALUE self, VALUE protocol, int remaining_depth);
|
|
430
483
|
static void skip_map_contents(VALUE protocol, VALUE key_type_value, VALUE value_type_value, int size);
|
|
431
484
|
static void skip_list_or_set_contents(VALUE protocol, VALUE element_type_value, int size);
|
|
432
485
|
|
|
433
|
-
static void set_field_value(VALUE obj, VALUE field_name, VALUE value) {
|
|
434
|
-
|
|
486
|
+
static inline void set_field_value(VALUE obj, VALUE field_name, VALUE value) {
|
|
487
|
+
rb_ivar_set(obj, field_ivar_id(field_name), value);
|
|
488
|
+
}
|
|
435
489
|
|
|
436
|
-
|
|
437
|
-
|
|
490
|
+
/* Ruby's rescue and iteration APIs require addressable callback functions. */
|
|
491
|
+
static VALUE duplicate_default_value(VALUE value) {
|
|
492
|
+
return rb_obj_dup(value);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
static VALUE retain_default_value(VALUE value, VALUE exception) {
|
|
496
|
+
(void)exception;
|
|
497
|
+
return value;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
static int reset_struct_field(VALUE field_id, VALUE field_info, VALUE self) {
|
|
501
|
+
(void)field_id;
|
|
502
|
+
|
|
503
|
+
VALUE field_name = rb_hash_aref(field_info, name_sym);
|
|
504
|
+
ID ivar_id = field_ivar_id(field_name);
|
|
505
|
+
VALUE default_value = rb_hash_aref(field_info, default_sym);
|
|
506
|
+
|
|
507
|
+
if (NIL_P(default_value)) {
|
|
508
|
+
if (!NIL_P(rb_ivar_get(self, ivar_id))) {
|
|
509
|
+
rb_ivar_set(self, ivar_id, Qnil);
|
|
510
|
+
}
|
|
511
|
+
} else {
|
|
512
|
+
VALUE value = rb_rescue2(
|
|
513
|
+
duplicate_default_value,
|
|
514
|
+
default_value,
|
|
515
|
+
retain_default_value,
|
|
516
|
+
default_value,
|
|
517
|
+
rb_eStandardError,
|
|
518
|
+
(VALUE)0
|
|
519
|
+
);
|
|
520
|
+
rb_ivar_set(self, ivar_id, value);
|
|
521
|
+
}
|
|
438
522
|
|
|
439
|
-
|
|
523
|
+
return ST_CONTINUE;
|
|
440
524
|
}
|
|
441
525
|
|
|
442
526
|
// Helper method to skip the contents of a map (assumes the map header has been read).
|
|
@@ -456,7 +540,7 @@ static void skip_list_or_set_contents(VALUE protocol, VALUE element_type_value,
|
|
|
456
540
|
}
|
|
457
541
|
}
|
|
458
542
|
|
|
459
|
-
static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
|
|
543
|
+
static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info, int remaining_depth) {
|
|
460
544
|
VALUE result = Qnil;
|
|
461
545
|
|
|
462
546
|
if (ttype == TTYPE_BOOL) {
|
|
@@ -483,21 +567,19 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
|
|
|
483
567
|
} else if (ttype == TTYPE_STRUCT) {
|
|
484
568
|
VALUE klass = rb_hash_aref(field_info, class_sym);
|
|
485
569
|
result = rb_class_new_instance(0, NULL, klass);
|
|
570
|
+
remaining_depth--;
|
|
571
|
+
validate_recursion_depth(remaining_depth);
|
|
486
572
|
|
|
487
573
|
if (rb_obj_is_kind_of(result, thrift_union_class)) {
|
|
488
|
-
|
|
574
|
+
rb_thrift_union_read_recursive(result, protocol, remaining_depth);
|
|
489
575
|
} else {
|
|
490
|
-
|
|
576
|
+
rb_thrift_struct_read_recursive(result, protocol, remaining_depth);
|
|
491
577
|
}
|
|
492
578
|
} else if (ttype == TTYPE_MAP) {
|
|
493
579
|
VALUE map_header = default_read_map_begin(protocol);
|
|
494
580
|
int key_ttype = FIX2INT(rb_ary_entry(map_header, 0));
|
|
495
581
|
int value_ttype = FIX2INT(rb_ary_entry(map_header, 1));
|
|
496
|
-
int num_entries =
|
|
497
|
-
|
|
498
|
-
if (num_entries < 0) {
|
|
499
|
-
rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_NEGATIVE_SIZE), rb_str_new2("Negative container size")));
|
|
500
|
-
}
|
|
582
|
+
int num_entries = container_size(protocol, rb_ary_entry(map_header, 2));
|
|
501
583
|
|
|
502
584
|
// Check the declared key and value types against the expected ones and skip the map contents
|
|
503
585
|
// if the types don't match.
|
|
@@ -513,8 +595,8 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
|
|
|
513
595
|
for (int i = 0; i < num_entries; ++i) {
|
|
514
596
|
VALUE key, val;
|
|
515
597
|
|
|
516
|
-
key = read_anything(protocol, key_ttype, key_info);
|
|
517
|
-
val = read_anything(protocol, value_ttype, value_info);
|
|
598
|
+
key = read_anything(protocol, key_ttype, key_info, remaining_depth);
|
|
599
|
+
val = read_anything(protocol, value_ttype, value_info, remaining_depth);
|
|
518
600
|
|
|
519
601
|
rb_hash_aset(result, key, val);
|
|
520
602
|
}
|
|
@@ -529,7 +611,7 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
|
|
|
529
611
|
} else if (ttype == TTYPE_LIST) {
|
|
530
612
|
VALUE list_header = default_read_list_begin(protocol);
|
|
531
613
|
int element_ttype = FIX2INT(rb_ary_entry(list_header, 0));
|
|
532
|
-
int num_elements =
|
|
614
|
+
int num_elements = container_size(protocol, rb_ary_entry(list_header, 1));
|
|
533
615
|
|
|
534
616
|
// Check the declared element type against the expected one and skip the list contents
|
|
535
617
|
// if the types don't match.
|
|
@@ -540,14 +622,12 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
|
|
|
540
622
|
result = new_container_array(num_elements);
|
|
541
623
|
|
|
542
624
|
for (int i = 0; i < num_elements; ++i) {
|
|
543
|
-
rb_ary_push(result, read_anything(protocol, element_ttype, rb_hash_aref(field_info, element_sym)));
|
|
625
|
+
rb_ary_push(result, read_anything(protocol, element_ttype, rb_hash_aref(field_info, element_sym), remaining_depth));
|
|
544
626
|
}
|
|
545
627
|
} else {
|
|
546
|
-
validate_container_size(num_elements);
|
|
547
628
|
skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements);
|
|
548
629
|
}
|
|
549
630
|
} else {
|
|
550
|
-
validate_container_size(num_elements);
|
|
551
631
|
skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements);
|
|
552
632
|
}
|
|
553
633
|
|
|
@@ -557,7 +637,7 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
|
|
|
557
637
|
|
|
558
638
|
VALUE set_header = default_read_set_begin(protocol);
|
|
559
639
|
int element_ttype = FIX2INT(rb_ary_entry(set_header, 0));
|
|
560
|
-
int num_elements =
|
|
640
|
+
int num_elements = container_size(protocol, rb_ary_entry(set_header, 1));
|
|
561
641
|
|
|
562
642
|
// Check the declared element type against the expected one and skip the set contents
|
|
563
643
|
// if the types don't match.
|
|
@@ -568,16 +648,14 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
|
|
|
568
648
|
items = new_container_array(num_elements);
|
|
569
649
|
|
|
570
650
|
for (int i = 0; i < num_elements; ++i) {
|
|
571
|
-
rb_ary_push(items, read_anything(protocol, element_ttype, rb_hash_aref(field_info, element_sym)));
|
|
651
|
+
rb_ary_push(items, read_anything(protocol, element_ttype, rb_hash_aref(field_info, element_sym), remaining_depth));
|
|
572
652
|
}
|
|
573
653
|
|
|
574
654
|
result = rb_class_new_instance(1, &items, rb_cSet);
|
|
575
655
|
} else {
|
|
576
|
-
validate_container_size(num_elements);
|
|
577
656
|
skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements);
|
|
578
657
|
}
|
|
579
658
|
} else {
|
|
580
|
-
validate_container_size(num_elements);
|
|
581
659
|
skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements);
|
|
582
660
|
}
|
|
583
661
|
|
|
@@ -589,12 +667,17 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
|
|
|
589
667
|
return result;
|
|
590
668
|
}
|
|
591
669
|
|
|
592
|
-
static VALUE
|
|
670
|
+
static VALUE rb_thrift_struct_read_recursive(VALUE self, VALUE protocol, int remaining_depth) {
|
|
671
|
+
VALUE struct_fields = STRUCT_FIELDS(self);
|
|
672
|
+
|
|
673
|
+
if (RHASH_SIZE(struct_fields) > 0 && rb_ivar_count(self) > 0) {
|
|
674
|
+
rb_check_frozen(self);
|
|
675
|
+
rb_hash_foreach(struct_fields, reset_struct_field, self);
|
|
676
|
+
}
|
|
677
|
+
|
|
593
678
|
// read struct begin
|
|
594
679
|
default_read_struct_begin(protocol);
|
|
595
680
|
|
|
596
|
-
VALUE struct_fields = STRUCT_FIELDS(self);
|
|
597
|
-
|
|
598
681
|
// read each field
|
|
599
682
|
while (true) {
|
|
600
683
|
VALUE field_header = default_read_field_begin(protocol);
|
|
@@ -613,7 +696,7 @@ static VALUE rb_thrift_struct_read(VALUE self, VALUE protocol) {
|
|
|
613
696
|
if (field_type == specified_type) {
|
|
614
697
|
// read the value
|
|
615
698
|
VALUE name = rb_hash_aref(field_info, name_sym);
|
|
616
|
-
set_field_value(self, name, read_anything(protocol, field_type, field_info));
|
|
699
|
+
set_field_value(self, name, read_anything(protocol, field_type, field_info, remaining_depth));
|
|
617
700
|
} else {
|
|
618
701
|
rb_funcall(protocol, skip_method_id, 1, field_type_value);
|
|
619
702
|
}
|
|
@@ -634,12 +717,28 @@ static VALUE rb_thrift_struct_read(VALUE self, VALUE protocol) {
|
|
|
634
717
|
return Qnil;
|
|
635
718
|
}
|
|
636
719
|
|
|
720
|
+
// cppcheck-suppress constParameterCallback
|
|
721
|
+
static VALUE rb_thrift_struct_read(int argc, VALUE *argv, VALUE self) {
|
|
722
|
+
VALUE protocol;
|
|
723
|
+
int remaining_depth = parse_recursive_args(argc, argv, &protocol);
|
|
724
|
+
return rb_thrift_struct_read_recursive(self, protocol, remaining_depth);
|
|
725
|
+
}
|
|
726
|
+
|
|
637
727
|
|
|
638
728
|
// --------------------------------
|
|
639
729
|
// Union section
|
|
640
730
|
// --------------------------------
|
|
641
731
|
|
|
642
|
-
static VALUE
|
|
732
|
+
static VALUE rb_thrift_union_read_recursive(VALUE self, VALUE protocol, int remaining_depth) {
|
|
733
|
+
rb_check_frozen(self);
|
|
734
|
+
|
|
735
|
+
if (!NIL_P(rb_ivar_get(self, setfield_id))) {
|
|
736
|
+
rb_ivar_set(self, setfield_id, Qnil);
|
|
737
|
+
}
|
|
738
|
+
if (!NIL_P(rb_ivar_get(self, setvalue_id))) {
|
|
739
|
+
rb_ivar_set(self, setvalue_id, Qnil);
|
|
740
|
+
}
|
|
741
|
+
|
|
643
742
|
// read struct begin
|
|
644
743
|
default_read_struct_begin(protocol);
|
|
645
744
|
|
|
@@ -657,8 +756,9 @@ static VALUE rb_thrift_union_read(VALUE self, VALUE protocol) {
|
|
|
657
756
|
if (field_type == specified_type) {
|
|
658
757
|
// read the value
|
|
659
758
|
VALUE name = rb_hash_aref(field_info, name_sym);
|
|
759
|
+
VALUE value = read_anything(protocol, field_type, field_info, remaining_depth);
|
|
660
760
|
rb_iv_set(self, "@setfield", rb_str_intern(name));
|
|
661
|
-
rb_iv_set(self, "@value",
|
|
761
|
+
rb_iv_set(self, "@value", value);
|
|
662
762
|
} else {
|
|
663
763
|
rb_funcall(protocol, skip_method_id, 1, field_type_value);
|
|
664
764
|
}
|
|
@@ -686,7 +786,14 @@ static VALUE rb_thrift_union_read(VALUE self, VALUE protocol) {
|
|
|
686
786
|
return Qnil;
|
|
687
787
|
}
|
|
688
788
|
|
|
689
|
-
|
|
789
|
+
// cppcheck-suppress constParameterCallback
|
|
790
|
+
static VALUE rb_thrift_union_read(int argc, VALUE *argv, VALUE self) {
|
|
791
|
+
VALUE protocol;
|
|
792
|
+
int remaining_depth = parse_recursive_args(argc, argv, &protocol);
|
|
793
|
+
return rb_thrift_union_read_recursive(self, protocol, remaining_depth);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
static VALUE rb_thrift_union_write_recursive(VALUE self, VALUE protocol, int remaining_depth) {
|
|
690
797
|
// call validate
|
|
691
798
|
rb_funcall(self, validate_method_id, 0);
|
|
692
799
|
|
|
@@ -710,7 +817,7 @@ static VALUE rb_thrift_union_write(VALUE self, VALUE protocol) {
|
|
|
710
817
|
|
|
711
818
|
default_write_field_begin(protocol, setfield, ttype_value, field_id);
|
|
712
819
|
|
|
713
|
-
write_anything(ttype, setvalue, protocol, field_info);
|
|
820
|
+
write_anything(ttype, setvalue, protocol, field_info, remaining_depth);
|
|
714
821
|
|
|
715
822
|
default_write_field_end(protocol);
|
|
716
823
|
|
|
@@ -722,17 +829,26 @@ static VALUE rb_thrift_union_write(VALUE self, VALUE protocol) {
|
|
|
722
829
|
return Qnil;
|
|
723
830
|
}
|
|
724
831
|
|
|
832
|
+
// cppcheck-suppress constParameterCallback
|
|
833
|
+
static VALUE rb_thrift_union_write(int argc, VALUE *argv, VALUE self) {
|
|
834
|
+
VALUE protocol;
|
|
835
|
+
int remaining_depth = parse_recursive_args(argc, argv, &protocol);
|
|
836
|
+
return rb_thrift_union_write_recursive(self, protocol, remaining_depth);
|
|
837
|
+
}
|
|
838
|
+
|
|
725
839
|
void Init_struct(void) {
|
|
726
840
|
VALUE struct_module = rb_const_get(thrift_module, rb_intern("Struct"));
|
|
727
841
|
|
|
728
|
-
|
|
729
|
-
|
|
842
|
+
recursion_limit = FIX2INT(rb_const_get(thrift_module, rb_intern("DEFAULT_RECURSION_DEPTH")));
|
|
843
|
+
|
|
844
|
+
rb_define_method(struct_module, "write", rb_thrift_struct_write, -1);
|
|
845
|
+
rb_define_method(struct_module, "read", rb_thrift_struct_read, -1);
|
|
730
846
|
|
|
731
847
|
thrift_union_class = rb_const_get(thrift_module, rb_intern("Union"));
|
|
732
848
|
rb_global_variable(&thrift_union_class);
|
|
733
849
|
|
|
734
|
-
rb_define_method(thrift_union_class, "write", rb_thrift_union_write, 1);
|
|
735
|
-
rb_define_method(thrift_union_class, "read", rb_thrift_union_read, 1);
|
|
850
|
+
rb_define_method(thrift_union_class, "write", rb_thrift_union_write, -1);
|
|
851
|
+
rb_define_method(thrift_union_class, "read", rb_thrift_union_read, -1);
|
|
736
852
|
|
|
737
853
|
setfield_id = rb_intern("@setfield");
|
|
738
854
|
rb_global_variable(&setfield_id);
|
|
@@ -748,4 +864,9 @@ void Init_struct(void) {
|
|
|
748
864
|
|
|
749
865
|
sorted_field_ids_method_id = rb_intern("sorted_field_ids");
|
|
750
866
|
rb_global_variable(&sorted_field_ids_method_id);
|
|
867
|
+
|
|
868
|
+
validate_container_size_method_id = rb_intern("validate_container_size");
|
|
869
|
+
|
|
870
|
+
default_sym = ID2SYM(rb_intern("default"));
|
|
871
|
+
rb_global_variable(&default_sym);
|
|
751
872
|
}
|