зеркало из https://github.com/github/ruby.git
Rework implementation of `IO::Buffer.for(string)` to use string locking.
This commit is contained in:
Родитель
98b442e013
Коммит
c833ece5f7
20
io_buffer.c
20
io_buffer.c
|
@ -182,6 +182,10 @@ io_buffer_free(struct rb_io_buffer *data)
|
|||
io_buffer_unmap(data->base, data->size);
|
||||
}
|
||||
|
||||
if (RB_TYPE_P(data->source, T_STRING)) {
|
||||
rb_str_unlocktmp(data->source);
|
||||
}
|
||||
|
||||
data->base = NULL;
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
@ -252,6 +256,21 @@ rb_io_buffer_type_allocate(VALUE self)
|
|||
return instance;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_io_buffer_type_for(VALUE klass, VALUE string)
|
||||
{
|
||||
VALUE instance = rb_io_buffer_type_allocate(klass);
|
||||
|
||||
struct rb_io_buffer *data = NULL;
|
||||
TypedData_Get_Struct(instance, struct rb_io_buffer, &rb_io_buffer_type, data);
|
||||
|
||||
rb_str_locktmp(string);
|
||||
|
||||
io_buffer_initialize(data, RSTRING_PTR(string), RSTRING_LEN(string), RB_IO_BUFFER_EXTERNAL, string);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_io_buffer_new(void *base, size_t size, enum rb_io_buffer_flags flags)
|
||||
{
|
||||
|
@ -1029,6 +1048,7 @@ Init_IO_Buffer(void)
|
|||
rb_cIOBuffer = rb_define_class_under(rb_cIO, "Buffer", rb_cObject);
|
||||
|
||||
rb_define_alloc_func(rb_cIOBuffer, rb_io_buffer_type_allocate);
|
||||
rb_define_singleton_method(rb_cIOBuffer, "for", rb_io_buffer_type_for, 1);
|
||||
|
||||
#ifdef _WIN32
|
||||
SYSTEM_INFO info;
|
||||
|
|
|
@ -62,6 +62,25 @@ class TestIOBuffer < Test::Unit::TestCase
|
|||
assert_include buffer.to_str, "Hello World"
|
||||
end
|
||||
|
||||
def test_string_mapped
|
||||
string = "Hello World"
|
||||
buffer = IO::Buffer.for(string)
|
||||
|
||||
# Cannot modify string as it's locked by the buffer:
|
||||
assert_raise RuntimeError do
|
||||
string[0] = "h"
|
||||
end
|
||||
|
||||
buffer.set(:U8, 0, "h".ord)
|
||||
|
||||
# Buffer releases it's ownership of the string:
|
||||
buffer.free
|
||||
|
||||
assert_equal "hello World", string
|
||||
string[0] = "H"
|
||||
assert_equal "Hello World", string
|
||||
end
|
||||
|
||||
def test_resize
|
||||
buffer = IO::Buffer.new(1024, IO::Buffer::MAPPED)
|
||||
buffer.resize(2048, 0)
|
||||
|
|
Загрузка…
Ссылка в новой задаче