@@ -36,12 +36,25 @@ fiddle_memview_mark(void *ptr)
3636}
3737
3838static void
39- fiddle_memview_free ( void * ptr )
39+ fiddle_memview_release ( struct memview_data * data )
4040{
41- struct memview_data * data = ptr ;
41+ if (NIL_P (data -> view .obj )) return ;
42+
4243 rb_memory_view_release (& data -> view );
43- if (data -> members )
44+ data -> view .obj = Qnil ;
45+ data -> view .byte_size = 0 ;
46+ if (data -> members ) {
4447 xfree (data -> members );
48+ data -> members = NULL ;
49+ data -> n_members = 0 ;
50+ }
51+ }
52+
53+ static void
54+ fiddle_memview_free (void * ptr )
55+ {
56+ struct memview_data * data = ptr ;
57+ fiddle_memview_release (data );
4558 xfree (ptr );
4659}
4760
@@ -63,11 +76,32 @@ rb_fiddle_memview_s_allocate(VALUE klass)
6376 struct memview_data * data ;
6477 VALUE obj = TypedData_Make_Struct (klass , struct memview_data , & fiddle_memview_data_type , data );
6578 data -> view .obj = Qnil ;
79+ data -> view .byte_size = 0 ;
6680 data -> members = NULL ;
6781 data -> n_members = 0 ;
6882 return obj ;
6983}
7084
85+ static VALUE
86+ rb_fiddle_memview_release (VALUE obj )
87+ {
88+ struct memview_data * data ;
89+ TypedData_Get_Struct (obj , struct memview_data , & fiddle_memview_data_type , data );
90+
91+ if (NIL_P (data -> view .obj )) return Qnil ;
92+ fiddle_memview_release (data );
93+ return Qnil ;
94+ }
95+
96+ static VALUE
97+ rb_fiddle_memview_s_export (VALUE klass , VALUE target )
98+ {
99+ ID id_new ;
100+ CONST_ID (id_new , "new" );
101+ VALUE memview = rb_funcall (klass , id_new , 1 , target );
102+ return rb_ensure (rb_yield , memview , rb_fiddle_memview_release , memview );
103+ }
104+
71105static VALUE
72106rb_fiddle_memview_initialize (VALUE obj , VALUE target )
73107{
@@ -269,7 +303,9 @@ Init_fiddle_memory_view(void)
269303{
270304 rb_cMemoryView = rb_define_class_under (mFiddle , "MemoryView" , rb_cObject );
271305 rb_define_alloc_func (rb_cMemoryView , rb_fiddle_memview_s_allocate );
306+ rb_define_singleton_method (rb_cMemoryView , "export" , rb_fiddle_memview_s_export , 1 );
272307 rb_define_method (rb_cMemoryView , "initialize" , rb_fiddle_memview_initialize , 1 );
308+ rb_define_method (rb_cMemoryView , "release" , rb_fiddle_memview_release , 0 );
273309 rb_define_method (rb_cMemoryView , "obj" , rb_fiddle_memview_get_obj , 0 );
274310 rb_define_method (rb_cMemoryView , "byte_size" , rb_fiddle_memview_get_byte_size , 0 );
275311 rb_define_method (rb_cMemoryView , "readonly?" , rb_fiddle_memview_get_readonly , 0 );
0 commit comments