summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--io_buffer.c62
-rw-r--r--test/ruby/test_io_buffer.rb19
2 files changed, 48 insertions, 33 deletions
diff --git a/io_buffer.c b/io_buffer.c
index cc022a7c9f..075a9bfb78 100644
--- a/io_buffer.c
+++ b/io_buffer.c
@@ -717,35 +717,6 @@ rb_io_buffer_slice(VALUE self, VALUE _offset, VALUE _length)
return instance;
}
-VALUE
-rb_io_buffer_to_str(int argc, VALUE *argv, VALUE self)
-{
- struct rb_io_buffer *data = NULL;
- TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, data);
-
- size_t offset = 0;
- size_t length = data->size;
-
- if (argc == 0) {
- // Defaults.
- }
- else if (argc == 1) {
- offset = NUM2SIZET(argv[0]);
- length = data->size - offset;
- }
- else if (argc == 2) {
- offset = NUM2SIZET(argv[0]);
- length = NUM2SIZET(argv[1]);
- }
- else {
- rb_error_arity(argc, 0, 2);
- }
-
- rb_io_buffer_validate(data, offset, length);
-
- return rb_usascii_str_new((char*)data->base + offset, length);
-}
-
void
rb_io_buffer_get_mutable(VALUE self, void **base, size_t *size)
{
@@ -1144,6 +1115,37 @@ io_buffer_set(VALUE self, VALUE type, VALUE _offset, VALUE value)
return SIZET2NUM(offset);
}
+static VALUE
+io_buffer_get_string(int argc, VALUE *argv, VALUE self)
+{
+ if (argc > 3) rb_error_arity(argc, 0, 3);
+
+ struct rb_io_buffer *data = NULL;
+ TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, data);
+
+ size_t offset = 0;
+ size_t length = data->size;
+ rb_encoding *encoding = NULL;
+
+ if (argc >= 1) {
+ offset = NUM2SIZET(argv[0]);
+ }
+
+ if (argc >= 2 && !RB_NIL_P(argv[1])) {
+ length = NUM2SIZET(argv[1]);
+ } else {
+ length = data->size - offset;
+ }
+
+ if (argc >= 3) {
+ encoding = rb_find_encoding(argv[2]);
+ }
+
+ rb_io_buffer_validate(data, offset, length);
+
+ return rb_enc_str_new((char*)data->base + offset, length, encoding);
+}
+
void
rb_io_buffer_clear(VALUE self, uint8_t value, size_t offset, size_t length)
{
@@ -1278,7 +1280,6 @@ Init_IO_Buffer(void)
// Manipulation:
rb_define_method(rb_cIOBuffer, "slice", rb_io_buffer_slice, 2);
- rb_define_method(rb_cIOBuffer, "to_str", rb_io_buffer_to_str, -1);
rb_define_method(rb_cIOBuffer, "copy", io_buffer_copy, 2);
rb_define_method(rb_cIOBuffer, "<=>", rb_io_buffer_compare, 1);
rb_define_method(rb_cIOBuffer, "resize", io_buffer_resize, 1);
@@ -1298,4 +1299,5 @@ Init_IO_Buffer(void)
// Data access:
rb_define_method(rb_cIOBuffer, "get", io_buffer_get, 2);
rb_define_method(rb_cIOBuffer, "set", io_buffer_set, 3);
+ rb_define_method(rb_cIOBuffer, "get_string", io_buffer_get_string, -1);
}
diff --git a/test/ruby/test_io_buffer.rb b/test/ruby/test_io_buffer.rb
index 9c989f5cfe..45aab318f9 100644
--- a/test/ruby/test_io_buffer.rb
+++ b/test/ruby/test_io_buffer.rb
@@ -71,7 +71,7 @@ class TestIOBuffer < Test::Unit::TestCase
def test_file_mapped
buffer = File.open(__FILE__) {|file| IO::Buffer.map(file)}
- assert_include buffer.to_str, "Hello World"
+ assert_include buffer.get_string, "Hello World"
end
def test_file_mapped_invalid
@@ -130,7 +130,7 @@ class TestIOBuffer < Test::Unit::TestCase
buffer = IO::Buffer.new(1024)
buffer.copy(message, 0)
buffer.resize(2048)
- assert_equal message, buffer.to_str(0, message.bytesize)
+ assert_equal message, buffer.get_string(0, message.bytesize)
end
def test_compare_same_size
@@ -157,7 +157,7 @@ class TestIOBuffer < Test::Unit::TestCase
buffer = IO::Buffer.new(128)
slice = buffer.slice(8, 32)
slice.copy("Hello World", 0)
- assert_equal("Hello World", buffer.to_str(8, 11))
+ assert_equal("Hello World", buffer.get_string(8, 11))
end
def test_slice_bounds
@@ -188,6 +188,19 @@ class TestIOBuffer < Test::Unit::TestCase
assert_equal 128, buffer.size
end
+ def test_get_string
+ message = "Hello World 🤓"
+
+ buffer = IO::Buffer.new(128)
+ buffer.copy(message, 0)
+
+ chunk = buffer.get_string(0, message.bytesize, Encoding::UTF_8)
+ assert_equal message, chunk
+ assert_equal Encoding::UTF_8, chunk.encoding
+
+ chunk = buffer.get_string(0, message.bytesize, Encoding::BINARY)
+ assert_equal Encoding::BINARY, chunk.encoding
+ end
def test_invalidation
input, output = IO.pipe