From 71bbc40ffa4bb16ef0fc31f8015f61709fac36ce Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Mon, 20 Dec 2021 12:11:21 +1300 Subject: Rename `to_str` -> `get_string` and add support for encodings. --- io_buffer.c | 62 +++++++++++++++++++++++---------------------- test/ruby/test_io_buffer.rb | 19 +++++++++++--- 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 -- cgit v1.2.1