Skip to content

Commit 8d1ad11

Browse files
committed
Support flags in Fiddle::MemoryView.new and .export
Accept an optional `flags` argument, expose the flag values as constants, and reject unsupported flags in `Fiddle::Pointer`'s provider.
1 parent d389bbf commit 8d1ad11

3 files changed

Lines changed: 46 additions & 6 deletions

File tree

‎ext/fiddle/memory_view.c‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,21 +97,25 @@ rb_fiddle_memview_release(VALUE obj)
9797
}
9898

9999
static VALUE
100-
rb_fiddle_memview_s_export(VALUE klass, VALUE target)
100+
rb_fiddle_memview_s_export(int argc, VALUE *argv, VALUE klass)
101101
{
102102
ID id_new;
103103
CONST_ID(id_new, "new");
104-
VALUE memview = rb_funcall(klass, id_new, 1, target);
104+
VALUE memview = rb_funcallv(klass, id_new, argc, argv);
105105
return rb_ensure(rb_yield, memview, rb_fiddle_memview_release, memview);
106106
}
107107

108108
static VALUE
109-
rb_fiddle_memview_initialize(VALUE obj, VALUE target)
109+
rb_fiddle_memview_initialize(int argc, VALUE *argv, VALUE obj)
110110
{
111+
VALUE target, flags_v;
112+
rb_scan_args(argc, argv, "11", &target, &flags_v);
113+
int flags = NIL_P(flags_v) ? 0 : NUM2INT(flags_v);
114+
111115
struct memview_data *data;
112116
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
113117

114-
if (!rb_memory_view_get(target, &data->view, 0)) {
118+
if (!rb_memory_view_get(target, &data->view, flags)) {
115119
data->view.obj = Qnil;
116120
rb_raise(rb_eArgError, "Unable to get a memory view from %+"PRIsVALUE, target);
117121
}
@@ -307,8 +311,8 @@ Init_fiddle_memory_view(void)
307311
{
308312
rb_cMemoryView = rb_define_class_under(mFiddle, "MemoryView", rb_cObject);
309313
rb_define_alloc_func(rb_cMemoryView, rb_fiddle_memview_s_allocate);
310-
rb_define_singleton_method(rb_cMemoryView, "export", rb_fiddle_memview_s_export, 1);
311-
rb_define_method(rb_cMemoryView, "initialize", rb_fiddle_memview_initialize, 1);
314+
rb_define_singleton_method(rb_cMemoryView, "export", rb_fiddle_memview_s_export, -1);
315+
rb_define_method(rb_cMemoryView, "initialize", rb_fiddle_memview_initialize, -1);
312316
rb_define_method(rb_cMemoryView, "release", rb_fiddle_memview_release, 0);
313317
rb_define_method(rb_cMemoryView, "obj", rb_fiddle_memview_get_obj, 0);
314318
rb_define_method(rb_cMemoryView, "byte_size", rb_fiddle_memview_get_byte_size, 0);
@@ -321,6 +325,15 @@ Init_fiddle_memory_view(void)
321325
rb_define_method(rb_cMemoryView, "sub_offsets", rb_fiddle_memview_get_sub_offsets, 0);
322326
rb_define_method(rb_cMemoryView, "[]", rb_fiddle_memview_aref, -1);
323327
rb_define_method(rb_cMemoryView, "to_s", rb_fiddle_memview_to_s, 0);
328+
rb_define_const(rb_cMemoryView, "SIMPLE", INT2NUM(RUBY_MEMORY_VIEW_SIMPLE));
329+
rb_define_const(rb_cMemoryView, "WRITABLE", INT2NUM(RUBY_MEMORY_VIEW_WRITABLE));
330+
rb_define_const(rb_cMemoryView, "FORMAT", INT2NUM(RUBY_MEMORY_VIEW_FORMAT));
331+
rb_define_const(rb_cMemoryView, "MULTI_DIMENSIONAL", INT2NUM(RUBY_MEMORY_VIEW_MULTI_DIMENSIONAL));
332+
rb_define_const(rb_cMemoryView, "STRIDES", INT2NUM(RUBY_MEMORY_VIEW_STRIDES));
333+
rb_define_const(rb_cMemoryView, "ROW_MAJOR", INT2NUM(RUBY_MEMORY_VIEW_ROW_MAJOR));
334+
rb_define_const(rb_cMemoryView, "COLUMN_MAJOR", INT2NUM(RUBY_MEMORY_VIEW_COLUMN_MAJOR));
335+
rb_define_const(rb_cMemoryView, "ANY_CONTIGUOUS", INT2NUM(RUBY_MEMORY_VIEW_ANY_CONTIGUOUS));
336+
rb_define_const(rb_cMemoryView, "INDIRECT", INT2NUM(RUBY_MEMORY_VIEW_INDIRECT));
324337
}
325338

326339
#endif /* HAVE_RUBY_MEMORY_VIEW_H */

‎ext/fiddle/pointer.c‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ fiddle_ptr_memory_view_available_p(VALUE obj)
116116
static bool
117117
fiddle_ptr_get_memory_view(VALUE obj, rb_memory_view_t *view, int flags)
118118
{
119+
if (flags != RUBY_MEMORY_VIEW_SIMPLE) return false;
120+
119121
struct ptr_data *data = fiddle_ptr_check_memory_view(obj);
120122
rb_memory_view_init_as_byte_array(view, obj, data->ptr, data->size, true);
121123

‎test/fiddle/test_memory_view.rb‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,31 @@ def test_memory_view_from_unsupported_obj
3030
end
3131
end
3232

33+
def test_new_with_flags
34+
ptr = Pointer["hello world"]
35+
mview = MemoryView.new(ptr, MemoryView::SIMPLE)
36+
begin
37+
assert_equal(ptr.size, mview.byte_size)
38+
ensure
39+
mview.release
40+
end
41+
end
42+
43+
def test_new_with_unsupported_flags
44+
ptr = Pointer["hello world"]
45+
assert_raise(ArgumentError) do
46+
MemoryView.new(ptr, MemoryView::WRITABLE)
47+
end
48+
end
49+
50+
def test_export_with_flags
51+
str = "hello world"
52+
mview_str = MemoryView.export(Pointer[str], MemoryView::SIMPLE) do |mview|
53+
mview.to_s
54+
end
55+
assert_equal(str, mview_str)
56+
end
57+
3358
def test_memory_view_from_pointer
3459
str = Marshal.load(Marshal.dump("hello world"))
3560
ptr = Pointer[str]

0 commit comments

Comments
 (0)