thrift 0.22.0 → 0.24.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 +235 -17
- data/benchmark/benchmark.rb +23 -8
- data/benchmark/client.rb +50 -6
- data/benchmark/server.rb +46 -7
- data/benchmark/thin_server.rb +2 -0
- data/ext/binary_protocol_accelerated.c +154 -42
- data/ext/bytes.c +14 -0
- data/ext/compact_protocol.c +138 -45
- data/ext/constants.h +12 -0
- data/ext/extconf.rb +17 -8
- data/ext/memory_buffer.c +44 -7
- data/ext/protocol.c +29 -0
- data/ext/protocol.h +35 -0
- data/ext/struct.c +48 -17
- data/ext/thrift_native.c +28 -3
- data/lib/thrift/bytes.rb +70 -100
- data/lib/thrift/client.rb +54 -13
- data/lib/thrift/exceptions.rb +6 -5
- data/lib/thrift/multiplexed_processor.rb +20 -10
- data/lib/thrift/processor.rb +7 -6
- data/lib/thrift/protocol/base_protocol.rb +52 -21
- data/lib/thrift/protocol/binary_protocol.rb +65 -20
- data/lib/thrift/protocol/binary_protocol_accelerated.rb +6 -5
- data/lib/thrift/protocol/compact_protocol.rb +76 -41
- data/lib/thrift/protocol/header_protocol.rb +321 -0
- data/lib/thrift/protocol/json_protocol.rb +44 -27
- data/lib/thrift/protocol/multiplexed_protocol.rb +6 -5
- data/lib/thrift/protocol/protocol_decorator.rb +13 -4
- data/lib/thrift/serializer/deserializer.rb +6 -5
- data/lib/thrift/serializer/serializer.rb +5 -5
- data/lib/thrift/server/base_server.rb +5 -4
- data/lib/thrift/server/mongrel_http_server.rb +7 -6
- data/lib/thrift/server/nonblocking_server.rb +35 -9
- data/lib/thrift/server/simple_server.rb +13 -5
- data/lib/thrift/server/thin_http_server.rb +4 -3
- data/lib/thrift/server/thread_pool_server.rb +7 -6
- data/lib/thrift/server/threaded_server.rb +13 -5
- data/lib/thrift/struct.rb +12 -11
- data/lib/thrift/struct_union.rb +14 -9
- data/lib/thrift/thrift_native.rb +3 -2
- data/lib/thrift/transport/base_server_transport.rb +8 -5
- data/lib/thrift/transport/base_transport.rb +18 -14
- data/lib/thrift/transport/buffered_transport.rb +7 -6
- data/lib/thrift/transport/framed_transport.rb +8 -7
- data/lib/thrift/transport/header_transport.rb +562 -0
- data/lib/thrift/transport/http_client_transport.rb +2 -1
- data/lib/thrift/transport/io_stream_transport.rb +4 -3
- data/lib/thrift/transport/memory_buffer_transport.rb +13 -6
- data/lib/thrift/transport/server_socket.rb +14 -8
- data/lib/thrift/transport/socket.rb +126 -60
- data/lib/thrift/transport/ssl_server_socket.rb +4 -3
- data/lib/thrift/transport/ssl_socket.rb +45 -13
- data/lib/thrift/transport/unix_server_socket.rb +9 -5
- data/lib/thrift/transport/unix_socket.rb +7 -6
- data/lib/thrift/types.rb +10 -6
- data/lib/thrift/union.rb +15 -8
- data/lib/thrift/uuid.rb +50 -0
- data/lib/thrift.rb +4 -1
- data/spec/ThriftSpec.thrift +21 -1
- data/spec/base_protocol_spec.rb +21 -2
- data/spec/base_transport_spec.rb +48 -8
- data/spec/binary_protocol_accelerated_spec.rb +1 -0
- data/spec/binary_protocol_spec.rb +1 -2
- data/spec/binary_protocol_spec_shared.rb +206 -155
- data/spec/bytes_spec.rb +71 -114
- data/spec/client_spec.rb +86 -19
- data/spec/compact_protocol_spec.rb +153 -16
- data/spec/constants_demo_spec.rb +102 -0
- data/spec/exception_spec.rb +1 -1
- data/spec/flat_spec.rb +1 -0
- data/spec/header_protocol_spec.rb +476 -0
- data/spec/header_transport_spec.rb +431 -0
- data/spec/http_client_spec.rb +5 -6
- data/spec/json_protocol_spec.rb +69 -47
- data/spec/multiplexed_processor_spec.rb +75 -0
- data/spec/namespaced_spec.rb +1 -1
- data/spec/nonblocking_server_spec.rb +174 -8
- data/spec/processor_spec.rb +1 -1
- data/spec/recursion_depth_spec.rb +223 -0
- data/spec/serializer_spec.rb +1 -1
- data/spec/server_socket_spec.rb +38 -1
- data/spec/server_spec.rb +60 -9
- data/spec/socket_spec.rb +119 -13
- data/spec/socket_spec_shared.rb +73 -9
- data/spec/spec_helper.rb +2 -1
- data/spec/ssl_server_socket_spec.rb +52 -1
- data/spec/ssl_socket_spec.rb +181 -11
- data/spec/struct_nested_containers_spec.rb +2 -2
- data/spec/struct_spec.rb +114 -9
- data/spec/support/header_protocol_helper.rb +55 -0
- data/spec/thin_http_server_spec.rb +4 -18
- data/spec/types_spec.rb +26 -26
- data/spec/union_spec.rb +70 -11
- data/spec/unix_socket_spec.rb +17 -2
- data/spec/uuid_validation_spec.rb +239 -0
- data/test/fuzz/Makefile +779 -0
- data/test/fuzz/Makefile.am +173 -0
- data/test/fuzz/Makefile.in +775 -0
- data/test/fuzz/README.md +149 -0
- data/test/fuzz/fuzz_common.rb +96 -0
- data/{lib/thrift/core_ext.rb → test/fuzz/fuzz_parse_binary_protocol.rb} +4 -4
- data/{lib/thrift/core_ext/fixnum.rb → test/fuzz/fuzz_parse_binary_protocol_accelerated.rb} +7 -13
- data/test/fuzz/fuzz_parse_binary_protocol_accelerated_harness.rb +23 -0
- data/test/fuzz/fuzz_parse_binary_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_parse_compact_protocol.rb +23 -0
- data/test/fuzz/fuzz_parse_compact_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_parse_json_protocol.rb +23 -0
- data/test/fuzz/fuzz_parse_json_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_binary_protocol.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated_harness.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_binary_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_compact_protocol.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_compact_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_json_protocol.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_json_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_tracer.rb +29 -0
- metadata +105 -70
|
@@ -20,30 +20,77 @@
|
|
|
20
20
|
#include <ruby.h>
|
|
21
21
|
#include <stdbool.h>
|
|
22
22
|
#include <stdint.h>
|
|
23
|
+
#include <string.h>
|
|
23
24
|
#include <constants.h>
|
|
24
25
|
#include <struct.h>
|
|
25
26
|
#include <macros.h>
|
|
26
27
|
#include <bytes.h>
|
|
28
|
+
#include <protocol.h>
|
|
27
29
|
|
|
28
30
|
VALUE rb_thrift_binary_proto_native_qmark(VALUE self) {
|
|
29
31
|
return Qtrue;
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
34
|
static int VERSION_1;
|
|
35
35
|
static int VERSION_MASK;
|
|
36
36
|
static int TYPE_MASK;
|
|
37
|
-
static int BAD_VERSION;
|
|
38
37
|
static ID rbuf_ivar_id;
|
|
39
38
|
|
|
39
|
+
static int64_t checked_integer_value(VALUE value) {
|
|
40
|
+
if (!RB_INTEGER_TYPE_P(value)) {
|
|
41
|
+
rb_raise(rb_eTypeError, "integer argument expected");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return NUM2LL(value);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static int64_t checked_integer_range(VALUE value, int64_t min, int64_t max) {
|
|
48
|
+
int64_t integer = checked_integer_value(value);
|
|
49
|
+
|
|
50
|
+
if (integer < min || integer > max) {
|
|
51
|
+
rb_raise(rb_eRangeError, "integer out of bounds");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return integer;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static int8_t checked_byte_value(VALUE value) {
|
|
58
|
+
return (int8_t)checked_integer_range(value, INT8_MIN, INT8_MAX);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static int16_t checked_i16_value(VALUE value) {
|
|
62
|
+
return (int16_t)checked_integer_range(value, INT16_MIN, INT16_MAX);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static int32_t checked_i32_value(VALUE value) {
|
|
66
|
+
return (int32_t)checked_integer_range(value, INT32_MIN, INT32_MAX);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
static int32_t checked_size_value(VALUE value) {
|
|
70
|
+
return (int32_t)checked_integer_range(value, 0, INT32_MAX);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
static int64_t checked_i64_value(VALUE value) {
|
|
74
|
+
return checked_integer_range(value, INT64_MIN, INT64_MAX);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static int32_t checked_string_length(VALUE str) {
|
|
78
|
+
long length = RSTRING_LEN(str);
|
|
79
|
+
|
|
80
|
+
if (length > INT32_MAX) {
|
|
81
|
+
rb_raise(rb_eRangeError, "string too long");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return (int32_t)length;
|
|
85
|
+
}
|
|
86
|
+
|
|
40
87
|
static void write_byte_direct(VALUE trans, int8_t b) {
|
|
41
88
|
WRITE(trans, (char*)&b, 1);
|
|
42
89
|
}
|
|
43
90
|
|
|
44
91
|
static void write_i16_direct(VALUE trans, int16_t value) {
|
|
45
92
|
char data[2];
|
|
46
|
-
|
|
93
|
+
|
|
47
94
|
data[1] = value;
|
|
48
95
|
data[0] = (value >> 8);
|
|
49
96
|
|
|
@@ -82,7 +129,7 @@ static void write_string_direct(VALUE trans, VALUE str) {
|
|
|
82
129
|
rb_raise(rb_eStandardError, "Value should be a string");
|
|
83
130
|
}
|
|
84
131
|
str = convert_to_utf8_byte_buffer(str);
|
|
85
|
-
write_i32_direct(trans, (
|
|
132
|
+
write_i32_direct(trans, checked_string_length(str));
|
|
86
133
|
rb_funcall(trans, write_method_id, 1, str);
|
|
87
134
|
}
|
|
88
135
|
|
|
@@ -123,23 +170,24 @@ VALUE rb_thrift_binary_proto_write_message_begin(VALUE self, VALUE name, VALUE t
|
|
|
123
170
|
VALUE strict_write = GET_STRICT_WRITE(self);
|
|
124
171
|
|
|
125
172
|
if (strict_write == Qtrue) {
|
|
126
|
-
|
|
173
|
+
int8_t message_type = checked_byte_value(type);
|
|
174
|
+
write_i32_direct(trans, VERSION_1 | message_type);
|
|
127
175
|
write_string_direct(trans, name);
|
|
128
|
-
write_i32_direct(trans,
|
|
176
|
+
write_i32_direct(trans, checked_i32_value(seqid));
|
|
129
177
|
} else {
|
|
130
178
|
write_string_direct(trans, name);
|
|
131
|
-
write_byte_direct(trans,
|
|
132
|
-
write_i32_direct(trans,
|
|
179
|
+
write_byte_direct(trans, checked_byte_value(type));
|
|
180
|
+
write_i32_direct(trans, checked_i32_value(seqid));
|
|
133
181
|
}
|
|
134
|
-
|
|
182
|
+
|
|
135
183
|
return Qnil;
|
|
136
184
|
}
|
|
137
185
|
|
|
138
186
|
VALUE rb_thrift_binary_proto_write_field_begin(VALUE self, VALUE name, VALUE type, VALUE id) {
|
|
139
187
|
VALUE trans = GET_TRANSPORT(self);
|
|
140
|
-
write_byte_direct(trans,
|
|
141
|
-
write_i16_direct(trans,
|
|
142
|
-
|
|
188
|
+
write_byte_direct(trans, checked_byte_value(type));
|
|
189
|
+
write_i16_direct(trans, checked_i16_value(id));
|
|
190
|
+
|
|
143
191
|
return Qnil;
|
|
144
192
|
}
|
|
145
193
|
|
|
@@ -150,18 +198,18 @@ VALUE rb_thrift_binary_proto_write_field_stop(VALUE self) {
|
|
|
150
198
|
|
|
151
199
|
VALUE rb_thrift_binary_proto_write_map_begin(VALUE self, VALUE ktype, VALUE vtype, VALUE size) {
|
|
152
200
|
VALUE trans = GET_TRANSPORT(self);
|
|
153
|
-
write_byte_direct(trans,
|
|
154
|
-
write_byte_direct(trans,
|
|
155
|
-
write_i32_direct(trans,
|
|
156
|
-
|
|
201
|
+
write_byte_direct(trans, checked_byte_value(ktype));
|
|
202
|
+
write_byte_direct(trans, checked_byte_value(vtype));
|
|
203
|
+
write_i32_direct(trans, checked_size_value(size));
|
|
204
|
+
|
|
157
205
|
return Qnil;
|
|
158
206
|
}
|
|
159
207
|
|
|
160
208
|
VALUE rb_thrift_binary_proto_write_list_begin(VALUE self, VALUE etype, VALUE size) {
|
|
161
209
|
VALUE trans = GET_TRANSPORT(self);
|
|
162
|
-
write_byte_direct(trans,
|
|
163
|
-
write_i32_direct(trans,
|
|
164
|
-
|
|
210
|
+
write_byte_direct(trans, checked_byte_value(etype));
|
|
211
|
+
write_i32_direct(trans, checked_size_value(size));
|
|
212
|
+
|
|
165
213
|
return Qnil;
|
|
166
214
|
}
|
|
167
215
|
|
|
@@ -177,25 +225,25 @@ VALUE rb_thrift_binary_proto_write_bool(VALUE self, VALUE b) {
|
|
|
177
225
|
|
|
178
226
|
VALUE rb_thrift_binary_proto_write_byte(VALUE self, VALUE byte) {
|
|
179
227
|
CHECK_NIL(byte);
|
|
180
|
-
write_byte_direct(GET_TRANSPORT(self),
|
|
228
|
+
write_byte_direct(GET_TRANSPORT(self), checked_byte_value(byte));
|
|
181
229
|
return Qnil;
|
|
182
230
|
}
|
|
183
231
|
|
|
184
232
|
VALUE rb_thrift_binary_proto_write_i16(VALUE self, VALUE i16) {
|
|
185
233
|
CHECK_NIL(i16);
|
|
186
|
-
write_i16_direct(GET_TRANSPORT(self),
|
|
234
|
+
write_i16_direct(GET_TRANSPORT(self), checked_i16_value(i16));
|
|
187
235
|
return Qnil;
|
|
188
236
|
}
|
|
189
237
|
|
|
190
238
|
VALUE rb_thrift_binary_proto_write_i32(VALUE self, VALUE i32) {
|
|
191
239
|
CHECK_NIL(i32);
|
|
192
|
-
write_i32_direct(GET_TRANSPORT(self),
|
|
240
|
+
write_i32_direct(GET_TRANSPORT(self), checked_i32_value(i32));
|
|
193
241
|
return Qnil;
|
|
194
242
|
}
|
|
195
243
|
|
|
196
244
|
VALUE rb_thrift_binary_proto_write_i64(VALUE self, VALUE i64) {
|
|
197
245
|
CHECK_NIL(i64);
|
|
198
|
-
write_i64_direct(GET_TRANSPORT(self),
|
|
246
|
+
write_i64_direct(GET_TRANSPORT(self), checked_i64_value(i64));
|
|
199
247
|
return Qnil;
|
|
200
248
|
}
|
|
201
249
|
|
|
@@ -223,11 +271,51 @@ VALUE rb_thrift_binary_proto_write_binary(VALUE self, VALUE buf) {
|
|
|
223
271
|
CHECK_NIL(buf);
|
|
224
272
|
VALUE trans = GET_TRANSPORT(self);
|
|
225
273
|
buf = force_binary_encoding(buf);
|
|
226
|
-
write_i32_direct(trans, (
|
|
274
|
+
write_i32_direct(trans, checked_string_length(buf));
|
|
227
275
|
rb_funcall(trans, write_method_id, 1, buf);
|
|
228
276
|
return Qnil;
|
|
229
277
|
}
|
|
230
278
|
|
|
279
|
+
VALUE rb_thrift_binary_proto_write_uuid(VALUE self, VALUE uuid) {
|
|
280
|
+
if (NIL_P(uuid) || TYPE(uuid) != T_STRING) {
|
|
281
|
+
rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_INVALID_DATA), rb_str_new2("UUID must be a string")));
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
VALUE trans = GET_TRANSPORT(self);
|
|
285
|
+
char bytes[16];
|
|
286
|
+
const char* str = RSTRING_PTR(uuid);
|
|
287
|
+
long len = RSTRING_LEN(uuid);
|
|
288
|
+
|
|
289
|
+
// Parse UUID string (format: "550e8400-e29b-41d4-a716-446655440000")
|
|
290
|
+
// Expected length: 36 characters (32 hex + 4 hyphens)
|
|
291
|
+
if (len != 36 || str[8] != '-' || str[13] != '-' || str[18] != '-' || str[23] != '-') {
|
|
292
|
+
rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_INVALID_DATA), rb_str_new2("Invalid UUID format")));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Parse hex string to bytes using direct conversion, skipping hyphens
|
|
296
|
+
int byte_idx = 0;
|
|
297
|
+
for (int i = 0; i < len && byte_idx < 16; i++) {
|
|
298
|
+
if (str[i] == '-') continue;
|
|
299
|
+
if (i + 1 >= len || str[i + 1] == '-') break;
|
|
300
|
+
|
|
301
|
+
// Convert two hex characters to one byte
|
|
302
|
+
int high = hex_char_to_int(str[i]);
|
|
303
|
+
int low = hex_char_to_int(str[i + 1]);
|
|
304
|
+
|
|
305
|
+
if (high < 0 || low < 0) break;
|
|
306
|
+
|
|
307
|
+
bytes[byte_idx++] = (unsigned char)((high << 4) | low);
|
|
308
|
+
i++; // skip next char since we processed two
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (byte_idx != 16) {
|
|
312
|
+
rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_INVALID_DATA), rb_str_new2("Invalid UUID format")));
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
WRITE(trans, bytes, 16);
|
|
316
|
+
return Qnil;
|
|
317
|
+
}
|
|
318
|
+
|
|
231
319
|
//---------------------------------------
|
|
232
320
|
// interface reading methods
|
|
233
321
|
//---------------------------------------
|
|
@@ -272,13 +360,6 @@ static int64_t read_i64_direct(VALUE self) {
|
|
|
272
360
|
return (hi << 32) | lo;
|
|
273
361
|
}
|
|
274
362
|
|
|
275
|
-
static VALUE get_protocol_exception(VALUE code, VALUE message) {
|
|
276
|
-
VALUE args[2];
|
|
277
|
-
args[0] = code;
|
|
278
|
-
args[1] = message;
|
|
279
|
-
return rb_class_new_instance(2, (VALUE*)&args, protocol_exception_class);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
363
|
VALUE rb_thrift_binary_proto_read_message_end(VALUE self) {
|
|
283
364
|
return Qnil;
|
|
284
365
|
}
|
|
@@ -311,25 +392,25 @@ VALUE rb_thrift_binary_proto_read_message_begin(VALUE self) {
|
|
|
311
392
|
VALUE strict_read = GET_STRICT_READ(self);
|
|
312
393
|
VALUE name, seqid;
|
|
313
394
|
int type;
|
|
314
|
-
|
|
395
|
+
|
|
315
396
|
int version = read_i32_direct(self);
|
|
316
|
-
|
|
397
|
+
|
|
317
398
|
if (version < 0) {
|
|
318
399
|
if ((version & VERSION_MASK) != VERSION_1) {
|
|
319
|
-
rb_exc_raise(get_protocol_exception(INT2FIX(
|
|
400
|
+
rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_BAD_VERSION), rb_str_new2("Missing version identifier")));
|
|
320
401
|
}
|
|
321
402
|
type = version & TYPE_MASK;
|
|
322
403
|
name = rb_thrift_binary_proto_read_string(self);
|
|
323
404
|
seqid = rb_thrift_binary_proto_read_i32(self);
|
|
324
405
|
} else {
|
|
325
406
|
if (strict_read == Qtrue) {
|
|
326
|
-
rb_exc_raise(get_protocol_exception(INT2FIX(
|
|
407
|
+
rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_BAD_VERSION), rb_str_new2("No version identifier, old protocol client?")));
|
|
327
408
|
}
|
|
328
409
|
name = READ(self, version);
|
|
329
410
|
type = read_byte_direct(self);
|
|
330
411
|
seqid = rb_thrift_binary_proto_read_i32(self);
|
|
331
412
|
}
|
|
332
|
-
|
|
413
|
+
|
|
333
414
|
return rb_ary_new3(3, name, INT2FIX(type), seqid);
|
|
334
415
|
}
|
|
335
416
|
|
|
@@ -343,17 +424,24 @@ VALUE rb_thrift_binary_proto_read_field_begin(VALUE self) {
|
|
|
343
424
|
}
|
|
344
425
|
}
|
|
345
426
|
|
|
427
|
+
#define CHECK_NEGATIVE_SIZE(size) \
|
|
428
|
+
if (RB_UNLIKELY((size) < 0)) { \
|
|
429
|
+
rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_NEGATIVE_SIZE), rb_str_new2("Negative size"))); \
|
|
430
|
+
}
|
|
431
|
+
|
|
346
432
|
VALUE rb_thrift_binary_proto_read_map_begin(VALUE self) {
|
|
347
433
|
VALUE ktype = rb_thrift_binary_proto_read_byte(self);
|
|
348
434
|
VALUE vtype = rb_thrift_binary_proto_read_byte(self);
|
|
349
|
-
|
|
350
|
-
|
|
435
|
+
int size = read_i32_direct(self);
|
|
436
|
+
CHECK_NEGATIVE_SIZE(size);
|
|
437
|
+
return rb_ary_new3(3, ktype, vtype, INT2NUM(size));
|
|
351
438
|
}
|
|
352
439
|
|
|
353
440
|
VALUE rb_thrift_binary_proto_read_list_begin(VALUE self) {
|
|
354
441
|
VALUE etype = rb_thrift_binary_proto_read_byte(self);
|
|
355
|
-
|
|
356
|
-
|
|
442
|
+
int size = read_i32_direct(self);
|
|
443
|
+
CHECK_NEGATIVE_SIZE(size);
|
|
444
|
+
return rb_ary_new3(2, etype, INT2NUM(size));
|
|
357
445
|
}
|
|
358
446
|
|
|
359
447
|
VALUE rb_thrift_binary_proto_read_set_begin(VALUE self) {
|
|
@@ -397,10 +485,32 @@ VALUE rb_thrift_binary_proto_read_string(VALUE self) {
|
|
|
397
485
|
|
|
398
486
|
VALUE rb_thrift_binary_proto_read_binary(VALUE self) {
|
|
399
487
|
int size = read_i32_direct(self);
|
|
488
|
+
CHECK_NEGATIVE_SIZE(size);
|
|
400
489
|
return READ(self, size);
|
|
401
490
|
}
|
|
402
491
|
|
|
403
|
-
|
|
492
|
+
VALUE rb_thrift_binary_proto_read_uuid(VALUE self) {
|
|
493
|
+
VALUE data = READ(self, 16);
|
|
494
|
+
const unsigned char* bytes = (const unsigned char*)RSTRING_PTR(data);
|
|
495
|
+
|
|
496
|
+
// Format as UUID string: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
|
497
|
+
char uuid_str[37];
|
|
498
|
+
char* p = uuid_str;
|
|
499
|
+
|
|
500
|
+
for (int i = 0; i < 16; i++) {
|
|
501
|
+
*p++ = int_to_hex_char((bytes[i] >> 4) & 0x0F);
|
|
502
|
+
*p++ = int_to_hex_char(bytes[i] & 0x0F);
|
|
503
|
+
if (i == 3 || i == 5 || i == 7 || i == 9) {
|
|
504
|
+
*p++ = '-';
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
*p = '\0';
|
|
509
|
+
|
|
510
|
+
return rb_str_new(uuid_str, 36);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
void Init_binary_protocol_accelerated(void) {
|
|
404
514
|
VALUE thrift_binary_protocol_class = rb_const_get(thrift_module, rb_intern("BinaryProtocol"));
|
|
405
515
|
|
|
406
516
|
VERSION_1 = (int)rb_num2ll(rb_const_get(thrift_binary_protocol_class, rb_intern("VERSION_1")));
|
|
@@ -425,6 +535,7 @@ void Init_binary_protocol_accelerated() {
|
|
|
425
535
|
rb_define_method(bpa_class, "write_double", rb_thrift_binary_proto_write_double, 1);
|
|
426
536
|
rb_define_method(bpa_class, "write_string", rb_thrift_binary_proto_write_string, 1);
|
|
427
537
|
rb_define_method(bpa_class, "write_binary", rb_thrift_binary_proto_write_binary, 1);
|
|
538
|
+
rb_define_method(bpa_class, "write_uuid", rb_thrift_binary_proto_write_uuid, 1);
|
|
428
539
|
// unused methods
|
|
429
540
|
rb_define_method(bpa_class, "write_message_end", rb_thrift_binary_proto_write_message_end, 0);
|
|
430
541
|
rb_define_method(bpa_class, "write_struct_begin", rb_thrift_binary_proto_write_struct_begin, 1);
|
|
@@ -447,6 +558,7 @@ void Init_binary_protocol_accelerated() {
|
|
|
447
558
|
rb_define_method(bpa_class, "read_double", rb_thrift_binary_proto_read_double, 0);
|
|
448
559
|
rb_define_method(bpa_class, "read_string", rb_thrift_binary_proto_read_string, 0);
|
|
449
560
|
rb_define_method(bpa_class, "read_binary", rb_thrift_binary_proto_read_binary, 0);
|
|
561
|
+
rb_define_method(bpa_class, "read_uuid", rb_thrift_binary_proto_read_uuid, 0);
|
|
450
562
|
// unused methods
|
|
451
563
|
rb_define_method(bpa_class, "read_message_end", rb_thrift_binary_proto_read_message_end, 0);
|
|
452
564
|
rb_define_method(bpa_class, "read_struct_begin", rb_thrift_binary_proto_read_struct_begin, 0);
|
data/ext/bytes.c
CHANGED
|
@@ -24,6 +24,20 @@
|
|
|
24
24
|
#include <constants.h>
|
|
25
25
|
|
|
26
26
|
VALUE force_binary_encoding(VALUE buffer) {
|
|
27
|
+
if (RB_TYPE_P(buffer, T_STRING)) {
|
|
28
|
+
if (rb_enc_get_index(buffer) == rb_ascii8bit_encindex()) {
|
|
29
|
+
return buffer;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (RB_OBJ_FROZEN(buffer)) {
|
|
33
|
+
buffer = rb_obj_dup(buffer);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
rb_enc_associate_index(buffer, rb_ascii8bit_encindex());
|
|
37
|
+
|
|
38
|
+
return buffer;
|
|
39
|
+
}
|
|
40
|
+
|
|
27
41
|
return rb_funcall(thrift_bytes_module, force_binary_encoding_id, 1, buffer);
|
|
28
42
|
}
|
|
29
43
|
|