upfluence-thrift 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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,192 @@
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
+ require 'set'
20
+
21
+ module Thrift
22
+ module Struct_Union
23
+ def name_to_id(name)
24
+ names_to_ids = self.class.instance_variable_get(:@names_to_ids)
25
+ unless names_to_ids
26
+ names_to_ids = {}
27
+ struct_fields.each do |fid, field_def|
28
+ names_to_ids[field_def[:name]] = fid
29
+ end
30
+ self.class.instance_variable_set(:@names_to_ids, names_to_ids)
31
+ end
32
+ names_to_ids[name]
33
+ end
34
+
35
+ def sorted_field_ids
36
+ sorted_field_ids = self.class.instance_variable_get(:@sorted_field_ids)
37
+ unless sorted_field_ids
38
+ sorted_field_ids = struct_fields.keys.sort
39
+ self.class.instance_variable_set(:@sorted_field_ids, sorted_field_ids)
40
+ end
41
+ sorted_field_ids
42
+ end
43
+
44
+ def each_field
45
+ sorted_field_ids.each do |fid|
46
+ data = struct_fields[fid]
47
+ yield fid, data
48
+ end
49
+ end
50
+
51
+ def read_field(iprot, field = {})
52
+ case field[:type]
53
+ when Types::STRUCT
54
+ value = field[:class].new
55
+ value.read(iprot)
56
+ when Types::MAP
57
+ key_type, val_type, size = iprot.read_map_begin
58
+ # Skip the map contents if the declared key or value types don't match the expected ones.
59
+ if (size != 0 && (key_type != field[:key][:type] || val_type != field[:value][:type]))
60
+ size.times do
61
+ iprot.skip(key_type)
62
+ iprot.skip(val_type)
63
+ end
64
+ value = nil
65
+ else
66
+ value = {}
67
+ size.times do
68
+ k = read_field(iprot, field_info(field[:key]))
69
+ v = read_field(iprot, field_info(field[:value]))
70
+ value[k] = v
71
+ end
72
+ end
73
+ iprot.read_map_end
74
+ when Types::LIST
75
+ e_type, size = iprot.read_list_begin
76
+ # Skip the list contents if the declared element type doesn't match the expected one.
77
+ if (e_type != field[:element][:type])
78
+ size.times do
79
+ iprot.skip(e_type)
80
+ end
81
+ value = nil
82
+ else
83
+ value = Array.new(size) do |n|
84
+ read_field(iprot, field_info(field[:element]))
85
+ end
86
+ end
87
+ iprot.read_list_end
88
+ when Types::SET
89
+ e_type, size = iprot.read_set_begin
90
+ # Skip the set contents if the declared element type doesn't match the expected one.
91
+ if (e_type != field[:element][:type])
92
+ size.times do
93
+ iprot.skip(e_type)
94
+ end
95
+ else
96
+ value = Set.new
97
+ size.times do
98
+ element = read_field(iprot, field_info(field[:element]))
99
+ value << element
100
+ end
101
+ end
102
+ iprot.read_set_end
103
+ else
104
+ value = iprot.read_type(field)
105
+ end
106
+ value
107
+ end
108
+
109
+ def write_data(oprot, value, field)
110
+ if is_container? field[:type]
111
+ write_container(oprot, value, field)
112
+ else
113
+ oprot.write_type(field, value)
114
+ end
115
+ end
116
+
117
+ def write_container(oprot, value, field = {})
118
+ case field[:type]
119
+ when Types::MAP
120
+ oprot.write_map_begin(field[:key][:type], field[:value][:type], value.size)
121
+ value.each do |k, v|
122
+ write_data(oprot, k, field[:key])
123
+ write_data(oprot, v, field[:value])
124
+ end
125
+ oprot.write_map_end
126
+ when Types::LIST
127
+ oprot.write_list_begin(field[:element][:type], value.size)
128
+ value.each do |elem|
129
+ write_data(oprot, elem, field[:element])
130
+ end
131
+ oprot.write_list_end
132
+ when Types::SET
133
+ oprot.write_set_begin(field[:element][:type], value.size)
134
+ value.each do |v,| # the , is to preserve compatibility with the old Hash-style sets
135
+ write_data(oprot, v, field[:element])
136
+ end
137
+ oprot.write_set_end
138
+ else
139
+ raise "Not a container type: #{field[:type]}"
140
+ end
141
+ end
142
+
143
+ CONTAINER_TYPES = []
144
+ CONTAINER_TYPES[Types::LIST] = true
145
+ CONTAINER_TYPES[Types::MAP] = true
146
+ CONTAINER_TYPES[Types::SET] = true
147
+ def is_container?(type)
148
+ CONTAINER_TYPES[type]
149
+ end
150
+
151
+ def field_info(field)
152
+ { :type => field[:type],
153
+ :class => field[:class],
154
+ :key => field[:key],
155
+ :value => field[:value],
156
+ :element => field[:element] }
157
+ end
158
+
159
+ def inspect_field(value, field_info)
160
+ if enum_class = field_info[:enum_class]
161
+ "#{enum_class.const_get(:VALUE_MAP)[value]} (#{value})"
162
+ elsif value.is_a? Hash
163
+ if field_info[:type] == Types::MAP
164
+ map_buf = []
165
+ value.each do |k, v|
166
+ map_buf << inspect_field(k, field_info[:key]) + ": " + inspect_field(v, field_info[:value])
167
+ end
168
+ "{" + map_buf.join(", ") + "}"
169
+ else
170
+ # old-style set
171
+ inspect_collection(value.keys, field_info)
172
+ end
173
+ elsif value.is_a? Array
174
+ inspect_collection(value, field_info)
175
+ elsif value.is_a? Set
176
+ inspect_collection(value, field_info)
177
+ elsif value.is_a?(String) && field_info[:binary]
178
+ value.unpack("H*").first
179
+ else
180
+ value.inspect
181
+ end
182
+ end
183
+
184
+ def inspect_collection(collection, field_info)
185
+ buf = []
186
+ collection.each do |k|
187
+ buf << inspect_field(k, field_info[:element])
188
+ end
189
+ "[" + buf.join(", ") + "]"
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,24 @@
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
+ begin
21
+ require "thrift_native"
22
+ rescue LoadError
23
+ puts "Unable to load thrift_native extension. Defaulting to pure Ruby libraries."
24
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: ascii-8bit
2
+ #
3
+ # Licensed to the Apache Software Foundation (ASF) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The ASF licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+ #
20
+
21
+ module Thrift
22
+ class BaseServerTransport
23
+ def listen
24
+ raise NotImplementedError
25
+ end
26
+
27
+ def accept
28
+ raise NotImplementedError
29
+ end
30
+
31
+ def close; nil; end
32
+
33
+ def closed?
34
+ raise NotImplementedError
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,109 @@
1
+ # encoding: ascii-8bit
2
+ #
3
+ # Licensed to the Apache Software Foundation (ASF) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The ASF licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+ #
20
+
21
+ module Thrift
22
+ class TransportException < Exception
23
+ UNKNOWN = 0
24
+ NOT_OPEN = 1
25
+ ALREADY_OPEN = 2
26
+ TIMED_OUT = 3
27
+ END_OF_FILE = 4
28
+
29
+ attr_reader :type
30
+
31
+ def initialize(type=UNKNOWN, message=nil)
32
+ super(message)
33
+ @type = type
34
+ end
35
+ end
36
+
37
+ module TransportUtils
38
+ # Deprecated: Use Thrift::Bytes instead
39
+ def self.get_string_byte(string, index)
40
+ Bytes.get_string_byte(string, index)
41
+ end
42
+
43
+ # Deprecated: Use Thrift::Bytes instead
44
+ def self.set_string_byte(string, index, byte)
45
+ Bytes.set_string_byte(string, index, byte)
46
+ end
47
+ end
48
+
49
+ class BaseTransport
50
+ def open?; end
51
+
52
+ def open; end
53
+
54
+ def close; end
55
+
56
+ # Reads a number of bytes from the transports. In Ruby 1.9+, the String returned will have a BINARY (aka ASCII8BIT) encoding.
57
+ #
58
+ # sz - The number of bytes to read from the transport.
59
+ #
60
+ # Returns a String acting as a byte buffer.
61
+ def read(sz)
62
+ raise NotImplementedError
63
+ end
64
+
65
+ # Returns an unsigned byte as a Fixnum in the range (0..255).
66
+ def read_byte
67
+ buf = read_all(1)
68
+ return Bytes.get_string_byte(buf, 0)
69
+ end
70
+
71
+ # Reads size bytes and copies them into buffer[0..size].
72
+ def read_into_buffer(buffer, size)
73
+ tmp = read_all(size)
74
+ i = 0
75
+ tmp.each_byte do |byte|
76
+ Bytes.set_string_byte(buffer, i, byte)
77
+ i += 1
78
+ end
79
+ i
80
+ end
81
+
82
+ def read_all(size)
83
+ return Bytes.empty_byte_buffer if size <= 0
84
+ buf = read(size)
85
+ while (buf.length < size)
86
+ chunk = read(size - buf.length)
87
+ buf << chunk
88
+ end
89
+
90
+ buf
91
+ end
92
+
93
+ # Writes the byte buffer to the transport. In Ruby 1.9+, the buffer will be forced into BINARY encoding.
94
+ #
95
+ # buf - A String acting as a byte buffer.
96
+ #
97
+ # Returns nothing.
98
+ def write(buf); end
99
+ alias_method :<<, :write
100
+
101
+ def flush; end
102
+ end
103
+
104
+ class BaseTransportFactory
105
+ def get_transport(trans)
106
+ return trans
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,114 @@
1
+ # encoding: ascii-8bit
2
+ #
3
+ # Licensed to the Apache Software Foundation (ASF) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The ASF licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+ #
20
+
21
+ module Thrift
22
+ class BufferedTransport < BaseTransport
23
+ DEFAULT_BUFFER = 4096
24
+
25
+ def initialize(transport)
26
+ @transport = transport
27
+ @wbuf = Bytes.empty_byte_buffer
28
+ @rbuf = Bytes.empty_byte_buffer
29
+ @index = 0
30
+ end
31
+
32
+ def open?
33
+ return @transport.open?
34
+ end
35
+
36
+ def open
37
+ @transport.open
38
+ end
39
+
40
+ def close
41
+ flush
42
+ @transport.close
43
+ end
44
+
45
+ def read(sz)
46
+ @index += sz
47
+ ret = @rbuf.slice(@index - sz, sz) || Bytes.empty_byte_buffer
48
+
49
+ if ret.length == 0
50
+ @rbuf = @transport.read([sz, DEFAULT_BUFFER].max)
51
+ @index = sz
52
+ ret = @rbuf.slice(0, sz) || Bytes.empty_byte_buffer
53
+ end
54
+
55
+ ret
56
+ end
57
+
58
+ def read_byte
59
+ # If the read buffer is exhausted, try to read up to DEFAULT_BUFFER more bytes into it.
60
+ if @index >= @rbuf.size
61
+ @rbuf = @transport.read(DEFAULT_BUFFER)
62
+ @index = 0
63
+ end
64
+
65
+ # The read buffer has some data now, read a single byte. Using get_string_byte() avoids
66
+ # allocating a temp string of size 1 unnecessarily.
67
+ @index += 1
68
+ return Bytes.get_string_byte(@rbuf, @index - 1)
69
+ end
70
+
71
+ # Reads a number of bytes from the transport into the buffer passed.
72
+ #
73
+ # buffer - The String (byte buffer) to write data to; this is assumed to have a BINARY encoding.
74
+ # size - The number of bytes to read from the transport and write to the buffer.
75
+ #
76
+ # Returns the number of bytes read.
77
+ def read_into_buffer(buffer, size)
78
+ i = 0
79
+ while i < size
80
+ # If the read buffer is exhausted, try to read up to DEFAULT_BUFFER more bytes into it.
81
+ if @index >= @rbuf.size
82
+ @rbuf = @transport.read(DEFAULT_BUFFER)
83
+ @index = 0
84
+ end
85
+
86
+ # The read buffer has some data now, so copy bytes over to the output buffer.
87
+ byte = Bytes.get_string_byte(@rbuf, @index)
88
+ Bytes.set_string_byte(buffer, i, byte)
89
+ @index += 1
90
+ i += 1
91
+ end
92
+ i
93
+ end
94
+
95
+ def write(buf)
96
+ @wbuf << Bytes.force_binary_encoding(buf)
97
+ end
98
+
99
+ def flush
100
+ unless @wbuf.empty?
101
+ @transport.write(@wbuf)
102
+ @wbuf = Bytes.empty_byte_buffer
103
+ end
104
+
105
+ @transport.flush
106
+ end
107
+ end
108
+
109
+ class BufferedTransportFactory < BaseTransportFactory
110
+ def get_transport(transport)
111
+ return BufferedTransport.new(transport)
112
+ end
113
+ end
114
+ end