upfluence-thrift 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +43 -0
  3. data/benchmark/Benchmark.thrift +24 -0
  4. data/benchmark/benchmark.rb +271 -0
  5. data/benchmark/client.rb +74 -0
  6. data/benchmark/gen-rb/benchmark_constants.rb +11 -0
  7. data/benchmark/gen-rb/benchmark_service.rb +80 -0
  8. data/benchmark/gen-rb/benchmark_types.rb +10 -0
  9. data/benchmark/server.rb +82 -0
  10. data/benchmark/thin_server.rb +44 -0
  11. data/ext/binary_protocol_accelerated.c +460 -0
  12. data/ext/binary_protocol_accelerated.h +20 -0
  13. data/ext/bytes.c +36 -0
  14. data/ext/bytes.h +31 -0
  15. data/ext/compact_protocol.c +637 -0
  16. data/ext/compact_protocol.h +20 -0
  17. data/ext/constants.h +99 -0
  18. data/ext/extconf.rb +34 -0
  19. data/ext/macros.h +41 -0
  20. data/ext/memory_buffer.c +134 -0
  21. data/ext/memory_buffer.h +20 -0
  22. data/ext/protocol.c +0 -0
  23. data/ext/protocol.h +0 -0
  24. data/ext/strlcpy.c +41 -0
  25. data/ext/strlcpy.h +34 -0
  26. data/ext/struct.c +707 -0
  27. data/ext/struct.h +25 -0
  28. data/ext/thrift_native.c +201 -0
  29. data/lib/thrift.rb +68 -0
  30. data/lib/thrift/bytes.rb +131 -0
  31. data/lib/thrift/client.rb +71 -0
  32. data/lib/thrift/core_ext.rb +23 -0
  33. data/lib/thrift/core_ext/fixnum.rb +29 -0
  34. data/lib/thrift/exceptions.rb +87 -0
  35. data/lib/thrift/multiplexed_processor.rb +76 -0
  36. data/lib/thrift/processor.rb +57 -0
  37. data/lib/thrift/protocol/base_protocol.rb +379 -0
  38. data/lib/thrift/protocol/binary_protocol.rb +237 -0
  39. data/lib/thrift/protocol/binary_protocol_accelerated.rb +39 -0
  40. data/lib/thrift/protocol/compact_protocol.rb +435 -0
  41. data/lib/thrift/protocol/json_protocol.rb +769 -0
  42. data/lib/thrift/protocol/multiplexed_protocol.rb +40 -0
  43. data/lib/thrift/protocol/protocol_decorator.rb +194 -0
  44. data/lib/thrift/serializer/deserializer.rb +33 -0
  45. data/lib/thrift/serializer/serializer.rb +34 -0
  46. data/lib/thrift/server/base_server.rb +31 -0
  47. data/lib/thrift/server/mongrel_http_server.rb +60 -0
  48. data/lib/thrift/server/nonblocking_server.rb +305 -0
  49. data/lib/thrift/server/rack_application.rb +61 -0
  50. data/lib/thrift/server/simple_server.rb +43 -0
  51. data/lib/thrift/server/thin_http_server.rb +51 -0
  52. data/lib/thrift/server/thread_pool_server.rb +75 -0
  53. data/lib/thrift/server/threaded_server.rb +47 -0
  54. data/lib/thrift/struct.rb +237 -0
  55. data/lib/thrift/struct_union.rb +192 -0
  56. data/lib/thrift/thrift_native.rb +24 -0
  57. data/lib/thrift/transport/base_server_transport.rb +37 -0
  58. data/lib/thrift/transport/base_transport.rb +109 -0
  59. data/lib/thrift/transport/buffered_transport.rb +114 -0
  60. data/lib/thrift/transport/framed_transport.rb +117 -0
  61. data/lib/thrift/transport/http_client_transport.rb +56 -0
  62. data/lib/thrift/transport/io_stream_transport.rb +39 -0
  63. data/lib/thrift/transport/memory_buffer_transport.rb +125 -0
  64. data/lib/thrift/transport/server_socket.rb +63 -0
  65. data/lib/thrift/transport/socket.rb +139 -0
  66. data/lib/thrift/transport/unix_server_socket.rb +60 -0
  67. data/lib/thrift/transport/unix_socket.rb +40 -0
  68. data/lib/thrift/types.rb +101 -0
  69. data/lib/thrift/union.rb +179 -0
  70. data/spec/BaseService.thrift +27 -0
  71. data/spec/ExtendedService.thrift +25 -0
  72. data/spec/Referenced.thrift +44 -0
  73. data/spec/ThriftNamespacedSpec.thrift +53 -0
  74. data/spec/ThriftSpec.thrift +183 -0
  75. data/spec/base_protocol_spec.rb +217 -0
  76. data/spec/base_transport_spec.rb +350 -0
  77. data/spec/binary_protocol_accelerated_spec.rb +42 -0
  78. data/spec/binary_protocol_spec.rb +66 -0
  79. data/spec/binary_protocol_spec_shared.rb +455 -0
  80. data/spec/bytes_spec.rb +160 -0
  81. data/spec/client_spec.rb +99 -0
  82. data/spec/compact_protocol_spec.rb +143 -0
  83. data/spec/exception_spec.rb +141 -0
  84. data/spec/flat_spec.rb +62 -0
  85. data/spec/gen-rb/base/base_service.rb +80 -0
  86. data/spec/gen-rb/base/base_service_constants.rb +11 -0
  87. data/spec/gen-rb/base/base_service_types.rb +26 -0
  88. data/spec/gen-rb/extended/extended_service.rb +78 -0
  89. data/spec/gen-rb/extended/extended_service_constants.rb +11 -0
  90. data/spec/gen-rb/extended/extended_service_types.rb +12 -0
  91. data/spec/gen-rb/flat/namespaced_nonblocking_service.rb +272 -0
  92. data/spec/gen-rb/flat/referenced_constants.rb +11 -0
  93. data/spec/gen-rb/flat/referenced_types.rb +17 -0
  94. data/spec/gen-rb/flat/thrift_namespaced_spec_constants.rb +11 -0
  95. data/spec/gen-rb/flat/thrift_namespaced_spec_types.rb +28 -0
  96. data/spec/gen-rb/namespaced_spec_namespace/namespaced_nonblocking_service.rb +272 -0
  97. data/spec/gen-rb/namespaced_spec_namespace/thrift_namespaced_spec_constants.rb +11 -0
  98. data/spec/gen-rb/namespaced_spec_namespace/thrift_namespaced_spec_types.rb +28 -0
  99. data/spec/gen-rb/nonblocking_service.rb +272 -0
  100. data/spec/gen-rb/other_namespace/referenced_constants.rb +11 -0
  101. data/spec/gen-rb/other_namespace/referenced_types.rb +17 -0
  102. data/spec/gen-rb/thrift_spec_constants.rb +11 -0
  103. data/spec/gen-rb/thrift_spec_types.rb +538 -0
  104. data/spec/http_client_spec.rb +120 -0
  105. data/spec/json_protocol_spec.rb +513 -0
  106. data/spec/namespaced_spec.rb +67 -0
  107. data/spec/nonblocking_server_spec.rb +263 -0
  108. data/spec/processor_spec.rb +80 -0
  109. data/spec/serializer_spec.rb +67 -0
  110. data/spec/server_socket_spec.rb +79 -0
  111. data/spec/server_spec.rb +147 -0
  112. data/spec/socket_spec.rb +61 -0
  113. data/spec/socket_spec_shared.rb +104 -0
  114. data/spec/spec_helper.rb +64 -0
  115. data/spec/struct_nested_containers_spec.rb +191 -0
  116. data/spec/struct_spec.rb +293 -0
  117. data/spec/thin_http_server_spec.rb +141 -0
  118. data/spec/types_spec.rb +115 -0
  119. data/spec/union_spec.rb +203 -0
  120. data/spec/unix_socket_spec.rb +107 -0
  121. data/test/debug_proto/gen-rb/debug_proto_test_constants.rb +274 -0
  122. data/test/debug_proto/gen-rb/debug_proto_test_types.rb +761 -0
  123. data/test/debug_proto/gen-rb/empty_service.rb +24 -0
  124. data/test/debug_proto/gen-rb/inherited.rb +79 -0
  125. data/test/debug_proto/gen-rb/reverse_order_service.rb +82 -0
  126. data/test/debug_proto/gen-rb/service_for_exception_with_a_map.rb +81 -0
  127. data/test/debug_proto/gen-rb/srv.rb +330 -0
  128. metadata +388 -0
@@ -0,0 +1,20 @@
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+
20
+ void Init_compact_protocol();
@@ -0,0 +1,99 @@
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+
20
+ extern int TTYPE_STOP;
21
+ extern int TTYPE_BOOL;
22
+ extern int TTYPE_BYTE;
23
+ extern int TTYPE_I16;
24
+ extern int TTYPE_I32;
25
+ extern int TTYPE_I64;
26
+ extern int TTYPE_DOUBLE;
27
+ extern int TTYPE_STRING;
28
+ extern int TTYPE_MAP;
29
+ extern int TTYPE_SET;
30
+ extern int TTYPE_LIST;
31
+ extern int TTYPE_STRUCT;
32
+
33
+ extern ID validate_method_id;
34
+ extern ID write_struct_begin_method_id;
35
+ extern ID write_struct_end_method_id;
36
+ extern ID write_field_begin_method_id;
37
+ extern ID write_field_end_method_id;
38
+ extern ID write_boolean_method_id;
39
+ extern ID write_byte_method_id;
40
+ extern ID write_i16_method_id;
41
+ extern ID write_i32_method_id;
42
+ extern ID write_i64_method_id;
43
+ extern ID write_double_method_id;
44
+ extern ID write_string_method_id;
45
+ extern ID write_binary_method_id;
46
+ extern ID write_map_begin_method_id;
47
+ extern ID write_map_end_method_id;
48
+ extern ID write_list_begin_method_id;
49
+ extern ID write_list_end_method_id;
50
+ extern ID write_set_begin_method_id;
51
+ extern ID write_set_end_method_id;
52
+ extern ID read_bool_method_id;
53
+ extern ID read_byte_method_id;
54
+ extern ID read_i16_method_id;
55
+ extern ID read_i32_method_id;
56
+ extern ID read_i64_method_id;
57
+ extern ID read_string_method_id;
58
+ extern ID read_binary_method_id;
59
+ extern ID read_double_method_id;
60
+ extern ID read_map_begin_method_id;
61
+ extern ID read_map_end_method_id;
62
+ extern ID read_list_begin_method_id;
63
+ extern ID read_list_end_method_id;
64
+ extern ID read_set_begin_method_id;
65
+ extern ID read_set_end_method_id;
66
+ extern ID read_struct_begin_method_id;
67
+ extern ID read_struct_end_method_id;
68
+ extern ID read_field_begin_method_id;
69
+ extern ID read_field_end_method_id;
70
+ extern ID keys_method_id;
71
+ extern ID entries_method_id;
72
+ extern ID write_field_stop_method_id;
73
+ extern ID skip_method_id;
74
+ extern ID write_method_id;
75
+ extern ID read_all_method_id;
76
+ extern ID read_into_buffer_method_id;
77
+ extern ID force_binary_encoding_id;
78
+ extern ID convert_to_utf8_byte_buffer_id;
79
+ extern ID convert_to_string_id;
80
+
81
+ extern ID fields_const_id;
82
+ extern ID transport_ivar_id;
83
+ extern ID strict_read_ivar_id;
84
+ extern ID strict_write_ivar_id;
85
+
86
+ extern VALUE type_sym;
87
+ extern VALUE name_sym;
88
+ extern VALUE key_sym;
89
+ extern VALUE value_sym;
90
+ extern VALUE element_sym;
91
+ extern VALUE class_sym;
92
+ extern VALUE binary_sym;
93
+
94
+ extern VALUE rb_cSet;
95
+ extern VALUE thrift_module;
96
+ extern VALUE thrift_types_module;
97
+ extern VALUE thrift_bytes_module;
98
+ extern VALUE class_thrift_protocol;
99
+ extern VALUE protocol_exception_class;
@@ -0,0 +1,34 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one
3
+ # or more contributor license agreements. See the NOTICE file
4
+ # distributed with this work for additional information
5
+ # regarding copyright ownership. The ASF licenses this file
6
+ # to you under the Apache License, Version 2.0 (the
7
+ # "License"); you may not use this file except in compliance
8
+ # with the License. You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing,
13
+ # software distributed under the License is distributed on an
14
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ # KIND, either express or implied. See the License for the
16
+ # specific language governing permissions and limitations
17
+ # under the License.
18
+ #
19
+
20
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /jruby/
21
+ File.open('Makefile', 'w'){|f| f.puts "all:\n\ninstall:\n" }
22
+ else
23
+ require 'mkmf'
24
+ require 'rbconfig'
25
+
26
+ $ARCH_FLAGS = RbConfig::CONFIG['CFLAGS'].scan( /(-arch )(\S+)/ ).map{|x,y| x + y + ' ' }.join('')
27
+
28
+
29
+ $CFLAGS = "-fsigned-char -g -O2 -Wall -Werror " + $ARCH_FLAGS
30
+
31
+ have_func("strlcpy", "string.h")
32
+
33
+ create_makefile 'thrift_native'
34
+ end
@@ -0,0 +1,41 @@
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+
20
+ #define GET_TRANSPORT(obj) rb_ivar_get(obj, transport_ivar_id)
21
+ #define GET_STRICT_READ(obj) rb_ivar_get(obj, strict_read_ivar_id)
22
+ #define GET_STRICT_WRITE(obj) rb_ivar_get(obj, strict_write_ivar_id)
23
+ #define WRITE(obj, data, length) rb_funcall(obj, write_method_id, 1, rb_str_new(data, length))
24
+ #define CHECK_NIL(obj) if (NIL_P(obj)) { rb_raise(rb_eStandardError, "nil argument not allowed!");}
25
+ #define READ(obj, length) rb_funcall(GET_TRANSPORT(obj), read_all_method_id, 1, INT2FIX(length))
26
+
27
+ #ifndef RFLOAT_VALUE
28
+ # define RFLOAT_VALUE(v) RFLOAT(rb_Float(v))->value
29
+ #endif
30
+
31
+ #ifndef RSTRING_LEN
32
+ # define RSTRING_LEN(v) RSTRING(rb_String(v))->len
33
+ #endif
34
+
35
+ #ifndef RSTRING_PTR
36
+ # define RSTRING_PTR(v) RSTRING(rb_String(v))->ptr
37
+ #endif
38
+
39
+ #ifndef RARRAY_LEN
40
+ # define RARRAY_LEN(v) RARRAY(rb_Array(v))->len
41
+ #endif
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+
20
+ #include <ruby.h>
21
+ #include <constants.h>
22
+ #include <bytes.h>
23
+ #include <macros.h>
24
+
25
+ ID buf_ivar_id;
26
+ ID index_ivar_id;
27
+
28
+ ID slice_method_id;
29
+
30
+ int GARBAGE_BUFFER_SIZE;
31
+
32
+ #define GET_BUF(self) rb_ivar_get(self, buf_ivar_id)
33
+
34
+ VALUE rb_thrift_memory_buffer_write(VALUE self, VALUE str);
35
+ VALUE rb_thrift_memory_buffer_read(VALUE self, VALUE length_value);
36
+ VALUE rb_thrift_memory_buffer_read_byte(VALUE self);
37
+ VALUE rb_thrift_memory_buffer_read_into_buffer(VALUE self, VALUE buffer_value, VALUE size_value);
38
+
39
+ VALUE rb_thrift_memory_buffer_write(VALUE self, VALUE str) {
40
+ VALUE buf = GET_BUF(self);
41
+ str = force_binary_encoding(str);
42
+ rb_str_buf_cat(buf, StringValuePtr(str), RSTRING_LEN(str));
43
+ return Qnil;
44
+ }
45
+
46
+ VALUE rb_thrift_memory_buffer_read(VALUE self, VALUE length_value) {
47
+ int length = FIX2INT(length_value);
48
+
49
+ VALUE index_value = rb_ivar_get(self, index_ivar_id);
50
+ int index = FIX2INT(index_value);
51
+
52
+ VALUE buf = GET_BUF(self);
53
+ VALUE data = rb_funcall(buf, slice_method_id, 2, index_value, length_value);
54
+
55
+ index += length;
56
+ if (index > RSTRING_LEN(buf)) {
57
+ index = RSTRING_LEN(buf);
58
+ }
59
+ if (index >= GARBAGE_BUFFER_SIZE) {
60
+ rb_ivar_set(self, buf_ivar_id, rb_funcall(buf, slice_method_id, 2, INT2FIX(index), INT2FIX(RSTRING_LEN(buf) - 1)));
61
+ index = 0;
62
+ }
63
+ rb_ivar_set(self, index_ivar_id, INT2FIX(index));
64
+
65
+ if (RSTRING_LEN(data) < length) {
66
+ rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer");
67
+ }
68
+
69
+ return data;
70
+ }
71
+
72
+ VALUE rb_thrift_memory_buffer_read_byte(VALUE self) {
73
+ VALUE index_value = rb_ivar_get(self, index_ivar_id);
74
+ int index = FIX2INT(index_value);
75
+
76
+ VALUE buf = GET_BUF(self);
77
+ if (index >= RSTRING_LEN(buf)) {
78
+ rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer");
79
+ }
80
+ char byte = RSTRING_PTR(buf)[index++];
81
+
82
+ if (index >= GARBAGE_BUFFER_SIZE) {
83
+ rb_ivar_set(self, buf_ivar_id, rb_funcall(buf, slice_method_id, 2, INT2FIX(index), INT2FIX(RSTRING_LEN(buf) - 1)));
84
+ index = 0;
85
+ }
86
+ rb_ivar_set(self, index_ivar_id, INT2FIX(index));
87
+
88
+ int result = (int) byte;
89
+ return INT2FIX(result);
90
+ }
91
+
92
+ VALUE rb_thrift_memory_buffer_read_into_buffer(VALUE self, VALUE buffer_value, VALUE size_value) {
93
+ int i = 0;
94
+ int size = FIX2INT(size_value);
95
+ int index;
96
+ VALUE buf = GET_BUF(self);
97
+
98
+ index = FIX2INT(rb_ivar_get(self, index_ivar_id));
99
+ while (i < size) {
100
+ if (index >= RSTRING_LEN(buf)) {
101
+ rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer");
102
+ }
103
+ char byte = RSTRING_PTR(buf)[index++];
104
+
105
+ if (i >= RSTRING_LEN(buffer_value)) {
106
+ rb_raise(rb_eIndexError, "index %d out of string", i);
107
+ }
108
+ ((char*)RSTRING_PTR(buffer_value))[i] = byte;
109
+ i++;
110
+ }
111
+
112
+ if (index >= GARBAGE_BUFFER_SIZE) {
113
+ rb_ivar_set(self, buf_ivar_id, rb_funcall(buf, slice_method_id, 2, INT2FIX(index), INT2FIX(RSTRING_LEN(buf) - 1)));
114
+ index = 0;
115
+ }
116
+ rb_ivar_set(self, index_ivar_id, INT2FIX(index));
117
+
118
+ return INT2FIX(i);
119
+ }
120
+
121
+ void Init_memory_buffer() {
122
+ VALUE thrift_memory_buffer_class = rb_const_get(thrift_module, rb_intern("MemoryBufferTransport"));
123
+ rb_define_method(thrift_memory_buffer_class, "write", rb_thrift_memory_buffer_write, 1);
124
+ rb_define_method(thrift_memory_buffer_class, "read", rb_thrift_memory_buffer_read, 1);
125
+ rb_define_method(thrift_memory_buffer_class, "read_byte", rb_thrift_memory_buffer_read_byte, 0);
126
+ rb_define_method(thrift_memory_buffer_class, "read_into_buffer", rb_thrift_memory_buffer_read_into_buffer, 2);
127
+
128
+ buf_ivar_id = rb_intern("@buf");
129
+ index_ivar_id = rb_intern("@index");
130
+
131
+ slice_method_id = rb_intern("slice");
132
+
133
+ GARBAGE_BUFFER_SIZE = FIX2INT(rb_const_get(thrift_memory_buffer_class, rb_intern("GARBAGE_BUFFER_SIZE")));
134
+ }
@@ -0,0 +1,20 @@
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+
20
+ void Init_memory_buffer();
File without changes
File without changes
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+
20
+ #include "strlcpy.h"
21
+
22
+ #ifndef HAVE_STRLCPY
23
+ #define HAVE_STRLCPY
24
+ size_t
25
+ strlcpy (char *dst, const char *src, size_t dst_sz)
26
+ {
27
+ size_t n;
28
+
29
+ for (n = 0; n < dst_sz; n++) {
30
+ if ((*dst++ = *src++) == '\0')
31
+ break;
32
+ }
33
+
34
+ if (n < dst_sz)
35
+ return n;
36
+ if (n > 0)
37
+ *(dst - 1) = '\0';
38
+ return n + strlen (src);
39
+ }
40
+ #endif
41
+
@@ -0,0 +1,34 @@
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+
20
+ #include <sys/types.h>
21
+ #include <string.h>
22
+
23
+ #ifndef __has_builtin
24
+ #define __has_builtin(x) 0
25
+ #endif
26
+
27
+ #ifndef HAVE_STRLCPY
28
+ size_t strlcpy (char *dst, const char *src, size_t dst_sz);
29
+ #else
30
+ #if !__has_builtin(strlcpy)
31
+ extern size_t strlcpy(char *, const char *, size_t);
32
+ #endif
33
+ #endif
34
+
@@ -0,0 +1,707 @@
1
+ /**
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+
20
+ #include "struct.h"
21
+ #include "constants.h"
22
+ #include "macros.h"
23
+ #include "strlcpy.h"
24
+
25
+ VALUE thrift_union_class;
26
+
27
+ ID setfield_id;
28
+ ID setvalue_id;
29
+
30
+ ID to_s_method_id;
31
+ ID name_to_id_method_id;
32
+ static ID sorted_field_ids_method_id;
33
+
34
+ #define IS_CONTAINER(ttype) ((ttype) == TTYPE_MAP || (ttype) == TTYPE_LIST || (ttype) == TTYPE_SET)
35
+ #define STRUCT_FIELDS(obj) rb_const_get(CLASS_OF(obj), fields_const_id)
36
+
37
+ //-------------------------------------------
38
+ // Writing section
39
+ //-------------------------------------------
40
+
41
+ // default fn pointers for protocol stuff here
42
+
43
+ VALUE default_write_bool(VALUE protocol, VALUE value) {
44
+ rb_funcall(protocol, write_boolean_method_id, 1, value);
45
+ return Qnil;
46
+ }
47
+
48
+ VALUE default_write_byte(VALUE protocol, VALUE value) {
49
+ rb_funcall(protocol, write_byte_method_id, 1, value);
50
+ return Qnil;
51
+ }
52
+
53
+ VALUE default_write_i16(VALUE protocol, VALUE value) {
54
+ rb_funcall(protocol, write_i16_method_id, 1, value);
55
+ return Qnil;
56
+ }
57
+
58
+ VALUE default_write_i32(VALUE protocol, VALUE value) {
59
+ rb_funcall(protocol, write_i32_method_id, 1, value);
60
+ return Qnil;
61
+ }
62
+
63
+ VALUE default_write_i64(VALUE protocol, VALUE value) {
64
+ rb_funcall(protocol, write_i64_method_id, 1, value);
65
+ return Qnil;
66
+ }
67
+
68
+ VALUE default_write_double(VALUE protocol, VALUE value) {
69
+ rb_funcall(protocol, write_double_method_id, 1, value);
70
+ return Qnil;
71
+ }
72
+
73
+ VALUE default_write_string(VALUE protocol, VALUE value) {
74
+ rb_funcall(protocol, write_string_method_id, 1, value);
75
+ return Qnil;
76
+ }
77
+
78
+ VALUE default_write_binary(VALUE protocol, VALUE value) {
79
+ rb_funcall(protocol, write_binary_method_id, 1, value);
80
+ return Qnil;
81
+ }
82
+
83
+ VALUE default_write_list_begin(VALUE protocol, VALUE etype, VALUE length) {
84
+ rb_funcall(protocol, write_list_begin_method_id, 2, etype, length);
85
+ return Qnil;
86
+ }
87
+
88
+ VALUE default_write_list_end(VALUE protocol) {
89
+ rb_funcall(protocol, write_list_end_method_id, 0);
90
+ return Qnil;
91
+ }
92
+
93
+ VALUE default_write_set_begin(VALUE protocol, VALUE etype, VALUE length) {
94
+ rb_funcall(protocol, write_set_begin_method_id, 2, etype, length);
95
+ return Qnil;
96
+ }
97
+
98
+ VALUE default_write_set_end(VALUE protocol) {
99
+ rb_funcall(protocol, write_set_end_method_id, 0);
100
+ return Qnil;
101
+ }
102
+
103
+ VALUE default_write_map_begin(VALUE protocol, VALUE ktype, VALUE vtype, VALUE length) {
104
+ rb_funcall(protocol, write_map_begin_method_id, 3, ktype, vtype, length);
105
+ return Qnil;
106
+ }
107
+
108
+ VALUE default_write_map_end(VALUE protocol) {
109
+ rb_funcall(protocol, write_map_end_method_id, 0);
110
+ return Qnil;
111
+ }
112
+
113
+ VALUE default_write_struct_begin(VALUE protocol, VALUE struct_name) {
114
+ rb_funcall(protocol, write_struct_begin_method_id, 1, struct_name);
115
+ return Qnil;
116
+ }
117
+
118
+ VALUE default_write_struct_end(VALUE protocol) {
119
+ rb_funcall(protocol, write_struct_end_method_id, 0);
120
+ return Qnil;
121
+ }
122
+
123
+ VALUE default_write_field_begin(VALUE protocol, VALUE name, VALUE type, VALUE id) {
124
+ rb_funcall(protocol, write_field_begin_method_id, 3, name, type, id);
125
+ return Qnil;
126
+ }
127
+
128
+ VALUE default_write_field_end(VALUE protocol) {
129
+ rb_funcall(protocol, write_field_end_method_id, 0);
130
+ return Qnil;
131
+ }
132
+
133
+ VALUE default_write_field_stop(VALUE protocol) {
134
+ rb_funcall(protocol, write_field_stop_method_id, 0);
135
+ return Qnil;
136
+ }
137
+
138
+ VALUE default_read_field_begin(VALUE protocol) {
139
+ return rb_funcall(protocol, read_field_begin_method_id, 0);
140
+ }
141
+
142
+ VALUE default_read_field_end(VALUE protocol) {
143
+ return rb_funcall(protocol, read_field_end_method_id, 0);
144
+ }
145
+
146
+ VALUE default_read_map_begin(VALUE protocol) {
147
+ return rb_funcall(protocol, read_map_begin_method_id, 0);
148
+ }
149
+
150
+ VALUE default_read_map_end(VALUE protocol) {
151
+ return rb_funcall(protocol, read_map_end_method_id, 0);
152
+ }
153
+
154
+ VALUE default_read_list_begin(VALUE protocol) {
155
+ return rb_funcall(protocol, read_list_begin_method_id, 0);
156
+ }
157
+
158
+ VALUE default_read_list_end(VALUE protocol) {
159
+ return rb_funcall(protocol, read_list_end_method_id, 0);
160
+ }
161
+
162
+ VALUE default_read_set_begin(VALUE protocol) {
163
+ return rb_funcall(protocol, read_set_begin_method_id, 0);
164
+ }
165
+
166
+ VALUE default_read_set_end(VALUE protocol) {
167
+ return rb_funcall(protocol, read_set_end_method_id, 0);
168
+ }
169
+
170
+ VALUE default_read_byte(VALUE protocol) {
171
+ return rb_funcall(protocol, read_byte_method_id, 0);
172
+ }
173
+
174
+ VALUE default_read_bool(VALUE protocol) {
175
+ return rb_funcall(protocol, read_bool_method_id, 0);
176
+ }
177
+
178
+ VALUE default_read_i16(VALUE protocol) {
179
+ return rb_funcall(protocol, read_i16_method_id, 0);
180
+ }
181
+
182
+ VALUE default_read_i32(VALUE protocol) {
183
+ return rb_funcall(protocol, read_i32_method_id, 0);
184
+ }
185
+
186
+ VALUE default_read_i64(VALUE protocol) {
187
+ return rb_funcall(protocol, read_i64_method_id, 0);
188
+ }
189
+
190
+ VALUE default_read_double(VALUE protocol) {
191
+ return rb_funcall(protocol, read_double_method_id, 0);
192
+ }
193
+
194
+ VALUE default_read_string(VALUE protocol) {
195
+ return rb_funcall(protocol, read_string_method_id, 0);
196
+ }
197
+
198
+ VALUE default_read_binary(VALUE protocol) {
199
+ return rb_funcall(protocol, read_binary_method_id, 0);
200
+ }
201
+
202
+ VALUE default_read_struct_begin(VALUE protocol) {
203
+ return rb_funcall(protocol, read_struct_begin_method_id, 0);
204
+ }
205
+
206
+ VALUE default_read_struct_end(VALUE protocol) {
207
+ return rb_funcall(protocol, read_struct_end_method_id, 0);
208
+ }
209
+
210
+ // end default protocol methods
211
+
212
+ static VALUE rb_thrift_union_write (VALUE self, VALUE protocol);
213
+ static VALUE rb_thrift_struct_write(VALUE self, VALUE protocol);
214
+ static void write_anything(int ttype, VALUE value, VALUE protocol, VALUE field_info);
215
+
216
+ VALUE get_field_value(VALUE obj, VALUE field_name) {
217
+ char name_buf[RSTRING_LEN(field_name) + 2];
218
+
219
+ name_buf[0] = '@';
220
+ strlcpy(&name_buf[1], RSTRING_PTR(field_name), RSTRING_LEN(field_name) + 1);
221
+
222
+ VALUE value = rb_ivar_get(obj, rb_intern(name_buf));
223
+
224
+ return value;
225
+ }
226
+
227
+ static void write_container(int ttype, VALUE field_info, VALUE value, VALUE protocol) {
228
+ int sz, i;
229
+
230
+ if (ttype == TTYPE_MAP) {
231
+ VALUE keys;
232
+ VALUE key;
233
+ VALUE val;
234
+
235
+ Check_Type(value, T_HASH);
236
+
237
+ VALUE key_info = rb_hash_aref(field_info, key_sym);
238
+ VALUE keytype_value = rb_hash_aref(key_info, type_sym);
239
+ int keytype = FIX2INT(keytype_value);
240
+
241
+ VALUE value_info = rb_hash_aref(field_info, value_sym);
242
+ VALUE valuetype_value = rb_hash_aref(value_info, type_sym);
243
+ int valuetype = FIX2INT(valuetype_value);
244
+
245
+ keys = rb_funcall(value, keys_method_id, 0);
246
+
247
+ sz = RARRAY_LEN(keys);
248
+
249
+ default_write_map_begin(protocol, keytype_value, valuetype_value, INT2FIX(sz));
250
+
251
+ for (i = 0; i < sz; i++) {
252
+ key = rb_ary_entry(keys, i);
253
+ val = rb_hash_aref(value, key);
254
+
255
+ if (IS_CONTAINER(keytype)) {
256
+ write_container(keytype, key_info, key, protocol);
257
+ } else {
258
+ write_anything(keytype, key, protocol, key_info);
259
+ }
260
+
261
+ if (IS_CONTAINER(valuetype)) {
262
+ write_container(valuetype, value_info, val, protocol);
263
+ } else {
264
+ write_anything(valuetype, val, protocol, value_info);
265
+ }
266
+ }
267
+
268
+ default_write_map_end(protocol);
269
+ } else if (ttype == TTYPE_LIST) {
270
+ Check_Type(value, T_ARRAY);
271
+
272
+ sz = RARRAY_LEN(value);
273
+
274
+ VALUE element_type_info = rb_hash_aref(field_info, element_sym);
275
+ VALUE element_type_value = rb_hash_aref(element_type_info, type_sym);
276
+ int element_type = FIX2INT(element_type_value);
277
+
278
+ default_write_list_begin(protocol, element_type_value, INT2FIX(sz));
279
+ for (i = 0; i < sz; ++i) {
280
+ VALUE val = rb_ary_entry(value, i);
281
+ if (IS_CONTAINER(element_type)) {
282
+ write_container(element_type, element_type_info, val, protocol);
283
+ } else {
284
+ write_anything(element_type, val, protocol, element_type_info);
285
+ }
286
+ }
287
+ default_write_list_end(protocol);
288
+ } else if (ttype == TTYPE_SET) {
289
+ VALUE items;
290
+
291
+ if (TYPE(value) == T_ARRAY) {
292
+ items = value;
293
+ } else {
294
+ if (rb_cSet == CLASS_OF(value)) {
295
+ items = rb_funcall(value, entries_method_id, 0);
296
+ } else {
297
+ Check_Type(value, T_HASH);
298
+ items = rb_funcall(value, keys_method_id, 0);
299
+ }
300
+ }
301
+
302
+ sz = RARRAY_LEN(items);
303
+
304
+ VALUE element_type_info = rb_hash_aref(field_info, element_sym);
305
+ VALUE element_type_value = rb_hash_aref(element_type_info, type_sym);
306
+ int element_type = FIX2INT(element_type_value);
307
+
308
+ default_write_set_begin(protocol, element_type_value, INT2FIX(sz));
309
+
310
+ for (i = 0; i < sz; i++) {
311
+ VALUE val = rb_ary_entry(items, i);
312
+ if (IS_CONTAINER(element_type)) {
313
+ write_container(element_type, element_type_info, val, protocol);
314
+ } else {
315
+ write_anything(element_type, val, protocol, element_type_info);
316
+ }
317
+ }
318
+
319
+ default_write_set_end(protocol);
320
+ } else {
321
+ rb_raise(rb_eNotImpError, "can't write container of type: %d", ttype);
322
+ }
323
+ }
324
+
325
+ static void write_anything(int ttype, VALUE value, VALUE protocol, VALUE field_info) {
326
+ if (ttype == TTYPE_BOOL) {
327
+ default_write_bool(protocol, value);
328
+ } else if (ttype == TTYPE_BYTE) {
329
+ default_write_byte(protocol, value);
330
+ } else if (ttype == TTYPE_I16) {
331
+ default_write_i16(protocol, value);
332
+ } else if (ttype == TTYPE_I32) {
333
+ default_write_i32(protocol, value);
334
+ } else if (ttype == TTYPE_I64) {
335
+ default_write_i64(protocol, value);
336
+ } else if (ttype == TTYPE_DOUBLE) {
337
+ default_write_double(protocol, value);
338
+ } else if (ttype == TTYPE_STRING) {
339
+ VALUE is_binary = rb_hash_aref(field_info, binary_sym);
340
+ if (is_binary != Qtrue) {
341
+ default_write_string(protocol, value);
342
+ } else {
343
+ default_write_binary(protocol, value);
344
+ }
345
+ } else if (IS_CONTAINER(ttype)) {
346
+ write_container(ttype, field_info, value, protocol);
347
+ } else if (ttype == TTYPE_STRUCT) {
348
+ if (rb_obj_is_kind_of(value, thrift_union_class)) {
349
+ rb_thrift_union_write(value, protocol);
350
+ } else {
351
+ rb_thrift_struct_write(value, protocol);
352
+ }
353
+ } else {
354
+ rb_raise(rb_eNotImpError, "Unknown type for binary_encoding: %d", ttype);
355
+ }
356
+ }
357
+
358
+ static VALUE rb_thrift_struct_write(VALUE self, VALUE protocol) {
359
+ // call validate
360
+ rb_funcall(self, validate_method_id, 0);
361
+
362
+ // write struct begin
363
+ default_write_struct_begin(protocol, rb_class_name(CLASS_OF(self)));
364
+
365
+ // iterate through all the fields here
366
+ VALUE struct_fields = STRUCT_FIELDS(self);
367
+ VALUE sorted_field_ids = rb_funcall(self, sorted_field_ids_method_id, 0);
368
+
369
+ int i = 0;
370
+ for (i=0; i < RARRAY_LEN(sorted_field_ids); i++) {
371
+ VALUE field_id = rb_ary_entry(sorted_field_ids, i);
372
+
373
+ VALUE field_info = rb_hash_aref(struct_fields, field_id);
374
+
375
+ VALUE ttype_value = rb_hash_aref(field_info, type_sym);
376
+ int ttype = FIX2INT(ttype_value);
377
+ VALUE field_name = rb_hash_aref(field_info, name_sym);
378
+
379
+ VALUE field_value = get_field_value(self, field_name);
380
+
381
+ if (!NIL_P(field_value)) {
382
+ default_write_field_begin(protocol, field_name, ttype_value, field_id);
383
+
384
+ write_anything(ttype, field_value, protocol, field_info);
385
+
386
+ default_write_field_end(protocol);
387
+ }
388
+ }
389
+
390
+ default_write_field_stop(protocol);
391
+
392
+ // write struct end
393
+ default_write_struct_end(protocol);
394
+
395
+ return Qnil;
396
+ }
397
+
398
+ //-------------------------------------------
399
+ // Reading section
400
+ //-------------------------------------------
401
+
402
+ static VALUE rb_thrift_union_read(VALUE self, VALUE protocol);
403
+ static VALUE rb_thrift_struct_read(VALUE self, VALUE protocol);
404
+ static void skip_map_contents(VALUE protocol, VALUE key_type_value, VALUE value_type_value, int size);
405
+ static void skip_list_or_set_contents(VALUE protocol, VALUE element_type_value, int size);
406
+
407
+ static void set_field_value(VALUE obj, VALUE field_name, VALUE value) {
408
+ char name_buf[RSTRING_LEN(field_name) + 2];
409
+
410
+ name_buf[0] = '@';
411
+ strlcpy(&name_buf[1], RSTRING_PTR(field_name), RSTRING_LEN(field_name)+1);
412
+
413
+ rb_ivar_set(obj, rb_intern(name_buf), value);
414
+ }
415
+
416
+ // Helper method to skip the contents of a map (assumes the map header has been read).
417
+ static void skip_map_contents(VALUE protocol, VALUE key_type_value, VALUE value_type_value, int size) {
418
+ int i;
419
+ for (i = 0; i < size; i++) {
420
+ rb_funcall(protocol, skip_method_id, 1, key_type_value);
421
+ rb_funcall(protocol, skip_method_id, 1, value_type_value);
422
+ }
423
+ }
424
+
425
+ // Helper method to skip the contents of a list or set (assumes the list/set header has been read).
426
+ static void skip_list_or_set_contents(VALUE protocol, VALUE element_type_value, int size) {
427
+ int i;
428
+ for (i = 0; i < size; i++) {
429
+ rb_funcall(protocol, skip_method_id, 1, element_type_value);
430
+ }
431
+ }
432
+
433
+ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
434
+ VALUE result = Qnil;
435
+
436
+ if (ttype == TTYPE_BOOL) {
437
+ result = default_read_bool(protocol);
438
+ } else if (ttype == TTYPE_BYTE) {
439
+ result = default_read_byte(protocol);
440
+ } else if (ttype == TTYPE_I16) {
441
+ result = default_read_i16(protocol);
442
+ } else if (ttype == TTYPE_I32) {
443
+ result = default_read_i32(protocol);
444
+ } else if (ttype == TTYPE_I64) {
445
+ result = default_read_i64(protocol);
446
+ } else if (ttype == TTYPE_STRING) {
447
+ VALUE is_binary = rb_hash_aref(field_info, binary_sym);
448
+ if (is_binary != Qtrue) {
449
+ result = default_read_string(protocol);
450
+ } else {
451
+ result = default_read_binary(protocol);
452
+ }
453
+ } else if (ttype == TTYPE_DOUBLE) {
454
+ result = default_read_double(protocol);
455
+ } else if (ttype == TTYPE_STRUCT) {
456
+ VALUE klass = rb_hash_aref(field_info, class_sym);
457
+ result = rb_class_new_instance(0, NULL, klass);
458
+
459
+ if (rb_obj_is_kind_of(result, thrift_union_class)) {
460
+ rb_thrift_union_read(result, protocol);
461
+ } else {
462
+ rb_thrift_struct_read(result, protocol);
463
+ }
464
+ } else if (ttype == TTYPE_MAP) {
465
+ int i;
466
+
467
+ VALUE map_header = default_read_map_begin(protocol);
468
+ int key_ttype = FIX2INT(rb_ary_entry(map_header, 0));
469
+ int value_ttype = FIX2INT(rb_ary_entry(map_header, 1));
470
+ int num_entries = FIX2INT(rb_ary_entry(map_header, 2));
471
+
472
+ // Check the declared key and value types against the expected ones and skip the map contents
473
+ // if the types don't match.
474
+ VALUE key_info = rb_hash_aref(field_info, key_sym);
475
+ VALUE value_info = rb_hash_aref(field_info, value_sym);
476
+
477
+ if (!NIL_P(key_info) && !NIL_P(value_info)) {
478
+ int specified_key_type = FIX2INT(rb_hash_aref(key_info, type_sym));
479
+ int specified_value_type = FIX2INT(rb_hash_aref(value_info, type_sym));
480
+ if (num_entries == 0 || (specified_key_type == key_ttype && specified_value_type == value_ttype)) {
481
+ result = rb_hash_new();
482
+
483
+ for (i = 0; i < num_entries; ++i) {
484
+ VALUE key, val;
485
+
486
+ key = read_anything(protocol, key_ttype, key_info);
487
+ val = read_anything(protocol, value_ttype, value_info);
488
+
489
+ rb_hash_aset(result, key, val);
490
+ }
491
+ } else {
492
+ skip_map_contents(protocol, INT2FIX(key_ttype), INT2FIX(value_ttype), num_entries);
493
+ }
494
+ } else {
495
+ skip_map_contents(protocol, INT2FIX(key_ttype), INT2FIX(value_ttype), num_entries);
496
+ }
497
+
498
+ default_read_map_end(protocol);
499
+ } else if (ttype == TTYPE_LIST) {
500
+ int i;
501
+
502
+ VALUE list_header = default_read_list_begin(protocol);
503
+ int element_ttype = FIX2INT(rb_ary_entry(list_header, 0));
504
+ int num_elements = FIX2INT(rb_ary_entry(list_header, 1));
505
+
506
+ // Check the declared element type against the expected one and skip the list contents
507
+ // if the types don't match.
508
+ VALUE element_info = rb_hash_aref(field_info, element_sym);
509
+ if (!NIL_P(element_info)) {
510
+ int specified_element_type = FIX2INT(rb_hash_aref(element_info, type_sym));
511
+ if (specified_element_type == element_ttype) {
512
+ result = rb_ary_new2(num_elements);
513
+
514
+ for (i = 0; i < num_elements; ++i) {
515
+ rb_ary_push(result, read_anything(protocol, element_ttype, rb_hash_aref(field_info, element_sym)));
516
+ }
517
+ } else {
518
+ skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements);
519
+ }
520
+ } else {
521
+ skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements);
522
+ }
523
+
524
+ default_read_list_end(protocol);
525
+ } else if (ttype == TTYPE_SET) {
526
+ VALUE items;
527
+ int i;
528
+
529
+ VALUE set_header = default_read_set_begin(protocol);
530
+ int element_ttype = FIX2INT(rb_ary_entry(set_header, 0));
531
+ int num_elements = FIX2INT(rb_ary_entry(set_header, 1));
532
+
533
+ // Check the declared element type against the expected one and skip the set contents
534
+ // if the types don't match.
535
+ VALUE element_info = rb_hash_aref(field_info, element_sym);
536
+ if (!NIL_P(element_info)) {
537
+ int specified_element_type = FIX2INT(rb_hash_aref(element_info, type_sym));
538
+ if (specified_element_type == element_ttype) {
539
+ items = rb_ary_new2(num_elements);
540
+
541
+ for (i = 0; i < num_elements; ++i) {
542
+ rb_ary_push(items, read_anything(protocol, element_ttype, rb_hash_aref(field_info, element_sym)));
543
+ }
544
+
545
+ result = rb_class_new_instance(1, &items, rb_cSet);
546
+ } else {
547
+ skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements);
548
+ }
549
+ } else {
550
+ skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements);
551
+ }
552
+
553
+ default_read_set_end(protocol);
554
+ } else {
555
+ rb_raise(rb_eNotImpError, "read_anything not implemented for type %d!", ttype);
556
+ }
557
+
558
+ return result;
559
+ }
560
+
561
+ static VALUE rb_thrift_struct_read(VALUE self, VALUE protocol) {
562
+ // read struct begin
563
+ default_read_struct_begin(protocol);
564
+
565
+ VALUE struct_fields = STRUCT_FIELDS(self);
566
+
567
+ // read each field
568
+ while (true) {
569
+ VALUE field_header = default_read_field_begin(protocol);
570
+ VALUE field_type_value = rb_ary_entry(field_header, 1);
571
+ int field_type = FIX2INT(field_type_value);
572
+
573
+ if (field_type == TTYPE_STOP) {
574
+ break;
575
+ }
576
+
577
+ // make sure we got a type we expected
578
+ VALUE field_info = rb_hash_aref(struct_fields, rb_ary_entry(field_header, 2));
579
+
580
+ if (!NIL_P(field_info)) {
581
+ int specified_type = FIX2INT(rb_hash_aref(field_info, type_sym));
582
+ if (field_type == specified_type) {
583
+ // read the value
584
+ VALUE name = rb_hash_aref(field_info, name_sym);
585
+ set_field_value(self, name, read_anything(protocol, field_type, field_info));
586
+ } else {
587
+ rb_funcall(protocol, skip_method_id, 1, field_type_value);
588
+ }
589
+ } else {
590
+ rb_funcall(protocol, skip_method_id, 1, field_type_value);
591
+ }
592
+
593
+ // read field end
594
+ default_read_field_end(protocol);
595
+ }
596
+
597
+ // read struct end
598
+ default_read_struct_end(protocol);
599
+
600
+ // call validate
601
+ rb_funcall(self, validate_method_id, 0);
602
+
603
+ return Qnil;
604
+ }
605
+
606
+
607
+ // --------------------------------
608
+ // Union section
609
+ // --------------------------------
610
+
611
+ static VALUE rb_thrift_union_read(VALUE self, VALUE protocol) {
612
+ // read struct begin
613
+ default_read_struct_begin(protocol);
614
+
615
+ VALUE struct_fields = STRUCT_FIELDS(self);
616
+
617
+ VALUE field_header = default_read_field_begin(protocol);
618
+ VALUE field_type_value = rb_ary_entry(field_header, 1);
619
+ int field_type = FIX2INT(field_type_value);
620
+
621
+ // make sure we got a type we expected
622
+ VALUE field_info = rb_hash_aref(struct_fields, rb_ary_entry(field_header, 2));
623
+
624
+ if (!NIL_P(field_info)) {
625
+ int specified_type = FIX2INT(rb_hash_aref(field_info, type_sym));
626
+ if (field_type == specified_type) {
627
+ // read the value
628
+ VALUE name = rb_hash_aref(field_info, name_sym);
629
+ rb_iv_set(self, "@setfield", rb_str_intern(name));
630
+ rb_iv_set(self, "@value", read_anything(protocol, field_type, field_info));
631
+ } else {
632
+ rb_funcall(protocol, skip_method_id, 1, field_type_value);
633
+ }
634
+ } else {
635
+ rb_funcall(protocol, skip_method_id, 1, field_type_value);
636
+ }
637
+
638
+ // read field end
639
+ default_read_field_end(protocol);
640
+
641
+ field_header = default_read_field_begin(protocol);
642
+ field_type_value = rb_ary_entry(field_header, 1);
643
+ field_type = FIX2INT(field_type_value);
644
+
645
+ if (field_type != TTYPE_STOP) {
646
+ rb_raise(rb_eRuntimeError, "too many fields in union!");
647
+ }
648
+
649
+ // read struct end
650
+ default_read_struct_end(protocol);
651
+
652
+ // call validate
653
+ rb_funcall(self, validate_method_id, 0);
654
+
655
+ return Qnil;
656
+ }
657
+
658
+ static VALUE rb_thrift_union_write(VALUE self, VALUE protocol) {
659
+ // call validate
660
+ rb_funcall(self, validate_method_id, 0);
661
+
662
+ // write struct begin
663
+ default_write_struct_begin(protocol, rb_class_name(CLASS_OF(self)));
664
+
665
+ VALUE struct_fields = STRUCT_FIELDS(self);
666
+
667
+ VALUE setfield = rb_ivar_get(self, setfield_id);
668
+ VALUE setvalue = rb_ivar_get(self, setvalue_id);
669
+ VALUE field_id = rb_funcall(self, name_to_id_method_id, 1, rb_funcall(setfield, to_s_method_id, 0));
670
+
671
+ VALUE field_info = rb_hash_aref(struct_fields, field_id);
672
+
673
+ VALUE ttype_value = rb_hash_aref(field_info, type_sym);
674
+ int ttype = FIX2INT(ttype_value);
675
+
676
+ default_write_field_begin(protocol, setfield, ttype_value, field_id);
677
+
678
+ write_anything(ttype, setvalue, protocol, field_info);
679
+
680
+ default_write_field_end(protocol);
681
+
682
+ default_write_field_stop(protocol);
683
+
684
+ // write struct end
685
+ default_write_struct_end(protocol);
686
+
687
+ return Qnil;
688
+ }
689
+
690
+ void Init_struct() {
691
+ VALUE struct_module = rb_const_get(thrift_module, rb_intern("Struct"));
692
+
693
+ rb_define_method(struct_module, "write", rb_thrift_struct_write, 1);
694
+ rb_define_method(struct_module, "read", rb_thrift_struct_read, 1);
695
+
696
+ thrift_union_class = rb_const_get(thrift_module, rb_intern("Union"));
697
+
698
+ rb_define_method(thrift_union_class, "write", rb_thrift_union_write, 1);
699
+ rb_define_method(thrift_union_class, "read", rb_thrift_union_read, 1);
700
+
701
+ setfield_id = rb_intern("@setfield");
702
+ setvalue_id = rb_intern("@value");
703
+
704
+ to_s_method_id = rb_intern("to_s");
705
+ name_to_id_method_id = rb_intern("name_to_id");
706
+ sorted_field_ids_method_id = rb_intern("sorted_field_ids");
707
+ }