thrift 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/benchmark/gen-rb/benchmark_constants.rb +3 -2
  2. data/benchmark/gen-rb/benchmark_service.rb +52 -52
  3. data/benchmark/gen-rb/benchmark_types.rb +3 -2
  4. data/ext/binary_protocol_accelerated.c +5 -2
  5. data/ext/bytes.c +36 -0
  6. data/ext/bytes.h +31 -0
  7. data/ext/compact_protocol.c +7 -4
  8. data/ext/constants.h +4 -0
  9. data/ext/extconf.rb +3 -1
  10. data/ext/memory_buffer.c +11 -8
  11. data/ext/thrift_native.c +9 -0
  12. data/lib/thrift.rb +2 -0
  13. data/lib/thrift/bytes.rb +131 -0
  14. data/lib/thrift/protocol/base_protocol.rb +10 -0
  15. data/lib/thrift/protocol/binary_protocol.rb +5 -5
  16. data/lib/thrift/protocol/compact_protocol.rb +4 -3
  17. data/lib/thrift/protocol/json_protocol.rb +765 -0
  18. data/lib/thrift/transport/base_transport.rb +22 -20
  19. data/lib/thrift/transport/buffered_transport.rb +16 -10
  20. data/lib/thrift/transport/framed_transport.rb +11 -10
  21. data/lib/thrift/transport/http_client_transport.rb +7 -5
  22. data/lib/thrift/transport/io_stream_transport.rb +1 -1
  23. data/lib/thrift/transport/memory_buffer_transport.rb +6 -6
  24. data/lib/thrift/transport/socket.rb +4 -2
  25. data/spec/ThriftSpec.thrift +52 -1
  26. data/spec/base_protocol_spec.rb +44 -45
  27. data/spec/base_transport_spec.rb +49 -50
  28. data/spec/binary_protocol_accelerated_spec.rb +9 -13
  29. data/spec/binary_protocol_spec.rb +15 -10
  30. data/spec/binary_protocol_spec_shared.rb +62 -12
  31. data/spec/bytes_spec.rb +160 -0
  32. data/spec/client_spec.rb +13 -14
  33. data/spec/compact_protocol_spec.rb +3 -2
  34. data/spec/exception_spec.rb +39 -40
  35. data/spec/gen-rb/nonblocking_service.rb +193 -193
  36. data/spec/gen-rb/thrift_spec_constants.rb +3 -2
  37. data/spec/gen-rb/thrift_spec_types.rb +455 -262
  38. data/spec/http_client_spec.rb +16 -9
  39. data/spec/json_protocol_spec.rb +513 -0
  40. data/spec/mongrel_http_server_spec.rb +19 -22
  41. data/spec/nonblocking_server_spec.rb +18 -20
  42. data/spec/processor_spec.rb +13 -16
  43. data/spec/serializer_spec.rb +17 -19
  44. data/spec/server_socket_spec.rb +6 -7
  45. data/spec/server_spec.rb +46 -58
  46. data/spec/socket_spec.rb +11 -11
  47. data/spec/socket_spec_shared.rb +1 -1
  48. data/spec/spec_helper.rb +13 -10
  49. data/spec/struct_nested_containers_spec.rb +191 -0
  50. data/spec/struct_spec.rb +84 -86
  51. data/spec/types_spec.rb +65 -66
  52. data/spec/union_spec.rb +44 -46
  53. data/spec/unix_socket_spec.rb +8 -9
  54. data/test/debug_proto/gen-rb/debug_proto_test_constants.rb +8 -7
  55. data/test/debug_proto/gen-rb/debug_proto_test_types.rb +24 -23
  56. data/test/debug_proto/gen-rb/empty_service.rb +1 -1
  57. data/test/debug_proto/gen-rb/inherited.rb +3 -3
  58. data/test/debug_proto/gen-rb/reverse_order_service.rb +1 -1
  59. data/test/debug_proto/gen-rb/service_for_exception_with_a_map.rb +3 -3
  60. data/test/debug_proto/gen-rb/srv.rb +2 -2
  61. metadata +43 -49
@@ -1,10 +1,11 @@
1
1
  #
2
- # Autogenerated by Thrift Compiler (0.8.0)
2
+ # Autogenerated by Thrift Compiler (0.9.0)
3
3
  #
4
4
  # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5
5
  #
6
6
 
7
+ require 'thrift'
7
8
  require 'benchmark_types'
8
9
 
9
- module ThriftBenchmark
10
+ module ThriftBenchmark
10
11
  end
@@ -1,5 +1,5 @@
1
1
  #
2
- # Autogenerated by Thrift Compiler (0.8.0)
2
+ # Autogenerated by Thrift Compiler (0.9.0)
3
3
  #
4
4
  # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5
5
  #
@@ -7,74 +7,74 @@
7
7
  require 'thrift'
8
8
  require 'benchmark_types'
9
9
 
10
- module ThriftBenchmark
11
- module BenchmarkService
12
- class Client
13
- include ::Thrift::Client
10
+ module ThriftBenchmark
11
+ module BenchmarkService
12
+ class Client
13
+ include ::Thrift::Client
14
14
 
15
- def fibonacci(n)
16
- send_fibonacci(n)
17
- return recv_fibonacci()
18
- end
19
-
20
- def send_fibonacci(n)
21
- send_message('fibonacci', Fibonacci_args, :n => n)
22
- end
23
-
24
- def recv_fibonacci()
25
- result = receive_message(Fibonacci_result)
26
- return result.success unless result.success.nil?
27
- raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'fibonacci failed: unknown result')
28
- end
15
+ def fibonacci(n)
16
+ send_fibonacci(n)
17
+ return recv_fibonacci()
18
+ end
29
19
 
30
- end
20
+ def send_fibonacci(n)
21
+ send_message('fibonacci', Fibonacci_args, :n => n)
22
+ end
31
23
 
32
- class Processor
33
- include ::Thrift::Processor
24
+ def recv_fibonacci()
25
+ result = receive_message(Fibonacci_result)
26
+ return result.success unless result.success.nil?
27
+ raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'fibonacci failed: unknown result')
28
+ end
34
29
 
35
- def process_fibonacci(seqid, iprot, oprot)
36
- args = read_args(iprot, Fibonacci_args)
37
- result = Fibonacci_result.new()
38
- result.success = @handler.fibonacci(args.n)
39
- write_result(result, oprot, 'fibonacci', seqid)
40
- end
30
+ end
41
31
 
42
- end
32
+ class Processor
33
+ include ::Thrift::Processor
43
34
 
44
- # HELPER FUNCTIONS AND STRUCTURES
35
+ def process_fibonacci(seqid, iprot, oprot)
36
+ args = read_args(iprot, Fibonacci_args)
37
+ result = Fibonacci_result.new()
38
+ result.success = @handler.fibonacci(args.n)
39
+ write_result(result, oprot, 'fibonacci', seqid)
40
+ end
45
41
 
46
- class Fibonacci_args
47
- include ::Thrift::Struct, ::Thrift::Struct_Union
48
- N = 1
42
+ end
49
43
 
50
- FIELDS = {
51
- N => {:type => ::Thrift::Types::BYTE, :name => 'n'}
52
- }
44
+ # HELPER FUNCTIONS AND STRUCTURES
53
45
 
54
- def struct_fields; FIELDS; end
46
+ class Fibonacci_args
47
+ include ::Thrift::Struct, ::Thrift::Struct_Union
48
+ N = 1
55
49
 
56
- def validate
57
- end
50
+ FIELDS = {
51
+ N => {:type => ::Thrift::Types::BYTE, :name => 'n'}
52
+ }
58
53
 
59
- ::Thrift::Struct.generate_accessors self
60
- end
54
+ def struct_fields; FIELDS; end
61
55
 
62
- class Fibonacci_result
63
- include ::Thrift::Struct, ::Thrift::Struct_Union
64
- SUCCESS = 0
56
+ def validate
57
+ end
65
58
 
66
- FIELDS = {
67
- SUCCESS => {:type => ::Thrift::Types::I32, :name => 'success'}
68
- }
59
+ ::Thrift::Struct.generate_accessors self
60
+ end
69
61
 
70
- def struct_fields; FIELDS; end
62
+ class Fibonacci_result
63
+ include ::Thrift::Struct, ::Thrift::Struct_Union
64
+ SUCCESS = 0
71
65
 
72
- def validate
73
- end
66
+ FIELDS = {
67
+ SUCCESS => {:type => ::Thrift::Types::I32, :name => 'success'}
68
+ }
74
69
 
75
- ::Thrift::Struct.generate_accessors self
76
- end
70
+ def struct_fields; FIELDS; end
77
71
 
72
+ def validate
78
73
  end
79
74
 
75
+ ::Thrift::Struct.generate_accessors self
80
76
  end
77
+
78
+ end
79
+
80
+ end
@@ -1,9 +1,10 @@
1
1
  #
2
- # Autogenerated by Thrift Compiler (0.8.0)
2
+ # Autogenerated by Thrift Compiler (0.9.0)
3
3
  #
4
4
  # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5
5
  #
6
6
 
7
+ require 'thrift'
7
8
 
8
9
  module ThriftBenchmark
9
- end
10
+ end
@@ -22,7 +22,8 @@
22
22
  #include <stdint.h>
23
23
  #include <constants.h>
24
24
  #include <struct.h>
25
- #include "macros.h"
25
+ #include <macros.h>
26
+ #include <bytes.h>
26
27
 
27
28
  VALUE rb_thrift_binary_proto_native_qmark(VALUE self) {
28
29
  return Qtrue;
@@ -80,6 +81,7 @@ static void write_string_direct(VALUE trans, VALUE str) {
80
81
  if (TYPE(str) != T_STRING) {
81
82
  rb_raise(rb_eStandardError, "Value should be a string");
82
83
  }
84
+ str = convert_to_utf8_byte_buffer(str);
83
85
  write_i32_direct(trans, RSTRING_LEN(str));
84
86
  rb_funcall(trans, write_method_id, 1, str);
85
87
  }
@@ -380,7 +382,8 @@ VALUE rb_thrift_binary_proto_read_double(VALUE self) {
380
382
 
381
383
  VALUE rb_thrift_binary_proto_read_string(VALUE self) {
382
384
  int size = read_i32_direct(self);
383
- return READ(self, size);
385
+ VALUE buffer = READ(self, size);
386
+ return convert_to_string(buffer);
384
387
  }
385
388
 
386
389
  void Init_binary_protocol_accelerated() {
@@ -0,0 +1,36 @@
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
+ #ifdef HAVE_RUBY_ENCODING_H
22
+ #include <ruby/encoding.h>
23
+ #endif
24
+ #include <constants.h>
25
+
26
+ VALUE force_binary_encoding(VALUE buffer) {
27
+ return rb_funcall(thrift_bytes_module, force_binary_encoding_id, 1, buffer);
28
+ }
29
+
30
+ VALUE convert_to_utf8_byte_buffer(VALUE string) {
31
+ return rb_funcall(thrift_bytes_module, convert_to_utf8_byte_buffer_id, 1, string);
32
+ }
33
+
34
+ VALUE convert_to_string(VALUE utf8_buffer) {
35
+ return rb_funcall(thrift_bytes_module, convert_to_string_id, 1, utf8_buffer);
36
+ }
@@ -0,0 +1,31 @@
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
+
22
+ /*
23
+ * A collection of utilities for working with bytes and byte buffers.
24
+ *
25
+ * These methods are the native analogies to some of the methods in
26
+ * Thrift::Bytes (thrift/bytes.rb).
27
+ */
28
+
29
+ VALUE force_binary_encoding(VALUE buffer);
30
+ VALUE convert_to_utf8_byte_buffer(VALUE string);
31
+ VALUE convert_to_string(VALUE utf8_buffer);
@@ -20,9 +20,10 @@
20
20
  #include <ruby.h>
21
21
  #include <stdbool.h>
22
22
  #include <stdint.h>
23
- #include "constants.h"
24
- #include "struct.h"
25
- #include "macros.h"
23
+ #include <constants.h>
24
+ #include <struct.h>
25
+ #include <macros.h>
26
+ #include <bytes.h>
26
27
 
27
28
  #define LAST_ID(obj) FIX2INT(rb_ary_pop(rb_ivar_get(obj, last_field_id)))
28
29
  #define SET_LAST_ID(obj, val) rb_ary_push(rb_ivar_get(obj, last_field_id), val)
@@ -305,6 +306,7 @@ VALUE rb_thrift_compact_proto_write_double(VALUE self, VALUE dub) {
305
306
 
306
307
  VALUE rb_thrift_compact_proto_write_string(VALUE self, VALUE str) {
307
308
  VALUE transport = GET_TRANSPORT(self);
309
+ str = convert_to_utf8_byte_buffer(str);
308
310
  write_varint32(transport, RSTRING_LEN(str));
309
311
  WRITE(transport, RSTRING_PTR(str), RSTRING_LEN(str));
310
312
  return Qnil;
@@ -546,7 +548,8 @@ VALUE rb_thrift_compact_proto_read_double(VALUE self) {
546
548
 
547
549
  VALUE rb_thrift_compact_proto_read_string(VALUE self) {
548
550
  int64_t size = read_varint64(self);
549
- return READ(self, size);
551
+ VALUE buffer = READ(self, size);
552
+ return convert_to_string(buffer);
550
553
  }
551
554
 
552
555
  static void Init_constants() {
@@ -76,6 +76,9 @@ extern ID write_method_id;
76
76
  extern ID read_all_method_id;
77
77
  extern ID read_into_buffer_method_id;
78
78
  extern ID native_qmark_method_id;
79
+ extern ID force_binary_encoding_id;
80
+ extern ID convert_to_utf8_byte_buffer_id;
81
+ extern ID convert_to_string_id;
79
82
 
80
83
  extern ID fields_const_id;
81
84
  extern ID transport_ivar_id;
@@ -92,5 +95,6 @@ extern VALUE class_sym;
92
95
  extern VALUE rb_cSet;
93
96
  extern VALUE thrift_module;
94
97
  extern VALUE thrift_types_module;
98
+ extern VALUE thrift_bytes_module;
95
99
  extern VALUE class_thrift_protocol;
96
100
  extern VALUE protocol_exception_class;
@@ -22,7 +22,9 @@ if defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /jruby/
22
22
  else
23
23
  require 'mkmf'
24
24
 
25
- $CFLAGS = "-g -O2 -Wall -Werror"
25
+ $ARCH_FLAGS = Config::CONFIG['CFLAGS'].scan( /(-arch )(\S+)/ ).map{|x,y| x + y + ' ' }.join('')
26
+
27
+ $CFLAGS = "-g -O2 -Wall -Werror " + $ARCH_FLAGS
26
28
 
27
29
  have_func("strlcpy", "string.h")
28
30
 
@@ -19,7 +19,8 @@
19
19
 
20
20
  #include <ruby.h>
21
21
  #include <constants.h>
22
- #include "macros.h"
22
+ #include <bytes.h>
23
+ #include <macros.h>
23
24
 
24
25
  ID buf_ivar_id;
25
26
  ID index_ivar_id;
@@ -37,6 +38,7 @@ VALUE rb_thrift_memory_buffer_read_into_buffer(VALUE self, VALUE buffer_value, V
37
38
 
38
39
  VALUE rb_thrift_memory_buffer_write(VALUE self, VALUE str) {
39
40
  VALUE buf = GET_BUF(self);
41
+ str = force_binary_encoding(str);
40
42
  rb_str_buf_cat(buf, RSTRING_PTR(str), RSTRING_LEN(str));
41
43
  return Qnil;
42
44
  }
@@ -93,25 +95,26 @@ VALUE rb_thrift_memory_buffer_read_into_buffer(VALUE self, VALUE buffer_value, V
93
95
  int index;
94
96
  VALUE buf = GET_BUF(self);
95
97
 
98
+ index = FIX2INT(rb_ivar_get(self, index_ivar_id));
96
99
  while (i < size) {
97
- index = FIX2INT(rb_ivar_get(self, index_ivar_id));
98
100
  if (index >= RSTRING_LEN(buf)) {
99
101
  rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer");
100
102
  }
101
103
  char byte = RSTRING_PTR(buf)[index++];
102
104
 
103
- if (index >= GARBAGE_BUFFER_SIZE) {
104
- rb_ivar_set(self, buf_ivar_id, rb_funcall(buf, slice_method_id, 2, INT2FIX(index), INT2FIX(RSTRING_LEN(buf) - 1)));
105
- index = 0;
106
- }
107
- rb_ivar_set(self, index_ivar_id, INT2FIX(index));
108
-
109
105
  if (i >= RSTRING_LEN(buffer_value)) {
110
106
  rb_raise(rb_eIndexError, "index %d out of string", i);
111
107
  }
112
108
  ((char*)RSTRING_PTR(buffer_value))[i] = byte;
113
109
  i++;
114
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
+
115
118
  return INT2FIX(i);
116
119
  }
117
120
 
@@ -18,6 +18,7 @@
18
18
  */
19
19
 
20
20
  #include <ruby.h>
21
+ #include <bytes.h>
21
22
  #include <struct.h>
22
23
  #include <binary_protocol_accelerated.h>
23
24
  #include <compact_protocol.h>
@@ -27,6 +28,7 @@
27
28
  // cached classes/modules
28
29
  VALUE rb_cSet;
29
30
  VALUE thrift_module;
31
+ VALUE thrift_bytes_module;
30
32
  VALUE thrift_types_module;
31
33
 
32
34
  // TType constants
@@ -90,6 +92,9 @@ ID write_method_id;
90
92
  ID read_all_method_id;
91
93
  ID read_into_buffer_method_id;
92
94
  ID native_qmark_method_id;
95
+ ID force_binary_encoding_id;
96
+ ID convert_to_utf8_byte_buffer_id;
97
+ ID convert_to_string_id;
93
98
 
94
99
  // constant ids
95
100
  ID fields_const_id;
@@ -109,6 +114,7 @@ VALUE protocol_exception_class;
109
114
  void Init_thrift_native() {
110
115
  // cached classes
111
116
  thrift_module = rb_const_get(rb_cObject, rb_intern("Thrift"));
117
+ thrift_bytes_module = rb_const_get(thrift_module, rb_intern("Bytes"));
112
118
  thrift_types_module = rb_const_get(thrift_module, rb_intern("Types"));
113
119
  rb_cSet = rb_const_get(rb_cObject, rb_intern("Set"));
114
120
  protocol_exception_class = rb_const_get(thrift_module, rb_intern("ProtocolException"));
@@ -173,6 +179,9 @@ void Init_thrift_native() {
173
179
  read_all_method_id = rb_intern("read_all");
174
180
  read_into_buffer_method_id = rb_intern("read_into_buffer");
175
181
  native_qmark_method_id = rb_intern("native?");
182
+ force_binary_encoding_id = rb_intern("force_binary_encoding");
183
+ convert_to_utf8_byte_buffer_id = rb_intern("convert_to_utf8_byte_buffer");
184
+ convert_to_string_id = rb_intern("convert_to_string");
176
185
 
177
186
  // constant ids
178
187
  fields_const_id = rb_intern("FIELDS");
@@ -22,6 +22,7 @@
22
22
 
23
23
  $:.unshift File.dirname(__FILE__)
24
24
 
25
+ require 'thrift/bytes'
25
26
  require 'thrift/core_ext'
26
27
  require 'thrift/exceptions'
27
28
  require 'thrift/types'
@@ -40,6 +41,7 @@ require 'thrift/protocol/base_protocol'
40
41
  require 'thrift/protocol/binary_protocol'
41
42
  require 'thrift/protocol/binary_protocol_accelerated'
42
43
  require 'thrift/protocol/compact_protocol'
44
+ require 'thrift/protocol/json_protocol'
43
45
 
44
46
  # transport
45
47
  require 'thrift/transport/base_transport'
@@ -0,0 +1,131 @@
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
+ # A collection of utilities for working with bytes and byte buffers.
23
+ module Bytes
24
+ if RUBY_VERSION >= '1.9'
25
+ # Creates and empty byte buffer (String with BINARY encoding)
26
+ #
27
+ # size - The Integer size of the buffer (default: nil) to create
28
+ #
29
+ # Returns a String with BINARY encoding, filled with null characters
30
+ # if size is greater than zero
31
+ def self.empty_byte_buffer(size = nil)
32
+ if (size && size > 0)
33
+ "\0".force_encoding(Encoding::BINARY) * size
34
+ else
35
+ ''.force_encoding(Encoding::BINARY)
36
+ end
37
+ end
38
+
39
+ # Forces the encoding of the buffer to BINARY. If the buffer
40
+ # passed is frozen, then it will be duplicated.
41
+ #
42
+ # buffer - The String to force the encoding of.
43
+ #
44
+ # Returns the String passed with an encoding of BINARY; returned
45
+ # String may be a duplicate.
46
+ def self.force_binary_encoding(buffer)
47
+ buffer = buffer.dup if buffer.frozen?
48
+ buffer.force_encoding(Encoding::BINARY)
49
+ end
50
+
51
+ # Gets the byte value of a given position in a String.
52
+ #
53
+ # string - The String to retrive the byte value from.
54
+ # index - The Integer location of the byte value to retrieve.
55
+ #
56
+ # Returns an Integer value between 0 and 255.
57
+ def self.get_string_byte(string, index)
58
+ string.getbyte(index)
59
+ end
60
+
61
+ # Sets the byte value given to a given index in a String.
62
+ #
63
+ # string - The String to set the byte value in.
64
+ # index - The Integer location to set the byte value at.
65
+ # byte - The Integer value (0 to 255) to set in the string.
66
+ #
67
+ # Returns an Integer value of the byte value to set.
68
+ def self.set_string_byte(string, index, byte)
69
+ string.setbyte(index, byte)
70
+ end
71
+
72
+ # Converts the given String to a UTF-8 byte buffer.
73
+ #
74
+ # string - The String to convert.
75
+ #
76
+ # Returns a new String with BINARY encoding, containing the UTF-8
77
+ # bytes of the original string.
78
+ def self.convert_to_utf8_byte_buffer(string)
79
+ if string.encoding != Encoding::UTF_8
80
+ # transcode to UTF-8
81
+ string = string.encode(Encoding::UTF_8)
82
+ else
83
+ # encoding is already UTF-8, but a duplicate is needed
84
+ string = string.dup
85
+ end
86
+ string.force_encoding(Encoding::BINARY)
87
+ end
88
+
89
+ # Converts the given UTF-8 byte buffer into a String
90
+ #
91
+ # utf8_buffer - A String, with BINARY encoding, containing UTF-8 bytes
92
+ #
93
+ # Returns a new String with UTF-8 encoding,
94
+ def self.convert_to_string(utf8_buffer)
95
+ # duplicate the buffer, force encoding to UTF-8
96
+ utf8_buffer.dup.force_encoding(Encoding::UTF_8)
97
+ end
98
+ else
99
+ def self.empty_byte_buffer(size = nil)
100
+ if (size && size > 0)
101
+ "\0" * size
102
+ else
103
+ ''
104
+ end
105
+ end
106
+
107
+ def self.force_binary_encoding(buffer)
108
+ buffer
109
+ end
110
+
111
+ def self.get_string_byte(string, index)
112
+ string[index]
113
+ end
114
+
115
+ def self.set_string_byte(string, index, byte)
116
+ string[index] = byte
117
+ end
118
+
119
+ def self.convert_to_utf8_byte_buffer(string)
120
+ # This assumes $KCODE is 'UTF8'/'U', which would mean the String is already a UTF-8 byte buffer
121
+ # TODO consider handling other $KCODE values and transcoding with iconv
122
+ string
123
+ end
124
+
125
+ def self.convert_to_string(utf8_buffer)
126
+ # See comment in 'convert_to_utf8_byte_buffer' for relevant assumptions.
127
+ utf8_buffer
128
+ end
129
+ end
130
+ end
131
+ end