diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6099815 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,26 @@ +name: CI + +on: + push: + branches: [develop] + pull_request: + branches: [develop] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + ruby-version: ["3.1", "3.4"] + steps: + - uses: actions/checkout@v3 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version }} + - name: Install dependencies + run: | + sudo apt-get update && sudo apt-get install -y libmediainfo-dev + bundle install + - name: Run tests + run: bundle exec rake diff --git a/Rakefile b/Rakefile index 1904892..ba744de 100644 --- a/Rakefile +++ b/Rakefile @@ -6,3 +6,5 @@ Rake::ExtensionTask.new('mediainfo_native') desc "Run the specs." RSpec::Core::RakeTask.new('spec') task spec: [:clean, :compile] + +task default: :spec diff --git a/ext/mediainfo_native/MediaInfoDLL.h b/ext/mediainfo_native/MediaInfoDLL.h index 320be41..6918e93 100644 --- a/ext/mediainfo_native/MediaInfoDLL.h +++ b/ext/mediainfo_native/MediaInfoDLL.h @@ -15,9 +15,12 @@ #ifndef MediaInfoDLLH #define MediaInfoDLLH - +#ifndef UNICODE #define UNICODE +#endif +#ifndef _UNICODE #define _UNICODE +#endif //*************************************************************************** // Platforms (from libzen) diff --git a/ext/mediainfo_native/basestream.cpp b/ext/mediainfo_native/basestream.cpp index 1302192..f3521d4 100644 --- a/ext/mediainfo_native/basestream.cpp +++ b/ext/mediainfo_native/basestream.cpp @@ -8,7 +8,7 @@ namespace MediaInfoNative #define GET_BASESTREAM(var) \ BaseStream* var; \ - Data_Get_Struct(self, BaseStream, var) + TypedData_Get_Struct(self, BaseStream, &basestream_type, var) extern "C" { @@ -18,6 +18,17 @@ extern "C" delete ((BaseStream*) ptr); } + static const rb_data_type_t basestream_type = { + "BaseStream", + { + nullptr, // mark function + bs_free, // free function + nullptr, // memsize function + }, + nullptr, nullptr, + RUBY_TYPED_FREE_IMMEDIATELY + }; + static VALUE bs_lookup(VALUE self, VALUE key) { GET_BASESTREAM(bs); @@ -31,7 +42,9 @@ VALUE stream_klasses[STREAM_TYPE_MAX]; void Init_BaseStream(VALUE mMediaInfoNative) { VALUE cBaseStream = rb_define_class_under(mMediaInfoNative, "BaseStream", rb_cObject); + rb_undef_alloc_func(cBaseStream); VALUE cBaseStreamWithFramerate = rb_define_class_under(mMediaInfoNative, "BaseStreamWithFramerate", cBaseStream); + rb_undef_alloc_func(cBaseStreamWithFramerate); stream_klasses[GENERAL] = rb_define_class_under(mMediaInfoNative, "GeneralStream", cBaseStream); stream_klasses[VIDEO] = rb_define_class_under(mMediaInfoNative, "VideoStream", cBaseStreamWithFramerate); @@ -42,7 +55,8 @@ void Init_BaseStream(VALUE mMediaInfoNative) stream_klasses[MENU] = rb_define_class_under(mMediaInfoNative, "MenuStream", cBaseStream); for(unsigned int st = 0; st < STREAM_TYPE_MAX; ++st) { - rb_define_method(stream_klasses[st], "lookup", (VALUE(*)(...)) bs_lookup, 1); + rb_undef_alloc_func(stream_klasses[st]); + rb_define_method(stream_klasses[st], "lookup", RUBY_METHOD_FUNC(bs_lookup), 1); } } @@ -55,7 +69,7 @@ BaseStream::BaseStream(StreamType _type, unsigned int _idx, MediaInfoWrapper* _w VALUE BaseStream::wrap() { - return Data_Wrap_Struct(stream_klasses[type], 0, bs_free, this); + return TypedData_Wrap_Struct(stream_klasses[type], &basestream_type, this); } VALUE BaseStream::lookup(VALUE key) const diff --git a/ext/mediainfo_native/mediainfo_wrapper.cpp b/ext/mediainfo_native/mediainfo_wrapper.cpp index 1ba90b9..3bb1953 100644 --- a/ext/mediainfo_native/mediainfo_wrapper.cpp +++ b/ext/mediainfo_native/mediainfo_wrapper.cpp @@ -12,7 +12,7 @@ namespace MediaInfoNative #define GET_WRAPPER(var) \ MediaInfoWrapper* var; \ - Data_Get_Struct(self, MediaInfoWrapper, var) + TypedData_Get_Struct(self, MediaInfoWrapper, &mediainfo_wrapper_type, var) typedef struct { MediaInfoWrapper* miw; @@ -23,13 +23,22 @@ typedef struct { extern "C" { - typedef VALUE(*RUBYFUNC)(...); - static void miw_free(void* ptr) { delete ((MediaInfoWrapper*) ptr); } + static const rb_data_type_t mediainfo_wrapper_type = { + "MediaInfoWrapper", + { + nullptr, // mark function + miw_free, // free function + nullptr, // memsize function + }, + nullptr, nullptr, // parent, data + RUBY_TYPED_FREE_IMMEDIATELY + }; + static VALUE miw_new(VALUE klass, VALUE args) { if(RARRAY_LEN(args) > 1) @@ -46,7 +55,7 @@ extern "C" } MediaInfoWrapper* miw = new MediaInfoWrapper(ignore_continuous_file_names); - return Data_Wrap_Struct(klass, 0, miw_free, miw); + return TypedData_Wrap_Struct(klass, &mediainfo_wrapper_type, miw); } static VALUE miw_close(VALUE self) @@ -79,7 +88,7 @@ extern "C" } if(rb_block_given_p()) - return rb_ensure((RUBYFUNC) rb_yield, Qnil, (RUBYFUNC) miw_close, self); + return rb_ensure(rb_yield, Qnil, miw_close, self); else return Qnil; } @@ -123,16 +132,17 @@ extern "C" void Init_MediaInfoWrapper(VALUE mMediaInfoNative) { VALUE cMediaInfo = rb_define_class_under(mMediaInfoNative, "MediaInfo", rb_cObject); + rb_undef_alloc_func(cMediaInfo); - rb_define_singleton_method(cMediaInfo, "new", (RUBYFUNC) miw_new, -2); + rb_define_singleton_method(cMediaInfo, "new", RUBY_METHOD_FUNC(miw_new), -2); - rb_define_method(cMediaInfo, "close", (RUBYFUNC) miw_close, 0); - rb_define_method(cMediaInfo, "open", (RUBYFUNC) miw_open, 1); - rb_define_method(cMediaInfo, "is_open?", (RUBYFUNC) miw_is_open, 0); - rb_define_method(cMediaInfo, "streams", (RUBYFUNC) miw_streams, 0); + rb_define_method(cMediaInfo, "close", RUBY_METHOD_FUNC(miw_close), 0); + rb_define_method(cMediaInfo, "open", RUBY_METHOD_FUNC(miw_open), 1); + rb_define_method(cMediaInfo, "is_open?", RUBY_METHOD_FUNC(miw_is_open), 0); + rb_define_method(cMediaInfo, "streams", RUBY_METHOD_FUNC(miw_streams), 0); - rb_define_method(cMediaInfo, "inform", (RUBYFUNC) miw_inform, 1); - rb_define_method(cMediaInfo, "option", (RUBYFUNC) miw_option, 0); + rb_define_method(cMediaInfo, "inform", RUBY_METHOD_FUNC(miw_inform), 1); + rb_define_method(cMediaInfo, "option", RUBY_METHOD_FUNC(miw_option), 0); } /* ************************** MediaInfoWrapper ****************************** */ @@ -157,6 +167,9 @@ MediaInfoDLL::stream_t convertToMediaInfoStreamType(StreamType type) return MediaInfoDLL::Stream_Image; case MENU: return MediaInfoDLL::Stream_Menu; + default: + rb_raise(rb_eRuntimeError, "Invalid stream type: %d", (int)type); + __builtin_unreachable(); } }