thrift 0.23.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 +203 -40
- data/ext/binary_protocol_accelerated.c +130 -40
- data/ext/bytes.c +14 -0
- data/ext/compact_protocol.c +184 -91
- data/ext/constants.h +3 -0
- data/ext/extconf.rb +12 -4
- data/ext/macros.h +11 -0
- data/ext/memory_buffer.c +67 -12
- data/ext/struct.c +192 -71
- data/ext/thrift_native.c +7 -0
- data/lib/thrift/bytes.rb +6 -3
- data/lib/thrift/client.rb +31 -33
- data/lib/thrift/exceptions.rb +11 -8
- data/lib/thrift/multiplexed_processor.rb +17 -8
- data/lib/thrift/processor.rb +25 -3
- data/lib/thrift/protocol/base_protocol.rb +66 -31
- data/lib/thrift/protocol/binary_protocol.rb +80 -37
- data/lib/thrift/protocol/binary_protocol_accelerated.rb +7 -2
- data/lib/thrift/protocol/compact_protocol.rb +204 -88
- data/lib/thrift/protocol/header_protocol.rb +15 -3
- data/lib/thrift/protocol/json_protocol.rb +158 -109
- data/lib/thrift/protocol/multiplexed_protocol.rb +3 -3
- data/lib/thrift/protocol/protocol_decorator.rb +6 -2
- data/lib/thrift/serializer/deserializer.rb +1 -0
- data/lib/thrift/serializer/serializer.rb +7 -0
- data/lib/thrift/server/base_server.rb +11 -2
- data/lib/thrift/server/nonblocking_server.rb +69 -20
- data/lib/thrift/server/rack_application.rb +69 -0
- data/lib/thrift/server/simple_server.rb +27 -15
- data/lib/thrift/server/thin_http_server.rb +21 -44
- data/lib/thrift/server/thread_pool_server.rb +21 -17
- data/lib/thrift/server/threaded_server.rb +22 -18
- data/lib/thrift/struct.rb +34 -18
- data/lib/thrift/struct_union.rb +37 -36
- data/lib/thrift/thrift_native.rb +2 -1
- data/lib/thrift/transport/base_server_transport.rb +3 -0
- data/lib/thrift/transport/base_transport.rb +26 -4
- data/lib/thrift/transport/buffered_transport.rb +5 -4
- data/lib/thrift/transport/framed_transport.rb +33 -7
- data/lib/thrift/transport/header_transport.rb +159 -33
- data/lib/thrift/transport/http_client_transport.rb +28 -14
- data/lib/thrift/transport/io_stream_transport.rb +3 -1
- data/lib/thrift/transport/memory_buffer_transport.rb +14 -9
- data/lib/thrift/transport/server_socket.rb +10 -8
- data/lib/thrift/transport/socket.rb +85 -48
- data/lib/thrift/transport/ssl_server_socket.rb +67 -6
- data/lib/thrift/transport/ssl_socket.rb +73 -14
- data/lib/thrift/transport/unix_server_socket.rb +6 -2
- data/lib/thrift/transport/unix_socket.rb +5 -6
- data/lib/thrift/types.rb +23 -22
- data/lib/thrift/union.rb +21 -11
- data/lib/thrift/uuid.rb +9 -8
- data/lib/thrift.rb +40 -39
- metadata +7 -266
- data/benchmark/Benchmark.thrift +0 -24
- data/benchmark/benchmark.rb +0 -285
- data/benchmark/client.rb +0 -117
- data/benchmark/server.rb +0 -120
- data/benchmark/thin_server.rb +0 -45
- data/lib/thrift/server/mongrel_http_server.rb +0 -60
- 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 -187
- data/spec/base_protocol_spec.rb +0 -224
- data/spec/base_transport_spec.rb +0 -387
- data/spec/binary_protocol_accelerated_spec.rb +0 -46
- data/spec/binary_protocol_spec.rb +0 -72
- data/spec/binary_protocol_spec_shared.rb +0 -445
- data/spec/bytes_spec.rb +0 -99
- data/spec/client_spec.rb +0 -166
- data/spec/compact_protocol_spec.rb +0 -196
- data/spec/constants_demo_spec.rb +0 -101
- data/spec/exception_spec.rb +0 -140
- data/spec/flat_spec.rb +0 -62
- data/spec/header_protocol_spec.rb +0 -475
- data/spec/header_transport_spec.rb +0 -386
- data/spec/http_client_spec.rb +0 -159
- data/spec/json_protocol_spec.rb +0 -552
- data/spec/namespaced_spec.rb +0 -66
- data/spec/nonblocking_server_spec.rb +0 -361
- data/spec/processor_spec.rb +0 -79
- data/spec/serializer_spec.rb +0 -66
- data/spec/server_socket_spec.rb +0 -84
- data/spec/server_spec.rb +0 -186
- data/spec/socket_spec.rb +0 -67
- data/spec/socket_spec_shared.rb +0 -167
- data/spec/spec_helper.rb +0 -69
- data/spec/ssl_server_socket_spec.rb +0 -45
- data/spec/ssl_socket_spec.rb +0 -87
- data/spec/struct_nested_containers_spec.rb +0 -190
- data/spec/struct_spec.rb +0 -397
- data/spec/support/header_protocol_helper.rb +0 -54
- data/spec/thin_http_server_spec.rb +0 -126
- data/spec/types_spec.rb +0 -117
- data/spec/union_spec.rb +0 -272
- data/spec/unix_socket_spec.rb +0 -115
- data/spec/uuid_validation_spec.rb +0 -238
- data/test/fuzz/Makefile.am +0 -173
- data/test/fuzz/README.md +0 -149
- data/test/fuzz/fuzz_common.rb +0 -95
- data/test/fuzz/fuzz_parse_binary_protocol.rb +0 -22
- data/test/fuzz/fuzz_parse_binary_protocol_accelerated.rb +0 -22
- data/test/fuzz/fuzz_parse_binary_protocol_accelerated_harness.rb +0 -22
- data/test/fuzz/fuzz_parse_binary_protocol_harness.rb +0 -22
- data/test/fuzz/fuzz_parse_compact_protocol.rb +0 -22
- data/test/fuzz/fuzz_parse_compact_protocol_harness.rb +0 -22
- data/test/fuzz/fuzz_parse_json_protocol.rb +0 -22
- data/test/fuzz/fuzz_parse_json_protocol_harness.rb +0 -22
- data/test/fuzz/fuzz_roundtrip_binary_protocol.rb +0 -22
- data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated.rb +0 -22
- data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated_harness.rb +0 -22
- data/test/fuzz/fuzz_roundtrip_binary_protocol_harness.rb +0 -22
- data/test/fuzz/fuzz_roundtrip_compact_protocol.rb +0 -22
- data/test/fuzz/fuzz_roundtrip_compact_protocol_harness.rb +0 -22
- data/test/fuzz/fuzz_roundtrip_json_protocol.rb +0 -22
- data/test/fuzz/fuzz_roundtrip_json_protocol_harness.rb +0 -22
- data/test/fuzz/fuzz_tracer.rb +0 -28
data/ext/memory_buffer.c
CHANGED
|
@@ -28,11 +28,15 @@ ID index_ivar_id;
|
|
|
28
28
|
ID slice_method_id;
|
|
29
29
|
|
|
30
30
|
int GARBAGE_BUFFER_SIZE;
|
|
31
|
+
static VALUE transport_exception_class;
|
|
32
|
+
static VALUE transport_negative_size;
|
|
33
|
+
static ID new_method_id;
|
|
31
34
|
|
|
32
35
|
#define GET_BUF(self) rb_ivar_get(self, buf_ivar_id)
|
|
33
36
|
|
|
34
37
|
VALUE rb_thrift_memory_buffer_write(VALUE self, VALUE str);
|
|
35
38
|
VALUE rb_thrift_memory_buffer_read(VALUE self, VALUE length_value);
|
|
39
|
+
VALUE rb_thrift_memory_buffer_read_all(VALUE self, VALUE length_value);
|
|
36
40
|
VALUE rb_thrift_memory_buffer_read_byte(VALUE self);
|
|
37
41
|
VALUE rb_thrift_memory_buffer_read_into_buffer(VALUE self, VALUE buffer_value, VALUE size_value);
|
|
38
42
|
|
|
@@ -44,23 +48,28 @@ VALUE rb_thrift_memory_buffer_write(VALUE self, VALUE str) {
|
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
VALUE rb_thrift_memory_buffer_read(VALUE self, VALUE length_value) {
|
|
47
|
-
|
|
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
|
+
}
|
|
48
56
|
|
|
49
57
|
VALUE index_value = rb_ivar_get(self, index_ivar_id);
|
|
50
|
-
|
|
58
|
+
long index = NUM2LONG(index_value);
|
|
51
59
|
|
|
52
60
|
VALUE buf = GET_BUF(self);
|
|
53
61
|
VALUE data = rb_funcall(buf, slice_method_id, 2, index_value, length_value);
|
|
54
62
|
|
|
55
|
-
index
|
|
56
|
-
|
|
57
|
-
|
|
63
|
+
if (length > RSTRING_LEN(buf) - index) {
|
|
64
|
+
index = RSTRING_LEN(buf);
|
|
65
|
+
} else {
|
|
66
|
+
index += (long)length;
|
|
58
67
|
}
|
|
59
68
|
if (index >= GARBAGE_BUFFER_SIZE) {
|
|
60
|
-
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)));
|
|
61
70
|
index = 0;
|
|
62
71
|
}
|
|
63
|
-
rb_ivar_set(self, index_ivar_id,
|
|
72
|
+
rb_ivar_set(self, index_ivar_id, LONG2NUM(index));
|
|
64
73
|
|
|
65
74
|
if (RSTRING_LEN(data) < length) {
|
|
66
75
|
rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer");
|
|
@@ -69,6 +78,33 @@ VALUE rb_thrift_memory_buffer_read(VALUE self, VALUE length_value) {
|
|
|
69
78
|
return data;
|
|
70
79
|
}
|
|
71
80
|
|
|
81
|
+
VALUE rb_thrift_memory_buffer_read_all(VALUE self, VALUE length_value) {
|
|
82
|
+
long long length = NUM2LL(length_value);
|
|
83
|
+
|
|
84
|
+
if (RB_UNLIKELY(length < 0)) {
|
|
85
|
+
rb_exc_raise(rb_funcall(transport_exception_class, new_method_id, 2, transport_negative_size, rb_str_new2("Negative size")));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
VALUE index_value = rb_ivar_get(self, index_ivar_id);
|
|
89
|
+
long index = NUM2LONG(index_value);
|
|
90
|
+
VALUE buf = GET_BUF(self);
|
|
91
|
+
|
|
92
|
+
if (RB_UNLIKELY(length > RSTRING_LEN(buf) - index)) {
|
|
93
|
+
rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
VALUE data = rb_str_subseq(buf, index, (long)length);
|
|
97
|
+
|
|
98
|
+
index += (long)length;
|
|
99
|
+
if (index >= GARBAGE_BUFFER_SIZE) {
|
|
100
|
+
rb_ivar_set(self, buf_ivar_id, rb_str_subseq(buf, index, RSTRING_LEN(buf) - index));
|
|
101
|
+
index = 0;
|
|
102
|
+
}
|
|
103
|
+
rb_ivar_set(self, index_ivar_id, LONG2NUM(index));
|
|
104
|
+
|
|
105
|
+
return data;
|
|
106
|
+
}
|
|
107
|
+
|
|
72
108
|
VALUE rb_thrift_memory_buffer_read_byte(VALUE self) {
|
|
73
109
|
VALUE index_value = rb_ivar_get(self, index_ivar_id);
|
|
74
110
|
int index = FIX2INT(index_value);
|
|
@@ -77,7 +113,7 @@ VALUE rb_thrift_memory_buffer_read_byte(VALUE self) {
|
|
|
77
113
|
if (index >= RSTRING_LEN(buf)) {
|
|
78
114
|
rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer");
|
|
79
115
|
}
|
|
80
|
-
char byte = RSTRING_PTR(buf)[index++];
|
|
116
|
+
unsigned char byte = (unsigned char)RSTRING_PTR(buf)[index++];
|
|
81
117
|
|
|
82
118
|
if (index >= GARBAGE_BUFFER_SIZE) {
|
|
83
119
|
rb_ivar_set(self, buf_ivar_id, rb_funcall(buf, slice_method_id, 2, INT2FIX(index), INT2FIX(RSTRING_LEN(buf) - 1)));
|
|
@@ -85,8 +121,7 @@ VALUE rb_thrift_memory_buffer_read_byte(VALUE self) {
|
|
|
85
121
|
}
|
|
86
122
|
rb_ivar_set(self, index_ivar_id, INT2FIX(index));
|
|
87
123
|
|
|
88
|
-
|
|
89
|
-
return INT2FIX(result);
|
|
124
|
+
return INT2FIX(byte);
|
|
90
125
|
}
|
|
91
126
|
|
|
92
127
|
VALUE rb_thrift_memory_buffer_read_into_buffer(VALUE self, VALUE buffer_value, VALUE size_value) {
|
|
@@ -96,15 +131,29 @@ VALUE rb_thrift_memory_buffer_read_into_buffer(VALUE self, VALUE buffer_value, V
|
|
|
96
131
|
VALUE buf = GET_BUF(self);
|
|
97
132
|
|
|
98
133
|
index = FIX2INT(rb_ivar_get(self, index_ivar_id));
|
|
99
|
-
|
|
134
|
+
if (size > 0) {
|
|
100
135
|
if (index >= RSTRING_LEN(buf)) {
|
|
136
|
+
rb_ivar_set(self, index_ivar_id, INT2FIX(index));
|
|
101
137
|
rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer");
|
|
102
138
|
}
|
|
103
|
-
|
|
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
|
+
}
|
|
104
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
|
+
}
|
|
105
152
|
if (i >= RSTRING_LEN(buffer_value)) {
|
|
153
|
+
rb_ivar_set(self, index_ivar_id, INT2FIX(index));
|
|
106
154
|
rb_raise(rb_eIndexError, "index %d out of string", i);
|
|
107
155
|
}
|
|
156
|
+
char byte = RSTRING_PTR(buf)[index++];
|
|
108
157
|
((char*)RSTRING_PTR(buffer_value))[i] = byte;
|
|
109
158
|
i++;
|
|
110
159
|
}
|
|
@@ -122,6 +171,7 @@ void Init_memory_buffer(void) {
|
|
|
122
171
|
VALUE thrift_memory_buffer_class = rb_const_get(thrift_module, rb_intern("MemoryBufferTransport"));
|
|
123
172
|
rb_define_method(thrift_memory_buffer_class, "write", rb_thrift_memory_buffer_write, 1);
|
|
124
173
|
rb_define_method(thrift_memory_buffer_class, "read", rb_thrift_memory_buffer_read, 1);
|
|
174
|
+
rb_define_method(thrift_memory_buffer_class, "read_all", rb_thrift_memory_buffer_read_all, 1);
|
|
125
175
|
rb_define_method(thrift_memory_buffer_class, "read_byte", rb_thrift_memory_buffer_read_byte, 0);
|
|
126
176
|
rb_define_method(thrift_memory_buffer_class, "read_into_buffer", rb_thrift_memory_buffer_read_into_buffer, 2);
|
|
127
177
|
|
|
@@ -129,6 +179,11 @@ void Init_memory_buffer(void) {
|
|
|
129
179
|
index_ivar_id = rb_intern("@index");
|
|
130
180
|
|
|
131
181
|
slice_method_id = rb_intern("slice");
|
|
182
|
+
new_method_id = rb_intern("new");
|
|
132
183
|
|
|
133
184
|
GARBAGE_BUFFER_SIZE = FIX2INT(rb_const_get(thrift_memory_buffer_class, rb_intern("GARBAGE_BUFFER_SIZE")));
|
|
185
|
+
transport_exception_class = rb_const_get(thrift_module, rb_intern("TransportException"));
|
|
186
|
+
transport_negative_size = rb_const_get(transport_exception_class, rb_intern("NEGATIVE_SIZE"));
|
|
187
|
+
rb_global_variable(&transport_exception_class);
|
|
188
|
+
rb_global_variable(&transport_negative_size);
|
|
134
189
|
}
|
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,20 +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
|
|
39
|
-
if (
|
|
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
|
}
|
|
53
|
+
}
|
|
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
|
+
}
|
|
47
91
|
|
|
92
|
+
static VALUE new_container_array(int size) {
|
|
48
93
|
return rb_ary_new2(size > 1024 ? 1024 : size);
|
|
49
94
|
}
|
|
50
95
|
|
|
@@ -232,28 +277,28 @@ VALUE default_read_struct_end(VALUE protocol) {
|
|
|
232
277
|
|
|
233
278
|
// end default protocol methods
|
|
234
279
|
|
|
235
|
-
static VALUE
|
|
236
|
-
static VALUE
|
|
237
|
-
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);
|
|
238
283
|
|
|
239
|
-
|
|
284
|
+
static inline ID field_ivar_id(VALUE field_name) {
|
|
240
285
|
char name_buf[RSTRING_LEN(field_name) + 2];
|
|
241
286
|
|
|
242
287
|
name_buf[0] = '@';
|
|
243
288
|
strlcpy(&name_buf[1], RSTRING_PTR(field_name), RSTRING_LEN(field_name) + 1);
|
|
244
289
|
|
|
245
|
-
|
|
290
|
+
return rb_intern(name_buf);
|
|
291
|
+
}
|
|
246
292
|
|
|
247
|
-
|
|
293
|
+
VALUE get_field_value(VALUE obj, VALUE field_name) {
|
|
294
|
+
return rb_ivar_get(obj, field_ivar_id(field_name));
|
|
248
295
|
}
|
|
249
296
|
|
|
250
|
-
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) {
|
|
251
298
|
long sz, i;
|
|
252
299
|
|
|
253
300
|
if (ttype == TTYPE_MAP) {
|
|
254
301
|
VALUE keys;
|
|
255
|
-
VALUE key;
|
|
256
|
-
VALUE val;
|
|
257
302
|
|
|
258
303
|
Check_Type(value, T_HASH);
|
|
259
304
|
|
|
@@ -272,19 +317,19 @@ static void write_container(int ttype, VALUE field_info, VALUE value, VALUE prot
|
|
|
272
317
|
default_write_map_begin(protocol, keytype_value, valuetype_value, INT2FIX(sz));
|
|
273
318
|
|
|
274
319
|
for (i = 0; i < sz; i++) {
|
|
275
|
-
key = rb_ary_entry(keys, i);
|
|
276
|
-
val = rb_hash_aref(value, key);
|
|
320
|
+
VALUE key = rb_ary_entry(keys, i);
|
|
321
|
+
VALUE val = rb_hash_aref(value, key);
|
|
277
322
|
|
|
278
323
|
if (IS_CONTAINER(keytype)) {
|
|
279
|
-
write_container(keytype, key_info, key, protocol);
|
|
324
|
+
write_container(keytype, key_info, key, protocol, remaining_depth);
|
|
280
325
|
} else {
|
|
281
|
-
write_anything(keytype, key, protocol, key_info);
|
|
326
|
+
write_anything(keytype, key, protocol, key_info, remaining_depth);
|
|
282
327
|
}
|
|
283
328
|
|
|
284
329
|
if (IS_CONTAINER(valuetype)) {
|
|
285
|
-
write_container(valuetype, value_info, val, protocol);
|
|
330
|
+
write_container(valuetype, value_info, val, protocol, remaining_depth);
|
|
286
331
|
} else {
|
|
287
|
-
write_anything(valuetype, val, protocol, value_info);
|
|
332
|
+
write_anything(valuetype, val, protocol, value_info, remaining_depth);
|
|
288
333
|
}
|
|
289
334
|
}
|
|
290
335
|
|
|
@@ -302,9 +347,9 @@ static void write_container(int ttype, VALUE field_info, VALUE value, VALUE prot
|
|
|
302
347
|
for (i = 0; i < sz; ++i) {
|
|
303
348
|
VALUE val = rb_ary_entry(value, i);
|
|
304
349
|
if (IS_CONTAINER(element_type)) {
|
|
305
|
-
write_container(element_type, element_type_info, val, protocol);
|
|
350
|
+
write_container(element_type, element_type_info, val, protocol, remaining_depth);
|
|
306
351
|
} else {
|
|
307
|
-
write_anything(element_type, val, protocol, element_type_info);
|
|
352
|
+
write_anything(element_type, val, protocol, element_type_info, remaining_depth);
|
|
308
353
|
}
|
|
309
354
|
}
|
|
310
355
|
default_write_list_end(protocol);
|
|
@@ -314,7 +359,7 @@ static void write_container(int ttype, VALUE field_info, VALUE value, VALUE prot
|
|
|
314
359
|
if (TYPE(value) == T_ARRAY) {
|
|
315
360
|
items = value;
|
|
316
361
|
} else {
|
|
317
|
-
if (
|
|
362
|
+
if (rb_obj_is_kind_of(value, rb_cSet)) {
|
|
318
363
|
items = rb_funcall(value, entries_method_id, 0);
|
|
319
364
|
} else {
|
|
320
365
|
Check_Type(value, T_HASH);
|
|
@@ -333,9 +378,9 @@ static void write_container(int ttype, VALUE field_info, VALUE value, VALUE prot
|
|
|
333
378
|
for (i = 0; i < sz; i++) {
|
|
334
379
|
VALUE val = rb_ary_entry(items, i);
|
|
335
380
|
if (IS_CONTAINER(element_type)) {
|
|
336
|
-
write_container(element_type, element_type_info, val, protocol);
|
|
381
|
+
write_container(element_type, element_type_info, val, protocol, remaining_depth);
|
|
337
382
|
} else {
|
|
338
|
-
write_anything(element_type, val, protocol, element_type_info);
|
|
383
|
+
write_anything(element_type, val, protocol, element_type_info, remaining_depth);
|
|
339
384
|
}
|
|
340
385
|
}
|
|
341
386
|
|
|
@@ -345,7 +390,7 @@ static void write_container(int ttype, VALUE field_info, VALUE value, VALUE prot
|
|
|
345
390
|
}
|
|
346
391
|
}
|
|
347
392
|
|
|
348
|
-
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) {
|
|
349
394
|
if (ttype == TTYPE_BOOL) {
|
|
350
395
|
default_write_bool(protocol, value);
|
|
351
396
|
} else if (ttype == TTYPE_BYTE) {
|
|
@@ -368,19 +413,21 @@ static void write_anything(int ttype, VALUE value, VALUE protocol, VALUE field_i
|
|
|
368
413
|
} else if (ttype == TTYPE_UUID) {
|
|
369
414
|
default_write_uuid(protocol, value);
|
|
370
415
|
} else if (IS_CONTAINER(ttype)) {
|
|
371
|
-
write_container(ttype, field_info, value, protocol);
|
|
416
|
+
write_container(ttype, field_info, value, protocol, remaining_depth);
|
|
372
417
|
} else if (ttype == TTYPE_STRUCT) {
|
|
418
|
+
remaining_depth--;
|
|
419
|
+
validate_recursion_depth(remaining_depth);
|
|
373
420
|
if (rb_obj_is_kind_of(value, thrift_union_class)) {
|
|
374
|
-
|
|
421
|
+
rb_thrift_union_write_recursive(value, protocol, remaining_depth);
|
|
375
422
|
} else {
|
|
376
|
-
|
|
423
|
+
rb_thrift_struct_write_recursive(value, protocol, remaining_depth);
|
|
377
424
|
}
|
|
378
425
|
} else {
|
|
379
426
|
rb_raise(rb_eNotImpError, "Unknown type for binary_encoding: %d", ttype);
|
|
380
427
|
}
|
|
381
428
|
}
|
|
382
429
|
|
|
383
|
-
static VALUE
|
|
430
|
+
static VALUE rb_thrift_struct_write_recursive(VALUE self, VALUE protocol, int remaining_depth) {
|
|
384
431
|
// call validate
|
|
385
432
|
rb_funcall(self, validate_method_id, 0);
|
|
386
433
|
|
|
@@ -406,7 +453,7 @@ static VALUE rb_thrift_struct_write(VALUE self, VALUE protocol) {
|
|
|
406
453
|
if (!NIL_P(field_value)) {
|
|
407
454
|
default_write_field_begin(protocol, field_name, ttype_value, field_id);
|
|
408
455
|
|
|
409
|
-
write_anything(ttype, field_value, protocol, field_info);
|
|
456
|
+
write_anything(ttype, field_value, protocol, field_info, remaining_depth);
|
|
410
457
|
|
|
411
458
|
default_write_field_end(protocol);
|
|
412
459
|
}
|
|
@@ -420,22 +467,60 @@ static VALUE rb_thrift_struct_write(VALUE self, VALUE protocol) {
|
|
|
420
467
|
return Qnil;
|
|
421
468
|
}
|
|
422
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
|
+
|
|
423
477
|
//-------------------------------------------
|
|
424
478
|
// Reading section
|
|
425
479
|
//-------------------------------------------
|
|
426
480
|
|
|
427
|
-
static VALUE
|
|
428
|
-
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);
|
|
429
483
|
static void skip_map_contents(VALUE protocol, VALUE key_type_value, VALUE value_type_value, int size);
|
|
430
484
|
static void skip_list_or_set_contents(VALUE protocol, VALUE element_type_value, int size);
|
|
431
485
|
|
|
432
|
-
static void set_field_value(VALUE obj, VALUE field_name, VALUE value) {
|
|
433
|
-
|
|
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
|
+
}
|
|
434
489
|
|
|
435
|
-
|
|
436
|
-
|
|
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
|
+
}
|
|
437
494
|
|
|
438
|
-
|
|
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
|
+
}
|
|
522
|
+
|
|
523
|
+
return ST_CONTINUE;
|
|
439
524
|
}
|
|
440
525
|
|
|
441
526
|
// Helper method to skip the contents of a map (assumes the map header has been read).
|
|
@@ -455,7 +540,7 @@ static void skip_list_or_set_contents(VALUE protocol, VALUE element_type_value,
|
|
|
455
540
|
}
|
|
456
541
|
}
|
|
457
542
|
|
|
458
|
-
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) {
|
|
459
544
|
VALUE result = Qnil;
|
|
460
545
|
|
|
461
546
|
if (ttype == TTYPE_BOOL) {
|
|
@@ -482,23 +567,19 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
|
|
|
482
567
|
} else if (ttype == TTYPE_STRUCT) {
|
|
483
568
|
VALUE klass = rb_hash_aref(field_info, class_sym);
|
|
484
569
|
result = rb_class_new_instance(0, NULL, klass);
|
|
570
|
+
remaining_depth--;
|
|
571
|
+
validate_recursion_depth(remaining_depth);
|
|
485
572
|
|
|
486
573
|
if (rb_obj_is_kind_of(result, thrift_union_class)) {
|
|
487
|
-
|
|
574
|
+
rb_thrift_union_read_recursive(result, protocol, remaining_depth);
|
|
488
575
|
} else {
|
|
489
|
-
|
|
576
|
+
rb_thrift_struct_read_recursive(result, protocol, remaining_depth);
|
|
490
577
|
}
|
|
491
578
|
} else if (ttype == TTYPE_MAP) {
|
|
492
|
-
int i;
|
|
493
|
-
|
|
494
579
|
VALUE map_header = default_read_map_begin(protocol);
|
|
495
580
|
int key_ttype = FIX2INT(rb_ary_entry(map_header, 0));
|
|
496
581
|
int value_ttype = FIX2INT(rb_ary_entry(map_header, 1));
|
|
497
|
-
int num_entries =
|
|
498
|
-
|
|
499
|
-
if (num_entries < 0) {
|
|
500
|
-
rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_NEGATIVE_SIZE), rb_str_new2("Negative container size")));
|
|
501
|
-
}
|
|
582
|
+
int num_entries = container_size(protocol, rb_ary_entry(map_header, 2));
|
|
502
583
|
|
|
503
584
|
// Check the declared key and value types against the expected ones and skip the map contents
|
|
504
585
|
// if the types don't match.
|
|
@@ -511,11 +592,11 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
|
|
|
511
592
|
if (num_entries == 0 || (specified_key_type == key_ttype && specified_value_type == value_ttype)) {
|
|
512
593
|
result = rb_hash_new();
|
|
513
594
|
|
|
514
|
-
for (i = 0; i < num_entries; ++i) {
|
|
595
|
+
for (int i = 0; i < num_entries; ++i) {
|
|
515
596
|
VALUE key, val;
|
|
516
597
|
|
|
517
|
-
key = read_anything(protocol, key_ttype, key_info);
|
|
518
|
-
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);
|
|
519
600
|
|
|
520
601
|
rb_hash_aset(result, key, val);
|
|
521
602
|
}
|
|
@@ -528,11 +609,9 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
|
|
|
528
609
|
|
|
529
610
|
default_read_map_end(protocol);
|
|
530
611
|
} else if (ttype == TTYPE_LIST) {
|
|
531
|
-
int i;
|
|
532
|
-
|
|
533
612
|
VALUE list_header = default_read_list_begin(protocol);
|
|
534
613
|
int element_ttype = FIX2INT(rb_ary_entry(list_header, 0));
|
|
535
|
-
int num_elements =
|
|
614
|
+
int num_elements = container_size(protocol, rb_ary_entry(list_header, 1));
|
|
536
615
|
|
|
537
616
|
// Check the declared element type against the expected one and skip the list contents
|
|
538
617
|
// if the types don't match.
|
|
@@ -542,8 +621,8 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
|
|
|
542
621
|
if (specified_element_type == element_ttype) {
|
|
543
622
|
result = new_container_array(num_elements);
|
|
544
623
|
|
|
545
|
-
for (i = 0; i < num_elements; ++i) {
|
|
546
|
-
rb_ary_push(result, read_anything(protocol, element_ttype, rb_hash_aref(field_info, element_sym)));
|
|
624
|
+
for (int i = 0; i < num_elements; ++i) {
|
|
625
|
+
rb_ary_push(result, read_anything(protocol, element_ttype, rb_hash_aref(field_info, element_sym), remaining_depth));
|
|
547
626
|
}
|
|
548
627
|
} else {
|
|
549
628
|
skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements);
|
|
@@ -555,11 +634,10 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
|
|
|
555
634
|
default_read_list_end(protocol);
|
|
556
635
|
} else if (ttype == TTYPE_SET) {
|
|
557
636
|
VALUE items;
|
|
558
|
-
int i;
|
|
559
637
|
|
|
560
638
|
VALUE set_header = default_read_set_begin(protocol);
|
|
561
639
|
int element_ttype = FIX2INT(rb_ary_entry(set_header, 0));
|
|
562
|
-
int num_elements =
|
|
640
|
+
int num_elements = container_size(protocol, rb_ary_entry(set_header, 1));
|
|
563
641
|
|
|
564
642
|
// Check the declared element type against the expected one and skip the set contents
|
|
565
643
|
// if the types don't match.
|
|
@@ -569,8 +647,8 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
|
|
|
569
647
|
if (specified_element_type == element_ttype) {
|
|
570
648
|
items = new_container_array(num_elements);
|
|
571
649
|
|
|
572
|
-
for (i = 0; i < num_elements; ++i) {
|
|
573
|
-
rb_ary_push(items, read_anything(protocol, element_ttype, rb_hash_aref(field_info, element_sym)));
|
|
650
|
+
for (int i = 0; i < num_elements; ++i) {
|
|
651
|
+
rb_ary_push(items, read_anything(protocol, element_ttype, rb_hash_aref(field_info, element_sym), remaining_depth));
|
|
574
652
|
}
|
|
575
653
|
|
|
576
654
|
result = rb_class_new_instance(1, &items, rb_cSet);
|
|
@@ -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
|
}
|