gir_ffi-0.6.7/0000755000004100000410000000000012224462647013172 5ustar www-datawww-datagir_ffi-0.6.7/test/0000755000004100000410000000000012224462647014151 5ustar www-datawww-datagir_ffi-0.6.7/test/base_test_helper.rb0000644000004100000410000000444712224462647020017 0ustar www-datawww-dataif RUBY_PLATFORM == 'java' require 'rubygems' end if RUBY_VERSION >= "1.9" require 'simplecov' SimpleCov.start do add_filter "/test/" end end require 'minitest/autorun' require 'rr' require 'gir_ffi-base' require 'ffi-gobject_introspection' GObjectIntrospection::IRepository.prepend_search_path File.join(File.dirname(__FILE__), 'lib') module GObjectIntrospection class IRepository def shared_library_with_regress namespace case namespace when "Regress" return File.join(File.dirname(__FILE__), 'lib', 'libregress.so') when "GIMarshallingTests" return File.join(File.dirname(__FILE__), 'lib', 'libgimarshallingtests.so') else return shared_library_without_regress namespace end end alias shared_library_without_regress shared_library alias shared_library shared_library_with_regress end end Thread.abort_on_exception = true class Minitest::Test include RR::Adapters::TestUnit def assert_defines_singleton_method klass, method, msg = nil method = method.to_sym methods = klass.singleton_methods(false).map { |name| name.to_sym } msg = message(msg) { "Expected #{mu_pp(klass)} to define singleton method #{mu_pp(method)}, " + "but only found #{mu_pp(methods)}" } assert_includes methods, method, msg end def refute_defines_singleton_method klass, method, msg = nil method = method.to_sym methods = klass.singleton_methods(false).map { |name| name.to_sym } msg = message(msg) { "Expected #{mu_pp(klass)} not to define singleton method #{mu_pp(method)}" } refute_includes methods, method, msg end def assert_defines_instance_method klass, method, msg = nil method = method.to_sym methods = klass.instance_methods(false).map { |name| name.to_sym } msg = message(msg) { "Expected #{mu_pp(klass)} to define instance method #{mu_pp(method)}, " + "but only found #{mu_pp(methods)}" } assert_includes methods, method, msg end def refute_defines_instance_method klass, method, msg = nil method = method.to_sym methods = klass.instance_methods(false).map { |name| name.to_sym } msg = message(msg) { "Expected #{mu_pp(klass)} not to define instance method #{mu_pp(method)}" } refute_includes methods, method, msg end end gir_ffi-0.6.7/test/gir_ffi-base/0000755000004100000410000000000012224462647016466 5ustar www-datawww-datagir_ffi-0.6.7/test/gir_ffi-base/glib/0000755000004100000410000000000012224462647017403 5ustar www-datawww-datagir_ffi-0.6.7/test/gir_ffi-base/glib/strv_test.rb0000644000004100000410000000210712224462647021765 0ustar www-datawww-datarequire 'base_test_helper' describe GLib::Strv do it "wraps a pointer" do strv = GLib::Strv.new :some_pointer assert_equal :some_pointer, strv.to_ptr end describe "::wrap" do it "takes a pointer and returns a GLib::Strv wrapping it" do strv = GLib::Strv.wrap :some_pointer assert_instance_of GLib::Strv, strv assert_equal :some_pointer, strv.to_ptr end end describe "#each" do it "yields each string element" do ary = ["one", "two", "three"] ptrs = ary.map {|a| FFI::MemoryPointer.from_string(a)} ptrs << nil block = FFI::MemoryPointer.new(:pointer, ptrs.length) block.write_array_of_pointer ptrs strv = GLib::Strv.new block arr = [] strv.each do |str| arr << str end assert_equal ["one", "two", "three"], arr end it "yields zero times for a Strv wrapping a null pointer" do strv = GLib::Strv.new FFI::Pointer.new(0) strv.each do |str| flunk end end end it "includes Enumerable" do GLib::Strv.must_include Enumerable end end gir_ffi-0.6.7/test/gir_ffi-base/glib/boolean_test.rb0000644000004100000410000000142512224462647022410 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GLib::Boolean do it "has the same native size as an int" do FFI.type_size(GLib::Boolean).must_equal FFI.type_size :int end describe ".from_native" do it "converts 0 to false" do GLib::Boolean.from_native(0, "whatever").must_equal false end it "converts 1 to true" do GLib::Boolean.from_native(1, "whatever").must_equal true end end describe ".to_native" do it "converts false to 0" do GLib::Boolean.to_native(false, "whatever").must_equal 0 end it "converts true to 1" do GLib::Boolean.to_native(true, "whatever").must_equal 1 end end describe ".size" do it "returns the correct type size" do GLib::Boolean.size.must_equal FFI.type_size :int end end end gir_ffi-0.6.7/test/gir_ffi_test.rb0000644000004100000410000000557012224462647017151 0ustar www-datawww-datarequire 'gir_ffi_test_helper' GirFFI.setup :GIMarshallingTests describe GirFFI do it "sets up cairo as Cairo" do GirFFI.setup :cairo assert Object.const_defined?(:Cairo) end it "sets up xlib, which has no shared library" do gir = GObjectIntrospection::IRepository.default gir.require 'xlib' assert_nil gir.shared_library('xlib'), "Precondition for test failed" GirFFI.setup :xlib end it "sets up dependencies" do save_module :GObject save_module :Regress GirFFI.setup :Regress assert Object.const_defined?(:GObject) restore_module :Regress restore_module :GObject end describe "::define_type" do describe "without a block" do before do @klass = Class.new GIMarshallingTests::OverridesObject Object.const_set "DerivedA#{Sequence.next}", @klass @gtype = GirFFI.define_type @klass end it "returns a GType for the derived class" do parent_gtype = GIMarshallingTests::OverridesObject.get_gtype @gtype.wont_equal parent_gtype GObject.type_name(@gtype).must_equal @klass.name end it "makes #get_gtype on the registered class return the new GType" do @klass.get_gtype.must_equal @gtype end it "registers a type with the same size as the parent" do q = GObject.type_query @gtype q.instance_size.must_equal GIMarshallingTests::OverridesObject::Struct.size end it "creates a struct class for the derived class with just one member" do @klass::Struct.members.must_equal [:parent] end it "allows the new class to be instantiated" do obj = @klass.new type = GObject.type_from_instance obj type.must_equal @gtype end it "makes GirFFI find the new class by GType" do klass = GirFFI::Builder.build_by_gtype @gtype klass.must_equal @klass end end describe "with a block with a call to #install_property" do before do @klass = Class.new GIMarshallingTests::OverridesObject Object.const_set "DerivedB#{Sequence.next}", @klass @gtype = GirFFI.define_type @klass do install_property GObject.param_spec_int("foo", "foo bar", "The Foo Bar Property", 10, 20, 15, 3) end end it "registers a type that is bigger than the parent" do q = GObject.type_query @gtype q.instance_size.must_be :>, GIMarshallingTests::OverridesObject::Struct.size end it "gives the types Struct the fields :parent and :foo" do @klass::Struct.members.must_equal [:parent, :foo] end it "creates accessor functions for the property" do obj = @klass.new obj.foo = 13 obj.foo.must_equal 13 end end end end gir_ffi-0.6.7/test/ffi-gobject_introspection/0000755000004100000410000000000012224462647021310 5ustar www-datawww-datagir_ffi-0.6.7/test/ffi-gobject_introspection/i_constant_info_test.rb0000644000004100000410000000107612224462647026054 0ustar www-datawww-datarequire 'introspection_test_helper' describe GObjectIntrospection::IConstantInfo do describe "for GLib::USEC_PER_SEC, a constant of type :gint32" do before do @info = get_introspection_data 'GLib', 'USEC_PER_SEC' end it "returns :gint32 as its type" do assert_equal :gint32, @info.constant_type.tag end it "returns a value union with member :v_int32 with value 1_000_000" do assert_equal 1_000_000, @info.value_union[:v_int32] end it "returns 1 as its value" do assert_equal 1_000_000, @info.value end end end gir_ffi-0.6.7/test/ffi-gobject_introspection/i_base_info_test.rb0000644000004100000410000000216512224462647025135 0ustar www-datawww-datarequire 'introspection_test_helper' describe GObjectIntrospection::IBaseInfo do let(:described_class) { GObjectIntrospection::IBaseInfo } describe "#initialize" do it "raises an error if a null pointer is passed" do mock(ptr = Object.new).null? { true } proc { described_class.new ptr }.must_raise ArgumentError end it "raises no error if a non-null pointer is passed" do mock(ptr = Object.new).null? { false } described_class.new ptr pass end end describe "upon garbage collection" do it "calls g_base_info_unref" do if defined?(RUBY_ENGINE) && ['jruby', 'rbx'].include?(RUBY_ENGINE) skip "cannot be reliably tested on JRuby and Rubinius" end mock(ptr = Object.new).null? { false } mock(lib = Object.new).g_base_info_unref(ptr) { nil } described_class.new ptr, lib GC.start # Yes, the next three lines are needed. https://gist.github.com/4277829 stub(ptr2 = Object.new).null? { false } stub(lib).g_base_info_unref(ptr2) { nil } described_class.new ptr2, lib GC.start GC.start end end end gir_ffi-0.6.7/test/ffi-gobject_introspection/i_repository_test.rb0000644000004100000410000000302112224462647025417 0ustar www-datawww-datarequire 'introspection_test_helper' describe GObjectIntrospection::IRepository do describe "an instance" do it "is not created by calling new()" do assert_raises NoMethodError do GObjectIntrospection::IRepository.new end end it "is created by calling default()" do gir = GObjectIntrospection::IRepository.default assert_kind_of GObjectIntrospection::IRepository, gir end it "is a singleton" do gir = GObjectIntrospection::IRepository.default gir2 = GObjectIntrospection::IRepository.default assert_equal gir, gir2 end end let(:gir) { GObjectIntrospection::IRepository.default } describe "#require" do it "raises an error if the namespace doesn't exist" do assert_raises RuntimeError do gir.require 'VeryUnlikelyGObjectNamespaceName', nil end end it "allows version to be nil" do gir.require 'GObject', nil pass end it "allows version to be left out" do gir.require 'GObject' pass end end describe "#find_by_gtype" do it "raises an error if 0 is passed as the gtype" do lambda { gir.find_by_gtype 0 }.must_raise ArgumentError end end describe "enumerating the infos for GObject" do before do gir.require 'GObject', "2.0" end it "yields more than one object" do assert_operator gir.n_infos('GObject'), :>, 0 end it "yields IBaseInfo objects" do assert_kind_of GObjectIntrospection::IBaseInfo, gir.info('GObject', 0) end end end gir_ffi-0.6.7/test/ffi-gobject_introspection/lib_test.rb0000644000004100000410000000043012224462647023437 0ustar www-datawww-datarequire 'introspection_test_helper' describe GObjectIntrospection::Lib::GIArgument do describe "its member :v_ssize" do it "is signed" do gia = GObjectIntrospection::Lib::GIArgument.new gia[:v_int64] = -1 assert_equal(-1, gia[:v_ssize]) end end end gir_ffi-0.6.7/test/ffi-gobject_introspection/i_function_info_test.rb0000644000004100000410000000013312224462647026041 0ustar www-datawww-datarequire 'introspection_test_helper' describe GObjectIntrospection::IFunctionInfo do end gir_ffi-0.6.7/test/ffi-gobject_introspection/i_enum_info_test.rb0000644000004100000410000000062612224462647025167 0ustar www-datawww-datarequire 'introspection_test_helper' describe GObjectIntrospection::IEnumInfo do describe "#find_method" do before do gir = GObjectIntrospection::IRepository.default gir.require 'Regress', nil @info = gir.find_by_name 'Regress', 'TestEnum' end it "finds a method by name" do result = @info.find_method("param") result.name.must_equal "param" end end end gir_ffi-0.6.7/test/ffi-gobject_introspection/i_object_info_test.rb0000644000004100000410000000056312224462647025471 0ustar www-datawww-datarequire 'introspection_test_helper' describe GObjectIntrospection::IObjectInfo do describe "#find_vfunc" do before do gir = GObjectIntrospection::IRepository.default gir.require 'GObject', nil @info = gir.find_by_name 'GObject', 'Object' end it "finds a vfunc by name" do @info.find_vfunc("finalize").wont_be_nil end end end gir_ffi-0.6.7/test/gir_ffi/0000755000004100000410000000000012224462647015556 5ustar www-datawww-datagir_ffi-0.6.7/test/gir_ffi/arg_helper_test.rb0000644000004100000410000000015412224462647021252 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::ArgHelper do it "has no more tests" do pass end end gir_ffi-0.6.7/test/gir_ffi/type_map_test.rb0000644000004100000410000000072712224462647020766 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::TypeMap do describe ".type_specification_to_ffitype" do it "returns the nested FFI::Enum for an Enum module" do GirFFI::TypeMap.type_specification_to_ffitype(GLib::DateMonth). must_equal GLib::DateMonth::Enum end it "returns the class itself for a Struct class" do GirFFI::TypeMap.type_specification_to_ffitype(GObject::EnumValue). must_equal GObject::EnumValue end end end gir_ffi-0.6.7/test/gir_ffi/info_ext/0000755000004100000410000000000012224462647017371 5ustar www-datawww-datagir_ffi-0.6.7/test/gir_ffi/info_ext/i_type_info_test.rb0000644000004100000410000003532412224462647023270 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::InfoExt::ITypeInfo do let(:klass) { Class.new do include GirFFI::InfoExt::ITypeInfo end } let(:type_info) { klass.new } let(:elmtype_info) { klass.new } let(:keytype_info) { klass.new } let(:valtype_info) { klass.new } let(:iface_info) { Object.new } let(:callback_type_info) { get_introspection_data('Regress', 'test_callback').args[0].argument_type } describe "#to_ffitype" do it "returns an array with elements subtype and size for type :array" do mock(type_info).pointer? { false } stub(type_info).tag { :array } mock(type_info).array_fixed_size { 2 } mock(elmtype_info).to_ffitype { :foo } mock(type_info).param_type(0) { elmtype_info } result = type_info.to_ffitype assert_equal [:foo, 2], result end describe "for an :interface type" do before do stub(type_info).interface { iface_info } stub(type_info).tag { :interface } stub(type_info).pointer? { false } end it "maps a the interface's ffitype" do stub(iface_info).to_ffitype { :foo } type_info.to_ffitype.must_equal :foo end end end describe "#element_type" do it "returns the element type for lists" do stub(elmtype_info).tag { :foo } mock(elmtype_info).pointer? { false } mock(type_info).tag {:glist} mock(type_info).param_type(0) { elmtype_info } result = type_info.element_type result.must_equal :foo end it "returns the key and value types for ghashes" do stub(keytype_info).tag { :foo } mock(keytype_info).pointer? { false } stub(valtype_info).tag { :bar } mock(valtype_info).pointer? { false } mock(type_info).tag {:ghash} mock(type_info).param_type(0) { keytype_info } mock(type_info).param_type(1) { valtype_info } result = type_info.element_type result.must_equal [:foo, :bar] end it "returns nil for other types" do mock(type_info).tag {:foo} result = type_info.element_type result.must_be_nil end it "returns [:pointer, :void] if the element type is a pointer with tag :void" do stub(elmtype_info).tag_or_class { [:pointer, :void] } mock(type_info).tag {:glist} mock(type_info).param_type(0) { elmtype_info } assert_equal [:pointer, :void], type_info.element_type end end describe "#flattened_tag" do describe "for a simple type" do it "returns the type tag" do stub(type_info).tag { :uint32 } type_info.flattened_tag.must_equal :uint32 end end describe "for a zero-terminated array" do before do stub(type_info).tag { :array } stub(type_info).param_type(0) { elmtype_info } stub(type_info).zero_terminated? { true } end describe "of utf8" do it "returns :strv" do stub(elmtype_info).tag { :utf8 } stub(elmtype_info).pointer? { true } type_info.flattened_tag.must_equal :strv end end describe "of filename" do it "returns :strv" do stub(elmtype_info).tag { :filename } stub(elmtype_info).pointer? { true } type_info.flattened_tag.must_equal :strv end end describe "of another type" do it "returns :zero_terminated" do stub(elmtype_info).tag { :foo } stub(elmtype_info).pointer? { false } type_info.flattened_tag.must_equal :zero_terminated end end end describe "for a fixed length c-like array" do it "returns :c" do mock(type_info).tag { :array } mock(type_info).zero_terminated? { false } mock(type_info).array_type { :c } type_info.flattened_tag.must_equal :c end end describe "for a GLib array" do it "returns :c" do mock(type_info).tag { :array } mock(type_info).zero_terminated? { false } mock(type_info).array_type { :array } type_info.flattened_tag.must_equal :array end end end describe "#subtype_tag_or_class" do describe "without a parameter" do it "returns the result of calling #tag_or_class on the first param_type" do mock(elmtype_info).tag_or_class { :foo } mock(type_info).param_type(0) { elmtype_info } type_info.subtype_tag_or_class.must_equal :foo end end end describe "#tag_or_class" do describe "for a simple type" do it "returns the type's tag" do stub(type_info).tag { :foo } mock(type_info).pointer? { false } type_info.tag_or_class.must_equal :foo end end describe "for utf8 strings" do it "returns the tag :utf8" do stub(type_info).tag { :utf8 } mock(type_info).pointer? { true } type_info.tag_or_class.must_equal :utf8 end end describe "for filename strings" do it "returns the tag :filename" do stub(type_info).tag { :filename } mock(type_info).pointer? { true } type_info.tag_or_class.must_equal :filename end end describe "for an interface class" do let(:interface) { Object.new } before do stub(type_info).tag { :interface } stub(type_info).interface { iface_info } mock(type_info).pointer? { false } mock(GirFFI::Builder).build_class(iface_info) { interface } end describe "when the interface type is :enum" do it "returns the built interface module" do stub(iface_info).info_type { :enum } type_info.tag_or_class.must_equal interface end end describe "when the interface type is :object" do it "returns an array with elements :pointer and built interface class" do stub(iface_info).info_type { :object } type_info.tag_or_class.must_equal [:pointer, interface] end end describe "when the interface type is :struct" do it "returns the built interface class" do stub(iface_info).info_type { :struct } type_info.tag_or_class.must_equal interface end end end describe "for a callback" do it "returns :callback" do callback_type_info.tag_or_class.must_equal :callback end end describe "for a pointer to simple type :foo" do it "returns [:pointer, :foo]" do stub(type_info).tag { :foo } mock(type_info).pointer? { true } type_info.tag_or_class.must_equal [:pointer, :foo] end end describe "for a pointer to :void" do it "returns [:pointer, :void]" do stub(type_info).tag { :void } stub(type_info).pointer? { true } type_info.tag_or_class.must_equal [:pointer, :void] end end end describe "#to_callback_ffitype" do describe "for an :interface argument" do before do stub(type_info).interface { iface_info } stub(type_info).tag { :interface } stub(type_info).pointer? { false } end it "correctly maps a :union argument to :pointer" do stub(iface_info).info_type { :union } type_info.to_callback_ffitype.must_equal :pointer end it "correctly maps a :flags argument to :int32" do stub(iface_info).info_type { :flags } type_info.to_callback_ffitype.must_equal :int32 end end end describe "#extra_conversion_arguments" do describe "for normal types" do before do stub(type_info).tag { :foo } end it "returns an empty array" do type_info.extra_conversion_arguments.must_equal [] end end describe "for a string" do before do stub(type_info).tag { :utf8 } end it "returns an array containing :utf8" do type_info.extra_conversion_arguments.must_equal [:utf8] end end describe "for a fixed-size array" do before do stub(type_info).tag { :array } stub(type_info).zero_terminated? { false } stub(type_info).array_type { :c } stub(type_info).array_fixed_size { 3 } stub(type_info).param_type(0) { elmtype_info } stub(elmtype_info).tag_or_class { :foo } end it "returns an array containing the element type" do type_info.extra_conversion_arguments.must_equal [:foo, 3] end end describe "for a zero-terminated array" do before do stub(type_info).tag { :array } stub(type_info).zero_terminated? { true } stub(type_info).param_type(0) { elmtype_info } stub(elmtype_info).tag_or_class { :foo } end it "returns an array containing the element type" do type_info.extra_conversion_arguments.must_equal [:foo] end end describe "for a GArray" do before do stub(type_info).tag { :array } stub(type_info).zero_terminated? { false } stub(type_info).array_type { :array } stub(type_info).param_type(0) { elmtype_info } stub(elmtype_info).tag_or_class { :foo } end it "returns an array containing the element type" do type_info.extra_conversion_arguments.must_equal [:foo] end end describe "for a GHashTable" do before do stub(type_info).tag {:ghash} stub(type_info).param_type(0) { keytype_info } stub(type_info).param_type(1) { valtype_info } stub(keytype_info).tag_or_class { :foo } stub(valtype_info).tag_or_class { :bar } end it "returns an array containing the element type pair" do type_info.extra_conversion_arguments.must_equal [[:foo, :bar]] end end describe "for a GList" do before do stub(type_info).tag { :glist } stub(type_info).param_type(0) { elmtype_info } stub(elmtype_info).tag_or_class { :foo } end it "returns an array containing the element type" do type_info.extra_conversion_arguments.must_equal [:foo] end end describe "for a GSList" do before do stub(type_info).tag { :gslist } stub(type_info).param_type(0) { elmtype_info } stub(elmtype_info).tag_or_class { :foo } end it "returns an array containing the element type" do type_info.extra_conversion_arguments.must_equal [:foo] end end describe "for a GPtrArray" do before do stub(type_info).tag { :array } stub(type_info).zero_terminated? { false } stub(type_info).array_type { :ptr_array } stub(type_info).param_type(0) { elmtype_info } stub(elmtype_info).tag_or_class { :foo } end it "returns an array containing the element type" do type_info.extra_conversion_arguments.must_equal [:foo] end end describe "for a :callback" do before do stub(interface_type_info = Object.new).namespace { "Bar" } stub(interface_type_info).name { "Foo" } stub(type_info).tag { :callback } stub(type_info).interface { interface_type_info } end it "has the correct value for #pre" do type_info.extra_conversion_arguments.must_equal [] end end end describe "#argument_class_name" do before do stub(type_info).tag { tag } end describe "for :gint32" do let(:tag) { :gint32 } it "is nil" do type_info.argument_class_name.must_be_nil end end describe "for interfaces" do let(:tag) { :interface } before do stub(type_info).interface { iface_info } stub(iface_info).info_type { interface_type } stub(iface_info).full_type_name { 'Bar::Foo' } end describe "for :struct" do let(:interface_type) { :struct } it "equals the struct class name" do type_info.argument_class_name.must_equal 'Bar::Foo' end end describe "for :union" do let(:interface_type) { :union } it "equals the union class name" do type_info.argument_class_name.must_equal 'Bar::Foo' end end describe "for :interface" do let(:interface_type) { :interface } it "equals the interface module name" do type_info.argument_class_name.must_equal 'Bar::Foo' end end describe "for :object" do let(:interface_type) { :object } it "equals the object class name" do type_info.argument_class_name.must_equal 'Bar::Foo' end end describe "for :callback" do let(:interface_type) { :callback } it "equals the callback type name" do type_info.argument_class_name.must_equal 'Bar::Foo' end end end describe "for :strv" do let(:tag) { :strv } it "equals GLib::Strv" do type_info.argument_class_name.must_equal 'GLib::Strv' end end describe "for arrays" do let(:tag) { :array } before do stub(type_info).param_type(0) { elmtype_info } stub(elmtype_info).tag_or_class { :foo } end describe "for :zero_terminated" do before do stub(type_info).zero_terminated? { true } end it "equals GirFFI::ZeroTerminated" do type_info.argument_class_name.must_equal "GirFFI::ZeroTerminated" end end describe "for :byte_array" do before do stub(type_info).zero_terminated? { false } stub(type_info).array_type { :byte_array } end it "equals GLib::ByteArray" do type_info.argument_class_name.must_equal 'GLib::ByteArray' end end describe "for :ptr_array" do before do stub(type_info).zero_terminated? { false } stub(type_info).array_type { :ptr_array } end it "equals GLib::PtrArray" do type_info.argument_class_name.must_equal 'GLib::PtrArray' end end describe "for :array" do before do stub(type_info).zero_terminated? { false } stub(type_info).array_type { :array } end it "equals GLib::Array" do type_info.argument_class_name.must_equal 'GLib::Array' end end end describe "for :glist" do let(:tag) { :glist } it "equals GLib::List" do type_info.argument_class_name.must_equal 'GLib::List' end end describe "for :gslist" do let(:tag) { :gslist } it "equals GLib::SList" do type_info.argument_class_name.must_equal 'GLib::SList' end end describe "for :ghash" do let(:tag) { :ghash } it "equals GLib::HashTable" do type_info.argument_class_name.must_equal 'GLib::HashTable' end end describe "for :error" do let(:tag) { :error } it "equals GLib::Error" do type_info.argument_class_name.must_equal 'GLib::Error' end end end end gir_ffi-0.6.7/test/gir_ffi/info_ext/i_callable_info_test.rb0000644000004100000410000000164412224462647024044 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::InfoExt::ICallableInfo do let(:klass) { Class.new do include GirFFI::InfoExt::ICallableInfo end } let(:callable_info) { klass.new } describe "#argument_ffi_types" do describe "for a simple callable with several arguments" do before do stub(arg_info1 = Object.new).to_ffitype { :type1 } stub(arg_info2 = Object.new).to_ffitype { :type2 } stub(callable_info).args { [arg_info1, arg_info2] } end it "returns the ffi types of the arguments" do callable_info.argument_ffi_types.must_equal [:type1, :type2] end end end describe "#return_ffi_type" do it "returns the ffi type of the return type" do stub(return_type_info = Object.new).to_ffitype { :some_type } stub(callable_info).return_type { return_type_info } callable_info.return_ffi_type.must_equal :some_type end end end gir_ffi-0.6.7/test/gir_ffi/info_ext/i_signal_info_test.rb0000644000004100000410000000260012224462647023553 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::InfoExt::ISignalInfo do let(:klass) { Class.new do include GirFFI::InfoExt::ICallableInfo include GirFFI::InfoExt::ISignalInfo end } let(:signal_info) { klass.new } describe "#signal_arguments_to_gvalue_array" do let(:object) { Regress::TestSubObj.new } let(:boxed) { Regress::TestSimpleBoxedA.const_return } let(:signal_info) { Regress::TestSubObj.find_signal "test-with-static-scope-arg" } let(:result) { signal_info.signal_arguments_to_gvalue_array(object, boxed) } it "wraps its arguments in a GObject::ValueArray" do result.must_be_instance_of GObject::ValueArray result.n_values.must_equal 2 end it "correctly wraps :object" do result.get_nth(0).get_value.must_equal object end it "correctly wraps :struct" do result_boxed = result.get_nth(1).get_value result_boxed.some_int8.must_equal boxed.some_int8 result_boxed.some_int.must_equal boxed.some_int end end describe "#return_ffi_type" do # FIXME: This is needed because callbacks are limited in the accepted # types. This should be fixed in FFI. it "returns :bool for the :gboolean type" do stub(return_type_info = Object.new).to_ffitype { GLib::Boolean } stub(signal_info).return_type { return_type_info } signal_info.return_ffi_type.must_equal :bool end end end gir_ffi-0.6.7/test/gir_ffi/info_ext/i_function_info_test.rb0000644000004100000410000000345512224462647024134 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::InfoExt::IFunctionInfo do let(:klass) { Class.new do include GirFFI::InfoExt::ICallableInfo include GirFFI::InfoExt::IFunctionInfo end } let(:function_info) { klass.new } describe "#argument_ffi_types" do before do stub(arg_info1 = Object.new).to_ffitype { :type1 } stub(arg_info2 = Object.new).to_ffitype { :type2 } stub(function_info).args { [arg_info1, arg_info2] } end describe "for a simple function with several arguments" do before do stub(function_info).method? { false } stub(function_info).throws? { false } end it "returns the ffi types of the arguments" do function_info.argument_ffi_types.must_equal [:type1, :type2] end end describe "for a throwing function with several arguments" do before do stub(function_info).method? { false } stub(function_info).throws? { true } end it "appends :pointer to represent the error argument" do function_info.argument_ffi_types.must_equal [:type1, :type2, :pointer] end end describe "for a method with several arguments" do before do stub(function_info).method? { true } stub(function_info).throws? { false } end it "prepends :pointer to represent the method reciever" do function_info.argument_ffi_types.must_equal [:pointer, :type1, :type2] end end describe "for a throwing method with several arguments" do before do stub(function_info).method? { true } stub(function_info).throws? { true } end it "adds :pointer for both the reciever and the error argument" do function_info.argument_ffi_types.must_equal [:pointer, :type1, :type2, :pointer] end end end end gir_ffi-0.6.7/test/gir_ffi/info_ext/safe_function_name_test.rb0000644000004100000410000000074712224462647024610 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::InfoExt::SafeFunctionName do let(:klass) { Class.new do include GirFFI::InfoExt::SafeFunctionName end } let(:info) { klass.new } describe "#safe_name" do it "keeps lower case names lower case" do mock(info).name { "foo" } assert_equal "foo", info.safe_name end it "returns a non-empty string if name is empty" do mock(info).name { "" } assert_equal "_", info.safe_name end end end gir_ffi-0.6.7/test/gir_ffi/info_ext/safe_constant_name_test.rb0000644000004100000410000000104012224462647024577 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::InfoExt::SafeConstantName do let(:klass) { Class.new do include GirFFI::InfoExt::SafeConstantName end } let(:info) { klass.new } describe "#safe_name" do it "makes names starting with an underscore safe" do mock(info).name { "_foo" } assert_equal "Private___foo", info.safe_name end it "makes names with dashes safe" do mock(info).name { "this-could-be-a-signal-name" } info.safe_name.must_equal "This_could_be_a_signal_name" end end end gir_ffi-0.6.7/test/gir_ffi/info_ext/i_field_info_test.rb0000644000004100000410000000155612224462647023372 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::InfoExt::IFieldInfo do let(:klass) { Class.new do include GirFFI::InfoExt::IFieldInfo end } let(:field_info) { klass.new } describe "#layout_specification" do it "returns an array of name, typespec and offset" do mock(type = Object.new).to_ffitype { :bar } mock(field_info).name { "foo" } mock(field_info).field_type { type } mock(field_info).offset { 0 } result = field_info.layout_specification assert_equal [:foo, :bar, 0], result end it "keeps a complex typespec intact" do mock(type = Object.new).to_ffitype { [:bar, 2] } mock(field_info).name { "foo" } mock(field_info).field_type { type } mock(field_info).offset { 0 } result = field_info.layout_specification assert_equal [:foo, [:bar, 2], 0], result end end end gir_ffi-0.6.7/test/gir_ffi/object_base_test.rb0000644000004100000410000000070212224462647021401 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::ObjectBase do let(:derived_class) { Class.new GirFFI::ObjectBase } describe ".wrap" do it "delegates conversion to the wrapped pointer" do mock(ptr = Object.new).to_object { "good-result" } derived_class.wrap(ptr).must_equal "good-result" end end describe ".to_ffitype" do it "returns :pointer" do derived_class.to_ffitype.must_equal :pointer end end end gir_ffi-0.6.7/test/gir_ffi/callback_base_test.rb0000644000004100000410000000044612224462647021674 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::CallbackBase do describe ".store_callback" do it "stores the passed in proc in CALLBACKS" do GirFFI::CallbackBase.store_callback "some-callback" GirFFI::CallbackBase::CALLBACKS.last.must_equal "some-callback" end end end gir_ffi-0.6.7/test/gir_ffi/user_defined_property_info_test.rb0000644000004100000410000000114712224462647024560 0ustar www-datawww-datarequire 'gir_ffi_test_helper' require 'gir_ffi/user_defined_property_info' describe GirFFI::UserDefinedPropertyInfo do describe "#param_spec" do it "returns the passed in parameter specification" do info = GirFFI::UserDefinedPropertyInfo.new :some_param_spec info.param_spec.must_equal :some_param_spec end end describe "#name" do it "returns the name retrieved from the parameter specification" do mock(param_spec = Object.new).get_name { :property_name } info = GirFFI::UserDefinedPropertyInfo.new param_spec info.name.must_equal :property_name end end end gir_ffi-0.6.7/test/gir_ffi/zero_terminated_test.rb0000644000004100000410000000455012224462647022341 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::ZeroTerminated do describe ".from" do let(:result) { GirFFI::ZeroTerminated.from :int32, [1, 2, 3] } it "converts the passed array into a zero-terminated c array" do ptr = result.to_ptr ptr.read_array_of_int32(4).must_equal [1, 2, 3, 0] end it "returns a GirFFI::ZeroTerminated object" do result.must_be_instance_of GirFFI::ZeroTerminated end end describe ".wrap" do it "wraps the given type and pointer" do ptr = GirFFI::InPointer.from_array :int32, [1, 2, 3, 0] zt = GirFFI::ZeroTerminated.wrap :foo, ptr zt.element_type.must_equal :foo zt.to_ptr.must_equal ptr end end describe "#each" do it "yields each element" do zt = GirFFI::ZeroTerminated.from :int32, [1, 2, 3] arr = [] zt.each do |int| arr << int end arr.must_equal [1, 2, 3] end it "yields zero times for a ZeroTerminated wrapping a null pointer" do zt = GirFFI::ZeroTerminated.wrap :int32, FFI::Pointer.new(0) zt.each do |str| flunk end end it "works for :int8" do zt = GirFFI::ZeroTerminated.from :int8, [1, 2, 3] arr = [] zt.each do |int| arr << int end arr.must_equal [1, 2, 3] end end describe "#==" do it "returns true when comparing to an array with the same elements" do zero_terminated = GirFFI::ZeroTerminated.from :int32, [1, 2, 3] (zero_terminated == [1, 2, 3]).must_equal true end it "returns false when comparing to an array with different elements" do zero_terminated = GirFFI::ZeroTerminated.from :int32, [1, 2, 3] (zero_terminated == [1, 2]).must_equal false end it "returns true when comparing to a zero-terminated array with the same elements" do zero_terminated = GirFFI::ZeroTerminated.from :int32, [1, 2, 3] other = GirFFI::ZeroTerminated.from :int32, [1, 2, 3] (zero_terminated == other).must_equal true end it "returns false when comparing to a zero-terminated array with different elements" do zero_terminated = GirFFI::ZeroTerminated.from :int32, [1, 2, 3] other = GirFFI::ZeroTerminated.from :int32, [1, 2] (zero_terminated == other).must_equal false end end it "includes Enumerable" do GirFFI::ZeroTerminated.must_include Enumerable end end gir_ffi-0.6.7/test/gir_ffi/builders/0000755000004100000410000000000012224462647017367 5ustar www-datawww-datagir_ffi-0.6.7/test/gir_ffi/builders/user_defined_builder_test.rb0000644000004100000410000000227112224462647025117 0ustar www-datawww-datarequire 'gir_ffi_test_helper' GirFFI.setup :GIMarshallingTests describe GirFFI::Builders::UserDefinedBuilder do describe "with type info containing one property" do before do @klass = Class.new GIMarshallingTests::OverridesObject Object.const_set "DerivedC#{Sequence.next}", @klass @info = GirFFI::UserDefinedTypeInfo.new @klass do install_property GObject.param_spec_int("foo", "foo bar", "The Foo Bar Property", 10, 20, 15, 3) end @builder = GirFFI::Builders::UserDefinedBuilder.new @info @builder.build_class end it "registers a type that is bigger than the parent" do gtype = @klass.get_gtype q = GObject.type_query gtype q.instance_size.must_be :>, GIMarshallingTests::OverridesObject::Struct.size end it "gives the types Struct the fields :parent and :foo" do @klass::Struct.members.must_equal [:parent, :foo] end it "creates accessor functions for the property" do obj = @klass.new obj.foo = 13 obj.foo.must_equal 13 end end end gir_ffi-0.6.7/test/gir_ffi/builders/module_builder_test.rb0000644000004100000410000000330612224462647023750 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::Builders::ModuleBuilder do describe "#function_definition" do it "delegates to GirFFI::Builders::FunctionBuilder#generate" do builder = GirFFI::Builders::ModuleBuilder.new "Foo" mock(fb = Object.new).generate { "function body" } mock(GirFFI::Builders::FunctionBuilder).new("info") { fb } result = builder.send :function_definition, "info" assert_equal "function body", result end end describe "#sub_builder" do describe "for a :function argument" do it "creates a GirFFI::Builders::FunctionBuilder object" do builder = GirFFI::Builders::ModuleBuilder.new "Foo" stub(info = Object.new).info_type { :function } result = builder.send :sub_builder, info assert_instance_of GirFFI::Builders::FunctionBuilder, result end end describe "for an :object argument" do it "creates a GirFFI::Builders::ObjectBuilder object" do builder = GirFFI::Builders::ModuleBuilder.new "Foo" stub(info = Object.new).info_type { :object } stub(info).namespace { "Foo" } stub(info).safe_name { "FooClass" } result = builder.send :sub_builder, info assert_instance_of GirFFI::Builders::ObjectBuilder, result end end end describe "#build_namespaced_class" do it "raises a clear error if the named class does not exist" do gir = GObjectIntrospection::IRepository.default stub(gir).require("Foo", nil) { } builder = GirFFI::Builders::ModuleBuilder.new "Foo" mock(gir).find_by_name("Foo", "Bar") { nil } assert_raises NameError do builder.build_namespaced_class :Bar end end end end gir_ffi-0.6.7/test/gir_ffi/builders/argument_builder_test.rb0000644000004100000410000004262112224462647024310 0ustar www-datawww-datarequire 'gir_ffi_test_helper' # Dummy module module Bar module Foo end end # NOTE: All cooperating classes were originally stubbed, but this became # unweildy as functionality was moved between classes. Also, IArgInfo and # related classes are not really classes controlled by GirFFI, as part of their # interface is dictated by GIR's implementation. Therefore, these tests are # being converted to a situation where they test behavior agains real instances # of IArgInfo. describe GirFFI::Builders::ArgumentBuilder do let(:argument_info) { Object.new } let(:type_info) { Object.new } let(:var_gen) { GirFFI::VariableNameGenerator.new } let(:builder) { GirFFI::Builders::ArgumentBuilder.new(var_gen, argument_info) } let(:conversion_arguments) { [] } let(:argument_class_name) { nil } before do stub(argument_info).name { 'foo' } stub(argument_info).argument_type { type_info } stub(argument_info).direction { direction } stub(argument_info).skip? { false } stub(type_info).argument_class_name { argument_class_name } stub(type_info).extra_conversion_arguments { conversion_arguments } end describe "for an argument with direction :in" do let(:direction) { :in } describe "for :callback" do let(:builder) { GirFFI::Builders::ArgumentBuilder.new(var_gen, arg_info) } let(:arg_info) { get_introspection_data('Regress', 'test_callback_destroy_notify').args[0] } it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = ::Regress::TestCallbackUserData.from(callback)" ] end it "has the correct value for #post" do builder.post.must_equal [ ] end end describe "for :zero_terminated" do let(:argument_class_name) { 'GirFFI::ZeroTerminated' } let(:conversion_arguments) { [:foo] } before do stub(type_info).flattened_tag { :zero_terminated } end it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::ZeroTerminated.from(:foo, foo)" ] end it "has the correct value for #post" do builder.post.must_equal [ ] end end end describe "for an argument with direction :out" do let(:direction) { :out } describe "for :enum" do let(:builder) { GirFFI::Builders::ArgumentBuilder.new(var_gen, arg_info) } let(:arg_info) { get_introspection_data("GIMarshallingTests", "genum_out").args[0] } it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.for GIMarshallingTests::GEnum" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = _v1.to_value" ] end end describe "for :flags" do let(:builder) { GirFFI::Builders::ArgumentBuilder.new(var_gen, arg_info) } let(:arg_info) { get_introspection_data("GIMarshallingTests", "flags_out").args[0] } it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.for GIMarshallingTests::Flags" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = _v1.to_value" ] end end describe "for :object" do let(:builder) { GirFFI::Builders::ArgumentBuilder.new(var_gen, arg_info) } let(:arg_info) { get_introspection_data("GIMarshallingTests", "param_spec_out").args[0] } before do # FIXME: Find alternative info that doesn't need a guard. skip unless get_introspection_data("GIMarshallingTests", "param_spec_out") end it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.for [:pointer, GObject::ParamSpec]" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = ::GObject::ParamSpec.wrap(_v1.to_value)" ] end end describe "for :struct" do let(:argument_class_name) { 'Bar::Foo' } before do stub(type_info).flattened_tag { :struct } end describe "when not allocated by the caller" do let(:builder) { GirFFI::Builders::ArgumentBuilder.new(var_gen, arg_info) } let(:arg_info) { get_introspection_data("GIMarshallingTests", "boxed_struct_out").args[0] } it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.for [:pointer, GIMarshallingTests::BoxedStruct]" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = ::GIMarshallingTests::BoxedStruct.wrap(_v1.to_value)" ] end end describe "when allocated by the caller" do before do stub(argument_info).caller_allocates? { true } end it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = Bar::Foo.new" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = _v1" ] end end end describe "for :strv" do let(:builder) { GirFFI::Builders::ArgumentBuilder.new(var_gen, arg_info) } let(:arg_info) { get_introspection_data("GIMarshallingTests", "gstrv_out").args[0] } it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.for [:pointer, :strv]" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = GLib::Strv.wrap(_v1.to_value)" ] end end describe "for :array" do let(:builder) { GirFFI::Builders::ArgumentBuilder.new(var_gen, arg_info) } describe "when allocated by the callee" do let(:arg_info) { get_introspection_data("GIMarshallingTests", "garray_utf8_none_out").args[0] } it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.for [:pointer, :array]" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = GLib::Array.wrap(:utf8, _v1.to_value)" ] end end describe "when allocated by the caller" do let(:arg_info) { get_introspection_data("GIMarshallingTests", "garray_utf8_full_out_caller_allocated").args[0] } before do # FIXME: Find alternative info that doesn't need a guard. skip unless get_introspection_data("GIMarshallingTests", "garray_utf8_full_out_caller_allocated") end it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GLib::Array.new :utf8" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = _v1" ] end end end describe "for :ptr_array" do let(:builder) { GirFFI::Builders::ArgumentBuilder.new(var_gen, arg_info) } let(:arg_info) { get_introspection_data("GIMarshallingTests", "gptrarray_utf8_none_out").args[0] } it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.for [:pointer, :ptr_array]" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = GLib::PtrArray.wrap(:utf8, _v1.to_value)" ] end end describe "for :error" do let(:builder) { GirFFI::Builders::ArgumentBuilder.new(var_gen, arg_info) } let(:arg_info) { get_introspection_data("GIMarshallingTests", "gerror_out").args[0] } it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.for [:pointer, :error]" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = GLib::Error.wrap(_v1.to_value)" ] end end describe "for :c" do let(:builder) { GirFFI::Builders::ArgumentBuilder.new(var_gen, arg_info) } describe "with fixed size" do let(:arg_info) { get_introspection_data("GIMarshallingTests", "array_fixed_out").args[0] } it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.for [:pointer, :c]" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = GLib::SizedArray.wrap(:gint32, 4, _v1.to_value)" ] end end describe "with separate size parameter" do let(:arg_info) { get_introspection_data("GIMarshallingTests", "array_out").args[0] } let(:length_argument) { Object.new } before do stub(length_argument).retname { "bar" } builder.length_arg = length_argument end it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.for [:pointer, :c]" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = GLib::SizedArray.wrap(:gint32, bar, _v1.to_value)" ] end end end describe "for :glist" do let(:builder) { GirFFI::Builders::ArgumentBuilder.new(var_gen, arg_info) } let(:arg_info) { get_introspection_data("GIMarshallingTests", "glist_utf8_none_out").args[0] } it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.for [:pointer, :glist]" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = GLib::List.wrap(:utf8, _v1.to_value)" ] end end describe "for :gslist" do let(:builder) { GirFFI::Builders::ArgumentBuilder.new(var_gen, arg_info) } let(:arg_info) { get_introspection_data("GIMarshallingTests", "gslist_utf8_none_out").args[0] } it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.for [:pointer, :gslist]" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = GLib::SList.wrap(:utf8, _v1.to_value)" ] end end describe "for :ghash" do let(:builder) { GirFFI::Builders::ArgumentBuilder.new(var_gen, arg_info) } let(:arg_info) { get_introspection_data("GIMarshallingTests", "ghashtable_utf8_none_out").args[0] } it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.for [:pointer, :ghash]" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = GLib::HashTable.wrap([:utf8, :utf8], _v1.to_value)" ] end end end describe "for an argument with direction :inout" do let(:direction) { :inout } describe "for :enum" do let(:argument_class_name) { 'Bar::Foo' } before do stub(type_info).flattened_tag { :enum } stub(type_info).tag_or_class { Bar::Foo } end it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.from Bar::Foo, foo" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = _v1.to_value" ] end end describe "for :flags" do let(:argument_class_name) { 'Bar::Foo' } before do stub(type_info).flattened_tag { :flags } stub(type_info).tag_or_class { Bar::Foo } end it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.from Bar::Foo, foo" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = _v1.to_value" ] end end describe "for :gint32" do before do stub(type_info).flattened_tag { :gint32 } stub(type_info).tag_or_class { :gint32 } end it "has the correct value for inarg" do builder.inarg.must_equal "foo" end it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.from :gint32, foo" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = _v1.to_value" ] end end describe "for an array length" do let(:function_info) { get_introspection_data('Regress', 'test_array_int_inout') } let(:arg_info) { function_info.args[0] } let(:array_arg_info) { function_info.args[1] } let(:builder) { GirFFI::Builders::ArgumentBuilder.new(var_gen, arg_info) } let(:array_arg_builder) { GirFFI::Builders::ArgumentBuilder.new(var_gen, array_arg_info) } before do builder.array_arg = array_arg_builder end it "has the correct value for #pre" do builder.pre.must_equal [ "n_ints = ints.nil? ? 0 : ints.length", "_v1 = GirFFI::InOutPointer.from :gint32, n_ints" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = _v1.to_value" ] end end describe "for :strv" do let(:argument_class_name) { 'GLib::Strv' } before do stub(type_info).flattened_tag { :strv } stub(type_info).tag_or_class { [:pointer, :array] } end it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.from [:pointer, :array], GLib::Strv.from(foo)" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = GLib::Strv.wrap(_v1.to_value)" ] end end describe "for :ptr_array" do let(:conversion_arguments) { [:foo] } let(:argument_class_name) { 'GLib::PtrArray' } before do stub(type_info).flattened_tag { :ptr_array } stub(type_info).tag_or_class { [:pointer, :array] } end it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.from [:pointer, :array], GLib::PtrArray.from(:foo, foo)" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = GLib::PtrArray.wrap(:foo, _v1.to_value)" ] end end describe "for :utf8" do let(:conversion_arguments) { [:utf8] } let(:argument_class_name) { 'GirFFI::InPointer' } before do stub(type_info).flattened_tag { :utf8 } stub(type_info).tag_or_class { :utf8 } end it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.from :utf8, GirFFI::InPointer.from(:utf8, foo)" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = _v1.to_value.to_utf8" ] end end describe "for :c" do let(:argument_class_name) { 'GLib::SizedArray' } before do stub(type_info).flattened_tag { :c } stub(type_info).tag_or_class { [:pointer, :c] } stub(type_info).subtype_tag_or_class { :bar } end describe "with fixed size" do let(:conversion_arguments) { [:bar, 3] } before do stub(type_info).array_fixed_size { 3 } end it "has the correct value for #pre" do builder.pre.must_equal [ "GirFFI::ArgHelper.check_fixed_array_size 3, foo, \"foo\"", "_v1 = GirFFI::InOutPointer.from [:pointer, :c], GLib::SizedArray.from(:bar, 3, foo)" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = GLib::SizedArray.wrap(:bar, 3, _v1.to_value)" ] end end describe "with separate size parameter" do let(:length_argument) { Object.new } let(:conversion_arguments) { [:bar, -1] } before do stub(type_info).array_fixed_size { -1 } stub(length_argument).retname { "baz" } builder.length_arg = length_argument end it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = GirFFI::InOutPointer.from [:pointer, :c], GLib::SizedArray.from(:bar, -1, foo)" ] end it "has the correct value for #post" do builder.post.must_equal [ "_v2 = GLib::SizedArray.wrap(:bar, baz, _v1.to_value)" ] end end end end describe "for a skipped argument with direction :in" do let(:direction) { :in } before do stub(argument_info).skip? { true } end describe "for :gint32" do before do stub(type_info).flattened_tag { :gint32 } end it "has the correct value for inarg" do builder.inarg.must_be_nil end it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = 0" ] end it "has the correct value for #post" do builder.post.must_equal [] end end end describe "for a skipped argument with direction :inout" do let(:direction) { :inout } before do stub(argument_info).skip? { true } end describe "for :gint32" do before do stub(type_info).flattened_tag { :gint32 } end it "has the correct value for inarg" do builder.inarg.must_be_nil end it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = nil" ] end it "has the correct value for #post" do builder.post.must_equal [] end end end describe "for a skipped argument with direction :out" do let(:direction) { :out } before do stub(argument_info).skip? { true } end describe "for :gint32" do before do stub(type_info).flattened_tag { :gint32 } end it "has the correct value for inarg" do builder.inarg.must_be_nil end it "has the correct value for #pre" do builder.pre.must_equal [ "_v1 = nil" ] end it "has the correct value for #post" do builder.post.must_equal [] end end end end gir_ffi-0.6.7/test/gir_ffi/builders/callback_builder_test.rb0000644000004100000410000000314612224462647024221 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::Builders::CallbackBuilder do let(:builder) { GirFFI::Builders::CallbackBuilder.new callback_info } describe "#mapping_method_definition" do describe "for a callback with arguments and return value" do let(:callback_info) { get_introspection_data "Regress", "TestCallbackFull" } it "returns a valid mapping method" do expected = <<-CODE.reset_indentation def self.call_with_argument_mapping(_proc, _v1, _v2, _v3) _v4 = _v3.to_utf8 _v5 = _proc.call(_v1, _v2, _v4) return _v5 end CODE builder.mapping_method_definition.must_equal expected end end describe "for a callback with no arguments or return value" do let(:callback_info) { get_introspection_data "Regress", "TestSimpleCallback" } it "returns a valid mapping method" do expected = <<-CODE.reset_indentation def self.call_with_argument_mapping(_proc) _proc.call() end CODE builder.mapping_method_definition.must_equal expected end end describe "for a callback with a closure argument" do let(:callback_info) { get_introspection_data "Regress", "TestCallbackUserData" } it "returns a valid mapping method" do expected = <<-CODE.reset_indentation def self.call_with_argument_mapping(_proc, _v1) _v2 = GirFFI::ArgHelper::OBJECT_STORE[_v1.address] _v3 = _proc.call(_v2) return _v3 end CODE builder.mapping_method_definition.must_equal expected end end end end gir_ffi-0.6.7/test/gir_ffi/builders/function_builder_test.rb0000644000004100000410000001365512224462647024320 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::Builders::FunctionBuilder do it "builds a correct definition of Regress:test_array_fixed_out_objects" do go = get_introspection_data 'Regress', 'test_array_fixed_out_objects' skip unless go fbuilder = GirFFI::Builders::FunctionBuilder.new go code = fbuilder.generate expected = <<-CODE def self.test_array_fixed_out_objects _v1 = GirFFI::InOutPointer.for [:pointer, :c] Regress::Lib.regress_test_array_fixed_out_objects _v1 _v2 = GLib::SizedArray.wrap([:pointer, Regress::TestObj], 2, _v1.to_value) return _v2 end CODE assert_equal expected.reset_indentation, code end it "builds a correct definition for functions having a linked length argument" do go = get_introspection_data 'Regress', 'test_array_gint16_in' fbuilder = GirFFI::Builders::FunctionBuilder.new go code = fbuilder.generate expected = <<-CODE def self.test_array_gint16_in ints n_ints = ints.nil? ? 0 : ints.length _v1 = n_ints _v2 = GLib::SizedArray.from(:gint16, -1, ints) _v3 = Regress::Lib.regress_test_array_gint16_in _v1, _v2 return _v3 end CODE assert_equal expected.reset_indentation, code end it "builds a correct definition for functions with callbacks" do go = get_introspection_data 'Regress', 'test_callback_destroy_notify' fbuilder = GirFFI::Builders::FunctionBuilder.new go code = fbuilder.generate expected = <<-CODE def self.test_callback_destroy_notify callback, user_data, notify _v1 = ::Regress::TestCallbackUserData.from(callback) _v2 = GirFFI::InPointer.from(:void, user_data) _v3 = ::GLib::DestroyNotify.from(notify) _v4 = Regress::Lib.regress_test_callback_destroy_notify _v1, _v2, _v3 return _v4 end CODE assert_equal expected.reset_indentation, code end it "builds correct definition for constructors" do go = get_method_introspection_data 'Regress', 'TestObj', 'new_from_file' fbuilder = GirFFI::Builders::FunctionBuilder.new go code = fbuilder.generate expected = <<-CODE def self.new_from_file x _v1 = GirFFI::InPointer.from(:utf8, x) _v2 = FFI::MemoryPointer.new(:pointer).write_pointer nil _v3 = Regress::Lib.regress_test_obj_new_from_file _v1, _v2 GirFFI::ArgHelper.check_error(_v2) _v4 = self.constructor_wrap(_v3) return _v4 end CODE assert_equal expected.reset_indentation, code end it "creates a call to GObject::Value#from for functions that take a GValue" do go = get_introspection_data 'GIMarshallingTests', 'gvalue_in' fbuilder = GirFFI::Builders::FunctionBuilder.new go code = fbuilder.generate expected = <<-CODE def self.gvalue_in value _v1 = ::GObject::Value.from(value) GIMarshallingTests::Lib.gi_marshalling_tests_gvalue_in _v1 end CODE assert_equal expected.reset_indentation, code end it "builds correct definition for functions with a nullable input array" do go = get_introspection_data 'Regress', 'test_array_int_null_in' fbuilder = GirFFI::Builders::FunctionBuilder.new go code = fbuilder.generate expected = <<-CODE def self.test_array_int_null_in arr _v1 = GLib::SizedArray.from(:gint32, -1, arr) len = arr.nil? ? 0 : arr.length _v2 = len Regress::Lib.regress_test_array_int_null_in _v1, _v2 end CODE assert_equal expected.reset_indentation, code end it "builds correct definition for functions with a nullable output array" do go = get_introspection_data 'Regress', 'test_array_int_null_out' fbuilder = GirFFI::Builders::FunctionBuilder.new go code = fbuilder.generate expected = <<-CODE def self.test_array_int_null_out _v1 = GirFFI::InOutPointer.for [:pointer, :c] _v2 = GirFFI::InOutPointer.for :gint32 Regress::Lib.regress_test_array_int_null_out _v1, _v2 _v3 = _v2.to_value _v4 = GLib::SizedArray.wrap(:gint32, _v3, _v1.to_value) return _v4 end CODE assert_equal expected.reset_indentation, code end it "builds the correct definition for a method with an inout array with size argument" do go = get_method_introspection_data 'GIMarshallingTests', 'Object', 'method_array_inout' fbuilder = GirFFI::Builders::FunctionBuilder.new go code = fbuilder.generate expected = <<-CODE def method_array_inout ints _v1 = GirFFI::InOutPointer.from [:pointer, :c], GLib::SizedArray.from(:gint32, -1, ints) length = ints.nil? ? 0 : ints.length _v2 = GirFFI::InOutPointer.from :gint32, length GIMarshallingTests::Lib.gi_marshalling_tests_object_method_array_inout self, _v1, _v2 _v3 = _v2.to_value _v4 = GLib::SizedArray.wrap(:gint32, _v3, _v1.to_value) return _v4 end CODE assert_equal expected.reset_indentation, code end it "builds a correct definition for a simple method" do go = get_method_introspection_data 'Regress', 'TestObj', 'instance_method' fbuilder = GirFFI::Builders::FunctionBuilder.new go code = fbuilder.generate expected = <<-CODE def instance_method _v1 = Regress::Lib.regress_test_obj_instance_method self return _v1 end CODE assert_equal expected.reset_indentation, code end describe "#generate" do let(:builder) { GirFFI::Builders::FunctionBuilder.new function_info } let(:code) { builder.generate } describe "for GLib::Variant.get_strv" do let(:function_info) { get_method_introspection_data 'GLib', 'Variant', 'get_strv' } it "builds a correct definition" do code.must_equal <<-CODE.reset_indentation def get_strv _v1 = nil _v2 = GLib::Lib.g_variant_get_strv self, _v1 _v3 = GLib::Strv.wrap(_v2) return _v3 end CODE end end end end gir_ffi-0.6.7/test/gir_ffi/builders/field_builder_test.rb0000644000004100000410000000605512224462647023552 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::Builders::FieldBuilder do let(:instance) { GirFFI::Builders::FieldBuilder.new field_info } describe "for a field of type :gint8 with an offset" do let(:field_info) { get_field_introspection_data "Regress", "TestSimpleBoxedA", "some_int8" } it "creates the right getter method" do expected = <<-CODE.reset_indentation def some_int8 _v1 = @struct.to_ptr + #{field_info.offset} _v2 = GirFFI::InOutPointer.new(:gint8, _v1) _v3 = _v2.to_value _v3 end CODE instance.getter_def.must_equal expected end it "creates the right setter method" do expected = <<-CODE.reset_indentation def some_int8= value _v1 = @struct.to_ptr + #{field_info.offset} _v2 = GirFFI::InOutPointer.new(:gint8, _v1) _v3 = value _v2.set_value _v3 end CODE instance.setter_def.must_equal expected end end describe "for a field of type :struct" do let(:field_info) { get_field_introspection_data "Regress", "TestBoxed", "nested_a" } it "creates the right getter method" do expected = <<-CODE.reset_indentation def nested_a _v1 = @struct.to_ptr + #{field_info.offset} _v2 = GirFFI::InOutPointer.new(Regress::TestSimpleBoxedA, _v1) _v3 = _v2.to_value _v4 = ::Regress::TestSimpleBoxedA.wrap(_v3) _v4 end CODE instance.getter_def.must_equal expected end end describe "for a field of type :enum" do let(:field_info) { get_field_introspection_data "Regress", "TestStructA", "some_enum" } it "creates the right getter method" do expected = <<-CODE.reset_indentation def some_enum _v1 = @struct.to_ptr + #{field_info.offset} _v2 = GirFFI::InOutPointer.new(Regress::TestEnum, _v1) _v3 = _v2.to_value _v3 end CODE instance.getter_def.must_equal expected end end describe "for an inline fixed-size array field" do let(:field_info) { get_field_introspection_data "Regress", "TestStructE", "some_union" } it "creates the right getter method" do expected = <<-CODE.reset_indentation def some_union _v1 = @struct.to_ptr + #{field_info.offset} _v2 = GirFFI::InOutPointer.new(:c, _v1) _v3 = _v2.to_value _v4 = GLib::SizedArray.wrap(Regress::TestStructE__some_union__union, 2, _v3) _v4 end CODE instance.getter_def.must_equal expected end it "creates the right setter method" do expected = <<-CODE.reset_indentation def some_union= value _v1 = @struct.to_ptr + #{field_info.offset} _v2 = GirFFI::InOutPointer.new(:c, _v1) GirFFI::ArgHelper.check_fixed_array_size 2, value, \"value\" _v3 = GLib::SizedArray.from(Regress::TestStructE__some_union__union, 2, value) _v2.set_value _v3 end CODE instance.setter_def.must_equal expected end end end gir_ffi-0.6.7/test/gir_ffi/builders/interface_builder_test.rb0000644000004100000410000000077312224462647024430 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::Builders::InterfaceBuilder do describe "#build_class" do before do info = get_introspection_data 'GObject', 'TypePlugin' @bldr = GirFFI::Builders::InterfaceBuilder.new info @iface = @bldr.build_class end it "builds an interface as a module" do assert_instance_of Module, @iface end it "creates methods on the interface" do assert_defines_instance_method @iface, :complete_interface_info end end end gir_ffi-0.6.7/test/gir_ffi/builders/struct_builder_test.rb0000644000004100000410000000650512224462647024013 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::Builders::StructBuilder do describe "#layout_specification" do it "returns the correct layout for Regress::TestStructA" do info = get_introspection_data 'Regress', 'TestStructA' builder = GirFFI::Builders::StructBuilder.new info builder.layout_specification.must_equal [:some_int, :int32, 0, :some_int8, :int8, 4, :some_double, :double, 8, :some_enum, Regress::TestEnum::Enum, 16] end end describe "for a struct with a simple layout" do before do module Foo class Bar class Struct end end module Lib end end @field = Object.new @struct = Object.new stub(@struct).safe_name { 'Bar' } stub(@struct).namespace { 'Foo' } stub(@struct).safe_namespace { 'Foo' } stub(@struct).fields { [ @field ] } @builder = GirFFI::Builders::StructBuilder.new @struct end it "creates the correct layout specification" do mock(@field).layout_specification { [:bar, :int32, 0] } spec = @builder.send :layout_specification assert_equal [:bar, :int32, 0], spec end it "creates getter and setter methods" do # FIXME: Loads of stubs. stub(type = Object.new).pointer? { false } stub(type).tag { :gint32 } stub(type).flattened_tag { :gint32 } stub(type).tag_or_class { :gint32 } stub(type).extra_conversion_arguments { [] } stub(@field).field_type { type } stub(@field).name { "bar" } stub(@field).writable? { true } stub(@field).offset { 4 } stub(@field).container { @struct } stub(@struct).find_instance_method { } stub(GirFFI::Builder).build_module('Foo') { Foo } refute Foo::Bar.method_defined?(:bar) refute Foo::Bar.method_defined?(:bar=) @builder.send :setup_field_accessors assert Foo::Bar.method_defined?(:bar) assert Foo::Bar.method_defined?(:bar=) end end describe "for a struct with a layout with a complex type" do it "does not flatten the complex type specification" do mock(simplefield = Object.new).layout_specification { [:bar, :foo, 0] } mock(complexfield = Object.new).layout_specification { [:baz, [:qux, 2], 0] } mock(struct = Object.new).fields { [ simplefield, complexfield ] } stub(struct).safe_name { 'Bar' } stub(struct).namespace { 'Foo' } builder = GirFFI::Builders::StructBuilder.new struct spec = builder.send :layout_specification assert_equal [:bar, :foo, 0, :baz, [:qux, 2], 0], spec end end describe "for a struct without defined fields" do it "uses a single field of the parent struct type as the default layout" do @gir = GObjectIntrospection::IRepository.default @gir.require 'GObject', nil stub(info = Object.new).parent { @gir.find_by_name 'GObject', 'Object' } stub(info).fields { [] } stub(info).info_type { :object } stub(info).safe_name { 'Bar' } stub(info).namespace { 'Foo' } @classbuilder = GirFFI::Builders::ObjectBuilder.new info spec = @classbuilder.send :layout_specification assert_equal [:parent, GObject::Object::Struct, 0], spec end end end gir_ffi-0.6.7/test/gir_ffi/builders/object_builder_test.rb0000644000004100000410000000410612224462647023730 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::Builders::ObjectBuilder do describe '#find_signal' do it 'finds the signal "test" for TestObj' do builder = GirFFI::Builders::ObjectBuilder.new get_introspection_data('Regress', 'TestObj') sig = builder.find_signal 'test' assert_equal 'test', sig.name end it 'finds the signal "test" for TestSubObj' do builder = GirFFI::Builders::ObjectBuilder.new get_introspection_data('Regress', 'TestSubObj') sig = builder.find_signal 'test' assert_equal 'test', sig.name end it 'finds the signal "changed" for Gtk::Entry' do builder = GirFFI::Builders::ObjectBuilder.new get_introspection_data('Gtk', 'Entry') sig = builder.find_signal 'changed' assert_equal 'changed', sig.name end end describe "#find_property" do it "finds a property specified on the class itself" do builder = GirFFI::Builders::ObjectBuilder.new( get_introspection_data('Regress', 'TestObj')) prop = builder.find_property("int") assert_equal "int", prop.name end it "finds a property specified on the parent class" do builder = GirFFI::Builders::ObjectBuilder.new( get_introspection_data('Regress', 'TestSubObj')) prop = builder.find_property("int") assert_equal "int", prop.name end it "raises an error if the property is not found" do builder = GirFFI::Builders::ObjectBuilder.new( get_introspection_data('Regress', 'TestSubObj')) assert_raises RuntimeError do builder.find_property("this-property-does-not-exist") end end end describe "#function_definition" do before do @cbuilder = GirFFI::Builders::ObjectBuilder.new get_introspection_data('Regress', 'TestObj') @go = get_method_introspection_data 'Regress', 'TestObj', 'instance_method' end it "delegates definition to FunctionBuilder" do code = @cbuilder.send :function_definition, @go expected = GirFFI::Builders::FunctionBuilder.new(@go).generate assert_equal cws(expected), cws(code) end end end gir_ffi-0.6.7/test/gir_ffi/builders/signal_builder_test.rb0000644000004100000410000000376612224462647023752 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::Builders::SignalBuilder do let(:builder) { GirFFI::Builders::SignalBuilder.new signal_info } describe "#mapping_method_definition" do describe "for a signal with no arguments or return value" do let(:signal_info) { get_signal_introspection_data "Regress", "TestObj", "test" } it "returns a valid mapping method including receiver and user data" do expected = <<-CODE.reset_indentation def self.call_with_argument_mapping(_proc, _v1, _v2) _v3 = ::Regress::TestObj.wrap(_v1) _v4 = GirFFI::ArgHelper::OBJECT_STORE[_v2.address] _proc.call(_v3, _v4) end CODE builder.mapping_method_definition.must_equal expected end end describe "for a signal with an argument and a return value" do let(:signal_info) { get_signal_introspection_data "Regress", "TestObj", "sig-with-int64-prop" } it "returns a valid mapping method" do skip unless signal_info expected = <<-CODE.reset_indentation def self.call_with_argument_mapping(_proc, _v1, _v2, _v3) _v4 = ::Regress::TestObj.wrap(_v1) _v5 = GirFFI::ArgHelper::OBJECT_STORE[_v3.address] _v6 = _proc.call(_v4, _v2, _v5) return _v6 end CODE builder.mapping_method_definition.must_equal expected end end describe "for a signal with an enum argument" do let(:signal_info) { get_signal_introspection_data "Gio", "MountOperation", "reply" } it "returns a valid mapping method" do expected = <<-CODE.reset_indentation def self.call_with_argument_mapping(_proc, _v1, _v2, _v3) _v4 = ::Gio::MountOperation.wrap(_v1) _v5 = ::Gio::MountOperationResult[_v2] _v6 = GirFFI::ArgHelper::OBJECT_STORE[_v3.address] _proc.call(_v4, _v5, _v6) end CODE builder.mapping_method_definition.must_equal expected end end end end gir_ffi-0.6.7/test/gir_ffi/builders/constant_builder_test.rb0000644000004100000410000000012112224462647024304 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::Builders::ConstantBuilder do end gir_ffi-0.6.7/test/gir_ffi/builders/enum_builder_test.rb0000644000004100000410000000075012224462647023427 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::Builders::EnumBuilder do describe "creating Regress::TestEnum" do before do save_module :Regress end it "makes the created type know its proper name" do info = get_introspection_data 'Regress', 'TestEnum' builder = GirFFI::Builders::EnumBuilder.new info enum = builder.build_class enum.inspect.must_equal "Regress::TestEnum" end after do restore_module :Regress end end end gir_ffi-0.6.7/test/gir_ffi/builders/return_value_builder_test.rb0000644000004100000410000002541412224462647025202 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::Builders::ReturnValueBuilder do let(:type_info) { Object.new } let(:var_gen) { GirFFI::VariableNameGenerator.new } let(:for_constructor) { false } let(:skip) { false } let(:builder) { GirFFI::Builders::ReturnValueBuilder.new(var_gen, type_info, for_constructor, skip) } let(:conversion_arguments) { [] } let(:argument_class_name) { flattened_tag } let(:flattened_tag) { nil } before do stub(type_info).argument_class_name { argument_class_name } stub(type_info).extra_conversion_arguments { conversion_arguments } stub(type_info).flattened_tag { flattened_tag } end describe "for :gint32" do let(:flattened_tag) { :gint32 } it "has no statements in #post" do builder.post.must_equal [] end it "returns the result of the c function directly" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v1" end end describe "for :struct" do let(:argument_class_name) { 'Bar::Foo' } let(:flattened_tag) { :struct } it "wraps the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = Bar::Foo.wrap(_v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end describe "for :union" do let(:argument_class_name) { 'Bar::Foo' } let(:flattened_tag) { :union } it "wraps the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = Bar::Foo.wrap(_v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end describe "for :interface" do let(:argument_class_name) { 'Bar::Foo' } let(:flattened_tag) { :interface } describe "when the method is not a constructor" do let(:for_constructor) { false } it "wraps the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = Bar::Foo.wrap(_v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end describe "when the method is a constructor" do let(:for_constructor) { true } it "wraps the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = self.constructor_wrap(_v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end end describe "for :object" do let(:argument_class_name) { 'Bar::Foo' } let(:flattened_tag) { :object } describe "when the method is not a constructor" do let(:for_constructor) { false } it "wraps the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = Bar::Foo.wrap(_v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end describe "when the method is a constructor" do let(:for_constructor) { true } it "wraps the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = self.constructor_wrap(_v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end end describe "for :strv" do let(:argument_class_name) { 'GLib::Strv' } let(:flattened_tag) { :strv } it "wraps the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = GLib::Strv.wrap(_v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end describe "for :zero_terminated" do let(:argument_class_name) { 'GirFFI::ZeroTerminated' } let(:conversion_arguments) { [:foo] } let(:flattened_tag) { :zero_terminated } it "wraps the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = GirFFI::ZeroTerminated.wrap(:foo, _v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end describe "for :byte_array" do let(:argument_class_name) { 'GLib::ByteArray' } let(:flattened_tag) { :byte_array } it "wraps the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = GLib::ByteArray.wrap(_v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end describe "for :ptr_array" do let(:argument_class_name) { 'GLib::PtrArray' } let(:conversion_arguments) { [:foo] } let(:flattened_tag) { :ptr_array } it "wraps the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = GLib::PtrArray.wrap(:foo, _v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end describe "for :glist" do let(:argument_class_name) { 'GLib::List' } let(:conversion_arguments) { [:foo] } let(:flattened_tag) { :glist } it "wraps the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = GLib::List.wrap(:foo, _v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end describe "for :gslist" do let(:argument_class_name) { 'GLib::SList' } let(:conversion_arguments) { [:foo] } let(:flattened_tag) { :gslist } it "wraps the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = GLib::SList.wrap(:foo, _v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end describe "for :ghash" do let(:argument_class_name) { 'GLib::HashTable' } let(:conversion_arguments) { [[:foo, :bar]] } let(:flattened_tag) { :ghash } it "wraps the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = GLib::HashTable.wrap([:foo, :bar], _v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end describe "for :array" do let(:argument_class_name) { 'GLib::Array' } let(:conversion_arguments) { [:foo] } let(:flattened_tag) { :array } it "wraps the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = GLib::Array.wrap(:foo, _v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end describe "for :error" do let(:argument_class_name) { 'GLib::Error' } let(:flattened_tag) { :error } it "wraps the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = GLib::Error.wrap(_v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end describe "for :c" do let(:argument_class_name) { 'GLib::SizedArray' } describe "with fixed size" do before do stub(type_info).flattened_tag { :c } stub(type_info).subtype_tag_or_class { :foo } stub(type_info).array_fixed_size { 3 } end it "converts the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = GLib::SizedArray.wrap(:foo, 3, _v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end describe "with separate size parameter" do let(:length_argument) { Object.new } before do stub(type_info).flattened_tag { :c } stub(type_info).subtype_tag_or_class { :foo } stub(type_info).array_fixed_size { -1 } stub(length_argument).retname { "bar" } builder.length_arg = length_argument end it "converts the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = GLib::SizedArray.wrap(:foo, bar, _v1)" ] end it "returns the wrapped result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end end describe "for :utf8" do before do stub(type_info).flattened_tag { :utf8 } end it "converts the result in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = _v1.to_utf8" ] end it "returns the converted result" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end describe "for :void pointer" do before do stub(type_info).flattened_tag { :void } stub(type_info).pointer? { true } end it "has no statements in #post" do builder.post.must_equal [] end it "returns the result of the c function directly" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v1" end end describe "for :void" do before do stub(type_info).flattened_tag { :void } stub(type_info).pointer? { false } end it "has no statements in #post" do builder.post.must_equal [] end it "marks itself as irrelevant" do builder.is_relevant?.must_equal false end it "returns nothing" do builder.retval.must_be_nil end end describe "for a closure argument" do let(:tp_info) { get_introspection_data("Regress", "TestCallbackUserData").args[0].argument_type } let(:builder) { GirFFI::Builders::ReturnValueBuilder.new(var_gen, tp_info) } before do builder.is_closure = true end it "fetches the stored object in #post" do builder.callarg.must_equal "_v1" builder.post.must_equal [ "_v2 = GirFFI::ArgHelper::OBJECT_STORE[_v1.address]" ] end it "returns the stored object" do builder.callarg.must_equal "_v1" builder.retval.must_equal "_v2" end end describe "for a skipped return value" do let(:skip) { true } before do stub(type_info).flattened_tag { :uint32 } stub(type_info).pointer? { false } end it "has no statements in #post" do builder.post.must_equal [] end it "marks itself as irrelevant" do builder.is_relevant?.must_equal false end it "returns nothing" do builder.retval.must_be_nil end end end gir_ffi-0.6.7/test/gir_ffi/builders/base_argument_builder_test.rb0000644000004100000410000000011412224462647025271 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::BaseArgumentBuilder do end gir_ffi-0.6.7/test/gir_ffi/builders/union_builder_test.rb0000644000004100000410000000173712224462647023621 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::Builders::UnionBuilder do let(:union_info) { get_introspection_data('GObject', 'TypeCValue') } let(:builder) { GirFFI::Builders::UnionBuilder.new union_info } describe "#setup_instance_method" do it "returns false looking for a method that doesn't exist" do builder.setup_instance_method('blub').must_equal false end end describe "#layout_specification" do it "returns the correct layout for GObject::TypeCValue" do builder.layout_specification.must_equal [:v_int, :int32, 0, :v_long, :int64, 0, :v_int64, :int64, 0, :v_double, :double, 0, :v_pointer, :pointer, 0] end end describe "#layout_superclass" do it "returns FFI::Union" do builder.layout_superclass.must_equal FFI::Union end end end gir_ffi-0.6.7/test/gir_ffi/builders/unintrospectable_builder_test.rb0000644000004100000410000000266412224462647026052 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::Builders::UnintrospectableBuilder do describe "building the GLocalFile type" do before do # Ensure existence of GLocalFile type GirFFI.setup :Gio unless Gio::Lib.respond_to? :g_file_new_for_path Gio.setup_method "file_new_for_path" end ptr = GirFFI::InPointer.from :utf8, '/' Gio::Lib.g_file_new_for_path(ptr) @gtype = GObject.type_from_name 'GLocalFile' @info = GirFFI::UnintrospectableTypeInfo.new(@gtype) @bldr = GirFFI::Builders::UnintrospectableBuilder.new(@info) @klass = @bldr.build_class end it "builds a class" do assert_instance_of Class, @klass end it "builds a class derived from GObject::Object" do assert_includes @klass.ancestors, GObject::Object end it "builds a class derived from Gio::File" do assert_includes @klass.ancestors, Gio::File end it "returns the same class when built again" do other_bldr = GirFFI::Builders::UnintrospectableBuilder.new(@info) other_klass = other_bldr.build_class assert_equal @klass, other_klass end describe "its #find_signal method" do it "raises correct error for a signal that doesn't exist" do msg = nil begin @bldr.find_signal "foo" rescue RuntimeError => e msg = e.message end assert_match(/^Signal/, msg) end end end end gir_ffi-0.6.7/test/gir_ffi/builder_test.rb0000644000004100000410000001554212224462647020577 0ustar www-datawww-datarequire 'gir_ffi_test_helper' GirFFI.setup :Regress describe GirFFI::Builder do let(:gir) { GObjectIntrospection::IRepository.default } describe '.build_class' do it "does not replace existing classes" do oldclass = GObject::Object GirFFI::Builder.build_class get_introspection_data('GObject', 'Object') GObject::Object.must_equal oldclass end end describe '.attach_ffi_function' do let(:lib) { Module.new } it "calls attach_function with the correct types for Regress.test_callback_destroy_notify" do function_info = get_introspection_data 'Regress', 'test_callback_destroy_notify' mock(lib). attach_function("regress_test_callback_destroy_notify", [ Regress::TestCallbackUserData, :pointer, GLib::DestroyNotify ], :int32) { true } GirFFI::Builder.attach_ffi_function(lib, function_info) end it "calls attach_function with the correct types for Regress::TestObj#torture_signature_0" do info = get_method_introspection_data 'Regress', 'TestObj', 'torture_signature_0' mock(lib). attach_function("regress_test_obj_torture_signature_0", [:pointer, :int32, :pointer, :pointer, :pointer, :pointer, :uint32], :void) { true } GirFFI::Builder.attach_ffi_function(lib, info) end it "calls attach_function with the correct types for Regress::TestObj#instance_method" do info = get_method_introspection_data 'Regress', 'TestObj', 'instance_method' mock(lib).attach_function("regress_test_obj_instance_method", [:pointer], :int32) { true } GirFFI::Builder.attach_ffi_function(lib, info) end it "calls attach_function with the correct types for Regress.test_array_gint32_in" do info = get_introspection_data 'Regress', 'test_array_gint32_in' mock(lib).attach_function("regress_test_array_gint32_in", [:int32, :pointer], :int32) { true } GirFFI::Builder.attach_ffi_function(lib, info) end end describe "looking at Regress.test_callback_destroy_notify" do before do save_module :GObject save_module :Regress GirFFI::Builder.build_module 'GObject' GirFFI::Builder.build_module 'Regress' @go = get_introspection_data 'Regress', 'test_callback_destroy_notify' end it "defines ffi callback types :Callback and :ClosureNotify" do Regress.setup_method 'test_callback_destroy_notify' tcud = Regress::Lib.find_type :TestCallbackUserData dn = GLib::Lib.find_type :DestroyNotify assert_equal FFI.find_type(:int32), tcud.result_type assert_equal FFI.find_type(:void), dn.result_type assert_equal [FFI.find_type(:pointer)], tcud.param_types assert_equal [FFI.find_type(:pointer)], dn.param_types end after do restore_module :Regress restore_module :GObject end end describe "building Regress::TestBoxed" do before do GirFFI::Builder.build_class get_introspection_data('Regress', 'TestBoxed') end it "sets up #wrap" do assert Regress::TestBoxed.respond_to? "wrap" end it "sets up #allocate" do assert Regress::TestBoxed.respond_to? "allocate" end end describe "built Regress module" do before do save_module :Regress GirFFI::Builder.build_module 'Regress' end it "autocreates singleton methods" do refute_defines_singleton_method Regress, :test_uint Regress.test_uint 31 assert_defines_singleton_method Regress, :test_uint end it "autocreates the TestObj class on first access" do assert !Regress.const_defined?(:TestObj) Regress::TestObj.must_be_instance_of Class assert Regress.const_defined? :TestObj end it "knows its own module builder" do assert GirFFI::Builders::ModuleBuilder === Regress.gir_ffi_builder end after do restore_module :Regress end end describe "having built Regress::TestObj" do before do GirFFI::Builder.build_class get_introspection_data('Regress', 'TestObj') end it "C functions for called instance methods get attached to Regress::Lib" do o = Regress::TestObj.new_from_file("foo") o.instance_method Regress::Lib.must_respond_to :regress_test_obj_instance_method end it "the built class knows its own GIR info" do Regress::TestObj.gir_info.name.must_equal 'TestObj' end it "the built class knows its own class builder" do Regress::TestObj.gir_ffi_builder.must_be_instance_of GirFFI::Builders::ObjectBuilder end end describe "built Regress::TestSubObj" do it "inherits #set_bare from its superclass" do o1 = Regress::TestSubObj.new o1.set_bare(nil) pass end it "overrides #instance_method" do obj = Regress::TestObj.new_from_file("foo") subobj = Regress::TestSubObj.new obj.instance_method.must_equal(-1) subobj.instance_method.must_equal 0 end end describe "building Regress::TestSubObj" do before do save_module :Regress GirFFI::Builder.build_class get_introspection_data('Regress', 'TestSubObj') end it "builds Regress namespace" do assert Regress.const_defined? :Lib assert Regress.respond_to? :method_missing end it "creates the Regress::Lib module ready to attach functions from the shared library" do expected = [gir.shared_library('Regress')] assert_equal expected, Regress::Lib.ffi_libraries.map(&:name) end it "builds parent classes also" do assert Regress.const_defined? :TestObj assert Object.const_defined? :GObject assert GObject.const_defined? :Object end it "sets up the inheritance chain" do ancestors = Regress::TestSubObj.ancestors assert_equal [ Regress::TestSubObj, Regress::TestObj, GObject::Object ], ancestors[0..2] end it "creates a Regress::TestSubObj#to_ptr method" do assert Regress::TestSubObj.public_method_defined? :to_ptr end after do restore_module :Regress end end describe "building Regress" do before do save_module :Regress GirFFI::Builder.build_module 'Regress' end it "creates a Lib module ready to attach functions from the shared library" do gir = GObjectIntrospection::IRepository.default expected = [gir.shared_library('Regress')] assert_equal expected, Regress::Lib.ffi_libraries.map(&:name) end it "does not replace existing module" do oldmodule = Regress GirFFI::Builder.build_module 'Regress' assert_equal oldmodule, Regress end it "does not replace existing Lib module" do oldmodule = Regress::Lib GirFFI::Builder.build_module 'Regress' assert_equal oldmodule, Regress::Lib end after do restore_module :Regress end end end gir_ffi-0.6.7/test/gir_ffi/ffi_ext/0000755000004100000410000000000012224462647017202 5ustar www-datawww-datagir_ffi-0.6.7/test/gir_ffi/ffi_ext/pointer_test.rb0000644000004100000410000000110512224462647022243 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::FFIExt::Pointer do let(:klass) { Class.new { include GirFFI::FFIExt::Pointer } } describe "#to_object" do it "finds the wrapping class by gtype and wraps the pointer in it" do ptr = klass.new mock(ptr).null? { false } object_class = Class.new mock(GObject).type_from_instance_pointer(ptr) { 0xdeadbeef } mock(GirFFI::Builder).build_by_gtype(0xdeadbeef) { object_class } mock(object_class).direct_wrap(ptr) { "good-result" } ptr.to_object.must_equal "good-result" end end end gir_ffi-0.6.7/test/gir_ffi/in_out_pointer_test.rb0000644000004100000410000000533112224462647022201 0ustar www-datawww-datarequire 'gir_ffi_test_helper' require 'gir_ffi/in_out_pointer' describe GirFFI::InOutPointer do describe ".new" do it "wraps an existing pointer and a type" do ptr = GirFFI::AllocationHelper.safe_malloc(FFI.type_size(:int32)) ptr.put_int32 0, 42 instance = GirFFI::InOutPointer.new :gint32, ptr instance.to_value.must_equal 42 end end describe "an instance created with .from" do before do @result = GirFFI::InOutPointer.from :gint32, 23 end it "holds a pointer to the given value" do assert_equal 23, @result.get_int32(0) end it "is an instance of GirFFI::InOutPointer" do assert_instance_of GirFFI::InOutPointer, @result end end describe ".from" do it "handles :gboolean false" do ptr = GirFFI::InOutPointer.from :gboolean, false ptr.read_int.must_equal 0 end it "handles :gboolean true" do ptr = GirFFI::InOutPointer.from :gboolean, true ptr.read_int.must_equal(1) end it "handles :utf8 pointers" do str_ptr = GirFFI::InPointer.from :utf8, "Hello" GirFFI::InOutPointer.from :utf8, str_ptr end end describe "in instance created with .for" do before do @result = GirFFI::InOutPointer.for :gint32 end it "holds a pointer to a null value" do assert_equal 0, @result.get_int32(0) end it "is an instance of GirFFI::InOutPointer" do assert_instance_of GirFFI::InOutPointer, @result end end describe ".for" do it "handles :gboolean" do GirFFI::InOutPointer.for :gboolean end it "handles :utf8" do GirFFI::InOutPointer.for :utf8 end end describe "#to_value" do it "returns the held value" do ptr = GirFFI::InOutPointer.from :gint32, 123 assert_equal 123, ptr.to_value end describe "for :gboolean values" do it "works when the value is false" do ptr = GirFFI::InOutPointer.from :gboolean, false ptr.to_value.must_equal false end it "works when the value is true" do ptr = GirFFI::InOutPointer.from :gboolean, true ptr.to_value.must_equal true end end describe "for :utf8 values" do it "returns a pointer to the held value" do str_ptr = GirFFI::InPointer.from :utf8, "Some value" ptr = GirFFI::InOutPointer.from :utf8, str_ptr assert_equal "Some value", ptr.to_value.read_string end end describe "for struct values" do it "returns a pointer to the held value" do val = GObject::EnumValue.new val.value = 3 ptr = GirFFI::InOutPointer.from GObject::EnumValue, val result = ptr.to_value GObject::EnumValue.wrap(result).value.must_equal 3 end end end end gir_ffi-0.6.7/test/gir_ffi/in_pointer_test.rb0000644000004100000410000001133512224462647021313 0ustar www-datawww-datarequire 'gir_ffi_test_helper' require 'gir_ffi/in_pointer' describe GirFFI::InPointer do describe ".from_array" do it "returns nil when passed nil" do result = GirFFI::InPointer.from_array :gint32, nil assert_nil result end it "handles type tag :GType" do GirFFI::InPointer.from_array :GType, [2] end it "handles enum types" do e = Module.new do extend GirFFI::EnumBase self::Enum = FFI::Enum.new [:foo, :bar, :baz] end ptr = GirFFI::InPointer.from_array e, [:bar, :foo, :baz] ptr.read_array_of_int32(3).must_equal [1, 0, 2] end it "handles struct types" do e = Class.new(GirFFI::StructBase) do self::Struct = Class.new(GirFFI::Struct) do layout :foo, :int32, :bar, :int32 end end struct = e::Struct.allocate struct[:foo] = 42 struct[:bar] = 24 ptr = GirFFI::InPointer.from_array e, [struct] ptr.wont_equal struct.to_ptr new_struct = e::Struct.new ptr new_struct[:foo].must_equal 42 new_struct[:bar].must_equal 24 end it "handles typed pointers" do p1 = GirFFI::InPointer.from :gint32, 42 p2 = GirFFI::InPointer.from :gint32, 24 ptr = GirFFI::InPointer.from_array [:pointer, :uint32], [p1, p2] ptr.read_array_of_pointer(2).must_equal [p1, p2] end end describe "an instance created with .from_array :gint32" do before do @result = GirFFI::InPointer.from_array :gint32, [24, 13] end it "holds a pointer to the correct input values" do assert_equal 24, @result.get_int(0) assert_equal 13, @result.get_int(4) end it "is an instance of GirFFI::InPointer" do assert_instance_of GirFFI::InPointer, @result end it "is zero-terminated" do assert_equal 0, @result.get_int(8) end end describe "an instance created with .from_array :utf8" do before do @result = GirFFI::InPointer.from_array :utf8, ["foo", "bar", "baz"] end it "returns an array of pointers to strings" do ary = @result.read_array_of_pointer(3) assert_equal ["foo", "bar", "baz"], ary.map {|p| p.read_string} end end describe "an instance created with .from_array :filename" do before do @result = GirFFI::InPointer.from_array :filename, ["foo", "bar", "baz"] end it "returns an array of pointers to strings" do ary = @result.read_array_of_pointer(3) assert_equal ["foo", "bar", "baz"], ary.map {|p| p.read_string} end end describe "an instance created with .from :utf8" do before do @result = GirFFI::InPointer.from :utf8, "foo" end it "returns a pointer to the given string" do assert_equal "foo", @result.read_string end it "is an instance of GirFFI::InPointer" do assert_instance_of GirFFI::InPointer, @result end end describe "an instance created with .from :guint32" do before do @result = GirFFI::InPointer.from :guint32, 12345 end it "returns a pointer with an address equal to the given value" do assert_equal 12345, @result.address end it "is an instance of GirFFI::InPointer" do assert_instance_of GirFFI::InPointer, @result end end describe "an instance created with .from :filename" do before do @result = GirFFI::InPointer.from :filename, "foo" end it "returns a pointer to the given string" do assert_equal "foo", @result.read_string end end describe ".from" do it "returns nil when passed nil" do result = GirFFI::InPointer.from :foo, nil assert_nil result end it "sets the pointer's address to the passed value for type :gint8" do result = GirFFI::InPointer.from :gint8, 23 assert_equal 23, result.address end it "handles enum types" do e = Module.new do self::Enum = FFI::Enum.new [:foo, :bar, :baz] def self.[](val) self::Enum[val] end end ptr = GirFFI::InPointer.from e, :bar ptr.address.must_equal 1 end end describe ".from_object" do describe "when called with an object implementing to_ptr" do it "returns the result of to_ptr" do obj = Object.new def obj.to_ptr; :test_value; end GirFFI::InPointer.from_object(obj).must_equal :test_value end end describe "when called with nil" do it "returns nil" do GirFFI::InPointer.from_object(nil).must_equal nil end end describe "when called with a string" do it "stores the string in GirFFI::ArgHelper::OBJECT_STORE" do str = "Foo" ptr = GirFFI::InPointer.from_object(str) result = GirFFI::ArgHelper::OBJECT_STORE[ptr.address] result.must_equal str end end end end gir_ffi-0.6.7/test/gir_ffi/variable_name_generator_test.rb0000644000004100000410000000064512224462647024002 0ustar www-datawww-datarequire 'gir_ffi_test_helper' require 'gir_ffi/variable_name_generator' describe GirFFI::VariableNameGenerator do describe "#new_var" do it "generates a sequence of predictable variable names" do gen = GirFFI::VariableNameGenerator.new assert_equal "_v1", gen.new_var assert_equal "_v2", gen.new_var assert_equal "_v3", gen.new_var assert_equal "_v4", gen.new_var end end end gir_ffi-0.6.7/test/gir_ffi/class_base_test.rb0000644000004100000410000000615012224462647021243 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::ClassBase do describe "a simple descendant" do let(:klass) { Class.new(GirFFI::ClassBase) do self::Struct = Class.new(FFI::Struct) do layout :foo, :int32 end end } let(:object) { klass.wrap FFI::MemoryPointer.new(:int32) } it "has #from as a pass-through method" do result = klass.from :foo result.must_equal :foo end describe "#==" do it "returns true when comparing to an object of the same class and pointer" do other = klass.wrap object.to_ptr object.must_be :==, other other.must_be :==, object end it "returns true when comparing to an object of the same class and a pointer with the same address" do ptr = FFI::Pointer.new object.to_ptr other = klass.wrap ptr object.must_be :==, other other.must_be :==, object end it "returns false when comparing to an object of a sub/superclass and the same pointer" do subclass = Class.new(klass) other = subclass.wrap object.to_ptr object.wont_be :==, other other.wont_be :==, object end it "returns false when comparing to an object of the same class and different pointer" do other = klass.wrap FFI::MemoryPointer.new(:int32) object.wont_be :==, other other.wont_be :==, object end it "returns false when comparing to an object that doesn't respond to #to_ptr" do other = Object.new object.wont_be :==, other other.wont_be :==, object end it "returns false when comparing to an object of a different class and same pointer" do stub(other = Object.new).to_ptr { object.to_ptr } object.wont_be :==, other other.wont_be :==, object end it "returns false when comparing to an object of a different class and different pointer" do stub(other = Object.new).to_ptr { FFI::MemoryPointer.new(:int32) } object.wont_be :==, other other.wont_be :==, object end end end describe "a descendant with multiple builders" do it "looks up class methods in all builders" do mock(builder = Object.new).setup_method("foo") { true } klass = Class.new GirFFI::ClassBase klass.const_set :GIR_FFI_BUILDER, builder mock(sub_builder = Object.new).setup_method("foo") { false } sub_klass = Class.new klass do def self.foo; end end sub_klass.const_set :GIR_FFI_BUILDER, sub_builder sub_klass.setup_and_call :foo end it "looks up class methods in all builders" do mock(builder = Object.new).setup_instance_method("foo") { true } klass = Class.new GirFFI::ClassBase klass.const_set :GIR_FFI_BUILDER, builder mock(sub_builder = Object.new).setup_instance_method("foo") { false } sub_klass = Class.new klass do def foo; end def initialize; end def self.new; self._real_new; end end sub_klass.const_set :GIR_FFI_BUILDER, sub_builder obj = sub_klass.new obj.setup_and_call :foo end end end gir_ffi-0.6.7/test/gir_ffi/unintrospectable_type_info_test.rb0000644000004100000410000000607412224462647024606 0ustar www-datawww-datarequire 'gir_ffi_test_helper' require 'gir_ffi/unintrospectable_type_info' describe GirFFI::UnintrospectableTypeInfo do describe "#info_type" do it "returns :unintrospectable" do info = GirFFI::UnintrospectableTypeInfo.new :some_type info.info_type.must_equal :unintrospectable end end describe "#parent" do describe "when the GIR knows about the parent gtype" do it "finds the parent's info by gtype" do gobject = Object.new gir = Object.new mock(gobject).type_parent(:some_type) { :foo } mock(gir).find_by_gtype(:foo) { :foo_info } info = GirFFI::UnintrospectableTypeInfo.new(:some_type, gir, gobject) info.parent.must_equal :foo_info end end describe "when the GIR does not know about the parent gtype" do it "creates a new UnintrospectableTypeInfo from the parent gtype" do gobject = Object.new gir = Object.new mock(gobject).type_parent(:some_type) { :foo } mock(gir).find_by_gtype(:foo) { nil } info = GirFFI::UnintrospectableTypeInfo.new(:some_type, gir, gobject) info.parent.g_type.must_equal :foo end end end describe "#interfaces" do it "finds interface infos by gtype" do gobject = Object.new gir = Object.new mock(gobject).type_interfaces(:some_type) { [:foo, :bar ] } mock(gir).find_by_gtype(:foo) { :foo_info } mock(gir).find_by_gtype(:bar) { :bar_info } info = GirFFI::UnintrospectableTypeInfo.new(:some_type, gir, gobject) info.interfaces.must_equal [:foo_info, :bar_info] end it "skips interfaces that have no introspection data" do gobject = Object.new gir = Object.new mock(gobject).type_interfaces(:some_type) { [:foo, :bar ] } mock(gir).find_by_gtype(:foo) { :foo_info } mock(gir).find_by_gtype(:bar) { nil } info = GirFFI::UnintrospectableTypeInfo.new(:some_type, gir, gobject) info.interfaces.must_equal [:foo_info] end end describe "#g_type" do it "returns the passed-in gtype" do info = GirFFI::UnintrospectableTypeInfo.new(:some_type) info.g_type.must_equal :some_type end end describe "#fields" do it "returns an empty array" do info = GirFFI::UnintrospectableTypeInfo.new(:some_type) info.fields.must_equal [] end end describe "#namespace" do it "returns the parent class' namespace" do gobject = Object.new gir = Object.new parent_info = Object.new mock(gobject).type_parent(:some_type) { :foo } mock(gir).find_by_gtype(:foo) { parent_info } mock(parent_info).namespace { 'FooNamespace' } info = GirFFI::UnintrospectableTypeInfo.new(:some_type, gir, gobject) info.namespace.must_equal 'FooNamespace' end end describe "#safe_name" do it "finds the class name by gtype" do gobject = Object.new mock(gobject).type_name(:some_type) { 'GSomeType' } info = GirFFI::UnintrospectableTypeInfo.new(:some_type, nil, gobject) info.safe_name.must_equal 'GSomeType' end end end gir_ffi-0.6.7/test/gir_ffi/user_defined_type_info_test.rb0000644000004100000410000000203712224462647023654 0ustar www-datawww-datarequire 'gir_ffi_test_helper' require 'gir_ffi/user_defined_type_info' describe GirFFI::UserDefinedTypeInfo do describe "#described_class" do it "returns the class passed to #initialize" do info = GirFFI::UserDefinedTypeInfo.new :some_class info.described_class.must_equal :some_class end end describe "#install_property" do it "adds the passed in property to the list of properties" do mock(foo_spec = Object.new).get_name { :foo } info = GirFFI::UserDefinedTypeInfo.new :some_class info.install_property foo_spec info.properties.map(&:name).must_equal [:foo] end end describe "#initialize" do it "takes a block that is evaluated in the context of the instance" do mock(foo_spec = Object.new).get_name { :foo } mock(bar_spec = Object.new).get_name { :bar } info = GirFFI::UserDefinedTypeInfo.new :some_class do install_property foo_spec install_property bar_spec end info.properties.map(&:name).must_equal [:foo, :bar] end end end gir_ffi-0.6.7/test/gir_ffi/interface_base_test.rb0000644000004100000410000000050012224462647022067 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GirFFI::InterfaceBase do describe "#wrap" do it "delegates conversion to the wrapped pointer" do mod = Module.new { extend GirFFI::InterfaceBase } mock(ptr = Object.new).to_object { "good-result" } mod.wrap(ptr).must_equal "good-result" end end end gir_ffi-0.6.7/test/ffi-gobject_test.rb0000644000004100000410000000747312224462647017727 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GObject do before do GirFFI.setup :Regress end describe "::signal_emit" do it "emits a signal" do a = 1 o = Regress::TestSubObj.new callback = Proc.new { a = 2 } ::GObject::Lib.g_signal_connect_data o, "test", callback, nil, nil, 0 GObject.signal_emit o, "test" assert_equal 2, a end it "handles return values" do s = Gio::SocketService.new argtypes = [:pointer, :pointer, :pointer, :pointer] callback = FFI::Function.new(:bool, argtypes) { |a,b,c,d| true } ::GObject::Lib.g_signal_connect_data s, "incoming", callback, nil, nil, 0 rv = GObject.signal_emit s, "incoming" assert_equal true, rv.get_value end it "passes in extra arguments" do o = Regress::TestSubObj.new sb = Regress::TestSimpleBoxedA.new sb.some_int8 = 31 sb.some_double = 2.42 sb.some_enum = :value2 b2 = nil argtypes = [:pointer, :pointer, :pointer] callback = FFI::Function.new(:void, argtypes) do |a,b,c| b2 = b end ::GObject::Lib.g_signal_connect_data o, "test-with-static-scope-arg", callback, nil, nil, 0 GObject.signal_emit o, "test-with-static-scope-arg", sb sb2 = Regress::TestSimpleBoxedA.wrap b2 assert sb.equals(sb2) end it "allows specifying signal detail" do a = 1 o = Regress::TestSubObj.new callback = FFI::Function.new(:void, [:pointer, :pointer, :pointer]) { a = 2 } ::GObject::Lib.g_signal_connect_data o, "notify::detail", callback, nil, nil, 0 GObject.signal_emit o, "notify::detail" a.must_equal 2 end end describe "::signal_connect" do it "installs a signal handler" do a = 1 o = Regress::TestSubObj.new GObject.signal_connect(o, "test") { a = 2 } GObject.signal_emit o, "test" assert_equal 2, a end it "passes user data to handler" do a = 1 o = Regress::TestSubObj.new GObject.signal_connect(o, "test", 2) { |i, d| a = d } GObject.signal_emit o, "test" assert_equal 2, a end it "passes object to handler" do o = Regress::TestSubObj.new o2 = nil GObject.signal_connect(o, "test") { |i, d| o2 = i } GObject.signal_emit o, "test" assert_instance_of Regress::TestSubObj, o2 assert_equal o.to_ptr, o2.to_ptr end it "does not allow connecting an invalid signal" do o = Regress::TestSubObj.new assert_raises RuntimeError do GObject.signal_connect(o, "not-really-a-signal") {} end end it "handles return values" do s = Gio::SocketService.new GObject.signal_connect(s, "incoming") { true } rv = GObject.signal_emit s, "incoming" assert_equal true, rv.get_value end it "requires a block" do o = Regress::TestSubObj.new assert_raises ArgumentError do GObject.signal_connect o, "test" end end it "allows specifying signal detail" do a = 1 o = Regress::TestSubObj.new GObject.signal_connect(o, "notify::detail", 2) { |i, _, d| a = d } GObject.signal_emit o, "notify::detail" assert_equal 2, a end describe "connecting a signal with extra arguments" do before do @a = nil @b = 2 o = Regress::TestSubObj.new sb = Regress::TestSimpleBoxedA.new sb.some_int = 23 GObject.signal_connect(o, "test-with-static-scope-arg", 2) { |i, object, d| @a = d @b = object } GObject.signal_emit o, "test-with-static-scope-arg", sb end it "moves the user data argument" do assert_equal 2, @a end it "passes on the extra arguments" do assert_instance_of Regress::TestSimpleBoxedA, @b assert_equal 23, @b.some_int end end end end gir_ffi-0.6.7/test/integration/0000755000004100000410000000000012224462647016474 5ustar www-datawww-datagir_ffi-0.6.7/test/integration/generated_gio_test.rb0000644000004100000410000000500412224462647022653 0ustar www-datawww-datarequire 'gir_ffi_test_helper' # Tests generated methods and functions in the Gio namespace. describe "The generated Gio module" do before do GirFFI.setup :Gio end describe "#file_new_for_path, a method returning an interface," do it "returns an object of a more specific class" do file = Gio.file_new_for_path('/') refute_instance_of Gio::File, file assert_includes file.class.ancestors, Gio::File end end describe "the result of #file_new_from_path" do before do @it = Gio.file_new_for_path('/') end it "is able to set up a method in a class that is not the first ancestor" do anc = @it.class.ancestors assert_equal [Gio::File, GObject::Object], anc[1, 2] refute_defines_instance_method Gio::File, :get_qdata assert_defines_instance_method GObject::Object, :get_qdata @it.setup_and_call :get_qdata, 1 end it "knows its GType" do instance_gtype = GObject.type_from_instance @it @it.class.get_gtype.must_equal instance_gtype end end describe "the FileInfo class" do describe "an instance" do before do file = Gio.file_new_for_path('/') @fileinfo = file.query_info "*", :none, nil end it "has a working #get_attribute_type method" do type = @fileinfo.get_attribute_type "standard::display-name" assert_equal :string, type end end end describe "the action-added signal" do before do @grp = Gio::SimpleActionGroup.new end it "correctly passes on the string parameter 'action_name'" do a = nil GObject.signal_connect @grp, "action-added" do |grp, action_name, user_data| a = action_name end GObject.signal_emit @grp, "action-added", "foo" assert_equal "foo", a end end describe "the reply signal" do before do @mo = Gio::MountOperation.new end it "correctly passes on the enum parameter 'result'" do a = nil GObject.signal_connect @mo, "reply" do |mnt, result, user_data| a = result end GObject.signal_emit @mo, "reply", 2 assert_equal :unhandled, a end end describe "the CharsetConverter class" do it "includes two interfaces" do klass = Gio::CharsetConverter assert_includes klass.ancestors, Gio::Converter assert_includes klass.ancestors, Gio::Initable end it "allows an instance to find the #reset method" do cnv = Gio::CharsetConverter.new "utf8", "utf8" cnv.reset pass end end end gir_ffi-0.6.7/test/integration/generated_secret_test.rb0000644000004100000410000000060612224462647023365 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe "The generated Secret module" do describe "Secret::Schema" do it "has a working constructor" do begin GirFFI.setup :Secret rescue skip "No GIR data for Secret available" end instance = Secret::Schema.new("foo", :none, "bar" => :string) instance.must_be_instance_of Secret::Schema end end end gir_ffi-0.6.7/test/integration/method_lookup_test.rb0000644000004100000410000000146612224462647022740 0ustar www-datawww-datarequire 'gir_ffi_test_helper' # Tests how methods are looked up and generated on first use. describe "Looking up methods" do before do save_module :Regress GirFFI.setup :Regress end describe "an instance method" do it "is found from a subclass" do assert_defines_instance_method Regress::TestObj, :forced_method refute_defines_instance_method Regress::TestSubObj, :forced_method sub_object = Regress::TestSubObj.new sub_object.forced_method end end describe "a class method" do it "is found from a subclass" do assert_defines_singleton_method Regress::TestObj, :static_method refute_defines_singleton_method Regress::TestSubObj, :static_method Regress::TestSubObj.static_method 42 end end after do restore_module :Regress end end gir_ffi-0.6.7/test/integration/generated_pango_ft2_test.rb0000644000004100000410000000066412224462647023763 0ustar www-datawww-data# coding: utf-8 require 'gir_ffi_test_helper' GirFFI.setup :PangoFT2 # Tests generated methods and functions in the PangoFT2 namespace. describe PangoFT2 do describe PangoFT2::FontMap do it "has a working method #load_font" do font_map = PangoFT2::FontMap.new context = font_map.create_context font_description = Pango::FontDescription.new font_map.load_font context, font_description end end end gir_ffi-0.6.7/test/integration/generated_gobject_test.rb0000644000004100000410000000174512224462647023522 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe "The generated GObject module" do before do GirFFI.setup :GObject end describe "#type_interfaces" do it "works, showing that returning an array of GType works" do klass = GObject::TypeModule ifcs = GObject.type_interfaces klass.get_gtype assert_equal 1, ifcs.size end end describe "the TypePlugin interface" do it "is implemented as a module" do mod = GObject::TypePlugin assert_instance_of Module, mod refute_instance_of Class, mod end end describe "the TypeModule class" do it "has the GObject::TypePlugin module as an ancestor" do klass = GObject::TypeModule assert_includes klass.ancestors, GObject::TypePlugin end end describe "the ValueArray struct class" do it "uses the constructor provided by GObject" do instance = GObject::ValueArray.new 16 instance.n_prealloced.must_equal 16 instance.n_values.must_equal 0 end end end gir_ffi-0.6.7/test/integration/generated_gimarshallingtests_test.rb0000644000004100000410000022623512224462647026014 0ustar www-datawww-data# coding: utf-8 require 'gir_ffi_test_helper' require 'gir_ffi' GirFFI.setup :GIMarshallingTests # Tests generated methods and functions in the GIMarshallingTests namespace. describe GIMarshallingTests do describe "GIMarshallingTests::BoxedStruct" do let(:instance) { GIMarshallingTests::BoxedStruct.new } it "has a writable field long_" do instance.long_ = 42 assert_equal 42, instance.long_ instance.long_ = 43 assert_equal 43, instance.long_ end it "has a writable field string_" do skip unless get_field_introspection_data("GIMarshallingTests", "BoxedStruct", "string_") instance.string_ = "foobar" instance.string_.must_equal "foobar" end it "has a writable field g_strv" do instance.g_strv.must_be :==, [] instance.g_strv = ["foo", "bar"] instance.g_strv.must_be :==, ["foo", "bar"] end it "creates an instance using #new" do bx = GIMarshallingTests::BoxedStruct.new assert_instance_of GIMarshallingTests::BoxedStruct, bx end it "has a working method #inv" do instance.long_ = 42 instance.inv pass end it "has a working function #inout" do bx = GIMarshallingTests::BoxedStruct.new bx.long_ = 42 res = GIMarshallingTests::BoxedStruct.inout bx assert_equal 42, bx.long_ assert_equal 0, res.long_ end it "has a working function #out" do res = GIMarshallingTests::BoxedStruct.out assert_equal 42, res.long_ end it "has a working function #returnv" do res = GIMarshallingTests::BoxedStruct.returnv assert_equal 42, res.long_ res.g_strv.must_be :==, ["0", "1", "2"] end end it "has the constant CONSTANT_GERROR_CODE" do assert_equal 5, GIMarshallingTests::CONSTANT_GERROR_CODE end it "has the constant CONSTANT_GERROR_DEBUG_MESSAGE" do GIMarshallingTests::CONSTANT_GERROR_DEBUG_MESSAGE.must_equal( "we got an error, life is shit") end it "has the constant CONSTANT_GERROR_DOMAIN" do assert_equal "gi-marshalling-tests-gerror-domain", GIMarshallingTests::CONSTANT_GERROR_DOMAIN end it "has the constant CONSTANT_GERROR_MESSAGE" do assert_equal "gi-marshalling-tests-gerror-message", GIMarshallingTests::CONSTANT_GERROR_MESSAGE end it "has the constant CONSTANT_NUMBER" do assert_equal 42, GIMarshallingTests::CONSTANT_NUMBER end it "has the constant CONSTANT_UTF8" do assert_equal "const ♥ utf8", GIMarshallingTests::CONSTANT_UTF8 end describe "GIMarshallingTests::Enum" do it "has the member :value1" do assert_equal 0, GIMarshallingTests::Enum[:value1] end it "has the member :value2" do assert_equal 1, GIMarshallingTests::Enum[:value2] end it "has the member :value3" do assert_equal 42, GIMarshallingTests::Enum[:value3] end end describe "GIMarshallingTests::Flags" do it "has the member :value1" do assert_equal 1, GIMarshallingTests::Flags[:value1] end it "has the member :value2" do assert_equal 2, GIMarshallingTests::Flags[:value2] end it "has the member :value3" do assert_equal 4, GIMarshallingTests::Flags[:value3] end it "has the member :mask" do assert_equal 3, GIMarshallingTests::Flags[:mask] end it "has the member :mask2" do assert_equal 3, GIMarshallingTests::Flags[:mask2] end it "has a working function #in" do GIMarshallingTests::Flags.in :value2 end it "has a working function #in_zero" do GIMarshallingTests::Flags.in_zero 0 end it "has a working function #inout" do result = GIMarshallingTests::Flags.inout :value2 result.must_equal :value1 end it "has a working function #out" do result = GIMarshallingTests::Flags.out result.must_equal :value2 end it "has a working function #returnv" do result = GIMarshallingTests::Flags.returnv result.must_equal :value2 end end describe "GIMarshallingTests::GEnum" do it "has the member :value1" do assert_equal 0, GIMarshallingTests::GEnum[:value1] end it "has the member :value2" do assert_equal 1, GIMarshallingTests::GEnum[:value2] end it "has the member :value3" do assert_equal 42, GIMarshallingTests::GEnum[:value3] end it "has a working function #in" do GIMarshallingTests::GEnum.in :value3 end it "has a working function #inout" do result = GIMarshallingTests::GEnum.inout :value3 result.must_equal :value1 end it "has a working function #out" do result = GIMarshallingTests::GEnum.out result.must_equal :value3 end it "has a working function #returnv" do result = GIMarshallingTests::GEnum.returnv result.must_equal :value3 end end describe "GIMarshallingTests::Interface" do it "has a working method #test_int8_in" do skip "Interfaces cannot be tested directly" end end describe "GIMarshallingTests::Interface2" do it "must be tested" do skip "Interfaces cannot be tested directly" end end describe "GIMarshallingTests::Interface3" do it "has a working method #test_variant_array_in" do skip "Interfaces cannot be tested directly" end end describe "GIMarshallingTests::NestedStruct" do let(:instance) { GIMarshallingTests::NestedStruct.new } it "has a writable field simple_struct" do assert_instance_of GIMarshallingTests::SimpleStruct, instance.simple_struct new_struct = GIMarshallingTests::SimpleStruct.new new_struct.int8 = 42 instance.simple_struct = new_struct instance.simple_struct.int8.must_equal 42 end end describe "GIMarshallingTests::NoTypeFlags" do it "has the member :value1" do assert_equal 1, GIMarshallingTests::NoTypeFlags[:value1] end it "has the member :value2" do assert_equal 2, GIMarshallingTests::NoTypeFlags[:value2] end it "has the member :value" do assert_equal 4, GIMarshallingTests::NoTypeFlags[:value3] end it "has the member :mask" do assert_equal 3, GIMarshallingTests::NoTypeFlags[:mask] end it "has the member :mask2" do assert_equal 3, GIMarshallingTests::NoTypeFlags[:mask2] end end describe "GIMarshallingTests::NotSimpleStruct" do let(:instance) { GIMarshallingTests::NotSimpleStruct.new } it "has a writable field pointer" do instance.pointer.must_be_nil nested = GIMarshallingTests::NestedStruct.new instance.pointer = nested instance.pointer.must_equal nested end end it "has the constant OVERRIDES_CONSTANT" do assert_equal 42, GIMarshallingTests::OVERRIDES_CONSTANT end describe "GIMarshallingTests::Object" do it "creates an instance using #new" do ob = GIMarshallingTests::Object.new 42 assert_instance_of GIMarshallingTests::Object, ob assert_equal 42, ob.int end it "has a working function #full_inout" do ob = GIMarshallingTests::Object.new 42 res = GIMarshallingTests::Object.full_inout ob assert_instance_of GIMarshallingTests::Object, res ob.wont_equal res end it "has a working function #full_out" do res = GIMarshallingTests::Object.full_out assert_instance_of GIMarshallingTests::Object, res end it "has a working function #full_return" do res = GIMarshallingTests::Object.full_return assert_instance_of GIMarshallingTests::Object, res end it "has a working function #inout_same" do skip "This function is only found in the header" end it "has a working function #none_inout" do ob = GIMarshallingTests::Object.new 42 res = GIMarshallingTests::Object.none_inout ob assert_instance_of GIMarshallingTests::Object, res ob.wont_equal res end it "has a working function #none_out" do res = GIMarshallingTests::Object.none_out assert_instance_of GIMarshallingTests::Object, res end it "has a working function #none_return" do res = GIMarshallingTests::Object.none_return assert_instance_of GIMarshallingTests::Object, res end it "has a working function #static_method" do GIMarshallingTests::Object.static_method pass end let(:instance) { GIMarshallingTests::Object.new 42 } it "has a working method #call_vfunc_with_callback" do # NOTE: To call this method, the callback slot vfunc_with_callback has to # be filled in the GIMarshallingTests::Object class structure. The # GIMarshallingTests library doesn't do this. skip "Needs vfunc setup" end it "has a working method #full_in" do skip "This function is only found in the header" end it "has a working method #get_ref_info_for_vfunc_in_object_transfer_full" do skip "Needs vfunc setup" end it "has a working method #get_ref_info_for_vfunc_in_object_transfer_none" do skip "Needs vfunc setup" end it "has a working method #get_ref_info_for_vfunc_out_object_transfer_full" do skip "Needs vfunc setup" end it "has a working method #get_ref_info_for_vfunc_out_object_transfer_none" do skip "Needs vfunc setup" end it "has a working method #get_ref_info_for_vfunc_return_object_transfer_full" do skip "Needs vfunc setup" end it "has a working method #get_ref_info_for_vfunc_return_object_transfer_none" do skip "Needs vfunc setup" end it "has a working method #int8_in" do skip "Needs vfunc setup" end it "has a working method #int8_out" do skip "Needs vfunc setup" end it "has a working method #method" do instance.method pass end it "has a working method #method_array_in" do instance.method_array_in [-1, 0, 1, 2] pass end it "has a working method #method_array_inout" do res = instance.method_array_inout [-1, 0, 1, 2] res.must_be :==, [-2, -1, 0, 1, 2] end it "has a working method #method_array_out" do res = instance.method_array_out res.must_be :==, [-1, 0, 1, 2] end it "has a working method #method_array_return" do res = instance.method_array_return res.must_be :==, [-1, 0, 1, 2] end it "has a working method #method_int8_arg_and_out_callee" do skip "Needs vfunc setup" end it "has a working method #method_int8_arg_and_out_caller" do skip "Needs vfunc setup" end it "has a working method #method_int8_in" do skip "Needs vfunc setup" end it "has a working method #method_int8_out" do skip "Needs vfunc setup" end it "has a working method #method_str_arg_out_ret" do skip "Needs vfunc setup" end it "has a working method #method_variant_array_in" do skip "Needs vfunc setup" end it "has a working method #method_with_default_implementation" do instance.method_with_default_implementation 104 assert_equal 104, instance.int end it "has a working method #none_in" do instance.none_in pass end it "has a working method #overridden_method" do instance.set_property("int", 0) instance.overridden_method pass end it "has a working method #vfunc_array_out_parameter" do skip "Needs vfunc setup" end it "has a working method #vfunc_caller_allocated_out_parameter" do skip "Needs vfunc setup" end it "has a working method #vfunc_meth_with_error" do skip "Needs vfunc setup" end it "has a working method #vfunc_multiple_out_parameters" do skip "Needs vfunc setup" end it "has a working method #vfunc_one_out_parameter" do skip "Needs vfunc setup" end it "has a working method #vfunc_out_enum" do skip "Needs vfunc setup" end it "has a working method #vfunc_return_enum" do skip "Needs vfunc setup" end it "has a working method #vfunc_return_value_and_multiple_out_parameters" do skip "Needs vfunc setup" end it "has a working method #vfunc_return_value_and_one_out_parameter" do skip "Needs vfunc setup" end it "has a working method #vfunc_return_value_only" do skip "Needs vfunc setup" end it "has a working method #vfunc_with_callback" do skip "Needs vfunc setup" end describe "its 'int' property" do it "can be retrieved with #get_property" do assert_equal 42, instance.get_property("int") end it "can be retrieved with #int" do assert_equal 42, instance.int end it "can be set with #set_property" do instance.set_property("int", 13) assert_equal 13, instance.get_property("int") end it "can be set with #int=" do instance.int = 1 assert_equal 1, instance.int end end end describe "GIMarshallingTests::OverridesObject" do it "creates an instance using #new" do ob = GIMarshallingTests::OverridesObject.new assert_instance_of GIMarshallingTests::OverridesObject, ob end it "has a working function #returnv" do ob = GIMarshallingTests::OverridesObject.returnv assert_instance_of GIMarshallingTests::OverridesObject, ob end let(:instance) { GIMarshallingTests::OverridesObject.new } it "has a working method #method" do result = instance.method result.must_equal 42 end it "does not have field accessor methods" do assert_raises(NoMethodError) { instance.parent_instance } assert_raises(NoMethodError) { instance.parent_instance = nil } assert_raises(NoMethodError) { instance.long_ } assert_raises(NoMethodError) { instance.long_ = 1 } end end describe "GIMarshallingTests::OverridesStruct" do let(:instance) { GIMarshallingTests::OverridesStruct.new } it "has a writable field long_" do instance.long_ = 43 instance.long_.must_equal 43 end it "creates an instance using #new" do ob = GIMarshallingTests::OverridesStruct.new assert_instance_of GIMarshallingTests::OverridesStruct, ob end it "has a working method #method" do instance.method.must_equal 42 end it "has a working function #returnv" do ob = GIMarshallingTests::OverridesStruct.returnv assert_instance_of GIMarshallingTests::OverridesStruct, ob end end describe "GIMarshallingTests::PointerStruct" do it "creates an instance using #new" do ps = GIMarshallingTests::PointerStruct.new assert_instance_of GIMarshallingTests::PointerStruct, ps end let(:instance) { GIMarshallingTests::PointerStruct.new } it "has a writable field long_" do assert_equal 0, instance.long_ instance.long_ = 1056 assert_equal 1056, instance.long_ end it "has a working method #inv" do instance.long_ = 42 instance.inv pass end it "has a working function #returnv" do ob = GIMarshallingTests::PointerStruct.returnv assert_instance_of GIMarshallingTests::PointerStruct, ob end end describe "GIMarshallingTests::PropertiesObject" do it "creates an instance using #new" do ob = GIMarshallingTests::PropertiesObject.new assert_instance_of GIMarshallingTests::PropertiesObject, ob end let(:instance) { GIMarshallingTests::PropertiesObject.new } describe "its 'some-boolean' property" do it "can be retrieved with #get_property" do instance.get_property("some-boolean").must_equal false end it "can be retrieved with #some_boolean" do instance.some_boolean.must_equal false end it "can be set with #set_property" do instance.set_property("some-boolean", true) instance.get_property("some-boolean").must_equal true end it "can be set with #some_boolean=" do instance.some_boolean = true instance.get_property("some-boolean").must_equal true end end describe "its 'some-boxed-glist' property" do before do skip unless get_property_introspection_data('GIMarshallingTests', 'PropertiesObject', 'some-boxed-glist') end it "can be retrieved with #get_property" do instance.get_property("some-boxed-glist").must_equal nil end it "can be retrieved with #some_boxed_glist" do instance.some_boxed_glist.must_equal nil end it "can be set with #set_property" do instance.set_property("some-boxed-glist", [1, 2, 3]) instance.get_property("some-boxed-glist").to_a.must_equal [1, 2, 3] end it "can be set with #some_boxed_glist=" do instance.some_boxed_glist = [1, 2, 3] instance.some_boxed_glist.to_a.must_equal [1, 2, 3] end end describe "its 'some-boxed-struct' property" do before do skip unless get_property_introspection_data('GIMarshallingTests', 'PropertiesObject', 'some-boxed-struct') end it "can be retrieved with #get_property" do instance.get_property("some-boxed-struct").must_equal nil end it "can be retrieved with #some_boxed_struct" do instance.some_boxed_struct.must_equal nil end it "can be set with #set_property" do boxed = GIMarshallingTests::BoxedStruct.new boxed.long_ = 42 instance.set_property("some-boxed-struct", boxed) instance.get_property("some-boxed-struct").long_.must_equal 42 end it "can be set with #some_boxed_struct=" do boxed = GIMarshallingTests::BoxedStruct.new boxed.long_ = 43 instance.some_boxed_struct = boxed instance.some_boxed_struct.long_.must_equal 43 end end describe "its 'some-char' property" do it "can be retrieved with #get_property" do instance.get_property("some-char").must_equal 0 end it "can be retrieved with #some_char" do instance.some_char.must_equal 0 end it "can be set with #set_property" do instance.set_property "some-char", 42 instance.get_property("some-char").must_equal 42 end it "can be set with #some_char=" do instance.some_char = 43 instance.some_char.must_equal 43 end end describe "its 'some-double' property" do it "can be retrieved with #get_property" do instance.get_property("some-double").must_equal 0.0 end it "can be retrieved with #some_double" do instance.some_double.must_equal 0.0 end it "can be set with #set_property" do instance.set_property("some-double", 3.14) instance.get_property("some-double").must_equal 3.14 end it "can be set with #some_double=" do instance.some_double = 3.14 instance.some_double.must_equal 3.14 end end describe "its 'some-float' property" do it "can be retrieved with #get_property" do instance.get_property("some-float").must_equal 0.0 end it "can be retrieved with #some_float" do instance.some_float.must_equal 0.0 end it "can be set with #set_property" do instance.set_property("some-float", 3.14) instance.get_property("some-float").must_be_close_to 3.14 end it "can be set with #some_float=" do instance.some_float = 3.14 instance.some_float.must_be_close_to 3.14 end end describe "its 'some-int' property" do it "can be retrieved with #get_property" do instance.get_property("some-int").must_equal 0 end it "can be retrieved with #some_int" do instance.some_int.must_equal 0 end it "can be set with #set_property" do instance.set_property "some-int", 4242 instance.get_property("some-int").must_equal 4242 end it "can be set with #some_int=" do instance.some_int = 4243 instance.some_int.must_equal 4243 end end describe "its 'some-int64' property" do it "can be retrieved with #get_property" do instance.get_property("some-int64").must_equal 0 end it "can be retrieved with #some_int64" do instance.some_int64.must_equal 0 end it "can be set with #set_property" do instance.set_property "some-int64", 42_000_000_000_000 instance.get_property("some-int64").must_equal 42_000_000_000_000 end it "can be set with #some_int64=" do instance.some_int64 = 43_000_000_000_000 instance.some_int64.must_equal 43_000_000_000_000 end end describe "its 'some-long' property" do it "can be retrieved with #get_property" do instance.get_property("some-long").must_equal 0 end it "can be retrieved with #some_long" do instance.some_long.must_equal 0 end it "can be set with #set_property" do instance.set_property "some-long", 4242 instance.get_property("some-long").must_equal 4242 end it "can be set with #some_long=" do instance.some_long = 4243 instance.some_long.must_equal 4243 end end describe "its 'some-object' property" do before do skip unless get_property_introspection_data('GIMarshallingTests', 'PropertiesObject', 'some-object') end it "can be retrieved with #get_property" do instance.get_property("some-object").must_be_nil end it "can be retrieved with #some_object" do instance.some_object.must_be_nil end it "can be set with #set_property" do ob = GIMarshallingTests::Object.new 42 instance.set_property "some-object", ob instance.get_property("some-object").must_equal ob end it "can be set with #some_object=" do ob = GIMarshallingTests::Object.new 42 instance.some_object = ob instance.some_object.must_equal ob end end describe "its 'some-strv' property" do before do skip unless get_property_introspection_data('GIMarshallingTests', 'PropertiesObject', 'some-strv') end it "can be retrieved with #get_property" do instance.get_property("some-strv").must_be :==, [] end it "can be retrieved with #some_strv" do instance.some_strv.must_be :==, [] end it "can be set with #set_property" do instance.set_property("some-strv", ["foo", "bar"]) instance.get_property("some-strv").must_be :==, ["foo", "bar"] end it "can be set with #some_strv=" do instance.some_strv = ["foo", "bar"] instance.some_strv.must_be :==, ["foo", "bar"] end end describe "its 'some-uchar' property" do it "can be retrieved with #get_property" do instance.get_property("some-uchar").must_equal 0 end it "can be retrieved with #some_uchar" do instance.some_uchar.must_equal 0 end it "can be set with #set_property" do instance.set_property "some-uchar", 42 instance.get_property("some-uchar").must_equal 42 end it "can be set with #some_uchar=" do instance.some_uchar = 43 instance.some_uchar.must_equal 43 end end describe "its 'some-uuint' property" do it "can be retrieved with #get_property" do instance.get_property("some-uint").must_equal 0 end it "can be retrieved with #some_uint" do instance.some_uint.must_equal 0 end it "can be set with #set_property" do instance.set_property "some-uint", 4242 instance.get_property("some-uint").must_equal 4242 end it "can be set with #some_uint=" do instance.some_uint = 4243 instance.some_uint.must_equal 4243 end end describe "its 'some-uint64' property" do it "can be retrieved with #get_property" do instance.get_property("some-uint64").must_equal 0 end it "can be retrieved with #some_uint64" do instance.some_uint64.must_equal 0 end it "can be set with #set_property" do instance.set_property "some-uint64", 42_000_000_000_000 instance.get_property("some-uint64").must_equal 42_000_000_000_000 end it "can be set with #some_uint64=" do instance.some_uint64 = 43_000_000_000_000 instance.some_uint64.must_equal 43_000_000_000_000 end end describe "its 'some-ulong' property" do it "can be retrieved with #get_property" do instance.get_property("some-ulong").must_equal 0 end it "can be retrieved with #some_ulong" do instance.some_ulong.must_equal 0 end it "can be set with #set_property" do instance.set_property "some-ulong", 4242 instance.get_property("some-ulong").must_equal 4242 end it "can be set with #some_ulong=" do instance.some_ulong = 4243 instance.some_ulong.must_equal 4243 end end describe "its 'some-variant' property" do before do skip unless get_property_introspection_data('GIMarshallingTests', 'PropertiesObject', 'some-variant') end it "can be retrieved with #get_property" do instance.get_property("some-variant").must_be_nil end it "can be retrieved with #some_variant" do instance.some_variant.must_be_nil end it "can be set with #set_property" do value = GLib::Variant.new_string("Foo") instance.set_property "some-variant", value instance.get_property("some-variant").must_equal value end it "can be set with #some_variant=" do value = GLib::Variant.new_string("Foo") instance.some_variant = value instance.some_variant.must_equal value end end end describe "GIMarshallingTests::SecondEnum" do it "has the member :secondvalue1" do assert_equal 0, GIMarshallingTests::SecondEnum[:secondvalue1] end it "has the member :secondvalue2" do assert_equal 1, GIMarshallingTests::SecondEnum[:secondvalue2] end end describe "GIMarshallingTests::SimpleStruct" do it "creates an instance using #new" do ss = GIMarshallingTests::SimpleStruct.new assert_instance_of GIMarshallingTests::SimpleStruct, ss end let(:instance) { GIMarshallingTests::SimpleStruct.new } it "has a writable field long_" do instance.long_.must_equal 0 instance.long_ = 1056 instance.long_.must_equal 1056 end it "has a writable field int8" do instance.int8.must_equal 0 instance.int8 = -43 instance.int8.must_equal(-43) end it "has a working method #inv" do instance.long_ = 6 instance.int8 = 7 instance.inv pass end it "has a working method #method" do instance.long_ = 6 instance.int8 = 7 instance.method pass end it "has a working function #returnv" do ss = GIMarshallingTests::SimpleStruct.returnv assert_instance_of GIMarshallingTests::SimpleStruct, ss end end describe "GIMarshallingTests::SubObject" do it "creates an instance using #new" do so = GIMarshallingTests::SubObject.new 42 assert_instance_of GIMarshallingTests::SubObject, so end let(:instance) { GIMarshallingTests::SubObject.new 0 } it "has a working method #overwritten_method" do instance.overwritten_method pass end it "has a working method #sub_method" do instance.sub_method pass end it "does not have field accessors" do assert_raises(NoMethodError) { instance.parent_instance } assert_raises(NoMethodError) { instance.parent_instance = nil } end end describe "GIMarshallingTests::SubSubObject" do it "creates an instance using #new" do so = GIMarshallingTests::SubSubObject.new 42 assert_instance_of GIMarshallingTests::SubSubObject, so end let(:instance) { GIMarshallingTests::SubSubObject.new 0 } it "does not have field accessors" do assert_raises(NoMethodError) { instance.parent_instance } assert_raises(NoMethodError) { instance.parent_instance = nil } end end describe "GIMarshallingTests::Union" do it "creates an instance with #new" do u = GIMarshallingTests::Union.new assert_instance_of GIMarshallingTests::Union, u end let(:instance) { GIMarshallingTests::Union.new } it "has a writable field long_" do assert_equal 0, instance.long_ instance.long_ = 1056 assert_equal 1056, instance.long_ end it "has a working method #inv" do instance.long_ = 42 instance.inv pass end it "has a working method #method" do instance.long_ = 42 instance.method pass end it "has a working function #inout" do skip "This function is defined in the header but not implemented" end it "has a working function #out" do skip "This function is defined in the header but not implemented" end it "has a working function #returnv" do u = GIMarshallingTests::Union.returnv assert_instance_of GIMarshallingTests::Union, u end end it "has a working function #array_enum_in" do GIMarshallingTests.array_enum_in [:value1, :value2, :value3] end it "has a working function #array_fixed_inout" do res = GIMarshallingTests.array_fixed_inout [-1, 0, 1, 2] res.must_be :==, [2, 1, 0, -1] end it "has a working function #array_fixed_int_in" do GIMarshallingTests.array_fixed_int_in [-1, 0, 1, 2] pass end it "has a working function #array_fixed_int_return" do res = GIMarshallingTests.array_fixed_int_return res.must_be :==, [-1, 0, 1, 2] end it "has a working function #array_fixed_out" do res = GIMarshallingTests.array_fixed_out res.must_be :==, [-1, 0, 1, 2] end it "has a working function #array_fixed_out_struct" do res = GIMarshallingTests.array_fixed_out_struct assert_equal [[7, 6], [6, 7]], res.map {|s| [s.long_, s.int8]} end it "has a working function #array_fixed_short_in" do GIMarshallingTests.array_fixed_short_in [-1, 0, 1, 2] pass end it "has a working function #array_fixed_short_return" do res = GIMarshallingTests.array_fixed_short_return res.must_be :==, [-1, 0, 1, 2] end it "has a working function #array_gvariant_container_in" do v1 = GLib::Variant.new_int32(27) v2 = GLib::Variant.new_string("Hello") result = GIMarshallingTests.array_gvariant_container_in [v1, v2] arr = result.to_a arr.size.must_equal 2 arr[0].get_int32.must_equal 27 arr[1].get_string.must_equal "Hello" end it "has a working function #array_gvariant_full_in" do v1 = GLib::Variant.new_int32(27) v2 = GLib::Variant.new_string("Hello") result = GIMarshallingTests.array_gvariant_full_in [v1, v2] arr = result.to_a arr.size.must_equal 2 arr[0].get_int32.must_equal 27 arr[1].get_string.must_equal "Hello" end it "has a working function #array_gvariant_none_in" do v1 = GLib::Variant.new_int32(27) v2 = GLib::Variant.new_string("Hello") result = GIMarshallingTests.array_gvariant_none_in [v1, v2] arr = result.to_a arr.size.must_equal 2 arr[0].get_int32.must_equal 27 arr[1].get_string.must_equal "Hello" end it "has a working function #array_in" do GIMarshallingTests.array_in [-1, 0, 1, 2] pass end it "has a working function #array_in_guint64_len" do GIMarshallingTests.array_in_guint64_len [-1, 0, 1, 2] pass end it "has a working function #array_in_guint8_len" do GIMarshallingTests.array_in_guint8_len [-1, 0, 1, 2] pass end it "has a working function #array_in_len_before" do GIMarshallingTests.array_in_len_before [-1, 0, 1, 2] pass end it "has a working function #array_in_len_zero_terminated" do GIMarshallingTests.array_in_len_zero_terminated [-1, 0, 1, 2] pass end it "has a working function #array_in_nonzero_nonlen" do skip unless get_introspection_data 'GIMarshallingTests', 'array_in_nonzero_nonlen' GIMarshallingTests.array_in_nonzero_nonlen 1, 'abcd'.bytes.to_a pass end it "has a working function #array_inout" do res = GIMarshallingTests.array_inout [-1, 0, 1, 2] res.must_be :==, [-2, -1, 0, 1, 2] end it "has a working function #array_inout_etc" do arr, sum = GIMarshallingTests.array_inout_etc 42, [-1, 0, 1, 2], 24 arr.must_be :==, [42, -1, 0, 1, 24] sum.must_equal 42 + 24 end it "has a working function #array_out" do res = GIMarshallingTests.array_out res.must_be :==, [-1, 0, 1, 2] end it "has a working function #array_out_etc" do arr, sum = GIMarshallingTests.array_out_etc 42, 24 arr.must_be :==, [42, 0, 1, 24] sum.must_equal 42 + 24 end it "has a working function #array_return" do res = GIMarshallingTests.array_return res.must_be :==, [-1, 0, 1, 2] end it "has a working function #array_return_etc" do arr, sum = GIMarshallingTests.array_return_etc 42, 24 arr.must_be :==, [42, 0, 1, 24] sum.must_equal 42 + 24 end it "has a working function #array_simple_struct_in" do arr = [1, 2, 3].map { |val| GIMarshallingTests::SimpleStruct.new.tap { |struct| struct.long_ = val } } GIMarshallingTests.array_simple_struct_in arr end it "has a working function #array_string_in" do GIMarshallingTests.array_string_in ["foo", "bar"] pass end it "has a working function #array_struct_in" do arr = [1, 2, 3].map { |val| GIMarshallingTests::BoxedStruct.new.tap { |struct| struct.long_ = val } } GIMarshallingTests.array_struct_in arr end # NOTE: Should be run with valgrind. See gimarhallingtests.c. it "has a working function #array_struct_take_in" do arr = [1, 2, 3].map { |val| GIMarshallingTests::BoxedStruct.new.tap { |struct| struct.long_ = val } } GIMarshallingTests.array_struct_take_in arr end it "has a working function #array_struct_value_in" do skip unless get_introspection_data 'GIMarshallingTests', 'array_struct_value_in' arr = [1, 2, 3].map { |val| GIMarshallingTests::BoxedStruct.new.tap { |struct| struct.long_ = val } } GIMarshallingTests.array_struct_value_in arr end it "has a working function #array_uint8_in" do arr = "abcd".bytes.to_a GIMarshallingTests.array_uint8_in arr pass end it "has a working function #array_zero_terminated_in" do GIMarshallingTests.array_zero_terminated_in ["0", "1", "2"] pass end it "has a working function #array_zero_terminated_inout" do res = GIMarshallingTests.array_zero_terminated_inout ["0", "1", "2"] res.must_be :==, ["-1", "0", "1", "2"] end it "has a working function #array_zero_terminated_out" do res = GIMarshallingTests.array_zero_terminated_out res.must_be :==, ["0", "1", "2"] end it "has a working function #array_zero_terminated_return" do res = GIMarshallingTests.array_zero_terminated_return res.must_be :==, ["0", "1", "2"] end it "has a working function #array_zero_terminated_return_null" do res = GIMarshallingTests.array_zero_terminated_return_null res.must_be :==, [] end it "has a working function #array_zero_terminated_return_struct" do res = GIMarshallingTests.array_zero_terminated_return_struct res.to_a.map(&:long_).must_equal [42, 43, 44] end it "has a working function #boolean_in_false" do GIMarshallingTests.boolean_in_false false pass end it "has a working function #boolean_in_true" do GIMarshallingTests.boolean_in_true true pass end it "has a working function #boolean_inout_false_true" do res = GIMarshallingTests.boolean_inout_false_true false assert_equal true, res end it "has a working function #boolean_inout_true_false" do res = GIMarshallingTests.boolean_inout_true_false true assert_equal false, res end it "has a working function #boolean_out_false" do res = GIMarshallingTests.boolean_out_false assert_equal false, res end it "has a working function #boolean_out_true" do res = GIMarshallingTests.boolean_out_true assert_equal true, res end it "has a working function #boolean_return_false" do res = GIMarshallingTests.boolean_return_false assert_equal false, res end it "has a working function #boolean_return_true" do res = GIMarshallingTests.boolean_return_true assert_equal true, res end it "has a working function #boxed_struct_inout" do bx = GIMarshallingTests::BoxedStruct.new bx.long_ = 42 res = GIMarshallingTests.boxed_struct_inout bx assert_equal 0, res.long_ end it "has a working function #boxed_struct_out" do res = GIMarshallingTests.boxed_struct_out assert_equal 42, res.long_ end it "has a working function #boxed_struct_returnv" do res = GIMarshallingTests.boxed_struct_returnv assert_equal 42, res.long_ res.g_strv.must_be :==, ["0", "1", "2"] end it "has a working function #bytearray_full_return" do ret = GIMarshallingTests.bytearray_full_return assert_instance_of GLib::ByteArray, ret assert_includes( ["0123".bytes.to_a, "\x001\xFF3".bytes.to_a], ret.to_string.bytes.to_a) end it "has a working function #bytearray_none_in" do val = GIMarshallingTests.bytearray_full_return.to_string ba = GLib::ByteArray.new ba = ba.append val GIMarshallingTests.bytearray_none_in ba pass end it "has a working function #callback_multiple_out_parameters" do skip "Out parameters for callbacks are not supported yet" end it "has a working function #callback_one_out_parameter" do skip "Out parameters for callbacks are not supported yet" end it "has a working function #callback_return_value_and_multiple_out_parameters" do skip "Out parameters for callbacks are not supported yet" end it "has a working function #callback_return_value_and_one_out_parameter" do skip "Out parameters for callbacks are not supported yet" end it "has a working function #callback_return_value_only" do result = GIMarshallingTests.callback_return_value_only lambda { 42 } result.must_equal 42 end it "has a working function #double_in" do GIMarshallingTests.double_in Float::MAX pass end it "has a working function #double_inout" do ret = GIMarshallingTests.double_inout Float::MAX assert_in_epsilon 2.225e-308, ret end it "has a working function #double_out" do ret = GIMarshallingTests.double_out assert_equal Float::MAX, ret end it "has a working function #double_return" do ret = GIMarshallingTests.double_return assert_equal Float::MAX, ret end it "has a working function #enum_in" do GIMarshallingTests.enum_in :value3 pass end it "has a working function #enum_inout" do e = GIMarshallingTests.enum_inout :value3 assert_equal :value1, e end it "has a working function #enum_out" do e = GIMarshallingTests.enum_out assert_equal :value3, e end it "has a working function #enum_returnv" do e = GIMarshallingTests.enum_returnv assert_equal :value3, e end it "has a working function #filename_list_return" do fl = GIMarshallingTests.filename_list_return assert_equal nil, fl end it "has a working function #flags_in" do GIMarshallingTests.flags_in :value2 pass end it "has a working function #flags_in_zero" do GIMarshallingTests.flags_in_zero 0 pass end it "has a working function #flags_inout" do res = GIMarshallingTests.flags_inout :value2 assert_equal :value1, res end it "has a working function #flags_out" do res = GIMarshallingTests.flags_out assert_equal :value2, res end it "has a working function #flags_returnv" do res = GIMarshallingTests.flags_returnv assert_equal :value2, res end it "has a working function #float_in" do # float_return returns MAX_FLT flt = GIMarshallingTests.float_return GIMarshallingTests.float_in flt pass end it "has a working function #float_inout" do # float_return returns MAX_FLT flt = GIMarshallingTests.float_return res = GIMarshallingTests.float_inout flt assert_in_epsilon 1.175e-38, res end it "has a working function #float_out" do flt = GIMarshallingTests.float_out assert_in_epsilon 3.402e+38, flt end it "has a working function #float_return" do flt = GIMarshallingTests.float_return assert_in_epsilon 3.402e+38, flt end it "has a working function #garray_int_none_in" do arr = [-1, 0, 1, 2] GIMarshallingTests.garray_int_none_in arr pass end it "has a working function #garray_int_none_return" do arr = GIMarshallingTests.garray_int_none_return arr.must_be :==, [-1, 0, 1, 2] end it "has a working function #garray_uint64_none_in" do skip unless get_introspection_data 'GIMarshallingTests', 'garray_uint64_none_in' GIMarshallingTests.garray_uint64_none_in [0, 0xffff_ffff_ffff_ffff] pass end it "has a working function #garray_uint64_none_return" do skip unless get_introspection_data 'GIMarshallingTests', 'garray_uint64_none_return' res = GIMarshallingTests.garray_uint64_none_return res.must_be :==, [0, 0xffff_ffff_ffff_ffff] end it "has a working function #garray_utf8_container_inout" do res = GIMarshallingTests.garray_utf8_container_inout ["0", "1", "2"] res.must_be :==, ["-2", "-1", "0", "1"] end it "has a working function #garray_utf8_container_out" do res = GIMarshallingTests.garray_utf8_container_out res.must_be :==, ["0", "1", "2"] end it "has a working function #garray_utf8_container_return" do res = GIMarshallingTests.garray_utf8_container_return res.must_be :==, ["0", "1", "2"] end it "has a working function #garray_utf8_full_inout" do arr = ["0", "1", "2"] res = GIMarshallingTests.garray_utf8_full_inout arr res.must_be :==, ["-2", "-1", "0", "1"] end it "has a working function #garray_utf8_full_out" do res = GIMarshallingTests.garray_utf8_full_out res.must_be :==, ["0", "1", "2"] end it "has a working function #garray_utf8_full_out_caller_allocated" do skip unless get_introspection_data 'GIMarshallingTests', 'garray_utf8_full_out_caller_allocated' res = GIMarshallingTests.garray_utf8_full_out_caller_allocated res.must_be :==, ["0", "1", "2"] end it "has a working function #garray_utf8_full_return" do res = GIMarshallingTests.garray_utf8_full_return res.must_be :==, ["0", "1", "2"] end it "has a working function #garray_utf8_none_in" do arr = ["0", "1", "2"] GIMarshallingTests.garray_utf8_none_in arr pass end it "has a working function #garray_utf8_none_inout" do arr = ["0", "1", "2"] res = GIMarshallingTests.garray_utf8_none_inout arr res.must_be :==, ["-2", "-1", "0", "1"] end it "has a working function #garray_utf8_none_out" do res = GIMarshallingTests.garray_utf8_none_out res.must_be :==, ["0", "1", "2"] end it "has a working function #garray_utf8_none_return" do res = GIMarshallingTests.garray_utf8_none_return res.must_be :==, ["0", "1", "2"] end it "has a working function #gbytes_full_return" do skip "GBytes is not supported yet" end it "has a working function #gbytes_none_in" do skip "GBytes is not supported yet" end it "has a working function #gclosure_in" do cl = GObject::RubyClosure.new { 42 } GIMarshallingTests.gclosure_in cl end it "has a working function #gclosure_return" do cl = GIMarshallingTests.gclosure_return gv = GObject::Value.wrap_ruby_value 0 cl.invoke gv, nil, nil assert_equal 42, gv.get_value end it "has a working function #genum_in" do GIMarshallingTests.genum_in :value3 pass end it "has a working function #genum_inout" do res = GIMarshallingTests.genum_inout :value3 assert_equal :value1, res end it "has a working function #genum_out" do res = GIMarshallingTests.genum_out assert_equal :value3, res end it "has a working function #genum_returnv" do res = GIMarshallingTests.genum_returnv assert_equal :value3, res end it "has a working function #gerror" do begin GIMarshallingTests.gerror flunk "Error should have been raised" rescue RuntimeError => e e.message.must_equal GIMarshallingTests::CONSTANT_GERROR_MESSAGE end end it "has a working function #gerror_array_in" do begin GIMarshallingTests.gerror_array_in [1, 2, 3] flunk "Error should have been raised" rescue RuntimeError => e e.message.must_equal GIMarshallingTests::CONSTANT_GERROR_MESSAGE end end it "has a working function #gerror_out" do error, debug = GIMarshallingTests.gerror_out debug.must_equal GIMarshallingTests::CONSTANT_GERROR_DEBUG_MESSAGE error.message.must_equal GIMarshallingTests::CONSTANT_GERROR_MESSAGE end it "has a working function #gerror_out_transfer_none" do error, debug = GIMarshallingTests.gerror_out_transfer_none debug.must_equal GIMarshallingTests::CONSTANT_GERROR_DEBUG_MESSAGE error.message.must_equal GIMarshallingTests::CONSTANT_GERROR_MESSAGE end it "has a working function #gerror_return" do error = GIMarshallingTests.gerror_return error.message.must_equal GIMarshallingTests::CONSTANT_GERROR_MESSAGE end it "has a working function #ghashtable_int_none_in" do GIMarshallingTests.ghashtable_int_none_in( {-1 => 1, 0 => 0, 1 => -1, 2 => -2}) end it "has a working function #ghashtable_int_none_return" do gh = GIMarshallingTests.ghashtable_int_none_return assert_equal({-1 => 1, 0 => 0, 1 => -1, 2 => -2}, gh.to_hash) end it "has a working function #ghashtable_utf8_container_in" do skip "This function is defined in the header but not implemented" end it "has a working function #ghashtable_utf8_container_inout" do hsh = {"-1" => "1", "0" => "0", "1" => "-1", "2" => "-2"} res = GIMarshallingTests.ghashtable_utf8_container_inout hsh assert_equal({"-1" => "1", "0" => "0", "1" => "1"}, res.to_hash) end it "has a working function #ghashtable_utf8_container_out" do res = GIMarshallingTests.ghashtable_utf8_container_out assert_equal({"-1" => "1", "0" => "0", "1" => "-1", "2" => "-2"}, res.to_hash) end it "has a working function #ghashtable_utf8_container_return" do res = GIMarshallingTests.ghashtable_utf8_container_return assert_equal({"-1" => "1", "0" => "0", "1" => "-1", "2" => "-2"}, res.to_hash) end it "has a working function #ghashtable_utf8_full_in" do skip "This function is defined in the header but not implemented" end it "has a working function #ghashtable_utf8_full_inout" do hsh = {"-1" => "1", "0" => "0", "1" => "-1", "2" => "-2"} res = GIMarshallingTests.ghashtable_utf8_full_inout hsh assert_equal({"-1" => "1", "0" => "0", "1" => "1"}, res.to_hash) end it "has a working function #ghashtable_utf8_full_out" do res = GIMarshallingTests.ghashtable_utf8_full_out assert_equal({"-1" => "1", "0" => "0", "1" => "-1", "2" => "-2"}, res.to_hash) end it "has a working function #ghashtable_utf8_full_return" do res = GIMarshallingTests.ghashtable_utf8_full_return assert_equal({"-1" => "1", "0" => "0", "1" => "-1", "2" => "-2"}, res.to_hash) end it "has a working function #ghashtable_utf8_none_in" do hsh = {"-1" => "1", "0" => "0", "1" => "-1", "2" => "-2"} GIMarshallingTests.ghashtable_utf8_none_in hsh pass end it "has a working function #ghashtable_utf8_none_inout" do hsh = {"-1" => "1", "0" => "0", "1" => "-1", "2" => "-2"} res = GIMarshallingTests.ghashtable_utf8_none_inout hsh assert_equal({"-1" => "1", "0" => "0", "1" => "1"}, res.to_hash) end it "has a working function #ghashtable_utf8_none_out" do res = GIMarshallingTests.ghashtable_utf8_none_out assert_equal({"-1" => "1", "0" => "0", "1" => "-1", "2" => "-2"}, res.to_hash) end it "has a working function #ghashtable_utf8_none_return" do res = GIMarshallingTests.ghashtable_utf8_none_return assert_equal({"-1" => "1", "0" => "0", "1" => "-1", "2" => "-2"}, res.to_hash) end it "has a working function #glist_int_none_in" do GIMarshallingTests.glist_int_none_in [-1, 0, 1, 2] pass end it "has a working function #glist_int_none_return" do res = GIMarshallingTests.glist_int_none_return res.must_be :==, [-1, 0, 1, 2] end it "has a working function #glist_uint32_none_in" do skip unless get_introspection_data 'GIMarshallingTests', 'glist_uint32_none_in' GIMarshallingTests.glist_uint32_none_in [0, 0xffff_ffff] pass end it "has a working function #glist_uint32_none_return" do skip unless get_introspection_data 'GIMarshallingTests', 'glist_uint32_none_return' res = GIMarshallingTests.glist_uint32_none_return res.must_be :==, [0, 0xffff_ffff] end it "has a working function #glist_utf8_container_inout" do res = GIMarshallingTests.glist_utf8_container_inout ["0", "1", "2"] res.must_be :==, ["-2", "-1", "0", "1"] end it "has a working function #glist_utf8_container_out" do res = GIMarshallingTests.glist_utf8_container_out res.must_be :==, ["0", "1", "2"] end it "has a working function #glist_utf8_container_return" do res = GIMarshallingTests.glist_utf8_container_return res.must_be :==, ["0", "1", "2"] end it "has a working function #glist_utf8_full_inout" do res = GIMarshallingTests.glist_utf8_full_inout ["0", "1", "2"] res.must_be :==, ["-2", "-1", "0", "1"] end it "has a working function #glist_utf8_full_out" do res = GIMarshallingTests.glist_utf8_full_out res.must_be :==, ["0", "1", "2"] end it "has a working function #glist_utf8_full_return" do res = GIMarshallingTests.glist_utf8_full_return res.must_be :==, ["0", "1", "2"] end it "has a working function #glist_utf8_none_in" do GIMarshallingTests.glist_utf8_none_in ["0", "1", "2"] end it "has a working function #glist_utf8_none_inout" do res = GIMarshallingTests.glist_utf8_none_inout ["0", "1", "2"] res.must_be :==, ["-2", "-1", "0", "1"] end it "has a working function #glist_utf8_none_out" do res = GIMarshallingTests.glist_utf8_none_out res.must_be :==, ["0", "1", "2"] end it "has a working function #glist_utf8_none_return" do res = GIMarshallingTests.glist_utf8_none_return res.must_be :==, ["0", "1", "2"] end it "has a working function #gptrarray_utf8_container_inout" do res = GIMarshallingTests.gptrarray_utf8_container_inout ["0", "1", "2"] res.must_be :==, ["-2", "-1", "0", "1"] end it "has a working function #gptrarray_utf8_container_out" do res = GIMarshallingTests.gptrarray_utf8_container_out res.must_be :==, ["0", "1", "2"] end it "has a working function #gptrarray_utf8_container_return" do res = GIMarshallingTests.gptrarray_utf8_container_return res.must_be :==, ["0", "1", "2"] end it "has a working function #gptrarray_utf8_full_inout" do res = GIMarshallingTests.gptrarray_utf8_full_inout ["0", "1", "2"] res.must_be :==, ["-2", "-1", "0", "1"] end it "has a working function #gptrarray_utf8_full_out" do res = GIMarshallingTests.gptrarray_utf8_full_out res.must_be :==, ["0", "1", "2"] end it "has a working function #gptrarray_utf8_full_return" do res = GIMarshallingTests.gptrarray_utf8_full_return res.must_be :==, ["0", "1", "2"] end it "has a working function #gptrarray_utf8_none_in" do GIMarshallingTests.gptrarray_utf8_none_in ["0", "1", "2"] end it "has a working function #gptrarray_utf8_none_inout" do res = GIMarshallingTests.gptrarray_utf8_none_inout ["0", "1", "2"] res.must_be :==, ["-2", "-1", "0", "1"] end it "has a working function #gptrarray_utf8_none_out" do res = GIMarshallingTests.gptrarray_utf8_none_out res.must_be :==, ["0", "1", "2"] end it "has a working function #gptrarray_utf8_none_return" do res = GIMarshallingTests.gptrarray_utf8_none_return res.must_be :==, ["0", "1", "2"] end it "has a working function #gslist_int_none_in" do GIMarshallingTests.gslist_int_none_in [-1, 0, 1, 2] pass end it "has a working function #gslist_int_none_return" do res = GIMarshallingTests.gslist_int_none_return res.must_be :==, [-1, 0, 1, 2] end it "has a working function #gslist_utf8_container_inout" do res = GIMarshallingTests.gslist_utf8_container_inout ["0", "1", "2"] res.must_be :==, ["-2", "-1", "0", "1"] end it "has a working function #gslist_utf8_container_out" do res = GIMarshallingTests.gslist_utf8_container_out res.must_be :==, ["0", "1", "2"] end it "has a working function #gslist_utf8_container_return" do res = GIMarshallingTests.gslist_utf8_container_return res.must_be :==, ["0", "1", "2"] end it "has a working function #gslist_utf8_full_inout" do res = GIMarshallingTests.gslist_utf8_full_inout ["0", "1", "2"] res.must_be :==, ["-2", "-1", "0", "1"] end it "has a working function #gslist_utf8_full_out" do res = GIMarshallingTests.gslist_utf8_full_out res.must_be :==, ["0", "1", "2"] end it "has a working function #gslist_utf8_full_return" do res = GIMarshallingTests.gslist_utf8_full_return res.must_be :==, ["0", "1", "2"] end it "has a working function #gslist_utf8_none_in" do GIMarshallingTests.gslist_utf8_none_in ["0", "1", "2"] pass end it "has a working function #gslist_utf8_none_inout" do res = GIMarshallingTests.gslist_utf8_none_inout ["0", "1", "2"] res.must_be :==, ["-2", "-1", "0", "1"] end it "has a working function #gslist_utf8_none_out" do res = GIMarshallingTests.gslist_utf8_none_out res.must_be :==, ["0", "1", "2"] end it "has a working function #gslist_utf8_none_return" do res = GIMarshallingTests.gslist_utf8_none_return res.must_be :==, ["0", "1", "2"] end it "has a working function #gstrv_in" do GIMarshallingTests.gstrv_in ["0", "1", "2"] pass end it "has a working function #gstrv_inout" do res = GIMarshallingTests.gstrv_inout ["0", "1", "2"] res.must_be :==, ["-1", "0", "1", "2"] end it "has a working function #gstrv_out" do res = GIMarshallingTests.gstrv_out res.must_be :==, ["0", "1", "2"] end it "has a working function #gstrv_return" do res = GIMarshallingTests.gstrv_return res.must_be :==, ["0", "1", "2"] end it "has a working function #gtype_in" do GIMarshallingTests.gtype_in GObject::TYPE_NONE pass end it "has a working function #gtype_inout" do res = GIMarshallingTests.gtype_inout GObject::TYPE_NONE res.must_equal GObject::TYPE_INT end it "has a working function #gtype_out" do res = GIMarshallingTests.gtype_out res.must_equal GObject::TYPE_NONE end it "has a working function #gtype_return" do res = GIMarshallingTests.gtype_return res.must_equal GObject::TYPE_NONE end it "has a working function #gtype_string_in" do GIMarshallingTests.gtype_string_in GObject::TYPE_STRING pass end it "has a working function #gtype_string_out" do res = GIMarshallingTests.gtype_string_out res.must_equal GObject::TYPE_STRING end it "has a working function #gtype_string_return" do res = GIMarshallingTests.gtype_string_return res.must_equal GObject::TYPE_STRING end it "has a working function #gvalue_flat_array" do GIMarshallingTests.gvalue_flat_array [42, "42", true] pass end it "has a working function #gvalue_flat_array_round_trip" do skip "Passing structs by-value is not supported yet" end it "has a working function #gvalue_in" do GIMarshallingTests.gvalue_in GObject::Value.wrap_ruby_value(42) GIMarshallingTests.gvalue_in 42 pass end it "has a working function #gvalue_in_enum" do gv = GObject::Value.new gv.init GIMarshallingTests::GEnum.get_gtype gv.set_enum GIMarshallingTests::GEnum[:value3] GIMarshallingTests.gvalue_in_enum gv pass end it "has a working function #gvalue_in_with_type" do gv = GObject::Value.new gv.init GIMarshallingTests::SubSubObject.get_gtype GIMarshallingTests.gvalue_in_with_type gv, GIMarshallingTests::Object.get_gtype end it "has a working function #gvalue_inout" do res = GIMarshallingTests.gvalue_inout GObject::Value.wrap_ruby_value(42) assert_equal "42", res.get_value res = GIMarshallingTests.gvalue_inout 42 assert_equal "42", res.get_value end it "has a working function #gvalue_int64_in" do skip unless get_introspection_data 'GIMarshallingTests', 'gvalue_int64_in' gv = GObject::Value.new gv.init GObject::TYPE_INT64 gv.set_value 0x7fff_ffff_ffff_ffff GIMarshallingTests.gvalue_int64_in gv pass end it "has a working function #gvalue_int64_out" do skip unless get_introspection_data 'GIMarshallingTests', 'gvalue_int64_out' gv = GIMarshallingTests.gvalue_int64_out gv.get_value.must_equal 0x7fff_ffff_ffff_ffff end it "has a working function #gvalue_out" do res = GIMarshallingTests.gvalue_out assert_equal 42, res.get_value end it "has a working function #gvalue_out_caller_allocates" do skip unless get_introspection_data 'GIMarshallingTests', 'gvalue_out_caller_allocates' res = GIMarshallingTests.gvalue_out_caller_allocates res.get_value.must_equal 42 end it "has a working function #gvalue_return" do res = GIMarshallingTests.gvalue_return assert_equal 42, res.get_value end it "has a working function #init_function" do res, arr = GIMarshallingTests.init_function ["foo", "bar", "baz"] res.must_equal true arr.must_be :==, ["foo", "bar"] end it "has a working function #int16_in_max" do GIMarshallingTests.int16_in_max 0x7fff pass end it "has a working function #int16_in_min" do GIMarshallingTests.int16_in_min(-0x8000) pass end it "has a working function #int16_inout_max_min" do res = GIMarshallingTests.int16_inout_max_min 0x7fff assert_equal res, -0x8000 end it "has a working function #int16_inout_min_max" do res = GIMarshallingTests.int16_inout_min_max(-0x8000) assert_equal 0x7fff, res end it "has a working function #int16_out_max" do res = GIMarshallingTests.int16_out_max assert_equal 0x7fff, res end it "has a working function #int16_out_min" do res = GIMarshallingTests.int16_out_min assert_equal(-0x8000, res) end it "has a working function #int16_return_max" do res = GIMarshallingTests.int16_return_max assert_equal 0x7fff, res end it "has a working function #int16_return_min" do res = GIMarshallingTests.int16_return_min assert_equal(-0x8000, res) end it "has a working function #int32_in_max" do GIMarshallingTests.int32_in_max 0x7fffffff pass end it "has a working function #int32_in_min" do GIMarshallingTests.int32_in_min(-0x80000000) pass end it "has a working function #int32_inout_max_min" do res = GIMarshallingTests.int32_inout_max_min 0x7fffffff assert_equal(-0x80000000, res) end it "has a working function #int32_inout_min_max" do res = GIMarshallingTests.int32_inout_min_max(-0x80000000) assert_equal 0x7fffffff, res end it "has a working function #int32_out_max" do res = GIMarshallingTests.int32_out_max assert_equal 0x7fffffff, res end it "has a working function #int32_out_min" do res = GIMarshallingTests.int32_out_min assert_equal(-0x80000000, res) end it "has a working function #int32_return_max" do res = GIMarshallingTests.int32_return_max assert_equal 0x7fffffff, res end it "has a working function #int32_return_min" do res = GIMarshallingTests.int32_return_min assert_equal(-0x80000000, res) end it "has a working function #int64_in_max" do GIMarshallingTests.int64_in_max 0x7fffffffffffffff pass end it "has a working function #int64_in_min" do GIMarshallingTests.int64_in_min(-0x8000000000000000) pass end it "has a working function #int64_inout_max_min" do res = GIMarshallingTests.int64_inout_max_min 0x7fffffffffffffff assert_equal(-0x8000000000000000, res) end it "has a working function #int64_inout_min_max" do res = GIMarshallingTests.int64_inout_min_max(-0x8000000000000000) assert_equal 0x7fffffffffffffff, res end it "has a working function #int64_out_max" do res = GIMarshallingTests.int64_out_max assert_equal 0x7fffffffffffffff, res end it "has a working function #int64_out_min" do res = GIMarshallingTests.int64_out_min assert_equal(-0x8000000000000000, res) end it "has a working function #int64_return_max" do res = GIMarshallingTests.int64_return_max assert_equal 0x7fffffffffffffff, res end it "has a working function #int64_return_min" do res = GIMarshallingTests.int64_return_min assert_equal(-0x8000000000000000, res) end it "has a working function #int8_in_max" do GIMarshallingTests.int8_in_max 0x7f pass end it "has a working function #int8_in_min" do GIMarshallingTests.int8_in_min(-0x80) pass end it "has a working function #int8_inout_max_min" do res = GIMarshallingTests.int8_inout_max_min 0x7f assert_equal(-0x80, res) end it "has a working function #int8_inout_min_max" do res = GIMarshallingTests.int8_inout_min_max(-0x80) assert_equal 0x7f, res end it "has a working function #int8_out_max" do res = GIMarshallingTests.int8_out_max assert_equal 0x7f, res end it "has a working function #int8_out_min" do res = GIMarshallingTests.int8_out_min assert_equal(-0x80, res) end it "has a working function #int8_return_max" do res = GIMarshallingTests.int8_return_max assert_equal 0x7f, res end it "has a working function #int8_return_min" do res = GIMarshallingTests.int8_return_min assert_equal(-0x80, res) end it "has a working function #int_in_max" do GIMarshallingTests.int_in_max 0x7fffffff pass end it "has a working function #int_in_min" do GIMarshallingTests.int_in_min(-0x80000000) pass end it "has a working function #int_inout_max_min" do res = GIMarshallingTests.int_inout_max_min 0x7fffffff assert_equal(-0x80000000, res) end it "has a working function #int_inout_min_max" do res = GIMarshallingTests.int_inout_min_max(-0x80000000) assert_equal 0x7fffffff, res end it "has a working function #int_out_max" do res = GIMarshallingTests.int_out_max assert_equal 0x7fffffff, res end it "has a working function #int_out_min" do res = GIMarshallingTests.int_out_min assert_equal(-0x80000000, res) end it "has a working function #int_out_out" do res = GIMarshallingTests.int_out_out assert_equal [6, 7], res end it "has a working function #int_return_max" do res = GIMarshallingTests.int_return_max assert_equal 0x7fffffff, res end it "has a working function #int_return_min" do res = GIMarshallingTests.int_return_min assert_equal(-0x80000000, res) end it "has a working function #int_return_out" do res = GIMarshallingTests.int_return_out assert_equal [6, 7], res end it "has a working function #int_three_in_three_out" do res = GIMarshallingTests.int_three_in_three_out 4, 5, 6 assert_equal [4, 5, 6], res end it "has a working function #long_in_max" do GIMarshallingTests.long_in_max max_long pass end it "has a working function #long_in_min" do GIMarshallingTests.long_in_min min_long pass end it "has a working function #long_inout_max_min" do res = GIMarshallingTests.long_inout_max_min max_long assert_equal min_long, res end it "has a working function #long_inout_min_max" do res = GIMarshallingTests.long_inout_min_max min_long assert_equal max_long, res end it "has a working function #long_out_max" do res = GIMarshallingTests.long_out_max assert_equal max_long, res end it "has a working function #long_out_min" do res = GIMarshallingTests.long_out_min assert_equal min_long, res end it "has a working function #long_return_max" do res = GIMarshallingTests.long_return_max assert_equal max_long, res end it "has a working function #long_return_min" do res = GIMarshallingTests.long_return_min assert_equal min_long, res end it "has a working function #multi_array_key_value_in" do keys = ["one", "two", "three"] values = [1, 2, 3].map { |val| GObject::Value.wrap_ruby_value val } GIMarshallingTests.multi_array_key_value_in keys, values end it "has a working function #no_type_flags_in" do GIMarshallingTests.no_type_flags_in :value2 pass end it "has a working function #no_type_flags_in_zero" do GIMarshallingTests.no_type_flags_in_zero 0 pass end it "has a working function #no_type_flags_inout" do res = GIMarshallingTests.no_type_flags_inout :value2 assert_equal :value1, res end it "has a working function #no_type_flags_out" do res = GIMarshallingTests.no_type_flags_out assert_equal :value2, res end it "has a working function #no_type_flags_returnv" do res = GIMarshallingTests.no_type_flags_returnv assert_equal :value2, res end it "has a working function #overrides_struct_returnv" do res = GIMarshallingTests.overrides_struct_returnv res.must_be_instance_of GIMarshallingTests::OverridesStruct end it "has a working function #param_spec_in_bool" do skip "param_spec_in_bool tests the wrong type" ps = GObject.param_spec_boolean "mybool", "nick", "blurb", true, :readable GIMarshallingTests.param_spec_in_bool ps end it "has a working function #param_spec_out" do skip unless get_introspection_data 'GIMarshallingTests', 'param_spec_out' res = GIMarshallingTests.param_spec_out res.value_type.must_equal GObject::TYPE_STRING res.get_name.must_equal "test-param" end it "has a working function #param_spec_return" do skip unless get_introspection_data 'GIMarshallingTests', 'param_spec_return' res = GIMarshallingTests.param_spec_return res.value_type.must_equal GObject::TYPE_STRING res.get_name.must_equal "test-param" end it "has a working function #pointer_in_return" do ptr = FFI::MemoryPointer.new 1 res = GIMarshallingTests.pointer_in_return ptr assert_equal ptr.address, res.address end it "has a working function #pointer_struct_get_type" do res = GIMarshallingTests.pointer_struct_get_type gtype = GObject.type_from_name "GIMarshallingTestsPointerStruct" assert_equal gtype, res end it "has a working function #pointer_struct_returnv" do res = GIMarshallingTests.pointer_struct_returnv assert_instance_of GIMarshallingTests::PointerStruct, res assert_equal 42, res.long_ end it "has a working function #return_gvalue_flat_array" do result = GIMarshallingTests.return_gvalue_flat_array arr = result.to_a arr[0].get_value.must_equal 42 arr[1].get_value.must_equal "42" arr[2].get_value.must_equal true end it "has a working function #short_in_max" do GIMarshallingTests.short_in_max 0x7fff pass end it "has a working function #short_in_min" do GIMarshallingTests.short_in_min(-0x8000) pass end it "has a working function #short_inout_max_min" do res = GIMarshallingTests.short_inout_max_min 0x7fff assert_equal(-0x8000, res) end it "has a working function #short_inout_min_max" do res = GIMarshallingTests.short_inout_min_max(-0x8000) assert_equal 0x7fff, res end it "has a working function #short_out_max" do res = GIMarshallingTests.short_out_max assert_equal 0x7fff, res end it "has a working function #short_out_min" do res = GIMarshallingTests.short_out_min assert_equal(-0x8000, res) end it "has a working function #short_return_max" do res = GIMarshallingTests.short_return_max assert_equal 0x7fff, res end it "has a working function #short_return_min" do res = GIMarshallingTests.short_return_min assert_equal(-0x8000, res) end it "has a working function #simple_struct_returnv" do res = GIMarshallingTests.simple_struct_returnv assert_instance_of GIMarshallingTests::SimpleStruct, res assert_equal 6, res.long_ assert_equal 7, res.int8 end it "has a working function #size_in" do GIMarshallingTests.size_in max_size_t end it "has a working function #size_inout" do res = GIMarshallingTests.size_inout max_size_t assert_equal 0, res end it "has a working function #size_out" do res = GIMarshallingTests.size_out assert_equal max_size_t, res end it "has a working function #size_return" do res = GIMarshallingTests.size_return assert_equal max_size_t, res end it "has a working function #ssize_in_max" do GIMarshallingTests.ssize_in_max max_ssize_t pass end it "has a working function #ssize_in_min" do GIMarshallingTests.ssize_in_min min_ssize_t pass end it "has a working function #ssize_inout_max_min" do res = GIMarshallingTests.ssize_inout_max_min max_ssize_t assert_equal min_ssize_t, res end it "has a working function #ssize_inout_min_max" do res = GIMarshallingTests.ssize_inout_min_max min_ssize_t assert_equal max_ssize_t, res end it "has a working function #ssize_out_max" do res = GIMarshallingTests.ssize_out_max assert_equal max_ssize_t, res end it "has a working function #ssize_out_min" do res = GIMarshallingTests.ssize_out_min assert_equal min_ssize_t, res end it "has a working function #ssize_return_max" do res = GIMarshallingTests.ssize_return_max assert_equal max_ssize_t, res end it "has a working function #ssize_return_min" do res = GIMarshallingTests.ssize_return_min assert_equal min_ssize_t, res end it "has a working function #test_interface_test_int8_in" do skip "Needs implementation of TestInterface" end it "has a working function #time_t_in" do GIMarshallingTests.time_t_in 1234567890 pass end it "has a working function #time_t_inout" do res = GIMarshallingTests.time_t_inout 1234567890 assert_equal 0, res end it "has a working function #time_t_out" do res = GIMarshallingTests.time_t_out assert_equal 1234567890, res end it "has a working function #time_t_return" do res = GIMarshallingTests.time_t_return assert_equal 1234567890, res end it "has a working function #uint16_in" do GIMarshallingTests.uint16_in 0xffff pass end it "has a working function #uint16_inout" do res = GIMarshallingTests.uint16_inout 0xffff assert_equal 0, res end it "has a working function #uint16_out" do res = GIMarshallingTests.uint16_out assert_equal 0xffff, res end it "has a working function #uint16_return" do res = GIMarshallingTests.uint16_return assert_equal 0xffff, res end it "has a working function #uint32_in" do GIMarshallingTests.uint32_in 0xffffffff end it "has a working function #uint32_inout" do res = GIMarshallingTests.uint32_inout 0xffffffff assert_equal 0, res end it "has a working function #uint32_out" do res = GIMarshallingTests.uint32_out assert_equal 0xffffffff, res end it "has a working function #uint32_return" do res = GIMarshallingTests.uint32_return assert_equal 0xffffffff, res end it "has a working function #uint64_in" do GIMarshallingTests.uint64_in 0xffff_ffff_ffff_ffff pass end it "has a working function #uint64_inout" do res = GIMarshallingTests.uint64_inout 0xffff_ffff_ffff_ffff assert_equal 0, res end it "has a working function #uint64_out" do res = GIMarshallingTests.uint64_out assert_equal 0xffff_ffff_ffff_ffff, res end it "has a working function #uint64_return" do res = GIMarshallingTests.uint64_return assert_equal 0xffff_ffff_ffff_ffff, res end it "has a working function #uint8_in" do GIMarshallingTests.uint8_in 0xff end it "has a working function #uint8_inout" do res = GIMarshallingTests.uint8_inout 0xff assert_equal 0, res end it "has a working function #uint8_out" do res = GIMarshallingTests.uint8_out assert_equal 0xff, res end it "has a working function #uint8_return" do res = GIMarshallingTests.uint8_return assert_equal 0xff, res end it "has a working function #uint_in" do GIMarshallingTests.uint_in max_uint pass end it "has a working function #uint_inout" do res = GIMarshallingTests.uint_inout max_uint assert_equal 0, res end it "has a working function #uint_out" do res = GIMarshallingTests.uint_out assert_equal max_uint, res end it "has a working function #uint_return" do res = GIMarshallingTests.uint_return assert_equal max_uint, res end it "has a working function #ulong_in" do GIMarshallingTests.ulong_in max_ulong end it "has a working function #ulong_inout" do res = GIMarshallingTests.ulong_inout max_ulong assert_equal 0, res end it "has a working function #ulong_out" do res = GIMarshallingTests.ulong_out assert_equal max_ulong, res end it "has a working function #ulong_return" do res = GIMarshallingTests.ulong_return assert_equal max_ulong, res end it "has a working function #union_inout" do skip "This function is defined in the header but not implemented" end it "has a working function #union_out" do skip "This function is defined in the header but not implemented" end it "has a working function #union_returnv" do res = GIMarshallingTests.union_returnv assert_instance_of GIMarshallingTests::Union, res assert_equal 42, res.long_ end it "has a working function #ushort_in" do GIMarshallingTests.ushort_in max_ushort pass end it "has a working function #ushort_inout" do res = GIMarshallingTests.ushort_inout max_ushort assert_equal 0, res end it "has a working function #ushort_out" do res = GIMarshallingTests.ushort_out assert_equal max_ushort, res end it "has a working function #ushort_return" do res = GIMarshallingTests.ushort_return assert_equal max_ushort, res end it "has a working function #utf8_as_uint8array_in" do skip unless get_introspection_data 'GIMarshallingTests', 'utf8_as_uint8array_in' GIMarshallingTests.utf8_as_uint8array_in GIMarshallingTests::CONSTANT_UTF8.bytes.to_a pass end it "has a working function #utf8_dangling_out" do res = GIMarshallingTests.utf8_dangling_out assert_nil res end it "has a working function #utf8_full_in" do skip "This function is defined in the header but not implemented" end it "has a working function #utf8_full_inout" do res = GIMarshallingTests.utf8_full_inout "const ♥ utf8" assert_equal "", res end it "has a working function #utf8_full_out" do res = GIMarshallingTests.utf8_full_out assert_equal "const ♥ utf8", res end it "has a working function #utf8_full_return" do res = GIMarshallingTests.utf8_full_return assert_equal "const ♥ utf8", res end it "has a working function #utf8_none_in" do GIMarshallingTests.utf8_none_in "const ♥ utf8" pass end it "has a working function #utf8_none_inout" do res = GIMarshallingTests.utf8_none_inout "const ♥ utf8" assert_equal "", res end it "has a working function #utf8_none_out" do res = GIMarshallingTests.utf8_none_out assert_equal "const ♥ utf8", res end it "has a working function #utf8_none_return" do res = GIMarshallingTests.utf8_none_return assert_equal "const ♥ utf8", res end end gir_ffi-0.6.7/test/integration/generated_regress_test.rb0000644000004100000410000020005312224462647023550 0ustar www-datawww-data# coding: utf-8 require 'gir_ffi_test_helper' GirFFI.setup :Regress def get_field_value obj, field struct = obj.instance_variable_get :@struct struct[field] end # Tests generated methods and functions in the Regress namespace. describe Regress do describe Regress::Lib do it "extends GirFFI::Library" do class << Regress::Lib self.must_be :include?, GirFFI::Library end end end describe "Regress::ATestError" do before do skip unless get_introspection_data 'Regress', 'ATestError' end it "has the member :code0" do Regress::ATestError[:code0].must_equal 0 end it "has the member :code1" do Regress::ATestError[:code1].must_equal 1 end it "has the member :code2" do Regress::ATestError[:code2].must_equal 2 end end it "has the constant DOUBLE_CONSTANT" do assert_equal 44.22, Regress::DOUBLE_CONSTANT end it "has the constant GUINT64_CONSTANT" do skip unless get_introspection_data 'Regress', 'GUINT64_CONSTANT' Regress::GUINT64_CONSTANT.must_equal 18446744073709551615 end it "has the constant GUINT64_CONSTANTA" do skip unless get_introspection_data 'Regress', 'GUINT64_CONSTANTA' Regress::GUINT64_CONSTANTA.must_equal 18446744073709551615 end it "has the constant G_GINT64_CONSTANT" do skip unless get_introspection_data 'Regress', 'G_GINT64_CONSTANT' Regress::G_GINT64_CONSTANT.must_equal 1000 end it "has the constant INT_CONSTANT" do assert_equal 4422, Regress::INT_CONSTANT end it "has the constant LONG_STRING_CONSTANT" do Regress::LONG_STRING_CONSTANT.must_equal %w(TYPE VALUE ENCODING CHARSET LANGUAGE DOM INTL POSTAL PARCEL HOME WORK PREF VOICE FAX MSG CELL PAGER BBS MODEM CAR ISDN VIDEO AOL APPLELINK ATTMAIL CIS EWORLD INTERNET IBMMAIL MCIMAIL POWERSHARE PRODIGY TLX X400 GIF CGM WMF BMP MET PMB DIB PICT TIFF PDF PS JPEG QTIME MPEG MPEG2 AVI WAVE AIFF PCM X509 PGP).join(",") end describe "Regress::LikeGnomeKeyringPasswordSchema" do before do skip unless get_introspection_data 'Regress', 'LikeGnomeKeyringPasswordSchema' end it "creates an instance using #new" do obj = Regress::LikeGnomeKeyringPasswordSchema.new obj.must_be_instance_of Regress::LikeGnomeKeyringPasswordSchema end let(:instance) { Regress::LikeGnomeKeyringPasswordSchema.new } it "has a writable field dummy" do instance.dummy.must_equal 0 instance.dummy = 42 instance.dummy.must_equal 42 end it "has a writable field attributes" do skip "This does not work yet" instance.attributes end it "has a writable field dummy2" do instance.dummy2.must_equal 0.0 instance.dummy2 = 42.42 instance.dummy2.must_equal 42.42 end end it "has the constant MAXUINT64" do skip unless get_introspection_data 'Regress', 'MAXUINT64' Regress::MAXUINT64.must_equal 0xffff_ffff_ffff_ffff end it "has the constant MININT64" do skip unless get_introspection_data 'Regress', 'MININT64' Regress::MININT64.must_equal(-0x8000_0000_0000_0000) end it "has the constant Mixed_Case_Constant" do assert_equal 4423, Regress::Mixed_Case_Constant end it "has the constant NEGATIVE_INT_CONSTANT" do skip unless get_introspection_data 'Regress', 'NEGATIVE_INT_CONSTANT' Regress::NEGATIVE_INT_CONSTANT.must_equal(-42) end it "has the constant STRING_CONSTANT" do assert_equal "Some String", Regress::STRING_CONSTANT end describe "Regress::TestABCError" do before do skip unless get_introspection_data 'Regress', 'TestABCError' end it "has the member :code1" do Regress::TestABCError[:code1].must_equal 1 end it "has the member :code2" do Regress::TestABCError[:code2].must_equal 2 end it "has the member :code3" do Regress::TestABCError[:code3].must_equal 3 end it "has a working function #quark" do quark = Regress::TestABCError.quark GLib.quark_to_string(quark).must_equal "regress-test-abc-error" end end describe "Regress::TestBoxed" do let(:instance) { Regress::TestBoxed.new_alternative_constructor1 123 } it "has a writable field some_int8" do instance.some_int8.must_equal 123 instance.some_int8 = -43 instance.some_int8.must_equal(-43) end it "has a writable field nested_a" do instance.nested_a.some_int.must_equal 0 nested = Regress::TestSimpleBoxedA.new nested.some_int = 12345 instance.nested_a = nested instance.nested_a.some_int.must_equal 12345 end it "has a writable field priv" do instance.priv.wont_be_nil other = Regress::TestBoxed.new instance.priv.wont_equal other.priv instance.priv = other.priv instance.priv.must_equal other.priv end it "creates an instance using #new" do tb = Regress::TestBoxed.new assert_instance_of Regress::TestBoxed, tb end it "creates an instance using #new_alternative_constructor1" do tb = Regress::TestBoxed.new_alternative_constructor1 1 assert_instance_of Regress::TestBoxed, tb assert_equal 1, tb.some_int8 end it "creates an instance using #new_alternative_constructor2" do tb = Regress::TestBoxed.new_alternative_constructor2 1, 2 assert_instance_of Regress::TestBoxed, tb assert_equal 1 + 2, tb.some_int8 end it "creates an instance using #new_alternative_constructor3" do tb = Regress::TestBoxed.new_alternative_constructor3 "54" assert_instance_of Regress::TestBoxed, tb assert_equal 54, tb.some_int8 end it "has non-zero positive result for #get_gtype" do assert Regress::TestBoxed.get_gtype > 0 end it "has a working method #copy" do tb2 = instance.copy assert_instance_of Regress::TestBoxed, tb2 assert_equal 123, tb2.some_int8 instance.some_int8 = 89 assert_equal 123, tb2.some_int8 end it "has a working method #equals" do tb2 = Regress::TestBoxed.new_alternative_constructor2 120, 3 assert_equal true, instance.equals(tb2) end end describe "Regress::TestBoxedB" do let(:instance) { Regress::TestBoxedB.new 8, 42 } it "has a writable field some_int8" do instance.some_int8.must_equal 8 instance.some_int8 = -43 instance.some_int8.must_equal(-43) end it "has a writable field some_long" do instance.some_long.must_equal 42 instance.some_long = -4342 instance.some_long.must_equal(-4342) end it "creates an instance using #new" do tb = Regress::TestBoxedB.new 8, 42 assert_instance_of Regress::TestBoxedB, tb end it "has a working method #copy" do cp = instance.copy cp.must_be_instance_of Regress::TestBoxedB cp.some_int8.must_equal 8 cp.some_long.must_equal 42 instance.some_int8 = 2 cp.some_int8.must_equal 8 end end describe "Regress::TestBoxedC" do before do skip unless get_introspection_data 'Regress', 'TestBoxedC' end let(:instance) { Regress::TestBoxedC.new } it "has a writable field refcount" do instance.refcount.must_equal 1 instance.refcount = 2 instance.refcount.must_equal 2 end it "has a writable field another_thing" do instance.another_thing.must_equal 42 instance.another_thing = 4342 instance.another_thing.must_equal 4342 end it "creates an instance using #new" do tb = Regress::TestBoxedC.new assert_instance_of Regress::TestBoxedC, tb end end describe "Regress::TestBoxedD" do before do skip unless get_introspection_data 'Regress', 'TestBoxedD' end it "creates an instance using #new" do instance = Regress::TestBoxedD.new "foo", 42 instance.must_be_instance_of Regress::TestBoxedD end it "has a working method #copy" do instance = Regress::TestBoxedD.new "foo", 42 copy = instance.copy copy.must_be_instance_of Regress::TestBoxedD instance.get_magic.must_equal copy.get_magic instance.wont_equal copy end it "has a working method #free" do instance = Regress::TestBoxedD.new "foo", 42 instance.free pass end it "has a working method #get_magic" do instance = Regress::TestBoxedD.new "foo", 42 instance.get_magic.must_equal "foo".length + 42 end end describe "Regress::TestDEFError" do before do skip unless get_introspection_data 'Regress', 'TestDEFError' end it "has the member :code0" do Regress::TestDEFError[:code0].must_equal 0 end it "has the member :code1" do Regress::TestDEFError[:code1].must_equal 1 end it "has the member :code2" do Regress::TestDEFError[:code2].must_equal 2 end end describe "Regress::TestEnum" do it "has the member :value1" do Regress::TestEnum[:value1].must_equal 0 end it "has the member :value2" do Regress::TestEnum[:value2].must_equal 1 end it "has the member :value3" do Regress::TestEnum[:value3].must_equal(-1) end it "has the member :value4" do Regress::TestEnum[:value4].must_equal 48 end it "has a working function #param" do Regress::TestEnum.param(:value1).must_equal("value1") Regress::TestEnum.param(:value2).must_equal("value2") Regress::TestEnum.param(:value3).must_equal("value3") Regress::TestEnum.param(:value4).must_equal("value4") Regress::TestEnum.param(0).must_equal("value1") Regress::TestEnum.param(1).must_equal("value2") Regress::TestEnum.param(-1).must_equal("value3") Regress::TestEnum.param(48).must_equal("value4") end end describe "Regress::TestEnumNoGEnum" do it "has the member :evalue1" do Regress::TestEnumNoGEnum[:evalue1].must_equal 0 end it "has the member :evalue2" do Regress::TestEnumNoGEnum[:evalue2].must_equal 42 end it "has the member :evalue3" do Regress::TestEnumNoGEnum[:evalue3].must_equal 48 end end describe "Regress::TestEnumUnsigned" do it "has the member :value1" do Regress::TestEnumUnsigned[:value1].must_equal 1 end # NOTE In c, the positive and negative values are not distinguished it "has the member :value2" do Regress::TestEnumUnsigned[:value2].must_equal(-2147483648) end end describe "Regress::TestError" do before do skip unless get_introspection_data 'Regress', 'TestError' end it "has the member :code1" do Regress::TestError[:code1].must_equal 1 end it "has the member :code2" do Regress::TestError[:code2].must_equal 2 end it "has the member :code3" do Regress::TestError[:code3].must_equal 3 end it "has a working function #quark" do quark = Regress::TestError.quark GLib.quark_to_string(quark).must_equal "regress-test-error" end end describe "Regress::TestFlags" do it "has the member :flag1" do assert_equal 1, Regress::TestFlags[:flag1] end it "has the member :flag2" do assert_equal 2, Regress::TestFlags[:flag2] end it "has the member :flag3" do assert_equal 4, Regress::TestFlags[:flag3] end end describe "Regress::TestFloating" do it "creates an instance using #new" do o = Regress::TestFloating.new o.must_be_instance_of Regress::TestFloating end describe "an instance" do before do @o = Regress::TestFloating.new end it "has a reference count of 1" do assert_equal 1, ref_count(@o) end it "has been sunk" do assert !is_floating?(@o) end end end describe "Regress::TestFundamentalObject" do it "does not have GObject::Object as an ancestor" do refute_includes Regress::TestFundamentalObject.ancestors, GObject::Object end it "cannot be instanciated" do proc { Regress::TestFundamentalObject.new }.must_raise NoMethodError end it "has a working method #ref" do skip "Can only be tested in the descendent class" end it "has a working method #unref" do skip "Can only be tested in the descendent class" end end describe "Regress::TestFundamentalSubObject" do it "creates an instance using #new" do obj = Regress::TestFundamentalSubObject.new "foo" obj.must_be_instance_of Regress::TestFundamentalSubObject end let(:instance) { Regress::TestFundamentalSubObject.new "foo" } it "is a subclass of TestFundamentalObject" do assert_kind_of Regress::TestFundamentalObject, instance end it "has a field :data storing the constructor parameter" do assert_equal "foo", instance.data end it "can access its parent class' fields directly" do instance.flags.must_equal 0 end # NOTE: The following tests test fields and methods on the abstract parent # class. it "has a refcount of 1" do assert_equal 1, instance.refcount end it "has a working method #ref" do instance.ref instance.refcount.must_equal 2 end it "has a working method #unref" do instance.unref instance.refcount.must_equal 0 end end describe "Regress::TestInterface" do it "is a module" do assert_instance_of Module, Regress::TestInterface end it "extends InterfaceBase" do metaclass = class << Regress::TestInterface; self; end assert_includes metaclass.ancestors, GirFFI::InterfaceBase end it "has non-zero positive result for #get_gtype" do Regress::TestInterface.get_gtype.must_be :>, 0 end end describe "Regress::TestObj" do it "creates an instance using #constructor" do obj = Regress::TestObj.constructor obj.must_be_instance_of Regress::TestObj end it "creates an instance using #new" do o1 = Regress::TestObj.constructor o2 = Regress::TestObj.new o1 o2.must_be_instance_of Regress::TestObj end it "creates an instance using #new_callback" do a = 1 o = Regress::TestObj.new_callback Proc.new { a = 2 }, nil, nil assert_instance_of Regress::TestObj, o a.must_equal 2 end it "creates an instance using #new_from_file" do o = Regress::TestObj.new_from_file("foo") assert_instance_of Regress::TestObj, o end it "has a working function #null_out" do obj = Regress::TestObj.null_out obj.must_be_nil end it "has a working function #static_method" do rv = Regress::TestObj.static_method 623 assert_equal 623.0, rv end it "has a working function #static_method_callback" do a = 1 Regress::TestObj.static_method_callback Proc.new { a = 2 } assert_equal 2, a end let(:instance) { Regress::TestObj.new_from_file("foo") } describe "its gtype" do it "can be found through get_gtype and GObject.type_from_instance" do gtype = Regress::TestObj.get_gtype r = GObject.type_from_instance instance assert_equal gtype, r end end it "has a reference count of 1" do assert_equal 1, ref_count(instance) end it "does not float" do assert !is_floating?(instance) end it "has a working method #matrix" do instance.matrix("bar").must_equal 42 end it "has a working method #do_matrix" do instance.do_matrix("bar").must_equal 42 end it "has a working method #emit_sig_with_foreign_struct" do skip unless get_method_introspection_data('Regress', 'TestObj', 'emit_sig_with_foreign_struct') has_fired = false instance.signal_connect "sig-with-foreign-struct" do |obj, cr| has_fired = true cr.must_be_instance_of Cairo::Context end instance.emit_sig_with_foreign_struct assert has_fired end it "has a working method #emit_sig_with_int64" do skip "This does not work yet" instance.signal_connect "sig-with-int64-prop" do |obj, i, ud| int end instance.emit_sig_with_int64 end it "has a working method #emit_sig_with_obj" do has_fired = false instance.signal_connect "sig-with-obj" do |it, obj| has_fired = true obj.int.must_equal 3 end instance.emit_sig_with_obj assert has_fired end it "has a working method #emit_sig_with_uint64" do skip "This does not work yet" instance.signal_connect "sig-with-uint64-prop" do |obj, i, ud| i end instance.emit_sig_with_uint64 end it "has a working method #forced_method" do instance.forced_method pass end it "has a working method #instance_method" do rv = instance.instance_method assert_equal(-1, rv) end it "has a working method #instance_method_callback" do a = 1 instance.instance_method_callback Proc.new { a = 2 } assert_equal 2, a end it "has a working method #set_bare" do obj = Regress::TestObj.new_from_file("bar") instance.set_bare obj instance.bare.must_equal obj end it "has a working method #skip_inout_param" do a = 1 c = 2.0 num1 = 3 num2 = 4 result, out_b, sum = instance.skip_inout_param a, c, num1, num2 result.must_equal true out_b.must_equal a + 1 sum.must_equal num1 + 10 * num2 end it "has a working method #skip_out_param" do a = 1 c = 2.0 d = 3 num1 = 4 num2 = 5 result, out_d, sum = instance.skip_out_param a, c, d, num1, num2 result.must_equal true out_d.must_equal d + 1 sum.must_equal num1 + 10 * num2 end it "has a working method #skip_param" do a = 1 d = 3 num1 = 4 num2 = 5 result, out_b, out_d, sum = instance.skip_param a, d, num1, num2 result.must_equal true out_b.must_equal a + 1 out_d.must_equal d + 1 sum.must_equal num1 + 10 * num2 end it "has a working method #skip_return_val" do a = 1 c = 2.0 d = 3 num1 = 4 num2 = 5 out_b, out_d, out_sum = instance.skip_return_val a, c, d, num1, num2 out_b.must_equal a + 1 out_d.must_equal d + 1 out_sum.must_equal num1 + 10 * num2 end it "has a working method #skip_return_val_no_out" do result = instance.skip_return_val_no_out 1 result.must_be_nil lambda { instance.skip_return_val_no_out 0 }.must_raise RuntimeError end it "has a working method #torture_signature_0" do y, z, q = instance.torture_signature_0(-21, "hello", 13) assert_equal [-21, 2 * -21, "hello".length + 13], [y, z, q] end it "has a working method #torture_signature_1" do ret, y, z, q = instance.torture_signature_1(-21, "hello", 12) assert_equal [true, -21, 2 * -21, "hello".length + 12], [ret, y, z, q] assert_raises RuntimeError do instance.torture_signature_1(-21, "hello", 11) end end describe "its 'bare' property" do it "can be retrieved with #get_property" do instance.get_property("bare").must_be_nil end it "can be retrieved with #bare" do instance.bare.must_be_nil end it "can be set with #set_property" do obj = Regress::TestObj.new_from_file("bar") instance.set_property "bare", obj instance.get_property("bare").must_equal obj end it "can be set with #bare=" do obj = Regress::TestObj.new_from_file("bar") instance.bare = obj instance.bare.must_equal obj instance.get_property("bare").must_equal obj end end describe "its 'boxed' property" do it "can be retrieved with #get_property" do instance.get_property("boxed").must_be_nil end it "can be retrieved with #boxed" do instance.boxed.must_be_nil end it "can be set with #set_property" do tb = Regress::TestBoxed.new_alternative_constructor1 75 instance.set_property "boxed", tb instance.get_property("boxed").some_int8.must_equal 75 end it "can be set with #boxed=" do tb = Regress::TestBoxed.new_alternative_constructor1 75 instance.boxed = tb instance.boxed.some_int8.must_equal tb.some_int8 instance.get_property("boxed").some_int8.must_equal tb.some_int8 end end describe "its 'double' property" do it "can be retrieved with #get_property" do instance.get_property("double").must_equal 0.0 end it "can be retrieved with #double" do instance.double.must_equal 0.0 end it "can be set with #set_property" do instance.set_property "double", 3.14 instance.get_property("double").must_equal 3.14 end it "can be set with #double=" do instance.double = 3.14 instance.double.must_equal 3.14 instance.get_property("double").must_equal 3.14 end end describe "its 'float' property" do it "can be retrieved with #get_property" do instance.get_property("float").must_equal 0.0 end it "can be retrieved with #float" do instance.float.must_equal 0.0 end it "can be set with #set_property" do instance.set_property "float", 3.14 instance.get_property("float").must_be_close_to 3.14 end it "can be set with #float=" do instance.float = 3.14 instance.float.must_be_close_to 3.14 instance.get_property("float").must_be_close_to 3.14 end end describe "its 'gtype' property" do before do skip unless get_property_introspection_data("Regress", "TestObj", "gtype") end it "can be retrieved with #get_property" do instance.get_property("gtype").must_equal 0 end it "can be retrieved with #gtype" do instance.gtype.must_equal 0 end it "can be set with #set_property" do instance.set_property "gtype", GObject::TYPE_INT64 instance.get_property("gtype").must_equal GObject::TYPE_INT64 end it "can be set with #gtype=" do instance.gtype = GObject::TYPE_STRING instance.gtype.must_equal GObject::TYPE_STRING instance.get_property("gtype").must_equal GObject::TYPE_STRING end end describe "its 'hash-table' property" do it "can be retrieved with #get_property" do instance.get_property("hash-table").must_be_nil end it "can be retrieved with #hash_table" do instance.hash_table.must_be_nil end it "can be set with #set_property" do instance.set_property "hash-table", {"foo" => 34, "bar" => 83} instance.get_property("hash-table").to_hash.must_equal({"foo" => 34, "bar" => 83}) end it "can be set with #hash_table=" do instance.set_property "hash-table", {"foo" => 34, "bar" => 83} instance.hash_table.to_hash.must_equal({"foo" => 34, "bar" => 83}) instance.get_property("hash-table").to_hash.must_equal({"foo" => 34, "bar" => 83}) end end describe "its 'hash-table-old' property" do it "can be retrieved with #get_property" do instance.get_property("hash-table-old").must_be_nil end it "can be retrieved with #hash_table_old" do instance.hash_table_old.must_be_nil end it "can be set with #set_property" do instance.set_property "hash-table-old", {"foo" => 34, "bar" => 83} instance.get_property("hash-table-old").to_hash.must_equal({"foo" => 34, "bar" => 83}) end it "can be set with #hash_table_old=" do instance.set_property "hash-table-old", {"foo" => 34, "bar" => 83} instance.hash_table_old.to_hash.must_equal({"foo" => 34, "bar" => 83}) instance.get_property("hash-table-old").to_hash.must_equal({"foo" => 34, "bar" => 83}) end end describe "its 'int' property" do it "can be retrieved with #get_property" do assert_equal 0, instance.get_property("int") end it "can be retrieved with #int" do assert_equal 0, instance.int end it "can be set with #set_property" do instance.set_property "int", 42 assert_equal 42, instance.get_property("int") end it "can be set with #int=" do instance.int = 41 assert_equal 41, instance.get_property("int") assert_equal 41, instance.int end end describe "its 'list' property" do it "can be retrieved with #get_property" do instance.get_property("list").must_be_nil end it "can be retrieved with #list" do instance.list.must_be_nil end it "can be set with #set_property" do instance.set_property "list", ["foo", "bar"] instance.get_property("list").must_be :==, ["foo", "bar"] end it "can be set with #list=" do instance.list = ["foo", "bar"] instance.list.must_be :==, ["foo", "bar"] instance.get_property("list").must_be :==, ["foo", "bar"] end end describe "its 'list-old' property" do it "can be retrieved with #get_property" do instance.get_property("list-old").must_be_nil end it "can be retrieved with #list_old" do instance.list_old.must_be_nil end it "can be set with #set_property" do instance.set_property "list-old", ["foo", "bar"] instance.get_property("list-old").must_be :==, ["foo", "bar"] end it "can be set with #list_old=" do instance.list_old = ["foo", "bar"] instance.list_old.must_be :==, ["foo", "bar"] instance.get_property("list-old").must_be :==, ["foo", "bar"] end end describe "its 'string' property" do it "can be retrieved with #get_property" do assert_nil instance.get_property("string") end it "can be retrieved with #string" do assert_nil instance.string end it "can be set with #set_property" do instance.set_property "string", "foobar" assert_equal "foobar", instance.get_property("string") end it "can be set with #string=" do instance.string = "foobar" assert_equal "foobar", instance.string assert_equal "foobar", instance.get_property("string") end end it "handles the 'all' signal" do a = nil GObject.signal_connect(instance, "all") { a = 4 } GObject.signal_emit instance, "all" a.must_equal 4 end it "handles the 'cleanup' signal" do a = nil GObject.signal_connect(instance, "cleanup") { a = 4 } GObject.signal_emit instance, "cleanup" a.must_equal 4 end it "handles the 'first' signal" do a = nil GObject.signal_connect(instance, "first") { a = 4 } GObject.signal_emit instance, "first" a.must_equal 4 end it "handles the 'sig-with-array-len-prop' signal" do skip end it "handles the 'sig-with-array-prop' signal" do a = nil GObject.signal_connect(instance, "sig-with-array-prop") {|_, arr, _| a = arr } # TODO: Automatically convert arguments to signal_emit. GObject.signal_emit instance, "sig-with-array-prop", GLib::Array.from(:uint, [1, 2, 3]) a.to_a.must_equal [1, 2, 3] end it "handles the 'sig-with-foreign-struct' signal" do skip end it "handles the 'sig-with-hash-prop' signal" do skip end it "handles the 'sig-with-int64-prop' signal" do skip end it "handles the 'sig-with-intarray-ret' signal" do skip end it "handles the 'sig-with-obj' signal" do skip end it "handles the 'sig-with-strv' signal" do skip end it "handles the 'sig-with-uint64-prop' signal" do skip end it "handles the 'test' signal" do a = b = nil o = Regress::TestSubObj.new GObject.signal_connect(o, "test", 2) { |i, d| a = d; b = i } GObject.signal_emit o, "test" assert_equal [2, o], [a, b] end it "handles the 'test-with-static-scope-arg' signal" do skip end end describe "Regress::TestOtherError" do before do skip unless get_introspection_data 'Regress', 'TestOtherError' end it "has the member :code1" do Regress::TestOtherError[:code1].must_equal 1 end it "has the member :code2" do Regress::TestOtherError[:code2].must_equal 2 end it "has the member :code3" do Regress::TestOtherError[:code3].must_equal 3 end it "has a working function #quark" do quark = Regress::TestOtherError.quark GLib.quark_to_string(quark).must_equal "regress-test-other-error" end end describe "Regress::TestPrivateEnum" do it "has the member :public_enum_before" do Regress::TestPrivateEnum[:public_enum_before].must_equal 1 end it "does not have the member :private" do Regress::TestPrivateEnum[:private].must_equal nil end it "has the member :public_enum_after" do Regress::TestPrivateEnum[:public_enum_after].must_equal 4 end end describe "Regress::TestPrivateStruct" do let(:instance) { Regress::TestPrivateStruct.new } it "has a writable field this_is_public_before" do instance.this_is_public_before.must_equal 0 instance.this_is_public_before = 42 instance.this_is_public_before.must_equal 42 end it "has a private field this_is_private" do skip "GIR identifies this field as readable" proc { instance.this_is_private }.must_raise NoMethodError proc { instance.this_is_private = 42 }.must_raise NoMethodError end it "has a writable field this_is_public_after" do instance.this_is_public_after.must_equal 0 instance.this_is_public_after = 42 instance.this_is_public_after.must_equal 42 end end describe "Regress::TestReferenceEnum" do before do skip unless get_introspection_data 'Regress', 'TestReferenceEnum' end it "has the member :0" do Regress::TestReferenceEnum[:"0"].must_equal 4 end it "has the member :1" do Regress::TestReferenceEnum[:"1"].must_equal 2 end it "has the member :2" do Regress::TestReferenceEnum[:"2"].must_equal 54 end it "has the member :3" do Regress::TestReferenceEnum[:"3"].must_equal 4 end it "has the member :4" do Regress::TestReferenceEnum[:"4"].must_equal 216 end it "has the member :5" do Regress::TestReferenceEnum[:"5"].must_equal(-217) end end describe "Regress::TestSimpleBoxedA" do it "creates an instance using #new" do obj = Regress::TestSimpleBoxedA.new assert_instance_of Regress::TestSimpleBoxedA, obj end let(:instance) { Regress::TestSimpleBoxedA.new } it "has a working method #copy" do instance.some_int = 4236 obj2 = instance.copy obj2.must_be_instance_of Regress::TestSimpleBoxedA obj2.some_int.must_equal instance.some_int instance.some_int = 89 obj2.some_int.wont_equal instance.some_int end it "has a working method #equals" do instance.some_int = 4236 ob2 = Regress::TestSimpleBoxedA.new ob2.some_int = 4236 ob2.equals(instance).must_equal true ob2.some_enum = :value3 ob2.equals(instance).must_equal true ob2.some_int = 42 ob2.equals(instance).wont_equal true end it "has a working function #const_return" do result = Regress::TestSimpleBoxedA.const_return [result.some_int, result.some_int8, result.some_double].must_equal [5, 6, 7.0] end end describe "Regress::TestSimpleBoxedB" do let(:instance) { Regress::TestSimpleBoxedB.new } it "has a writable field some_int8" do instance.some_int8.must_equal 0 instance.some_int8 = 42 instance.some_int8.must_equal 42 end it "has a writable field nested_a" do instance.nested_a.some_int.must_equal 0 instance.nested_a = Regress::TestSimpleBoxedA.const_return instance.nested_a.some_int.must_equal 5 end it "has a working method #copy" do instance.some_int8 = -42 instance.nested_a.some_int = 4242 copy = instance.copy [copy.some_int8, copy.nested_a.some_int].must_equal [-42, 4242] instance.some_int8 = 103 copy.some_int8.must_equal(-42) end end describe "Regress::TestStructA" do let(:instance) { Regress::TestStructA.new } it "has a writable field some_int" do instance.some_int.must_equal 0 instance.some_int = 2556 instance.some_int.must_equal 2556 end it "has a writable field some_int8" do instance.some_int8.must_equal 0 instance.some_int8 = -10 instance.some_int8.must_equal(-10) end it "has a writable field some_double" do instance.some_double.must_equal 0.0 instance.some_double = 1.03455e20 instance.some_double.must_equal 1.03455e20 end it "has a writable field some_enum" do instance.some_enum.must_equal :value1 instance.some_enum = :value2 instance.some_enum.must_equal :value2 end it "has a working method #clone" do a = Regress::TestStructA.new a.some_int = 2556 a.some_int8 = -10 a.some_double = 1.03455e20 a.some_enum = :value2 b = a.clone assert_equal 2556, b.some_int assert_equal(-10, b.some_int8) assert_equal 1.03455e20, b.some_double assert_equal :value2, b.some_enum end it "has a working function #parse" do skip unless get_method_introspection_data 'Regress', 'TestStructA', 'parse' a = Regress::TestStructA.parse("this string is actually ignored") a.some_int.must_equal 23 end end describe "Regress::TestStructB" do let(:instance) { Regress::TestStructB.new } it "has a writable field some_int8" do instance.some_int8.must_equal 0 instance.some_int8 = 42 instance.some_int8.must_equal 42 end it "has a writable field nested_a" do instance.nested_a.some_int.must_equal 0 nested = Regress::TestStructA.new nested.some_int = -4321 instance.nested_a = nested instance.nested_a.some_int.must_equal(-4321) end it "has a working method #clone" do a = Regress::TestStructB.new a.some_int8 = 42 a.nested_a.some_int = 2556 a.nested_a.some_int8 = -10 a.nested_a.some_double = 1.03455e20 a.nested_a.some_enum = :value2 b = a.clone assert_equal 42, b.some_int8 assert_equal 2556, b.nested_a.some_int assert_equal(-10, b.nested_a.some_int8) assert_equal 1.03455e20, b.nested_a.some_double assert_equal :value2, b.nested_a.some_enum end end describe "Regress::TestStructC" do let(:instance) { Regress::TestStructC.new } it "has a writable field another_int" do instance.another_int.must_equal 0 instance.another_int = 42 instance.another_int.must_equal 42 end it "has a writable field obj" do o = Regress::TestSubObj.new instance.obj.must_equal nil instance.obj = o instance.obj.must_equal o end end describe "Regress::TestStructD" do let(:instance) { Regress::TestStructD.new } it "has a writable field array1" do instance.array1.must_be :==, [] struct = Regress::TestStructA.new instance.array1 = [struct] instance.array1.must_be :==, [struct] end it "has a writable field array2" do instance.array2.must_be :==, [] o = Regress::TestSubObj.new instance.array2 = [o] instance.array2.must_be :==, [o] end it "has a writable field field" do instance.field.must_equal nil o = Regress::TestSubObj.new instance.field = o instance.field.must_equal o end end describe "Regress::TestStructE" do let(:instance) { Regress::TestStructE.new } it "has a writable field some_type" do instance.some_type.must_equal 0 instance.some_type = GObject::TYPE_STRING instance.some_type.must_equal GObject::TYPE_STRING end it "has a writable field some_union" do instance.some_union.map(&:v_int).must_equal [0, 0] union1 = Regress::TestStructE__some_union__union.new union1.v_int = 42 union2 = Regress::TestStructE__some_union__union.new union2.v_int = 84 instance.some_union = [union1, union2] instance.some_union.map(&:v_int).must_equal [42, 84] end end describe "Regress::TestStructE__some_union__union" do let(:instance) { Regress::TestStructE__some_union__union.new } it "has a writable field v_int" do instance.v_int.must_equal 0 instance.v_int = -54321 instance.v_int.must_equal(-54321) end it "has a writable field v_uint" do instance.v_uint.must_equal 0 instance.v_uint = 54321 instance.v_uint.must_equal 54321 end it "has a writable field v_long" do instance.v_long.must_equal 0 instance.v_long = -54321 instance.v_long.must_equal(-54321) end it "has a writable field v_ulong" do instance.v_long.must_equal 0 instance.v_long = 54321 instance.v_long.must_equal 54321 end it "has a writable field v_int64" do instance.v_int64.must_equal 0 instance.v_int64 = -54_321_000_000_000 instance.v_int64.must_equal(-54_321_000_000_000) end it "has a writable field v_uint64" do instance.v_uint64.must_equal 0 instance.v_uint64 = 54_321_000_000_000 instance.v_uint64.must_equal 54_321_000_000_000 end it "has a writable field v_float" do instance.v_float.must_equal 0 instance.v_float = 3.1415 instance.v_float.must_be_close_to 3.1415 end it "has a writable field v_double" do instance.v_double.must_equal 0 instance.v_double = 3.1415 instance.v_double.must_equal 3.1415 end it "has a writable field v_pointer" do instance.v_pointer.must_be :null? instance.v_pointer = FFI::Pointer.new 54321 instance.v_pointer.address.must_equal 54321 end end describe "Regress::TestStructF" do before do skip unless get_introspection_data 'Regress', 'TestStructF' end let(:instance) { Regress::TestStructF.new } it "has a writable field ref_count" do instance.ref_count.must_equal 0 instance.ref_count = 1 instance.ref_count.must_equal 1 end it "has a writable field data1" do instance.data1.must_be :null? instance.data1 = GirFFI::InOutPointer.from(:gint32, 42) instance.data1.read_int32.must_equal 42 end it "has a writable field data2" do skip "Introspection data cannot deal with type of this field yet" end it "has a writable field data3" do skip "Introspection data cannot deal with type of this field yet" end it "has a writable field data4" do skip "Introspection data cannot deal with type of this field yet" end it "has a writable field data5" do skip "Introspection data cannot deal with type of this field yet" end it "has a writable field data6" do skip "Introspection data cannot deal with type of this field yet" end end describe "Regress::TestStructFixedArray" do let(:instance) { Regress::TestStructFixedArray.new } it "has a writable field just_int" do instance.just_int.must_equal 0 instance.just_int = 42 instance.just_int.must_equal 42 end it "has a writable field array" do instance.array.must_be :==, [0] * 10 instance.array = (1..10).to_a instance.array.must_be :==, (1..10).to_a end it "has a working method #frob" do instance.array = (0..9).to_a instance.frob instance.array.must_be :==, (42..42+9).to_a instance.just_int.must_equal 7 end end describe "Regress::TestSubObj" do it "creates an instance using #new" do tso = Regress::TestSubObj.new assert_instance_of Regress::TestSubObj, tso end let(:instance) { Regress::TestSubObj.new } it "has a working method #instance_method" do res = instance.instance_method assert_equal 0, res end it "has a working method #unset_bare" do instance.unset_bare pass end it "does not have a field parent_instance" do assert_raises(NoMethodError) { instance.parent_instance } end end describe "Regress::TestWi8021x" do it "creates an instance using #new" do o = Regress::TestWi8021x.new assert_instance_of Regress::TestWi8021x, o end it "has a working function #static_method" do assert_equal(-84, Regress::TestWi8021x.static_method(-42)) end let(:instance) { Regress::TestWi8021x.new } it "has a working method #get_testbool" do instance.get_testbool.must_equal true end it "has a working method #set_testbool" do instance.set_testbool true instance.get_testbool.must_equal true instance.set_testbool false instance.get_testbool.must_equal false end describe "its 'testbool' property" do it "can be retrieved with #get_property" do instance.get_property("testbool").must_equal true end it "can be retrieved with #testbool" do instance.testbool.must_equal true end it "can be set with #set_property" do instance.set_property "testbool", true instance.get_testbool.must_equal true instance.get_property("testbool").must_equal true instance.set_property "testbool", false instance.get_testbool.must_equal false instance.get_property("testbool").must_equal false end it "can be set with #testbool=" do instance.testbool = true instance.testbool.must_equal true instance.get_testbool.must_equal true instance.get_property("testbool").must_equal true instance.testbool = false instance.testbool.must_equal false instance.get_testbool.must_equal false instance.get_property("testbool").must_equal false end end end it "has the constant UTF8_CONSTANT" do assert_equal "const ♥ utf8", Regress::UTF8_CONSTANT end it "has a working function #aliased_caller_alloc" do result = Regress.aliased_caller_alloc result.must_be_instance_of Regress::TestBoxed end it "has a working function #atest_error_quark" do skip unless get_introspection_data 'Regress', 'atest_error_quark' result = Regress.atest_error_quark GLib.quark_to_string(result).must_equal "regress-atest-error" end it "has a working function #func_obj_null_in" do Regress.func_obj_null_in nil Regress.func_obj_null_in Regress::TestObj.constructor pass end it "has a working function #global_get_flags_out" do skip end it "has a working function #has_parameter_named_attrs" do skip end it "has a working function #introspectable_via_alias" do skip end it "has a working function #set_abort_on_error" do Regress.set_abort_on_error false Regress.set_abort_on_error true pass end it "has a working function #test_abc_error_quark" do skip end it "has a working function #test_array_callback" do skip end it "has a working function #test_array_fixed_out_objects" do result = Regress.test_array_fixed_out_objects gtype = Regress::TestObj.get_gtype result.size.must_equal 2 result.each {|o| assert_instance_of Regress::TestObj, o assert_equal gtype, GObject.type_from_instance(o) } end it "has a working function #test_array_fixed_size_int_in" do assert_equal 5 + 4 + 3 + 2 + 1, Regress.test_array_fixed_size_int_in([5, 4, 3, 2, 1]) end describe "#test_array_fixed_size_int_in" do it "raises an error when called with the wrong number of arguments" do assert_raises ArgumentError do Regress.test_array_fixed_size_int_in [2] end end end it "has a working function #test_array_fixed_size_int_out" do Regress.test_array_fixed_size_int_out.must_be :==, [0, 1, 2, 3, 4] end it "has a working function #test_array_fixed_size_int_return" do Regress.test_array_fixed_size_int_return.must_be :==, [0, 1, 2, 3, 4] end it "has a working function #test_array_gint16_in" do assert_equal 5 + 4 + 3, Regress.test_array_gint16_in([5, 4, 3]) end it "has a working function #test_array_gint32_in" do assert_equal 5 + 4 + 3, Regress.test_array_gint32_in([5, 4, 3]) end it "has a working function #test_array_gint64_in" do assert_equal 5 + 4 + 3, Regress.test_array_gint64_in([5, 4, 3]) end it "has a working function #test_array_gint8_in" do assert_equal 5 + 4 + 3, Regress.test_array_gint8_in([5, 4, 3]) end it "has a working function #test_array_gtype_in" do t1 = GObject.type_from_name "gboolean" t2 = GObject.type_from_name "gint64" assert_equal "[gboolean,gint64,]", Regress.test_array_gtype_in([t1, t2]) end it "has a working function #test_array_int_full_out" do Regress.test_array_int_full_out.must_be :==, [0, 1, 2, 3, 4] end it "has a working function #test_array_int_in" do assert_equal 5 + 4 + 3, Regress.test_array_int_in([5, 4, 3]) end it "has a working function #test_array_int_inout" do Regress.test_array_int_inout([5, 2, 3]).must_be :==, [3, 4] end it "has a working function #test_array_int_none_out" do Regress.test_array_int_none_out.must_be :==, [1, 2, 3, 4, 5] end it "has a working function #test_array_int_null_in" do Regress.test_array_int_null_in nil pass end it "has a working function #test_array_int_null_out" do assert_equal nil, Regress.test_array_int_null_out end it "has a working function #test_array_int_out" do Regress.test_array_int_out.must_be :==, [0, 1, 2, 3, 4] end it "has a working function #test_async_ready_callback" do main_loop = GLib::MainLoop.new nil, false a = 1 Regress.test_async_ready_callback Proc.new { main_loop.quit a = 2 } main_loop.run assert_equal 2, a end it "has a working function #test_boolean" do assert_equal false, Regress.test_boolean(false) assert_equal true, Regress.test_boolean(true) end it "has a working function #test_boolean_false" do assert_equal false, Regress.test_boolean_false(false) end it "has a working function #test_boolean_true" do assert_equal true, Regress.test_boolean_true(true) end it "has a working function #test_cairo_context_full_return" do ct = Regress.test_cairo_context_full_return assert_instance_of Cairo::Context, ct end it "has a working function #test_cairo_context_none_in" do ct = Regress.test_cairo_context_full_return Regress.test_cairo_context_none_in ct end it "has a working function #test_cairo_surface_full_out" do cs = Regress.test_cairo_surface_full_out assert_instance_of Cairo::Surface, cs end it "has a working function #test_cairo_surface_full_return" do cs = Regress.test_cairo_surface_full_return assert_instance_of Cairo::Surface, cs end it "has a working function #test_cairo_surface_none_in" do cs = Regress.test_cairo_surface_full_return Regress.test_cairo_surface_none_in cs end it "has a working function #test_cairo_surface_none_return" do cs = Regress.test_cairo_surface_none_return assert_instance_of Cairo::Surface, cs end it "has a working function #test_callback" do result = Regress.test_callback Proc.new { 5 } assert_equal 5, result end it "has a working function #test_callback_async" do a = 1 Regress.test_callback_async Proc.new {|b| a = 2 b }, 44 r = Regress.test_callback_thaw_async assert_equal 44, r assert_equal 2, a end it "has a working function #test_callback_destroy_notify" do a = 1 r1 = Regress.test_callback_destroy_notify Proc.new {|b| a = 2 b }, 42, Proc.new { a = 3 } assert_equal 2, a assert_equal 42, r1 r2 = Regress.test_callback_thaw_notifications assert_equal 3, a assert_equal 42, r2 end it "has a working function #test_callback_destroy_notify_no_user_data" do skip end it "has a working function #test_callback_thaw_async" do skip end it "has a working function #test_callback_thaw_notifications" do skip end it "has a working function #test_callback_user_data" do a = "old-value" result = Regress.test_callback_user_data Proc.new {|u| a = u 5 }, "new-value" a.must_equal "new-value" result.must_equal 5 end describe "the #test_callback_user_data function" do it "handles boolean user_data" do a = false Regress.test_callback_user_data Proc.new {|u| a = u 5 }, true assert_equal true, a end end it "has a working function #test_closure" do c = GObject::RubyClosure.new { 5235 } r = Regress.test_closure c assert_equal 5235, r end it "has a working function #test_closure_one_arg" do c = GObject::RubyClosure.new { |a| a * 2 } r = Regress.test_closure_one_arg c, 2 assert_equal 4, r end it "has a working function #test_closure_variant" do skip end it "has a working function #test_date_in_gvalue" do r = Regress.test_date_in_gvalue date = r.get_value skip unless date.respond_to? :get_year assert_equal [1984, :december, 5], [date.get_year, date.get_month, date.get_day] end it "has a working function #test_def_error_quark" do skip end it "has a working function #test_double" do r = Regress.test_double 5435.32 assert_equal 5435.32, r end it "has a working function #test_enum_param" do r = Regress.test_enum_param :value3 assert_equal "value3", r end it "has a working function #test_error_quark" do skip end it "has a working function #test_filename_return" do arr = Regress.test_filename_return arr.must_be :==, ["åäö", "/etc/fstab"] end it "has a working function #test_float" do r = Regress.test_float 5435.32 assert_in_delta 5435.32, r, 0.001 end it "has a working function #test_garray_container_return" do arr = Regress.test_garray_container_return arr.must_be_instance_of GLib::PtrArray arr.len.must_equal 1 ptr = arr.pdata ptr2 = ptr.read_pointer ptr2.read_string.must_be :==, "regress" end it "has a working function #test_garray_full_return" do skip end it "has a working function #test_gerror_callback" do skip end it "has a working function #test_ghash_container_return" do hash = Regress.test_ghash_container_return hash.must_be_instance_of GLib::HashTable hash.to_hash.must_equal("foo" => "bar", "baz" => "bat", "qux" => "quux") end it "has a working function #test_ghash_everything_return" do ghash = Regress.test_ghash_everything_return ghash.to_hash.must_be :==, {"foo" => "bar", "baz" => "bat", "qux" => "quux"} end it "has a working function #test_ghash_gvalue_in" do skip end it "has a working function #test_ghash_gvalue_return" do skip end it "has a working function #test_ghash_nested_everything_return" do skip end it "has a working function #test_ghash_nested_everything_return2" do skip end it "has a working function #test_ghash_nothing_in" do Regress.test_ghash_nothing_in({"foo" => "bar", "baz" => "bat", "qux" => "quux"}) end it "has a working function #test_ghash_nothing_in2" do Regress.test_ghash_nothing_in2({"foo" => "bar", "baz" => "bat", "qux" => "quux"}) end it "has a working function #test_ghash_nothing_return" do ghash = Regress.test_ghash_nothing_return ghash.to_hash.must_be :==, {"foo" => "bar", "baz" => "bat", "qux" => "quux"} end it "has a working function #test_ghash_nothing_return2" do ghash = Regress.test_ghash_nothing_return2 ghash.to_hash.must_be :==, {"foo" => "bar", "baz" => "bat", "qux" => "quux"} end it "has a working function #test_ghash_null_in" do Regress.test_ghash_null_in(nil) end it "has a working function #test_ghash_null_out" do ghash = Regress.test_ghash_null_out ghash.must_be_nil end it "has a working function #test_ghash_null_return" do ghash = Regress.test_ghash_null_return ghash.must_be_nil end it "has a working function #test_glist_container_return" do list = Regress.test_glist_container_return assert_instance_of GLib::List, list list.must_be :==, ["1", "2", "3"] end it "has a working function #test_glist_everything_return" do list = Regress.test_glist_everything_return list.must_be :==, ["1", "2", "3"] end it "has a working function #test_glist_nothing_in" do Regress.test_glist_nothing_in ["1", "2", "3"] pass end it "has a working function #test_glist_nothing_in2" do Regress.test_glist_nothing_in2 ["1", "2", "3"] pass end it "has a working function #test_glist_nothing_return" do list = Regress.test_glist_nothing_return list.must_be :==, ["1", "2", "3"] end it "has a working function #test_glist_nothing_return2" do list = Regress.test_glist_nothing_return2 list.must_be :==, ["1", "2", "3"] end it "has a working function #test_glist_null_in" do Regress.test_glist_null_in nil pass end it "has a working function #test_glist_null_out" do result = Regress.test_glist_null_out assert_equal nil, result end it "has a working function #test_gslist_container_return" do slist = Regress.test_gslist_container_return assert_instance_of GLib::SList, slist slist.must_be :==, ["1", "2", "3"] end it "has a working function #test_gslist_everything_return" do slist = Regress.test_gslist_everything_return slist.must_be :==, ["1", "2", "3"] end it "has a working function #test_gslist_nothing_in" do Regress.test_gslist_nothing_in ["1", "2", "3"] pass end it "has a working function #test_gslist_nothing_in2" do Regress.test_gslist_nothing_in2 ["1", "2", "3"] pass end it "has a working function #test_gslist_nothing_return" do slist = Regress.test_gslist_nothing_return slist.must_be :==, ["1", "2", "3"] end it "has a working function #test_gslist_nothing_return2" do slist = Regress.test_gslist_nothing_return2 slist.must_be :==, ["1", "2", "3"] end it "has a working function #test_gslist_null_in" do Regress.test_gslist_null_in nil pass end it "has a working function #test_gslist_null_out" do result = Regress.test_gslist_null_out assert_equal nil, result end it "has a working function #test_gtype" do result = Regress.test_gtype 23 assert_equal 23, result end it "has a working function #test_gvariant_as" do Regress.test_gvariant_as.get_strv.to_a.must_equal ["one", "two", "three"] end it "has a working function #test_gvariant_asv" do result = Regress.test_gvariant_asv result.n_children.must_equal 2 result.lookup_value("name", nil).get_string.must_equal "foo" result.lookup_value("timeout", nil).get_int32.must_equal 10 end it "has a working function #test_gvariant_i" do Regress.test_gvariant_i.get_int32.must_equal 1 end it "has a working function #test_gvariant_s" do Regress.test_gvariant_s.get_string.must_equal "one" end it "has a working function #test_gvariant_v" do Regress.test_gvariant_v.get_variant.get_string.must_equal "contents" end it "has a working function #test_hash_table_callback" do value = nil Regress.test_hash_table_callback({"foo" => 42}, Proc.new {|hash| value = hash}) value.to_hash.must_equal({"foo" => 42}) end it "has a working function #test_int" do result = Regress.test_int 23 assert_equal 23, result end it "has a working function #test_int16" do result = Regress.test_int16 23 assert_equal 23, result end it "has a working function #test_int32" do result = Regress.test_int32 23 assert_equal 23, result end it "has a working function #test_int64" do result = Regress.test_int64 2300000000000 assert_equal 2300000000000, result end it "has a working function #test_int8" do result = Regress.test_int8 23 assert_equal 23, result end it "has a working function #test_int_out_utf8" do len = Regress.test_int_out_utf8 "How long?" assert_equal 9, len end it "has a working function #test_int_value_arg" do gv = GObject::Value.new gv.init GObject.type_from_name "gint" gv.set_int 343 result = Regress.test_int_value_arg gv assert_equal 343, result end it "has a working function #test_long" do long_val = FFI.type_size(:long) == 8 ? 2_300_000_000_000 : 2_000_000_000 result = Regress.test_long long_val assert_equal long_val, result end it "has a working function #test_multi_callback" do a = 1 result = Regress.test_multi_callback Proc.new { a += 1 23 } assert_equal 2 * 23, result assert_equal 3, a end it "has a working function #test_multi_double_args" do one, two = Regress.test_multi_double_args 23.1 assert_equal 2 * 23.1, one assert_equal 3 * 23.1, two end it "has a working function #test_multiline_doc_comments" do Regress.test_multiline_doc_comments.must_be_nil end it "has a working function #test_nested_parameter" do Regress.test_nested_parameter(3).must_be_nil end it "has a working function #test_null_gerror_callback" do value = nil Regress.test_owned_gerror_callback Proc.new {|err| value = err } value.message.must_equal "regression test owned error" end it "has a working function #test_owned_gerror_callback" do value = nil Regress.test_owned_gerror_callback Proc.new {|err| value = err } value.message.must_equal "regression test owned error" end it "has a working function #test_short" do result = Regress.test_short 23 assert_equal 23, result end it "has a working function #test_simple_boxed_a_const_return" do result = Regress.test_simple_boxed_a_const_return assert_equal [5, 6, 7.0], [result.some_int, result.some_int8, result.some_double] end it "has a working function #test_simple_callback" do a = 0 Regress.test_simple_callback Proc.new { a = 1 } assert_equal 1, a end it "has a working function #test_size" do assert_equal 2354, Regress.test_size(2354) end it "has a working function #test_ssize" do assert_equal(-2_000_000, Regress.test_ssize(-2_000_000)) end it "has a working function #test_struct_a_parse" do skip unless get_introspection_data 'Regress', 'test_struct_a_parse' a = Regress.test_struct_a_parse("this string is actually ignored") a.must_be_instance_of Regress::TestStructA a.some_int.must_equal 23 end it "has a working function #test_strv_in" do assert_equal true, Regress.test_strv_in(['1', '2', '3']) end it "has a working function #test_strv_in_gvalue" do gv = Regress.test_strv_in_gvalue gv.get_value.must_be :==, ['one', 'two', 'three'] end it "has a working function #test_strv_out" do arr = Regress.test_strv_out arr.must_be :==, ["thanks", "for", "all", "the", "fish"] end it "has a working function #test_strv_out_c" do arr = Regress.test_strv_out_c arr.must_be :==, ["thanks", "for", "all", "the", "fish"] end it "has a working function #test_strv_out_container" do arr = Regress.test_strv_out_container arr.must_be :==, ['1', '2', '3'] end it "has a working function #test_strv_outarg" do arr = Regress.test_strv_outarg arr.must_be :==, ['1', '2', '3'] end it "has a working function #test_timet" do # Time rounded to seconds. t = Time.at(Time.now.to_i) result = Regress.test_timet(t.to_i) assert_equal t, Time.at(result) end it "has a working function #test_torture_signature_0" do y, z, q = Regress.test_torture_signature_0 86, "foo", 2 assert_equal [86, 2*86, 3+2], [y, z, q] end it "has a working function #test_torture_signature_1" do ret, y, z, q = Regress.test_torture_signature_1(-21, "hello", 12) assert_equal [true, -21, 2 * -21, "hello".length + 12], [ret, y, z, q] assert_raises RuntimeError do Regress.test_torture_signature_1(-21, "hello", 11) end end it "has a working function #test_torture_signature_2" do a = 1 y, z, q = Regress.test_torture_signature_2 244, Proc.new {|u| a = u }, 2, Proc.new { a = 3 }, "foofoo", 31 assert_equal [244, 2*244, 6+31], [y, z, q] assert_equal 3, a end it "has a working function #test_uint" do assert_equal 31, Regress.test_uint(31) end it "has a working function #test_uint16" do assert_equal 31, Regress.test_uint16(31) end it "has a working function #test_uint32" do assert_equal 540000, Regress.test_uint32(540000) end it "has a working function #test_uint64" do assert_equal 54_000_000_000_000, Regress.test_uint64(54_000_000_000_000) end it "has a working function #test_uint8" do assert_equal 31, Regress.test_uint8(31) end it "has a working function #test_ulong" do assert_equal 54_000_000_000_000, Regress.test_uint64(54_000_000_000_000) end it "has a working function #test_unconventional_error_quark" do skip unless get_introspection_data 'Regress', 'test_unconventional_error_quark' result = Regress.test_unconventional_error_quark GLib.quark_to_string(result).must_equal "regress-test-other-error" end it "has a working function #test_unichar" do assert_equal 120, Regress.test_unichar(120) assert_equal 540_000, Regress.test_unichar(540_000) end it "has a working function #test_unsigned_enum_param" do assert_equal "value1", Regress.test_unsigned_enum_param(:value1) assert_equal "value2", Regress.test_unsigned_enum_param(:value2) end it "has a working function #test_ushort" do assert_equal 54_000_000, Regress.test_uint64(54_000_000) end it "has a working function #test_utf8_const_in" do Regress.test_utf8_const_in("const \xe2\x99\xa5 utf8") pass end it "has a working function #test_utf8_const_return" do result = Regress.test_utf8_const_return assert_equal "const \xe2\x99\xa5 utf8", result end it "has a working function #test_utf8_inout" do result = Regress.test_utf8_inout "const \xe2\x99\xa5 utf8" assert_equal "nonconst \xe2\x99\xa5 utf8", result end it "has a working function #test_utf8_nonconst_return" do result = Regress.test_utf8_nonconst_return assert_equal "nonconst \xe2\x99\xa5 utf8", result end it "has a working function #test_utf8_null_in" do Regress.test_utf8_null_in nil pass end it "has a working function #test_utf8_null_out" do assert_equal nil, Regress.test_utf8_null_out end it "has a working function #test_utf8_out" do result = Regress.test_utf8_out assert_equal "nonconst \xe2\x99\xa5 utf8", result end it "has a working function #test_utf8_out_nonconst_return" do r, out = Regress.test_utf8_out_nonconst_return assert_equal ["first", "second"], [r, out] end it "has a working function #test_utf8_out_out" do out0, out1 = Regress.test_utf8_out_nonconst_return assert_equal ["first", "second"], [out0, out1] end it "has a working function #test_value_return" do result = Regress.test_value_return 3423 assert_equal 3423, result.get_int end it "has a working function #test_versioning" do skip unless get_introspection_data 'Regress', 'test_versioning' Regress.test_versioning pass end it "raises an appropriate NoMethodError when a function is not found" do begin Regress.this_method_does_not_exist rescue => e e.message.must_match(/^undefined method `this_method_does_not_exist' (for Regress:Module|on Regress \(Module\))$/) end end end gir_ffi-0.6.7/test/integration/derived_classes_test.rb0000644000004100000410000000206612224462647023223 0ustar www-datawww-datarequire 'gir_ffi_test_helper' GirFFI.setup :Regress # Tests deriving Ruby classes from GObject classes. describe "For derived classes" do describe "setting up methods when first called" do before do save_module :GIMarshallingTests GirFFI.setup :GIMarshallingTests end describe "when an interface is mixed in" do before do @klass = Class.new GIMarshallingTests::OverridesObject @klass.send :include, GIMarshallingTests::Interface end it "finds class methods in the superclass" do @klass.returnv end it "finds instance methods in the superclass" do obj = @klass.new result = obj.method result.must_equal 42 end end after do restore_module :GIMarshallingTests end end describe "the initializer" do it "does not have to call super" do klass = Class.new Regress::TestSubObj do def initialize *args end end obj = klass.new obj.must_be_instance_of klass obj.to_ptr.wont_be_nil end end end gir_ffi-0.6.7/test/integration/generated_pango_test.rb0000644000004100000410000000105312224462647023201 0ustar www-datawww-data# coding: utf-8 require 'gir_ffi_test_helper' GirFFI.setup :Pango # Tests generated methods and functions in the Pango namespace. describe Pango do describe Pango::Language do it "has a working method #get_scripts" do lang = Pango::Language.from_string 'ja' result = lang.get_scripts if GLib::SizedArray === result scripts = result else ptr, size = *result scripts = GLib::SizedArray.new Pango::Script, size, ptr end scripts.must_be :==, [:han, :katakana, :hiragana] end end end gir_ffi-0.6.7/test/gir_ffi_test_helper.rb0000644000004100000410000000417712224462647020512 0ustar www-datawww-datarequire 'introspection_test_helper' require 'gir_ffi' # Global sequence provider. Needed to make unique class names. class Sequence @@seq = 0 def self.next @@seq += 1 end end class Minitest::Test def cws code code.gsub(/(^\s*|\s*$)/, "") end def get_field_introspection_data namespace, klass, name get_introspection_data(namespace, klass).find_field name end def get_method_introspection_data namespace, klass, name get_introspection_data(namespace, klass).find_method name end def get_property_introspection_data namespace, klass, name get_introspection_data(namespace, klass).find_property name end def get_signal_introspection_data namespace, klass, name get_introspection_data(namespace, klass).find_signal name end SAVED_MODULES = {} def save_module name if Object.const_defined? name puts "Saving #{name} over existing" if SAVED_MODULES.has_key? name SAVED_MODULES[name] = Object.const_get name Object.send(:remove_const, name) end end def restore_module name if Object.const_defined? name Object.send(:remove_const, name) end if SAVED_MODULES.has_key? name Object.const_set name, SAVED_MODULES[name] SAVED_MODULES.delete name end end def ref_count object GObject::Object::Struct.new(object.to_ptr)[:ref_count] end def is_floating? object (GObject::Object::Struct.new(object.to_ptr)[:qdata].address & 2) == 2 end def max_for_unsigned_type type ( 1 << (FFI.type_size(type) * 8) ) - 1 end def max_for_type type ( 1 << (FFI.type_size(type) * 8 - 1) ) - 1 end def min_for_type type ~max_for_type(type) end def max_long max_for_type :long end def min_long min_for_type :long end def max_size_t max_for_unsigned_type :size_t end def max_ssize_t # FFI has no :ssize_t, but it's the same number of bits as :size_t max_for_type :size_t end def min_ssize_t min_for_type :size_t end def max_ushort max_for_unsigned_type :ushort end def max_uint max_for_unsigned_type :uint end def max_ulong max_for_unsigned_type :ulong end end gir_ffi-0.6.7/test/ffi-gobject/0000755000004100000410000000000012224462647016330 5ustar www-datawww-datagir_ffi-0.6.7/test/ffi-gobject/gobject_test.rb0000644000004100000410000000561512224462647021340 0ustar www-datawww-datarequire 'gir_ffi_test_helper' require 'ffi-gobject' GirFFI.setup :GIMarshallingTests describe GObject do describe ".type_init" do it "does not raise an error" do GObject.type_init pass end end it "has constants for the fundamental GTypes" do assert_equal GObject.type_from_name("invalid"), GObject::TYPE_INVALID assert_equal nil, GObject.type_name(GObject::TYPE_INVALID) assert_equal "void", GObject.type_name(GObject::TYPE_NONE) assert_equal "GInterface", GObject.type_name(GObject::TYPE_INTERFACE) assert_equal "gchar", GObject.type_name(GObject::TYPE_CHAR) assert_equal "guchar", GObject.type_name(GObject::TYPE_UCHAR) assert_equal "gboolean", GObject.type_name(GObject::TYPE_BOOLEAN) assert_equal "gint", GObject.type_name(GObject::TYPE_INT) assert_equal "guint", GObject.type_name(GObject::TYPE_UINT) assert_equal "glong", GObject.type_name(GObject::TYPE_LONG) assert_equal "gulong", GObject.type_name(GObject::TYPE_ULONG) assert_equal "gint64", GObject.type_name(GObject::TYPE_INT64) assert_equal "guint64", GObject.type_name(GObject::TYPE_UINT64) assert_equal "GEnum", GObject.type_name(GObject::TYPE_ENUM) assert_equal "GFlags", GObject.type_name(GObject::TYPE_FLAGS) assert_equal "gfloat", GObject.type_name(GObject::TYPE_FLOAT) assert_equal "gdouble", GObject.type_name(GObject::TYPE_DOUBLE) assert_equal "gchararray", GObject.type_name(GObject::TYPE_STRING) assert_equal "gpointer", GObject.type_name(GObject::TYPE_POINTER) assert_equal "GBoxed", GObject.type_name(GObject::TYPE_BOXED) assert_equal "GParam", GObject.type_name(GObject::TYPE_PARAM) assert_equal "GObject", GObject.type_name(GObject::TYPE_OBJECT) assert_equal "GType", GObject.type_name(GObject::TYPE_GTYPE) assert_equal "GVariant", GObject.type_name(GObject::TYPE_VARIANT) assert_equal "GStrv", GObject.type_name(GObject::TYPE_STRV) assert_equal "GHashTable", GObject.type_name(GObject::TYPE_HASH_TABLE) end describe "::object_class_from_instance" do it "returns a GObject::ObjectClass with the correct GType" do obj = GIMarshallingTests::OverridesObject.new object_class = GObject.object_class_from_instance obj gtype = object_class.g_type_class.g_type object_class.must_be_instance_of GObject::ObjectClass gtype.must_equal GIMarshallingTests::OverridesObject.get_gtype end end describe "creating ParamSpecs" do describe "#param_spec_int" do it "creates a GObject::ParamSpecInt" do spec = GObject.param_spec_int("foo", "foo bar", "The Foo Bar Property", 10, 20, 15, 3) spec.must_be_instance_of GObject::ParamSpecInt spec.minimum.must_equal 10 spec.maximum.must_equal 20 spec.default_value.must_equal 15 end end end end gir_ffi-0.6.7/test/ffi-gobject/value_test.rb0000644000004100000410000001411212224462647021027 0ustar www-datawww-datarequire 'gir_ffi_test_helper' require 'ffi-gobject' describe GObject::Value do describe "::Struct" do describe "layout" do let(:layout) { GObject::Value::Struct.layout } it "consists of :g_type and :data" do layout.members.must_equal [:g_type, :data] end it "has an array as its second element" do types = layout.fields.map(&:type) types[1].class.must_equal FFI::Type::Array end end end describe "::wrap_ruby_value" do it "wraps a boolean false" do gv = GObject::Value.wrap_ruby_value false assert_instance_of GObject::Value, gv assert_equal false, gv.get_boolean end it "wraps a boolean true" do gv = GObject::Value.wrap_ruby_value true assert_instance_of GObject::Value, gv assert_equal true, gv.get_boolean end it "wraps an Integer" do gv = GObject::Value.wrap_ruby_value 42 assert_equal 42, gv.get_int end it "wraps a String" do gv = GObject::Value.wrap_ruby_value "Some Random String" assert_equal "Some Random String", gv.get_string end end describe "#set_value" do it "handles char values" do value = 83 gv = GObject::Value.for_g_type GObject::TYPE_CHAR gv.set_value value gv.get_char.must_equal value end it "handles GType values" do value = GObject::TYPE_STRING gv = GObject::Value.for_g_type GObject::TYPE_GTYPE gv.set_value value gv.get_gtype.must_equal value end it "handles int64 values" do value = 0x1234_5678_9012_3456 gv = GObject::Value.for_g_type GObject::TYPE_INT64 gv.set_value value gv.get_int64.must_equal value end it "handles long values" do value = 0x1234_5678_9012_3456 gv = GObject::Value.for_g_type GObject::TYPE_LONG gv.set_value value gv.get_long.must_equal value end it "handles uchar values" do value = 83 gv = GObject::Value.for_g_type GObject::TYPE_UCHAR gv.set_value value gv.get_uchar.must_equal value end it "handles uint values" do value = 0x1234_5678 gv = GObject::Value.for_g_type GObject::TYPE_UINT gv.set_value value gv.get_uint.must_equal value end it "handles uint64 values" do value = 0x1234_5678_9012_3456 gv = GObject::Value.for_g_type GObject::TYPE_UINT64 gv.set_value value gv.get_uint64.must_equal value end it "handles ulong values" do value = 0x1234_5678_9012_3456 gv = GObject::Value.for_g_type GObject::TYPE_ULONG gv.set_value value gv.get_ulong.must_equal value end it "handles variant values" do value = GLib::Variant.new_string("Foo") gv = GObject::Value.for_g_type GObject::TYPE_VARIANT gv.set_value value gv.get_variant.must_equal value end end describe "#get_value" do it "unwraps a boolean false" do gv = GObject::Value.wrap_ruby_value false result = gv.get_value assert_equal false, result end it "unwraps a boolean true" do gv = GObject::Value.wrap_ruby_value true result = gv.get_value assert_equal true, result end it "unwraps a char" do value = 3 gv = GObject::Value.for_g_type GObject::TYPE_CHAR gv.set_char value gv.get_value.must_equal value end it "unwraps a GType" do value = GObject::TYPE_STRING gv = GObject::Value.for_g_type GObject::TYPE_GTYPE gv.set_gtype value gv.get_value.must_equal value end it "unwraps an int64" do value = 0x1234_5678_9012_3456 gv = GObject::Value.for_g_type GObject::TYPE_INT64 gv.set_int64 value gv.get_value.must_equal value end it "unwraps a long" do value = 0x1234_5678_9012_3456 gv = GObject::Value.for_g_type GObject::TYPE_LONG gv.set_long value gv.get_value.must_equal value end it "unwraps an uchar" do value = 3 gv = GObject::Value.for_g_type GObject::TYPE_UCHAR gv.set_uchar value gv.get_value.must_equal value end it "unwraps an uint" do value = 0x1234_5678 gv = GObject::Value.for_g_type GObject::TYPE_UINT gv.set_uint value gv.get_value.must_equal value end it "unwraps an uint64" do value = 0x1234_5678_9012_3456 gv = GObject::Value.for_g_type GObject::TYPE_UINT64 gv.set_uint64 value gv.get_value.must_equal value end it "unwraps a ulong" do value = 0x1234_5678_9012_3456 gv = GObject::Value.for_g_type GObject::TYPE_ULONG gv.set_ulong value gv.get_value.must_equal value end it "unwraps a variant" do value = GLib::Variant.new_string("Foo") gv = GObject::Value.for_g_type GObject::TYPE_VARIANT gv.set_variant value gv.get_value.must_equal value end it "works with a ByteArray" do ba = GLib::ByteArray.new.append("some bytes") v = GObject::Value.for_g_type GObject.type_from_name("GByteArray") v.set_boxed ba result = v.get_value result.to_string.must_equal "some bytes" result.must_be_kind_of GLib::ByteArray end end describe "::from" do it "creates a gint GValue from a Ruby Integer" do gv = GObject::Value.from 21 gv.current_gtype_name.must_equal "gint" gv.get_value.must_equal 21 end it "returns its argument if given a GValue" do gv = GObject::Value.from 21 gv2 = GObject::Value.from gv gv2.current_gtype_name.must_equal "gint" gv2.get_value.must_equal 21 end end describe "#set_value" do before do GirFFI.setup :GIMarshallingTests end it "raises an error when setting an incompatible object type" do o = GIMarshallingTests::Object.new 1 v = GObject::Value.new.init(GIMarshallingTests::OverridesObject.get_gtype) proc { v.set_value o }.must_raise ArgumentError end it "works with a ByteArray" do ba = GLib::ByteArray.new.append("some bytes") v = GObject::Value.new.init(GObject.type_from_name("GByteArray")) v.set_value ba v.get_value.to_string.must_equal "some bytes" end end end gir_ffi-0.6.7/test/ffi-gobject/object_test.rb0000644000004100000410000000173512224462647021170 0ustar www-datawww-datarequire 'gir_ffi_test_helper' require 'ffi-gobject' describe GObject::Object do describe "#get_property" do it "is overridden to have arity 1" do assert_equal 1, GObject::Object.instance_method("get_property").arity end end describe "automatic accessor methods" do class AccessorTest < GObject::Object def get_x @x end def set_x(val) @x = val end end subject { AccessorTest.new GObject::TYPE_OBJECT, nil } it 'reads x by calling get_x' do subject.set_x(1) assert_equal 1, subject.x end it 'writes x by calling set_x' do subject.x = 2 assert_equal 2, subject.x end end describe "#signal_connect" do subject { GObject::Object.new GObject::TYPE_OBJECT, nil } it 'delegates to GObject' do mock(GObject).signal_connect(subject, 'some-event') subject.signal_connect('some-event') do nothing end RR.verify end end end gir_ffi-0.6.7/test/ffi-gobject/object_class_test.rb0000644000004100000410000000120512224462647022345 0ustar www-datawww-datarequire 'gir_ffi_test_helper' require 'ffi-gobject' describe GObject::ObjectClass do describe "#list_properties" do it "returns GIMarshallingTests::OverridesObject's properties" do obj = GIMarshallingTests::OverridesObject.new object_class = GObject.object_class_from_instance obj info = get_introspection_data 'GIMarshallingTests', 'OverridesObject' expected_props = info.properties.map(&:name) expected_props += info.parent.properties.map(&:name) props = object_class.list_properties prop_names = props.map(&:get_name) prop_names.sort.must_equal expected_props.sort end end end gir_ffi-0.6.7/test/lib/0000755000004100000410000000000012224462647014717 5ustar www-datawww-datagir_ffi-0.6.7/test/lib/autogen.sh0000755000004100000410000000457512224462647016733 0ustar www-datawww-data#!/bin/sh # Run this to generate all the initial makefiles, etc. PROJECT=GirFFITest if test ! -f configure.ac ; then echo "You must run this script in the top-level $PROJECT directory" exit 1 fi DIE=0 have_libtool=false if libtoolize --version < /dev/null > /dev/null 2>&1 ; then libtool_version=`libtoolize --version | head -1 | sed -e 's/^\(.*\)([^)]*)\(.*\)$/\1\2/g' \ -e 's/^[^0-9]*\([0-9.][0-9.]*\).*/\1/'` case $libtool_version in 2.2*) have_libtool=true ;; 2.4*) have_libtool=true ;; esac fi if $have_libtool ; then : ; else echo echo "You must have libtool >= 2.2 installed to compile $PROJECT." echo "Install the appropriate package for your distribution," echo "or get the source tarball at http://ftp.gnu.org/gnu/libtool/" DIE=1 fi if autoconf --version < /dev/null > /dev/null 2>&1 ; then : ; else echo echo "You must have autoconf installed to compile $PROJECT." echo "Install the appropriate package for your distribution," echo "or get the source tarball at http://ftp.gnu.org/gnu/autoconf/" DIE=1 fi if automake-1.13 --version < /dev/null > /dev/null 2>&1 ; then AUTOMAKE=automake-1.13 ACLOCAL=aclocal-1.13 else if automake-1.11 --version < /dev/null > /dev/null 2>&1 ; then AUTOMAKE=automake-1.11 ACLOCAL=aclocal-1.11 else if automake-1.10 --version < /dev/null > /dev/null 2>&1 ; then AUTOMAKE=automake-1.10 ACLOCAL=aclocal-1.10 else echo echo "You must have automake 1.13.x, 1.11.x or 1.10.x installed to compile $PROJECT." echo "Install the appropriate package for your distribution," echo "or get the source tarball at http://ftp.gnu.org/gnu/automake/" DIE=1 fi fi fi if test "$DIE" -eq 1; then exit 1 fi libtoolize --force || exit $? $ACLOCAL -I m4 || exit $? autoconf || exit $? $AUTOMAKE --add-missing || exit $? # NOCONFIGURE is used by gnome-common; support both if ! test -z "$AUTOGEN_SUBDIR_MODE"; then NOCONFIGURE=1 fi if test -z "$NOCONFIGURE"; then if test -z "$*"; then echo "I am going to run ./configure with no arguments - if you wish " echo "to pass any to it, please specify them on the $0 command line." fi ./configure --enable-maintainer-mode $AUTOGEN_CONFIGURE_ARGS "$@" || exit $? echo echo "Now type 'make' to compile $PROJECT." fi gir_ffi-0.6.7/test/lib/Makefile.am0000644000004100000410000000337112224462647016757 0ustar www-datawww-dataACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS = 1.7 # We need to build a shared library, which can be dlopened # it does not work with noinst_LTLIBRARIES testlib_LTLIBRARIES = libregress.la libgimarshallingtests.la testlibdir = $(prefix)/unused install-testlibLTLIBRARIES: # prevent it from being installed libregress_la_SOURCES = $(GI_DATADIR)/tests/regress.c $(GI_DATADIR)/tests/regress.h libregress_la_CFLAGS = $(GIO_CFLAGS) $(CAIRO_CFLAGS) libregress_la_LDFLAGS = -module -avoid-version $(GIO_LIBS) $(CAIRO_LIBS) libgimarshallingtests_la_SOURCES = $(GI_DATADIR)/tests/gimarshallingtests.c $(GI_DATADIR)/tests/gimarshallingtests.h libgimarshallingtests_la_CFLAGS = $(GIO_CFLAGS) libgimarshallingtests_la_LDFLAGS = -module -avoid-version # g-i doesn't ship these as shared libraries anymore; we build them here Regress-1.0.gir: libregress.la Makefile $(AM_V_GEN) g-ir-scanner --include=cairo-1.0 --include=Gio-2.0 \ --namespace=Regress --nsversion=1.0 --pkg=cairo-gobject \ --warn-all --warn-error \ --library=libregress.la \ --libtool="$(top_builddir)/libtool" \ --output $@ \ $(libregress_la_SOURCES) Regress-1.0.typelib: Regress-1.0.gir Makefile $(AM_V_GEN) g-ir-compiler $< -o $@ GIMarshallingTests-1.0.gir: libgimarshallingtests.la Makefile $(AM_V_GEN) g-ir-scanner --include=Gio-2.0 \ --namespace=GIMarshallingTests --nsversion=1.0 \ --symbol-prefix=gi_marshalling_tests \ --warn-all --warn-error \ --library=libgimarshallingtests.la \ --libtool="$(top_builddir)/libtool" \ --output $@ \ $(libgimarshallingtests_la_SOURCES) GIMarshallingTests-1.0.typelib: GIMarshallingTests-1.0.gir Makefile $(AM_V_GEN) g-ir-compiler $< -o $@ .la.so: test -L $@ || $(LN_S) .libs/$@ $@ all: $(testlib_LTLIBRARIES:.la=.so) Regress-1.0.typelib GIMarshallingTests-1.0.typelib gir_ffi-0.6.7/test/lib/m4/0000755000004100000410000000000012224462647015237 5ustar www-datawww-datagir_ffi-0.6.7/test/lib/m4/jhflags.m40000644000004100000410000000106112224462647017115 0ustar www-datawww-datadnl dnl JH_ADD_CFLAG(FLAG) dnl checks whether the C compiler supports the given flag, and if so, adds dnl it to $CFLAGS. If the flag is already present in the list, then the dnl check is not performed. AC_DEFUN([JH_ADD_CFLAG], [ case " $CFLAGS " in *@<:@\ \ @:>@$1@<:@\ \ @:>@*) ;; *) save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $1" AC_MSG_CHECKING([whether [$]CC understands $1]) AC_TRY_COMPILE([], [], [jh_has_option=yes], [jh_has_option=no]) AC_MSG_RESULT($jh_has_option) if test $jh_has_option = no; then CFLAGS="$save_CFLAGS" fi ;; esac]) gir_ffi-0.6.7/test/lib/configure.ac0000644000004100000410000000126712224462647017213 0ustar www-datawww-data# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) AC_INIT(dummy_test_lib, 0.0.1) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([1.7 foreign]) AM_MAINTAINER_MODE m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],) # Checks for programs. AC_PROG_CC AM_PROG_CC_C_O AC_PROG_LIBTOOL PKG_PROG_PKG_CONFIG if test "$GCC" = "yes"; then JH_ADD_CFLAG([-Wall]) JH_ADD_CFLAG([-fno-strict-aliasing]) fi PKG_CHECK_MODULES(GIO, [gio-2.0]) PKG_CHECK_MODULES(CAIRO, [cairo]) GI_DATADIR=$($PKG_CONFIG --variable=gidatadir gobject-introspection-1.0) AC_SUBST(GI_DATADIR) AC_CONFIG_FILES([Makefile]) AC_OUTPUT gir_ffi-0.6.7/test/introspection_test_helper.rb0000644000004100000410000000040512224462647021773 0ustar www-datawww-datarequire 'base_test_helper' require 'ffi-gobject_introspection' class Minitest::Test def get_introspection_data namespace, name gir = GObjectIntrospection::IRepository.default gir.require namespace, nil gir.find_by_name namespace, name end end gir_ffi-0.6.7/test/ffi-glib/0000755000004100000410000000000012224462647015630 5ustar www-datawww-datagir_ffi-0.6.7/test/ffi-glib/ruby_closure_test.rb0000644000004100000410000000272512224462647021737 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GObject::RubyClosure do it "has a constructor with a mandatory block argument" do assert_raises ArgumentError do GObject::RubyClosure.new end end it "is a kind of Closure" do c = GObject::RubyClosure.new {} assert_kind_of GObject::Closure, c end it "is able to retrieve its block from its struct" do a = 0 c = GObject::RubyClosure.new { a = 2 } c2 = GObject::RubyClosure.wrap(c.to_ptr) c2.block.call assert_equal 2, a end describe "its #marshaller singleton method" do it "invokes its closure argument's block" do a = 0 c = GObject::RubyClosure.new { a = 2 } GObject::RubyClosure.marshaller(c, nil, 0, nil, nil, nil) assert_equal 2, a end it "works when its closure argument is a GObject::Closure" do a = 0 c = GObject::RubyClosure.new { a = 2 } c2 = GObject::Closure.wrap(c.to_ptr) GObject::RubyClosure.marshaller(c2, nil, 0, nil, nil, nil) assert_equal 2, a end it "stores the closure's return value in the proper gvalue" do c = GObject::RubyClosure.new { 2 } gv = GObject::Value.new GObject::RubyClosure.marshaller(c, gv, 0, nil, nil, nil) assert_equal 2, gv.get_value end end it "has GObject::Closure#invoke call its block" do a = 0 c = GObject::RubyClosure.new { a = 2 } c2 = GObject::Closure.wrap(c.to_ptr) c2.invoke nil, nil, nil assert_equal 2, a end end gir_ffi-0.6.7/test/ffi-glib/s_list_test.rb0000644000004100000410000000354112224462647020514 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GLib::SList do it "knows its element type" do arr = GLib::SList.new :gint32 assert_equal :gint32, arr.element_type end describe "#prepend" do it "prepends integer values" do lst = GLib::SList.new :gint32 res = lst.prepend 1 assert_equal 1, res.data end it "prepends string values" do lst = GLib::SList.new :utf8 res = lst.prepend "bla" assert_equal "bla", res.data end it "prepends multiple values into a single list" do lst = GLib::SList.new :gint32 res = lst.prepend 1 res2 = res.prepend 2 assert_equal 2, res2.data assert_equal 1, res.data assert_equal res.to_ptr, res2.next.to_ptr end end describe "::from" do it "creates a GSList from a Ruby array" do lst = GLib::SList.from :gint32, [3, 2, 1] assert_equal [3, 2, 1], lst.to_a end it "return its argument if given a GSList" do lst = GLib::SList.from :gint32, [3, 2, 1] lst2 = GLib::SList.from :gint32, lst assert_equal lst, lst2 end end describe "#==" do it "returns true when comparing to an array with the same elements" do list = GLib::SList.from :gint32, [1, 2, 3] list.must_be :==, [1, 2, 3] end it "returns false when comparing to an array with different elements" do list = GLib::SList.from :gint32, [1, 2, 3] list.wont_be :==, [1, 2] end it "returns true when comparing to a list with the same elements" do list = GLib::SList.from :gint32, [1, 2, 3] other = GLib::SList.from :gint32, [1, 2, 3] list.must_be :==, other end it "returns false when comparing to a list with different elements" do list = GLib::SList.from :gint32, [1, 2, 3] other = GLib::SList.from :gint32, [1, 2] list.wont_be :==, other end end end gir_ffi-0.6.7/test/ffi-glib/sized_array_test.rb0000644000004100000410000000667612224462647021547 0ustar www-datawww-datarequire 'base_test_helper' describe GLib::SizedArray do describe "::wrap" do it "takes a type, size and pointer and returns a GLib::SizedArray wrapping them" do mock(ptr = Object.new).null? { false } sarr = GLib::SizedArray.wrap :gint32, 3, ptr assert_instance_of GLib::SizedArray, sarr assert_equal ptr, sarr.to_ptr assert_equal 3, sarr.size assert_equal :gint32, sarr.element_type end it "returns nil if the wrapped pointer is null" do mock(ptr = Object.new).null? { true } sarr = GLib::SizedArray.wrap :gint32, 3, ptr sarr.must_be_nil end end describe "#each" do it "yields each element" do ary = ["one", "two", "three"] ptrs = ary.map {|a| FFI::MemoryPointer.from_string(a)} ptrs << nil block = FFI::MemoryPointer.new(:pointer, ptrs.length) block.write_array_of_pointer ptrs sarr = GLib::SizedArray.new :utf8, 3, block arr = [] sarr.each do |str| arr << str end assert_equal ["one", "two", "three"], arr end end describe "::from" do describe "from a Ruby array" do it "creates a GLib::SizedArray with the same elements" do arr = GLib::SizedArray.from :gint32, 3, [3, 2, 1] arr.must_be_instance_of GLib::SizedArray assert_equal [3, 2, 1], arr.to_a end it "raises an error if the array has the wrong number of elements" do lambda { GLib::SizedArray.from :gint32, 4, [3, 2, 1] }.must_raise ArgumentError end it "uses the array's size if passed -1 as the size" do arr = GLib::SizedArray.from :gint32, -1, [3, 2, 1] arr.size.must_equal 3 end end describe "from a GLib::SizedArray" do it "return its argument" do arr = GLib::SizedArray.from :gint32, 3, [3, 2, 1] arr2 = GLib::SizedArray.from :gint32, 3, arr assert_equal arr, arr2 end it "raises an error if the argument has the wrong number of elements" do arr = GLib::SizedArray.from :gint32, 3, [3, 2, 1] lambda { GLib::SizedArray.from :gint32, 4, arr }.must_raise ArgumentError end end it "returns nil when passed nil" do arr = GLib::SizedArray.from :gint32, 0, nil arr.must_be_nil end it "wraps its argument if given a pointer" do arr = GLib::SizedArray.from :gint32, 3, [3, 2, 1] arr2 = GLib::SizedArray.from :gint32, 3, arr.to_ptr assert_instance_of GLib::SizedArray, arr2 refute arr2.equal? arr arr2.to_ptr.must_equal arr.to_ptr end end describe "#==" do it "returns true when comparing to an array with the same elements" do sized = GLib::SizedArray.from :int32, 3, [1, 2, 3] sized.must_be :==, [1, 2, 3] end it "returns false when comparing to an array with different elements" do sized = GLib::SizedArray.from :int32, 3, [1, 2, 3] sized.wont_be :==, [1, 2] end it "returns true when comparing to a sized array with the same elements" do sized = GLib::SizedArray.from :int32, 3, [1, 2, 3] other = GLib::SizedArray.from :int32, 3, [1, 2, 3] sized.must_be :==, other end it "returns false when comparing to a sized array with different elements" do sized = GLib::SizedArray.from :int32, 3, [1, 2, 3] other = GLib::SizedArray.from :int32, 2, [1, 2] sized.wont_be :==, other end end it "includes Enumerable" do GLib::SizedArray.must_include Enumerable end end gir_ffi-0.6.7/test/ffi-glib/strv_test.rb0000644000004100000410000000146612224462647020221 0ustar www-datawww-datarequire 'base_test_helper' describe GLib::Strv do describe "#==" do it "returns true when comparing to an array with the same elements" do strv = GLib::Strv.from ["1", "2", "3"] strv.must_be :==, ["1", "2", "3"] end it "returns false when comparing to an array with different elements" do strv = GLib::Strv.from ["1", "2", "3"] strv.wont_be :==, ["1", "2"] end it "returns true when comparing to a strv with the same elements" do strv = GLib::Strv.from ["1", "2", "3"] other = GLib::Strv.from ["1", "2", "3"] strv.must_be :==, other end it "returns false when comparing to a strv with different elements" do strv = GLib::Strv.from ["1", "2", "3"] other = GLib::Strv.from ["1", "2"] strv.wont_be :==, other end end end gir_ffi-0.6.7/test/ffi-glib/array_test.rb0000644000004100000410000001043412224462647020334 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GLib::Array do it "knows its element type" do arr = GLib::Array.new :gint32 assert_equal :gint32, arr.element_type end describe "#append_vals" do before do @arr = GLib::Array.new :gint32 @result = @arr.append_vals [1, 2, 3] end it "appends values" do assert_equal 3, @arr.len end it "returns self" do assert_equal @result, @arr end end describe "#each" do before do @arr = GLib::Array.new(:gint32).append_vals [1, 2, 3] end it "iterates over the values" do a = [] @arr.each {|v| a << v } assert_equal [1, 2, 3], a end end describe "::wrap" do it "wraps a pointer, taking the element type as the first argument" do arr = GLib::Array.new :gint32 arr.append_vals [1, 2, 3] arr2 = GLib::Array.wrap :gint32, arr.to_ptr assert_equal arr.to_a, arr2.to_a end it "warns the element sizes don't match" do arr = GLib::Array.new :gint32 arr.append_vals [1, 2, 3] proc { GLib::Array.wrap :gint8, arr.to_ptr }.must_output nil, /sizes do not match/ end it "handles a struct as the element type" do vals = [1, 2, 3].map {|i| GObject::EnumValue.new.tap {|ev| ev.value = i} } arr = GLib::Array.new GObject::EnumValue arr.append_vals vals arr2 = GLib::Array.wrap GObject::EnumValue, arr.to_ptr arr2.to_a.must_equal arr.to_a end end it "includes Enumerable" do GLib::Array.must_include Enumerable end it "has a working #to_a method" do arr = GLib::Array.new :gint32 arr.append_vals [1, 2, 3] assert_equal [1, 2, 3], arr.to_a end describe ".from" do it "creates a GArray from an array of :gint32" do arr = GLib::Array.from :gint32, [3, 2, 1] arr.data.read_array_of_int32(3).must_equal [3, 2, 1] end it "creates a GArray from an array of :gboolean" do arr = GLib::Array.from :gboolean, [true, false, true] arr.data.read_array_of_int(3).must_equal [1, 0, 1] end it "return its argument if given a GArray" do arr = GLib::Array.new :gint32 arr.append_vals [3, 2, 1] arr2 = GLib::Array.from :foo, arr assert arr2.equal? arr end it "wraps its argument if given a pointer" do arr = GLib::Array.new :gint32 arr.append_vals [3, 2, 1] pointer = arr.to_ptr assert_instance_of FFI::Pointer, pointer arr2 = GLib::Array.from :gint32, pointer assert_instance_of GLib::Array, arr2 refute arr2.equal? arr arr2.to_a.must_equal arr.to_a end end describe "#==" do it "returns true when comparing to an array with the same elements" do arr = GLib::Array.from :gint32, [1, 2, 3] arr.must_be :==, [1, 2, 3] end it "returns false when comparing to an array with different elements" do arr = GLib::Array.from :gint32, [1, 2, 3] arr.wont_be :==, [1, 2] end it "returns true when comparing to a GArray with the same elements" do arr = GLib::Array.from :gint32, [1, 2, 3] other = GLib::Array.from :gint32, [1, 2, 3] arr.must_be :==, other end it "returns false when comparing to a GArray with different elements" do arr = GLib::Array.from :gint32, [1, 2, 3] other = GLib::Array.from :gint32, [1, 2] arr.wont_be :==, other end end describe "#index" do it "returns the proper element for an array of :gint32" do arr = GLib::Array.from :gint32, [1, 2, 3] arr.index(2).must_equal 3 end it "returns the proper element for an array of :utf8" do arr = GLib::Array.from :utf8, ["a", "b", "c"] arr.index(1).must_equal "b" end it "returns the proper element for an array of :gboolean" do arr = GLib::Array.from :gboolean, [true, false, true] arr.index(1).must_equal false end it "returns the proper element for an array of struct" do vals = [1, 2, 3].map {|i| GObject::EnumValue.new.tap {|ev| ev.value = i} } arr = GLib::Array.from GObject::EnumValue, vals arr.index(1).value.must_equal 2 end it "raises an error if the index is out of bounds" do arr = GLib::Array.from :gint32, [1, 2, 3] lambda { arr.index(16) }.must_raise IndexError lambda { arr.index(-1) }.must_raise IndexError end end end gir_ffi-0.6.7/test/ffi-glib/hash_table_test.rb0000644000004100000410000000341212224462647021306 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GLib::HashTable do it "knows its key and value types" do hsh = GLib::HashTable.new :gint32, :utf8 assert_equal :gint32, hsh.key_type assert_equal :utf8, hsh.value_type end describe "::from" do it "creates a GHashTable from a Ruby array" do hsh = GLib::HashTable.from [:utf8, :gint32], {"foo" => 23, "bar" => 32} assert_equal({"foo" => 23, "bar" => 32}, hsh.to_hash) end it "return its argument if given a GHashTable" do hsh = GLib::HashTable.from [:utf8, :gint32], {"foo" => 23, "bar" => 32} hsh2 = GLib::HashTable.from [:utf8, :gint32], hsh assert hsh2.equal? hsh end it "wraps its argument if given a pointer" do hsh = GLib::HashTable.from [:utf8, :gint32], {"foo" => 23, "bar" => 32} pointer = hsh.to_ptr assert_instance_of FFI::Pointer, pointer hsh2 = GLib::HashTable.from [:utf8, :gint32], pointer assert_instance_of GLib::HashTable, hsh2 refute hsh2.equal? hsh hsh2.to_hash.must_equal hsh.to_hash end end it "allows key-value pairs to be inserted" do h = GLib::HashTable.new :utf8, :utf8 h.insert "foo", "bar" h.to_hash.must_equal "foo" => "bar" end it "includes Enumerable" do GLib::HashTable.must_include Enumerable end describe "a HashTable provided by the system" do before do GirFFI.setup :Regress @hash = Regress.test_ghash_container_return end it "has a working #each method" do a = {} @hash.each {|k, v| a[k] = v} a.must_be :==, {"foo" => "bar", "baz" => "bat", "qux" => "quux"} end it "has a working #to_hash method" do @hash.to_hash.must_be :==, {"foo" => "bar", "baz" => "bat", "qux" => "quux"} end end end gir_ffi-0.6.7/test/ffi-glib/ptr_array_test.rb0000644000004100000410000000532012224462647021217 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GLib::PtrArray do it "knows its element type" do arr = GLib::PtrArray.new :utf8 assert_equal :utf8, arr.element_type end describe "::add" do it "correctly takes the type into account" do arr = GLib::PtrArray.new :utf8 str = "test" GLib::PtrArray.add arr, str assert_equal str, arr.pdata.read_pointer.read_string end end describe "#each" do it "works normally" do arr = GLib::PtrArray.new :utf8 GLib::PtrArray.add arr, "test1" GLib::PtrArray.add arr, "test2" GLib::PtrArray.add arr, "test3" a = [] arr.each {|v| a << v} assert_equal ["test1", "test2", "test3"], a end it "works when exiting the loop prematurely" do arr = GLib::PtrArray.new :utf8 GLib::PtrArray.add arr, "test1" GLib::PtrArray.add arr, "test2" GLib::PtrArray.add arr, "test3" a = [] arr.each do |v| a << v break if v == "test2" end assert_equal ["test1", "test2"], a end end it "includes Enumerable" do GLib::PtrArray.must_include Enumerable end it "has a working #to_a method" do arr = GLib::PtrArray.new :utf8 GLib::PtrArray.add arr, "test1" GLib::PtrArray.add arr, "test2" GLib::PtrArray.add arr, "test3" assert_equal ["test1", "test2", "test3"], arr.to_a end it "has #add as an instance method too" do arr = GLib::PtrArray.new :utf8 arr.add "test1" assert_equal ["test1"], arr.to_a end describe "#==" do it "returns true when comparing to an array with the same elements" do arr = GLib::PtrArray.from :utf8, ["1", "2", "3"] arr.must_be :==, ["1", "2", "3"] end it "returns false when comparing to an array with different elements" do arr = GLib::PtrArray.from :utf8, ["1", "2", "3"] arr.wont_be :==, ["1", "2"] end it "returns true when comparing to a GPtrArray with the same elements" do arr = GLib::PtrArray.from :utf8, ["1", "2", "3"] other = GLib::PtrArray.from :utf8, ["1", "2", "3"] arr.must_be :==, other end it "returns false when comparing to a GPtrArray with different elements" do arr = GLib::PtrArray.from :utf8, ["1", "2", "3"] other = GLib::PtrArray.from :utf8, ["1", "2"] arr.wont_be :==, other end end describe "#index" do it "returns the correct element" do arr = GLib::PtrArray.from :utf8, ["1", "2", "3"] arr.index(1).must_equal "2" end it "raises an error if the index is out of bounds" do arr = GLib::PtrArray.from :utf8, ["1", "2", "3"] lambda { arr.index(16) }.must_raise IndexError lambda { arr.index(-1) }.must_raise IndexError end end end gir_ffi-0.6.7/test/ffi-glib/byte_array_test.rb0000644000004100000410000000071212224462647021355 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GLib::ByteArray do it "can succesfully be created with Glib::ByteArray.new" do ba = GLib::ByteArray.new assert_instance_of GLib::ByteArray, ba end it "allows strings to be appended to it" do ba = GLib::ByteArray.new ba.append "abdc" pass end it "has a working #to_string method" do ba = GLib::ByteArray.new ba = ba.append "abdc" assert_equal "abdc", ba.to_string end end gir_ffi-0.6.7/test/ffi-glib/variant_test.rb0000644000004100000410000000034712224462647020664 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GLib::Variant do describe "#get_string" do it "returns just the contained string" do var = GLib::Variant.new_string("Foo") var.get_string.must_equal "Foo" end end end gir_ffi-0.6.7/test/ffi-glib/list_test.rb0000644000004100000410000000417112224462647020172 0ustar www-datawww-datarequire 'gir_ffi_test_helper' describe GLib::List do it "knows its element type" do arr = GLib::List.new :gint32 assert_equal :gint32, arr.element_type end describe "#append" do it "appends integer values" do lst = GLib::List.new :gint32 res = lst.append 1 assert_equal 1, res.data end it "appends string values" do lst = GLib::List.new :utf8 res = lst.append "bla" assert_equal "bla", res.data end it "appends multiple values into a single list" do lst = GLib::List.new :gint32 lst = lst.append 1 lst = lst.append 2 assert_equal 1, lst.data nxt = lst.next assert_equal 2, nxt.data end end describe "::from" do it "creates a GList from a Ruby array" do lst = GLib::List.from :gint32, [3, 2, 1] assert_equal [3, 2, 1], lst.to_a end it "return its argument if given a GList" do lst = GLib::List.from :gint32, [3, 2, 1] lst2 = GLib::List.from :gint32, lst assert lst2.equal? lst end it "wraps its argument if given a pointer" do lst = GLib::List.from :gint32, [3, 2, 1] pointer = lst.to_ptr assert_instance_of FFI::Pointer, pointer lst2 = GLib::List.from :gint32, pointer assert_instance_of GLib::List, lst2 refute lst2.equal? lst lst2.to_a.must_equal lst.to_a end end describe "#==" do it "returns true when comparing to an array with the same elements" do list = GLib::List.from :gint32, [1, 2, 3] list.must_be :==, [1, 2, 3] end it "returns false when comparing to an array with different elements" do list = GLib::List.from :gint32, [1, 2, 3] list.wont_be :==, [1, 2] end it "returns true when comparing to a list with the same elements" do list = GLib::List.from :gint32, [1, 2, 3] other = GLib::List.from :gint32, [1, 2, 3] list.must_be :==, other end it "returns false when comparing to a list with different elements" do list = GLib::List.from :gint32, [1, 2, 3] other = GLib::List.from :gint32, [1, 2] list.wont_be :==, other end end end gir_ffi-0.6.7/DESIGN.rdoc0000644000004100000410000000473712224462647015027 0ustar www-datawww-data= Design of Gir-FFI == Basic Idea Gir-FFI uses FFI to read information from the GObject Introspection Repository. Based on that it creates bindings for the information read. == Class and method creation GirFFI::Builder creates classes and modules at runtime and adds appropriate method_missing methods to them to generate methods and perhaps other classes when required. The following options were discarded, at least for now. * Create classes and all of their methods at runtime. This would be very similar to the method chosen, but would concentrate all the overhead at start-up, some of which would be used for creating methods that will never get called. * Allow offline creation of ruby source generated from the GIR. This is still in interesting idea, but off-line source code generation is not really the Ruby way. == Method Naming Probably, get_x/set_x pairs should become x and x= to be more Ruby-like. This should be done either by defining them as such directly, or by aliasing. Blindly going by the name leads to weird results thoough, like having x, x= and x_full= as a set. Also, some get_ or set_ methods take extra arguments. These probably shouldn't become accessors either. Boolean-valued methods could get a ? at the end. This requires a lot more thought. For now, the full method names as defined in the GIR are used. == Ruby-GNOME Compatibility Full Ruby-GNOME compatibility cannot be achieved automatically, since its object hierarchy differs from that of standard GObject: It puts Object in the GLib namespace, and defines signal_connect and friends as methods of GLib::Instantiable; In standard GObject they are functions. Possibly, compatibility enhancing code can be added for these specific exceptions. == Reference Counting Because we can always make sure GObjects are unref'd when the Ruby object is GC'd, the mechanism of floating references actually gets in the way a bit. Therefore, when floating GObjects are constructed, GirFFI will sink them. All GObjects can then safely be unref'd using a Ruby finalizer. GObjects obtained through other mechanisms than with a constructor will be ref'd once when wrapping them in a ruby object. == Bootstrapping Class Design The interface to the GObject Introspection Repository itself is also introspectable. The interface is specified in terms of structs and functions rather than objects and methods. For now, the hard-coded Ruby bindings for this don't follow the introspected specification: Gir-FFI cannot bootstrap itself. gir_ffi-0.6.7/tasks/0000755000004100000410000000000012224462647014317 5ustar www-datawww-datagir_ffi-0.6.7/tasks/valgrind.rake0000644000004100000410000000016012224462647016766 0ustar www-datawww-datatask :valgrind do `valgrind --suppressions=gir_ffi-ruby1.9.1.supp ruby1.9.1 -Ilib -e "require 'gir_ffi'"` end gir_ffi-0.6.7/tasks/test.rake0000644000004100000410000001303212224462647016141 0ustar www-datawww-datarequire 'rake/testtask' require 'rexml/document' require 'rexml/streamlistener' # Listener class used to process GIR xml data, for creating test stubs. class Listener include REXML::StreamListener def initialize @inside_class = false @stack = [] @skip_state = [] end attr_accessor :result attr_accessor :namespace def tag_start name, attrs @stack.push [name, attrs] if @skip_state.last || skippable?(attrs) @skip_state.push true return else @skip_state.push false end obj_name = attrs['name'] case name when "constant" result.puts " it \"has the constant #{obj_name}\" do" when "record", "class", "enumeration", "bitfield", "interface", "union" result.puts " describe \"#{namespace}::#{obj_name}\" do" @inside_class = name when "constructor" result.puts " it \"creates an instance using ##{obj_name}\" do" when "field" if @inside_class != 'class' if attrs['private'] == "1" result.puts " it \"has a private field #{obj_name}\" do" elsif attrs['writable'] == "1" result.puts " it \"has a writable field #{obj_name}\" do" else result.puts " it \"has a read-only field #{obj_name}\" do" end end when "function", "method" spaces = @inside_class ? " " : "" result.puts " #{spaces}it \"has a working #{name} ##{obj_name}\" do" when "member" result.puts " it \"has the member :#{obj_name}\" do" when "namespace" result.puts "describe #{obj_name} do" when "property" accessor_name = obj_name.gsub(/-/, '_') result.puts " describe \"its '#{obj_name}' property\" do" result.puts " it \"can be retrieved with #get_property\" do" result.puts " end" result.puts " it \"can be retrieved with ##{accessor_name}\" do" result.puts " end" if attrs['writable'] == '1' result.puts " it \"can be set with #set_property\" do" result.puts " end" result.puts " it \"can be set with ##{accessor_name}=\" do" result.puts " end" end when "glib:signal" result.puts " it \"handles the '#{obj_name}' signal\" do" when "type", "alias", "return-value", "parameters", "instance-parameter", "parameter", "doc", "array", "repository", "include", "package" # Not printed" else puts "Skipping #{name}: #{attrs}" end end def tag_end name org_name, _ = *@stack.pop skipping = @skip_state.pop raise "Expected #{org_name}, got #{name}" if org_name != name return if skipping case name when "constant" result.puts " end" when "record", "class", "enumeration", "bitfield", "interface", "union" result.puts " end" @inside_class = false when "function", "method" if @inside_class result.puts " end" else result.puts " end" end when "constructor", "member", "property", "glib:signal" result.puts " end" when "field" if @inside_class != 'class' result.puts " end" end when "namespace" result.puts "end" end end def skippable? attrs return true if attrs['disguised'] == '1' return true if attrs['introspectable'] == '0' return true if attrs['glib:is-gtype-struct-for'] false end end namespace :test do def define_test_task name Rake::TestTask.new(name) do |t| t.libs = ['lib'] t.ruby_opts += ["-w -Itest"] yield t end end define_test_task(:base) do |t| t.test_files = FileList['test/gir_ffi-base/**/*_test.rb'] end define_test_task(:introspection) do |t| t.test_files = FileList['test/ffi-gobject_introspection/**/*_test.rb'] end define_test_task(:main) do |t| t.test_files = FileList['test/gir_ffi_test.rb', 'test/gir_ffi/**/*_test.rb'] end define_test_task(:overrides) do |t| t.test_files = FileList['test/ffi-gobject_test.rb', 'test/ffi-glib/**/*_test.rb', 'test/ffi-gobject/**/*_test.rb'] end define_test_task(:integration) do |t| t.test_files = FileList['test/integration/**/*_test.rb'] end desc 'Build Regress test library and typelib' task :lib => "test/lib/Makefile" do sh %{cd test/lib && make} end task :introspection => :lib task :main => :lib task :overrides => :lib task :integration => :lib desc 'Run the entire test suite as one' define_test_task(:all) do |t| t.test_files = FileList['test/**/*_test.rb'] end task :all => :lib desc 'Run all individual test suites separately' task :suites => [:base, :introspection, :main, :overrides, :integration] desc "Create stubs for Regress and GIMarshallingTests tests" task :stub => :lib do file = File.new 'test/lib/Regress-1.0.gir' listener = Listener.new listener.result = File.open('tmp/regress_lines.rb', 'w') listener.namespace = "Regress" REXML::Document.parse_stream file, listener file = File.new 'test/lib/GIMarshallingTests-1.0.gir' listener = Listener.new listener.result = File.open('tmp/gimarshallingtests_lines.rb', 'w') listener.namespace = "GIMarshallingTests" REXML::Document.parse_stream file, listener end end file "test/lib/Makefile" => "test/lib/configure" do sh %{cd test/lib && ./configure --enable-maintainer-mode} end file "test/lib/configure" do sh %{cd test/lib && NOCONFIGURE=1 ./autogen.sh} end gir_ffi-0.6.7/tasks/setup.rb0000644000004100000410000000031012224462647015776 0ustar www-datawww-datarequire 'rake/clean' # Load the other rake files in the tasks folder tasks_dir = File.expand_path(File.dirname(__FILE__)) rakefiles = Dir.glob(File.join(tasks_dir, '*.rake')).sort import(*rakefiles) gir_ffi-0.6.7/examples/0000755000004100000410000000000012224462647015010 5ustar www-datawww-datagir_ffi-0.6.7/examples/print_class.rb0000644000004100000410000000312412224462647017656 0ustar www-datawww-data$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib') require 'gir_ffi' # File activesupport/lib/active_support/inflector/methods.rb, line 48 def underscore(camel_cased_word) word = camel_cased_word.to_s.dup word.gsub!(/::/, '/') word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2') word.gsub!(/([a-z\d])([A-Z])/,'\1_\2') word.tr!("-", "_") word.downcase! word end namespace = 'GObject' GirFFI.setup namespace modul = Kernel.const_get(namespace) gir = GObjectIntrospection::IRepository.default gir.require namespace, nil infos = gir.infos namespace main_file = File.open(File.join('.', "#{underscore(namespace)}.rb"), 'w') main_file.write "module #{namespace}\n" infos.each do |info| case info.info_type when :function fbuilder = GirFFI::Builder::Function.new info, modul::Lib main_file.write "\n" main_file.write fbuilder.generate main_file.write "\n" when :object main_file.write "class #{info.name} < #{info.parent.name}\n" info.get_methods.each do |minfo| main_file.write "\n" unless minfo.method? main_file.write "class << self\n" end if minfo.constructor? main_file.write "# This method is a constructor\n" end main_file.write "# @return [#{minfo.return_type.tag}]\n" fbuilder = GirFFI::Builder::Function.new minfo, modul::Lib main_file.write fbuilder.generate unless minfo.method? main_file.write "end\n" end main_file.write "\n" end main_file.write "end\n" else puts "#{info.info_type}: #{info.name}\n" end end main_file.write "end\n" main_file.close gir_ffi-0.6.7/examples/demo_ffi_nested_struct.rb0000644000004100000410000000051612224462647022055 0ustar www-datawww-data# Demonstration program for FFI functionality. # # Basic demo of nested struct. Works in MRI, YARV, and JRuby. Does not work # in Rubinius. # require 'ffi' module LibTest class Foo < FFI::Struct layout :a, :int, :b, :int end class Bar < FFI::Struct layout :f, Foo, :g, :int end end puts LibTest::Bar.members.inspect gir_ffi-0.6.7/examples/leak_test.rb0000644000004100000410000000026612224462647017314 0ustar www-datawww-data# Test program to train Valgrind. require 'ffi' module LibC extend FFI::Library ffi_lib FFI::Library::LIBC attach_function :malloc, [:size_t], :pointer end LibC.malloc 2000 gir_ffi-0.6.7/examples/demo_ffi_safe_inherited_layout.rb0000644000004100000410000000144412224462647023536 0ustar www-datawww-data# Demonstrate safe inheritance with layout. # # Uses nested Struct class to separate inheritance from FFI::Struct from # main inheritance structure. Works with MRI and JRuby, without warnings. require 'ffi' require 'forwardable' class Foo extend Forwardable def_delegators :@struct, :[], :to_ptr class Struct < FFI::Struct layout :a, :int, :b, :int end def initialize(ptr=nil) @struct = ptr.nil? ? self.ffi_structure.new : self.ffi_structure.new(ptr) end def ffi_structure self.class.ffi_structure end class << self def ffi_structure self.const_get(:Struct) end end end class Bar < Foo class Struct < FFI::Struct layout :p, Foo.ffi_structure, :c, :int end end bar = Bar.new bar[:p][:a] = 20 foo = Foo.new(bar.to_ptr) puts foo[:a] gir_ffi-0.6.7/examples/hard_coded.rb0000644000004100000410000001026212224462647017412 0ustar www-datawww-data# Hard-code FFI-based Gtk+ test program. Nothing is generated here. require 'ffi' module GObject module Lib extend FFI::Library CALLBACKS = [] ffi_lib "gobject-2.0" callback :GCallback, [], :void enum :GConnectFlags, [:AFTER, (1<<0), :SWAPPED, (1<<1)] attach_function :g_signal_connect_data, [:pointer, :string, :GCallback, :pointer, :pointer, :GConnectFlags], :ulong end def self.signal_connect_data gobject, signal, prc, data, destroy_data, connect_flags Lib::CALLBACKS << prc Lib.g_signal_connect_data gobject.to_ptr, signal, prc, data, destroy_data, connect_flags end end module Gtk module Lib extend FFI::Library ffi_lib "gtk-x11-2.0" attach_function :gtk_init, [:pointer, :pointer], :void attach_function :gtk_main, [], :void attach_function :gtk_main_quit, [], :void attach_function :gtk_widget_show, [:pointer], :pointer attach_function :gtk_widget_destroy, [:pointer], :void attach_function :gtk_container_add, [:pointer, :pointer], :void enum :GtkWindowType, [:GTK_WINDOW_TOPLEVEL, :GTK_WINDOW_POPUP] attach_function :gtk_window_new, [:GtkWindowType], :pointer attach_function :gtk_button_new, [], :pointer attach_function :gtk_button_new_with_label, [:string], :pointer attach_function :gtk_label_new, [:string], :pointer end def self.init size, ary argv = self.string_array_to_inoutptr ary argc = self.int_to_inoutptr(size) Lib.gtk_init argc, argv outsize = self.outptr_to_int argc outary = self.outptr_to_string_array argv, ary.nil? ? 0 : ary.size return outsize, outary end def self.int_to_inoutptr val ptr = FFI::MemoryPointer.new(:int) ptr.write_int val return ptr end # Note: This implementation would dump core if the garbage collector runs # before the contents of the pointers is used. def self.string_array_to_inoutptr ary ptrs = ary.map {|a| FFI::MemoryPointer.from_string(a)} block = FFI::MemoryPointer.new(:pointer, ptrs.length) block.write_array_of_pointer ptrs argv = FFI::MemoryPointer.new(:pointer) argv.write_pointer block argv end def self.outptr_to_int ptr return ptr.read_int end def self.outptr_to_string_array ptr, size block = ptr.read_pointer ptrs = block.read_array_of_pointer(size) return ptrs.map {|p| p.null? ? nil : p.read_string} end def self.main; Lib.gtk_main; end def self.main_quit; Lib.gtk_main_quit; end class Widget def show Lib.gtk_widget_show(@gobj) end def destroy Lib.gtk_widget_destroy(@gobj) end def to_ptr @gobj end end class Container < Widget def add widget Lib.gtk_container_add self.to_ptr, widget.to_ptr end end class Window < Container def initialize type @gobj = Lib.gtk_window_new(type) end end class Button < Container class << self alias :real_new :new end def self.new *args obj = self.real_new *args ptr = Lib.gtk_button_new() obj.instance_variable_set :@gobj, ptr obj end def self.new_with_label text, *args obj = self.real_new *args ptr = Lib.gtk_button_new_with_label(text) obj.instance_variable_set :@gobj, ptr obj end end class MyButton < Button def initialize sym puts "Initializing a #{self.class} with symbol #{sym}" end def self.new super :foo end def self.new_with_label sym super "Hello world", sym end end end (my_len, my_args) = Gtk.init ARGV.length + 1, [$0, *ARGV] p [my_len, my_args] win = Gtk::Window.new(:GTK_WINDOW_TOPLEVEL) #btn = Gtk::Button.new_with_label('Hello World') #btn = Gtk::MyButton.new btn = Gtk::MyButton.new_with_label :foobar2 win.add btn quit_prc = Proc.new { Gtk.main_quit } # We can create callbacks with a different signature by using FFI::Function # directly. del_prc = FFI::Function.new(:bool, [:pointer, :pointer]) {|a, b| puts "delete event occured" true } GObject.signal_connect_data(win, "destroy", quit_prc, nil, nil, 0) GObject.signal_connect_data(win, "delete-event", del_prc, nil, nil, 0) GObject.signal_connect_data(btn, "clicked", Proc.new { win.destroy }, nil, nil, :SWAPPED) btn.show win.show Gtk.main gir_ffi-0.6.7/examples/demo_ffi_inherited_layout.rb0000644000004100000410000000065112224462647022537 0ustar www-datawww-data# Demonstration program for FFI functionality. # # Show what happens if we call layout again in a subclass. This works in # JRuby, but not in MRI (gives warnings with ffi 0.6.3, is explicitely # forbidden later). # require 'ffi' class Foo < FFI::Struct layout :a, :int, :b, :int end class Bar < Foo layout :p, Foo, :c, :int end bar = Bar.new foo = Foo.new(bar.to_ptr) foo[:a] = 20 puts "bar[:p][:a] = #{bar[:p][:a]}" gir_ffi-0.6.7/README.md0000644000004100000410000000577712224462647014471 0ustar www-datawww-data# GirFFI by Matijs van Zuijlen [![Build Status](https://secure.travis-ci.org/mvz/ruby-gir-ffi.png)](http://travis-ci.org/mvz/ruby-gir-ffi) ## Description Ruby bindings for GNOME using the GObject Introspection Repository. ## Features/Notes * Create bindings to any GObject-based library. * Bindings generated at runtime. * Provides overridden bindings for selected methods. * Install 'gir_ffi-gtk' and require 'gir_ffi-gtk2' or 'gir_ffi-gtk3' to load overrides for Gtk2 or Gtk3. ## Usage require 'gir_ffi' # Set up the namespace you wish to use GirFFI.setup :Gio # Create an object inet_address = Gio::InetAddress.new_from_string "127.0.0.1" # Call some methods on the object inet_address.is_loopback # => true inet_address.is_multicast # => false # Call a function in the namespace Gio.dbus_is_name "foo" # => false ## Install gem install gir_ffi ## Requirements GirFFI should work on MRI 1.8, 1.9 and 2.0, JRuby in both 1.8 and 1.9 modes, and on Rubinius in both 1.8 and 1.9 modes. You will also need gobject-introspection installed with some introspection data. Depending on the GIR data, GirFFI needs the actual libraries to be available under the name ending in plain `.so`. If GirFFI complains that it cannot find the library, try installing development packages for those libraries. GirFFI is developed on Debian sid, and tested through Travis CI on Ubuntu 12.04. Older versions of gobject-introspection than the ones used there are therefore not officially supported (although they may work). On Debian and Ubuntu, installing `libgirepository1.0-dev` and `gobject-introspection` should be enough to get `rake test` working. GirFFI has not been tested on Mac OS X or Microsoft Windows. YMMV. ## Overrides Sometimes, the GIR data is incorrect, or not detailed enough, and a reasonable binding cannot be created automatically. For these cases, overrides can be defined. The following gems with overrides already exist: * `gir_ffi-gtk`: overrides for Gtk+ 2 and 3. * `gir_ffi-cairo`: overrides for Cairo * `gir_ffi-pango`: overrides for Pango * `gir_ffi-tracker`: overrides for Tracker ## Hacking and contributing If you want to help out, have a look at TODO.rdoc, and check the notes in the code (e.g., using `dnote`). Feel free to file bugs or send pull requests. If you want to send pull requests or patches, please: * Make sure `rake test` runs without reporting any failures. If your code breaks existing stuff, it won't get merged in. * Add tests for your feature. Otherwise, I can't see if it works or if I break it later. * Make sure latest master merges cleanly with your branch. Things might have moved around since you forked. * Try not to include changes that are irrelevant to your feature in the same commit. ## License Copyright © 2009–2013 [Matijs van Zuijlen](http://www.matijs.net) GirFFI is free software, distributed under the terms of the GNU Lesser General Public License, version 2.1 or later. See the file COPYING.LIB for more information. gir_ffi-0.6.7/Rakefile0000644000004100000410000000006312224462647014636 0ustar www-datawww-dataload 'tasks/setup.rb' task :default => 'test:all' gir_ffi-0.6.7/History.txt0000644000004100000410000001763112224462647015404 0ustar www-datawww-data== 0.6.7 / 2013-09-28 * Uniform handling of callback, signal and method arguments * Automatically convert array elements to GValue * Support inline array fields * Support struct fields * Improved field setters and getters * Support many more types of properties * Support skipped arguments and return values * Fix refcount for the result of IBaseInfo#container * Check bounds in GLib::PtrArray#index and GLib::Array#index * Deprecate several methods * Lots of refactoring == 0.6.6 / 2013-08-05 * Handle GArrays of booleans and structs * Improve handling of gbooleans == 0.6.5 / 2013-08-03 * Handle inline arrays of structs * Implement equality operator for container types * Fix element size calculation for GArray == 0.6.4 / 2013-06-30 * Represent enum types by modules wrapping FFI::Enum * Support functions on enums * Handle zero-terminated arrays of types other than int32 * Add override for GLib::Variant#get_string * Handle non-throwing arguments and return values of type GError * Handle arguments and return values of type GPtrArray * Handle caller-allocated arguments of type GArray * Deprecate GObject::Value#ruby_value, replacing it with #get_value == 0.6.3 / 2013-06-15 * Make use of enums as element type for GHashTable and other containers work == 0.6.2 / 2013-06-14 * Handle introspectable types with introspectable parent types == 0.6.1 / 2013-06-09 * Handle SizedArray containing enums == 0.6.0 / 2013-06-07 * Support Rubinius * Lots of refactoring == 0.5.2 / 2013-04-23 * Handle signal details in GObject.signal_connect and .signal_emit * Make GValue#set_value check object GType compatibility * Eliminate GObject::Helper module * Handle more argument types * Support Ruby 2.0.0 == 0.5.1 / 2013-02-01 * Properly handle zero-terminated arrays of :filename * Loosen dependencies on ffi and minitest == 0.5.0 / 2013-01-19 * Update ffi dependency * Add finalizer to release memory for IBaseInfo and descendents * Remove deprecated methods * Remove pretty-printing functionality * Refactor argument handling == 0.4.3 / 2012-11-02 * Remove gobject-introspection version check * Make tests pass with gobject-introspection 1.34 * Ongoing refactoring == 0.4.2 / 2012-09-22 * Make objects and interfaces wrap poiners in the class that matches their GType. == 0.4.1 / 2012-09-18 * Remove workarounds for older versions of gobject-introspection * Mark certain methods as deprecated. These will be removed in 0.5.0 * Handle :filename type arguments in InPointer * Refactoring == 0.4.0 / 2012-08-24 * Move Gtk+ bindings to their own gem (gir_ffi-gtk). == 0.3.2 / 2012-08-24 * Correctly set FFI return type when callbacks that return GObjects have incomplete type specification. == 0.3.1 / 2012-05-13 * Correctly map Interface types in callbacks. == 0.3.0 / 2012-04-09 * Improve process of defining initializers in derived classes. * Make interfaces know their GType. * Make classes created by the Unintrospectable builder know their GType. * Create property accessors instead of field accessors for GObjects. * Add Ruby-style getter and setter methods (by Antonio Terceiro). * Add #signal_connect instance method (by Antonio Terceiro). * Make GirFFI's tests pass with gobject-introspection 0.10. * Improve unintrospectable type handling. * Bug fixes and refactorings. * Start implementing #define_type, for creating descendent types that the GObject system knows about. == 0.2.3 / 2011-12-31 * Fix issue #7: methods that take GValues will autoconvert other values. * Fix method lookup when include'ing a module that is an Interface. * Various refactorings. == 0.2.2 / 2011-12-07 * Fix issue #19: Check if a GLib::PtrArray.add method was generated before attempting to remove it. * Fix two issues with pretty printing that made output for GLib have syntax errors. == 0.2.1 / 2011-11-20 * Fix handling of output parameters that are arrays of pointers to structures (i.e., of type Foo***). == 0.2.0 / 2011-11-19 * Add support for properties, with #get_property and #set_property. * Add support for fields. - Create field accessor methods. - Get rid of #[] and #[]=. * Explicitely load libgirepository with ABI version 1. * Improve implementation of GLib container classes (GList etc.): - Real constructors. - #append and friends are instance methods now. - Conversion methods to cast Ruby containers to GLib containers. * Start implementing pretty printing. * Various refactorings. == 0.1.0 / 2011-10-28 * Put bindings for GObjectIntrospection in their own namespace. * GirFFI.setup no longer loads overrides. * Add ffi-gtk2 and ffi-gtk3 files for loading Gtk+ overrides. == 0.0.14 / 2011-10-28 * Support GObject Introspection version 1.30: - Add support for layouts with fixed-length arrays. - Handle type names starting with underscores. - Call g_signal_emitv directly to avoid conflict in introspection info with earlier versions of GObject Introspection. == 0.0.13 / 2011-09-09 * Remove IErrorDomain related code. This functinality was removed from GObject Introspection in version 1.29.17 == 0.0.12 / 2011-09-04 * No longer use _id2ref to locate objects past as user data pointers. * Fix failing tests on JRuby. == 0.0.11 / 2011-08-22 * Change interface to the underlying builder in generated modules and classes. * Handle string, enum, union, flags signal arguments. * Handle string arguments in GObject.signal_emit. * Handle enum signal arguments. * Fix finding signals in non-introspectable types. * Fix method setup in non-introspectable types. * Refactoring. == 0.0.10 / 2011-05-18 * Handle GObject interfaces properly. * Create types only defined by the GType system. * Support GType array return values. == 0.0.9 / 2011-05-02 * More complete support for the basic types. * Improved support for GList, GSList, GStrv, and GValue. * Add support for GHashTable, GVariant, GByteArray, and GArray. * Generate constants. * When setting up a module, set up its dependencies as well. * Test against the GIMarshallingTests test namespace. * Use minitest/spec for testing. * Various bug fixes and internal improvements. == 0.0.8 / 2011-04-08 * Generate modules with names starting with a lowercase letter (like cairo). * Allow specifying the typelib version on setup. * Rename methods #methods and #type of the introspection classes to avoid clashing with standard Ruby methods. * Refactoring. == 0.0.7 / 2011-04-01 * Support gobject-introspection 0.10, drop support for earlier versions. - Use Regress, not Everything, for testing. - Deal with functions that are no longer introspectable. * Correctly handle constructors that declare their return type different from their class. * Implement RubyClosure, a GObject::Closure for handling ruby callbacks. * Handle GLib's singly and doubly linked lists. * Handle callback types defined in-place (like Closure's marshal). * Refactoring. == 0.0.6 / 2011-03-01 * Cast returned GObjects to their actual type. * Properly cast callback arguments. * Handle the case where functions formally return interfaces. * Make sure Gtk::Window has the correct number of references after creation. * Refactoring and some small fixes. == 0.0.5 / 2010-12-30 * Don't create instance methods out of functions and vice versa. * Find signals on interfaces, too. * Implement tests for most of Everything. * Correctly handle array + size arguments. * Handle most other argument types. * Various internal changes and other fixes. == 0.0.4 / 2010-12-14 * Lots of changes to the internals. * Handle out-only arguments. * Make use of callbacks from other namespaces work. * Handle virtual methods where the invoker method has a different name. * Implement usable signal_connect and signal_emit. * Sink floating references when creating a GObject. * Implement Union type. * Many small bug fixes. == 0.0.3 / 2010-11-19 * Update to restore Ruby 1.9 support. * Handle functions with the 'throws' property set. * Handle classes without specified fields. == 0.0.2 / 2010-11-14 * Several fixes to method creation. == 0.0.1 / 2010-10-25 * Initial release. gir_ffi-0.6.7/metadata.yml0000644000004100000410000003355312224462647015506 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: gir_ffi version: !ruby/object:Gem::Version version: 0.6.7 prerelease: platform: ruby authors: - Matijs van Zuijlen autorequire: bindir: bin cert_chain: [] date: 2013-09-28 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: ffi requirement: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '1.8' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '1.8' - !ruby/object:Gem::Dependency name: indentation requirement: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: 0.0.6 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: 0.0.6 - !ruby/object:Gem::Dependency name: minitest requirement: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '5.0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '5.0' - !ruby/object:Gem::Dependency name: rr requirement: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: 1.0.4 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: 1.0.4 - !ruby/object:Gem::Dependency name: rake requirement: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '10.1' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '10.1' description: email: - matijs@matijs.net executables: [] extensions: [] extra_rdoc_files: - DESIGN.rdoc - History.txt - README.md - TODO.rdoc files: - lib/gir_ffi-base.rb - lib/ffi-gobject_introspection.rb - lib/gir_ffi.rb - lib/gir_ffi/lib_c.rb - lib/gir_ffi/method_stubber.rb - lib/gir_ffi/arg_helper.rb - lib/gir_ffi/info_ext.rb - lib/gir_ffi/struct_base.rb - lib/gir_ffi/allocation_helper.rb - lib/gir_ffi/ffi_ext.rb - lib/gir_ffi/type_map.rb - lib/gir_ffi/signal_base.rb - lib/gir_ffi/zero_terminated.rb - lib/gir_ffi/unintrospectable_type_info.rb - lib/gir_ffi/builders/enum_builder.rb - lib/gir_ffi/builders/registered_type_builder.rb - lib/gir_ffi/builders/constant_builder.rb - lib/gir_ffi/builders/mapping_method_builder.rb - lib/gir_ffi/builders/struct_builder.rb - lib/gir_ffi/builders/argument_builder.rb - lib/gir_ffi/builders/error_argument_builder.rb - lib/gir_ffi/builders/signal_builder.rb - lib/gir_ffi/builders/type_builder.rb - lib/gir_ffi/builders/union_builder.rb - lib/gir_ffi/builders/return_value_builder.rb - lib/gir_ffi/builders/property_builder.rb - lib/gir_ffi/builders/unintrospectable_builder.rb - lib/gir_ffi/builders/interface_builder.rb - lib/gir_ffi/builders/with_methods.rb - lib/gir_ffi/builders/with_layout.rb - lib/gir_ffi/builders/callback_builder.rb - lib/gir_ffi/builders/null_argument_builder.rb - lib/gir_ffi/builders/user_defined_builder.rb - lib/gir_ffi/builders/null_builder.rb - lib/gir_ffi/builders/field_builder.rb - lib/gir_ffi/builders/module_builder.rb - lib/gir_ffi/builders/base_argument_builder.rb - lib/gir_ffi/builders/base_type_builder.rb - lib/gir_ffi/builders/object_builder.rb - lib/gir_ffi/builders/function_builder.rb - lib/gir_ffi/user_defined_property_info.rb - lib/gir_ffi/ffi_ext/pointer.rb - lib/gir_ffi/setter_argument_info.rb - lib/gir_ffi/builder_helper.rb - lib/gir_ffi/variable_name_generator.rb - lib/gir_ffi/in_pointer.rb - lib/gir_ffi/enum_base.rb - lib/gir_ffi/callback_base.rb - lib/gir_ffi/type_base.rb - lib/gir_ffi/union_base.rb - lib/gir_ffi/in_out_pointer.rb - lib/gir_ffi/version.rb - lib/gir_ffi/builder.rb - lib/gir_ffi/interface_base.rb - lib/gir_ffi/info_ext/i_arg_info.rb - lib/gir_ffi/info_ext/i_type_info.rb - lib/gir_ffi/info_ext/i_function_info.rb - lib/gir_ffi/info_ext/i_callable_info.rb - lib/gir_ffi/info_ext/i_field_info.rb - lib/gir_ffi/info_ext/safe_constant_name.rb - lib/gir_ffi/info_ext/i_property_info.rb - lib/gir_ffi/info_ext/i_signal_info.rb - lib/gir_ffi/info_ext/safe_function_name.rb - lib/gir_ffi/info_ext/i_registered_type_info.rb - lib/gir_ffi/module_base.rb - lib/gir_ffi/user_defined_type_info.rb - lib/gir_ffi/class_base.rb - lib/gir_ffi/object_base.rb - lib/gir_ffi-base/gir_ffi/library.rb - lib/gir_ffi-base/gir_ffi/struct.rb - lib/gir_ffi-base/gobject/lib.rb - lib/gir_ffi-base/gobject.rb - lib/gir_ffi-base/glib/boolean.rb - lib/gir_ffi-base/glib/strv.rb - lib/ffi-gobject/ruby_closure.rb - lib/ffi-gobject/base.rb - lib/ffi-gobject/object.rb - lib/ffi-gobject/value.rb - lib/ffi-gobject/initially_unowned.rb - lib/ffi-gobject/closure.rb - lib/ffi-glib.rb - lib/ffi-glib/container_class_methods.rb - lib/ffi-glib/array.rb - lib/ffi-glib/list.rb - lib/ffi-glib/hash_table.rb - lib/ffi-glib/list_methods.rb - lib/ffi-glib/strv.rb - lib/ffi-glib/byte_array.rb - lib/ffi-glib/ptr_array.rb - lib/ffi-glib/variant.rb - lib/ffi-glib/sized_array.rb - lib/ffi-glib/s_list.rb - lib/ffi-gobject_introspection/i_struct_info.rb - lib/ffi-gobject_introspection/i_callback_info.rb - lib/ffi-gobject_introspection/i_arg_info.rb - lib/ffi-gobject_introspection/i_type_info.rb - lib/ffi-gobject_introspection/i_function_info.rb - lib/ffi-gobject_introspection/i_callable_info.rb - lib/ffi-gobject_introspection/i_field_info.rb - lib/ffi-gobject_introspection/i_vfunc_info.rb - lib/ffi-gobject_introspection/i_interface_info.rb - lib/ffi-gobject_introspection/i_property_info.rb - lib/ffi-gobject_introspection/i_enum_info.rb - lib/ffi-gobject_introspection/lib.rb - lib/ffi-gobject_introspection/i_repository.rb - lib/ffi-gobject_introspection/i_constant_info.rb - lib/ffi-gobject_introspection/i_value_info.rb - lib/ffi-gobject_introspection/i_signal_info.rb - lib/ffi-gobject_introspection/i_union_info.rb - lib/ffi-gobject_introspection/i_base_info.rb - lib/ffi-gobject_introspection/i_object_info.rb - lib/ffi-gobject_introspection/i_flags_info.rb - lib/ffi-gobject_introspection/i_registered_type_info.rb - lib/ffi-gobject_introspection/g_error.rb - lib/ffi-gobject.rb - test/lib/configure.ac - test/lib/Makefile.am - test/lib/m4/jhflags.m4 - test/lib/autogen.sh - test/gir_ffi_test_helper.rb - test/ffi-gobject_test.rb - test/integration/generated_pango_ft2_test.rb - test/integration/derived_classes_test.rb - test/integration/generated_regress_test.rb - test/integration/method_lookup_test.rb - test/integration/generated_gimarshallingtests_test.rb - test/integration/generated_gio_test.rb - test/integration/generated_pango_test.rb - test/integration/generated_secret_test.rb - test/integration/generated_gobject_test.rb - test/gir_ffi/callback_base_test.rb - test/gir_ffi/user_defined_property_info_test.rb - test/gir_ffi/zero_terminated_test.rb - test/gir_ffi/object_base_test.rb - test/gir_ffi/builder_test.rb - test/gir_ffi/in_pointer_test.rb - test/gir_ffi/in_out_pointer_test.rb - test/gir_ffi/arg_helper_test.rb - test/gir_ffi/builders/field_builder_test.rb - test/gir_ffi/builders/signal_builder_test.rb - test/gir_ffi/builders/enum_builder_test.rb - test/gir_ffi/builders/constant_builder_test.rb - test/gir_ffi/builders/unintrospectable_builder_test.rb - test/gir_ffi/builders/function_builder_test.rb - test/gir_ffi/builders/base_argument_builder_test.rb - test/gir_ffi/builders/struct_builder_test.rb - test/gir_ffi/builders/union_builder_test.rb - test/gir_ffi/builders/callback_builder_test.rb - test/gir_ffi/builders/argument_builder_test.rb - test/gir_ffi/builders/return_value_builder_test.rb - test/gir_ffi/builders/interface_builder_test.rb - test/gir_ffi/builders/object_builder_test.rb - test/gir_ffi/builders/module_builder_test.rb - test/gir_ffi/builders/user_defined_builder_test.rb - test/gir_ffi/variable_name_generator_test.rb - test/gir_ffi/ffi_ext/pointer_test.rb - test/gir_ffi/class_base_test.rb - test/gir_ffi/type_map_test.rb - test/gir_ffi/user_defined_type_info_test.rb - test/gir_ffi/unintrospectable_type_info_test.rb - test/gir_ffi/info_ext/i_callable_info_test.rb - test/gir_ffi/info_ext/i_type_info_test.rb - test/gir_ffi/info_ext/i_signal_info_test.rb - test/gir_ffi/info_ext/safe_constant_name_test.rb - test/gir_ffi/info_ext/safe_function_name_test.rb - test/gir_ffi/info_ext/i_field_info_test.rb - test/gir_ffi/info_ext/i_function_info_test.rb - test/gir_ffi/interface_base_test.rb - test/gir_ffi-base/glib/boolean_test.rb - test/gir_ffi-base/glib/strv_test.rb - test/ffi-gobject/object_class_test.rb - test/ffi-gobject/object_test.rb - test/ffi-gobject/gobject_test.rb - test/ffi-gobject/value_test.rb - test/base_test_helper.rb - test/ffi-glib/s_list_test.rb - test/ffi-glib/hash_table_test.rb - test/ffi-glib/list_test.rb - test/ffi-glib/array_test.rb - test/ffi-glib/ptr_array_test.rb - test/ffi-glib/byte_array_test.rb - test/ffi-glib/ruby_closure_test.rb - test/ffi-glib/variant_test.rb - test/ffi-glib/sized_array_test.rb - test/ffi-glib/strv_test.rb - test/ffi-gobject_introspection/i_repository_test.rb - test/ffi-gobject_introspection/i_constant_info_test.rb - test/ffi-gobject_introspection/i_base_info_test.rb - test/ffi-gobject_introspection/i_object_info_test.rb - test/ffi-gobject_introspection/lib_test.rb - test/ffi-gobject_introspection/i_function_info_test.rb - test/ffi-gobject_introspection/i_enum_info_test.rb - test/gir_ffi_test.rb - test/introspection_test_helper.rb - tasks/setup.rb - tasks/valgrind.rake - tasks/test.rake - examples/demo_ffi_nested_struct.rb - examples/hard_coded.rb - examples/leak_test.rb - examples/demo_ffi_safe_inherited_layout.rb - examples/demo_ffi_inherited_layout.rb - examples/print_class.rb - README.md - DESIGN.rdoc - TODO.rdoc - History.txt - Rakefile - COPYING.LIB homepage: http://www.github.com/mvz/ruby-gir-ffi licenses: [] post_install_message: rdoc_options: - --main - README.md require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 1.8.23 signing_key: specification_version: 3 summary: FFI-based GObject binding using the GObject Introspection Repository test_files: - test/base_test_helper.rb - test/ffi-glib/array_test.rb - test/ffi-glib/byte_array_test.rb - test/ffi-glib/hash_table_test.rb - test/ffi-glib/list_test.rb - test/ffi-glib/ptr_array_test.rb - test/ffi-glib/ruby_closure_test.rb - test/ffi-glib/s_list_test.rb - test/ffi-glib/sized_array_test.rb - test/ffi-glib/strv_test.rb - test/ffi-glib/variant_test.rb - test/ffi-gobject/gobject_test.rb - test/ffi-gobject/object_class_test.rb - test/ffi-gobject/object_test.rb - test/ffi-gobject/value_test.rb - test/ffi-gobject_introspection/i_base_info_test.rb - test/ffi-gobject_introspection/i_constant_info_test.rb - test/ffi-gobject_introspection/i_enum_info_test.rb - test/ffi-gobject_introspection/i_function_info_test.rb - test/ffi-gobject_introspection/i_object_info_test.rb - test/ffi-gobject_introspection/i_repository_test.rb - test/ffi-gobject_introspection/lib_test.rb - test/ffi-gobject_test.rb - test/gir_ffi-base/glib/boolean_test.rb - test/gir_ffi-base/glib/strv_test.rb - test/gir_ffi/arg_helper_test.rb - test/gir_ffi/builder_test.rb - test/gir_ffi/builders/argument_builder_test.rb - test/gir_ffi/builders/base_argument_builder_test.rb - test/gir_ffi/builders/callback_builder_test.rb - test/gir_ffi/builders/constant_builder_test.rb - test/gir_ffi/builders/enum_builder_test.rb - test/gir_ffi/builders/field_builder_test.rb - test/gir_ffi/builders/function_builder_test.rb - test/gir_ffi/builders/interface_builder_test.rb - test/gir_ffi/builders/module_builder_test.rb - test/gir_ffi/builders/object_builder_test.rb - test/gir_ffi/builders/return_value_builder_test.rb - test/gir_ffi/builders/signal_builder_test.rb - test/gir_ffi/builders/struct_builder_test.rb - test/gir_ffi/builders/unintrospectable_builder_test.rb - test/gir_ffi/builders/union_builder_test.rb - test/gir_ffi/builders/user_defined_builder_test.rb - test/gir_ffi/callback_base_test.rb - test/gir_ffi/class_base_test.rb - test/gir_ffi/ffi_ext/pointer_test.rb - test/gir_ffi/in_out_pointer_test.rb - test/gir_ffi/in_pointer_test.rb - test/gir_ffi/info_ext/i_callable_info_test.rb - test/gir_ffi/info_ext/i_field_info_test.rb - test/gir_ffi/info_ext/i_function_info_test.rb - test/gir_ffi/info_ext/i_signal_info_test.rb - test/gir_ffi/info_ext/i_type_info_test.rb - test/gir_ffi/info_ext/safe_constant_name_test.rb - test/gir_ffi/info_ext/safe_function_name_test.rb - test/gir_ffi/interface_base_test.rb - test/gir_ffi/object_base_test.rb - test/gir_ffi/type_map_test.rb - test/gir_ffi/unintrospectable_type_info_test.rb - test/gir_ffi/user_defined_property_info_test.rb - test/gir_ffi/user_defined_type_info_test.rb - test/gir_ffi/variable_name_generator_test.rb - test/gir_ffi/zero_terminated_test.rb - test/gir_ffi_test.rb - test/gir_ffi_test_helper.rb - test/integration/derived_classes_test.rb - test/integration/generated_gimarshallingtests_test.rb - test/integration/generated_gio_test.rb - test/integration/generated_gobject_test.rb - test/integration/generated_pango_ft2_test.rb - test/integration/generated_pango_test.rb - test/integration/generated_regress_test.rb - test/integration/generated_secret_test.rb - test/integration/method_lookup_test.rb - test/introspection_test_helper.rb - test/lib/Makefile.am - test/lib/autogen.sh - test/lib/configure.ac - test/lib/m4/jhflags.m4 has_rdoc: gir_ffi-0.6.7/COPYING.LIB0000644000004100000410000006347612224462647014652 0ustar www-datawww-data GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! gir_ffi-0.6.7/TODO.rdoc0000644000004100000410000000440012224462647014606 0ustar www-datawww-data= TODO == Memory managment GirFFI does not attempt to free any memory at the moment, or lower the reference count of any objects it gets from GObject. This task therefore involves two parts: - Free non-GObject pointers as needed (at garbage-collection time) - Lower reference count of GObjects (at garbage-collection time) == Refactorings These in the order they occured to me, and may therefore be fixed in any order. - Create Type objects for all FFI types, including the ones currently represented by a single symbol, so we can always do stuff like GirFFI::Types::UInt8.get_value_from_pointer(ptr) rather than having awkward dynamic method dispatch inside GirFFI::InOutPointer. - Move code in GirFFI::Struct to StructBase, then somehow unify UnionBase and StructBase. - Move to a single Pointer class, rather than InPointer, InOutPointer and Pointer monkeypatching. - Move special types like SizedArray to sane namespaces. Types (like GLib::List) that have actual GLib implementations go to the GLib namespace. Other types go to the GirFFI namespace. - Use argumentbuilders to build signal argument marshalling functions. == Persistent Ruby GObject identity GirFFI should make sure that if it gets a pointer to a GObject for which a Ruby object already exists, the existing object is returned. This involves the use of WeakRef, no doubt. == Handle fundamental objects that are not GObject. This is a big one. See commit 1e9822c7817062a9b853269b9418fd78782090b5 in gobject-introspection, and TestFundamentalObject in Regress. The tests for TestFundamentalObject accidentally pass, but there may be hidden issues. == Check binding of GObject: (11:37:03 PM) walters: the basic story is that GObject should be manually bound (11:47:02 PM) ebassi: the really necessary bits are: GObject/GInitiallyUnowned memory management; properties accessors; GSignal connection API (11:47:15 PM) ebassi: the rest is "nice to have" (11:47:37 PM) ebassi: oh, and probably GBinding - but that's just because I wrote it ;-) == Use FFI::DataConverter to automatically convert GObject types GirFFI now generates loads of Something.wrap(ptr) calls; Perhaps these can be replace by implementing to_native and from_native in ClassBase and including FFI::DataConverter. == See Also dnote gir_ffi-0.6.7/lib/0000755000004100000410000000000012224462647013740 5ustar www-datawww-datagir_ffi-0.6.7/lib/ffi-gobject.rb0000644000004100000410000000745012224462647016452 0ustar www-datawww-data# NOTE: Do not require this file directly. Require 'gir_ffi' instead. # GirFFI.setup :GObject require 'ffi-gobject/base' require 'ffi-gobject/value' require 'ffi-gobject/initially_unowned' require 'ffi-gobject/closure' require 'ffi-gobject/object' require 'ffi-gobject/ruby_closure' require 'gir_ffi/builders/user_defined_builder' module GObject def self.object_ref obj Lib::g_object_ref obj.to_ptr end def self.object_ref_sink obj Lib::g_object_ref_sink obj.to_ptr end def self.object_unref obj Lib::g_object_unref obj.to_ptr end def self.object_is_floating obj Lib::g_object_is_floating obj.to_ptr end def self.type_from_instance_pointer inst_ptr return nil if inst_ptr.null? klsptr = inst_ptr.get_pointer 0 klsptr.send "get_#{GirFFI::TypeMap::TAG_TYPE_MAP[:GType]}", 0 end def self.type_from_instance instance type_from_instance_pointer instance.to_ptr end def self.object_class_from_instance instance object_class_from_instance_pointer instance.to_ptr end def self.object_class_from_instance_pointer inst_ptr return nil if inst_ptr.null? klsptr = inst_ptr.get_pointer 0 ObjectClass.wrap klsptr end setup_method :signal_emitv def self.signal_lookup_from_instance signal, object signal_lookup signal, type_from_instance(object) end def self.signal_emit object, detailed_signal, *args signal, detail = detailed_signal.split('::') signal_id = signal_lookup_from_instance signal, object detail_quark = GLib.quark_from_string(detail) sig_info = object.class.find_signal signal arr = sig_info.signal_arguments_to_gvalue_array object, *args rval = sig_info.gvalue_for_signal_return_value Lib.g_signal_emitv arr.values, signal_id, detail_quark, rval return rval end def self.signal_connect object, detailed_signal, data=nil, &block signal, _ = detailed_signal.split('::') sig_info = object.class.find_signal signal callback = sig_info.signal_callback(&block) GirFFI::CallbackBase.store_callback callback data_ptr = GirFFI::InPointer.from_object data Lib.g_signal_connect_data object, detailed_signal, callback, data_ptr, nil, 0 end # Smells of :reek:LongParameterList: due to the C interface. def self.param_spec_int(name, nick, blurb, minimum, maximum, default_value, flags) ptr = Lib.g_param_spec_int(name, nick, blurb, minimum, maximum, default_value, flags) ParamSpecInt.wrap(ptr) end load_class :Callback load_class :ClosureNotify load_class :ConnectFlags load_class :ClosureMarshal load_class :ParamFlags module Lib # NOTE: This Lib module is set up in `gir_ffi-base/gobject/lib.rb`. attach_function :g_object_ref, [:pointer], :void attach_function :g_object_ref_sink, [:pointer], :void attach_function :g_object_unref, [:pointer], :void attach_function :g_object_is_floating, [:pointer], :bool attach_function :g_array_get_type, [], :size_t attach_function :g_hash_table_get_type, [], :size_t attach_function :g_strv_get_type, [], :size_t attach_function :g_signal_connect_data, [:pointer, :string, Callback, :pointer, ClosureNotify, ConnectFlags], :ulong attach_function :g_closure_set_marshal, [:pointer, ClosureMarshal], :void attach_function :g_param_spec_int, [:string, :string, :string, :int32, :int32, :int32, ParamFlags], :pointer end TYPE_ARRAY = Lib.g_array_get_type TYPE_HASH_TABLE = Lib.g_hash_table_get_type TYPE_STRV = Lib.g_strv_get_type TYPE_TAG_TO_GTYPE = { :array => TYPE_ARRAY, :gboolean => TYPE_BOOLEAN, :gdouble => TYPE_DOUBLE, :gfloat => TYPE_FLOAT, :ghash => TYPE_HASH_TABLE, :gint32 => TYPE_INT, :glist => TYPE_POINTER, :utf8 => TYPE_STRING, :void => TYPE_NONE } end gir_ffi-0.6.7/lib/gir_ffi-base/0000755000004100000410000000000012224462647016255 5ustar www-datawww-datagir_ffi-0.6.7/lib/gir_ffi-base/gobject.rb0000644000004100000410000000014712224462647020221 0ustar www-datawww-datarequire 'gir_ffi-base/gobject/lib' module GObject def self.type_init Lib::g_type_init end end gir_ffi-0.6.7/lib/gir_ffi-base/glib/0000755000004100000410000000000012224462647017172 5ustar www-datawww-datagir_ffi-0.6.7/lib/gir_ffi-base/glib/strv.rb0000644000004100000410000000132512224462647020516 0ustar www-datawww-datarequire 'ffi' module GLib # Represents a null-terminated array of strings. GLib uses this # construction, but does not provide any actual functions for this class. class Strv include Enumerable POINTER_SIZE = FFI.type_size(:pointer) def initialize ptr @ptr = ptr end def to_ptr @ptr end def each reset_iterator or return while (ptr = next_ptr) yield ptr.read_string end end def self.wrap ptr self.new ptr end private def reset_iterator return if @ptr.null? @offset = 0 end def next_ptr ptr = @ptr.get_pointer @offset @offset += POINTER_SIZE ptr unless ptr.null? end end end gir_ffi-0.6.7/lib/gir_ffi-base/glib/boolean.rb0000644000004100000410000000105412224462647021136 0ustar www-datawww-datarequire 'ffi' module GLib # Implementation of gboolean class Boolean extend FFI::DataConverter native_type FFI::Type::INT def self.from_native value, context value != 0 ? true : false end def self.to_native value, context value ? 1 : 0 end def self.size FFI.type_size FFI::Type::INT end def self.copy_value_to_pointer value, pointer pointer.put_int 0, to_native(value, nil) end def self.get_value_from_pointer pointer from_native pointer.get_int(0), nil end end end gir_ffi-0.6.7/lib/gir_ffi-base/gir_ffi/0000755000004100000410000000000012224462647017662 5ustar www-datawww-datagir_ffi-0.6.7/lib/gir_ffi-base/gir_ffi/library.rb0000644000004100000410000000036712224462647021661 0ustar www-datawww-datarequire 'ffi' module GirFFI module Library include FFI::Library def find_type type if type.is_a? Module if type.const_defined?(:Enum) return super type::Enum end end super end end end gir_ffi-0.6.7/lib/gir_ffi-base/gir_ffi/struct.rb0000644000004100000410000000110112224462647021524 0ustar www-datawww-datamodule GirFFI class Struct < FFI::Struct extend FFI::DataConverter def self.native_type FFI::Type::Struct.new(self) end def self.to_native value, context value end def self.from_native value, context value end # TODO: Find method to directly copy bytes, rather than reading and # putting them. def self.copy_value_to_pointer value, pointer, offset=0 pointer.put_bytes offset, value.to_ptr.read_bytes(size), 0, size end def self.get_value_from_pointer pointer pointer.to_ptr end end end gir_ffi-0.6.7/lib/gir_ffi-base/gobject/0000755000004100000410000000000012224462647017672 5ustar www-datawww-datagir_ffi-0.6.7/lib/gir_ffi-base/gobject/lib.rb0000644000004100000410000000020712224462647020764 0ustar www-datawww-datamodule GObject module Lib extend GirFFI::Library ffi_lib "gobject-2.0" attach_function :g_type_init, [], :void end end gir_ffi-0.6.7/lib/gir_ffi-base.rb0000644000004100000410000000053312224462647016603 0ustar www-datawww-data# This section contains code that is needed by GObjectIntrospection, but # belongs in modules that can only be created fully once GObjectIntrospection # is fully loaded. require 'gir_ffi-base/gir_ffi/library' require 'gir_ffi-base/gir_ffi/struct' require 'gir_ffi-base/glib/boolean' require 'gir_ffi-base/glib/strv' require 'gir_ffi-base/gobject' gir_ffi-0.6.7/lib/ffi-gobject_introspection/0000755000004100000410000000000012224462647021077 5ustar www-datawww-datagir_ffi-0.6.7/lib/ffi-gobject_introspection/i_repository.rb0000644000004100000410000000733312224462647024161 0ustar www-datawww-datarequire 'singleton' require 'ffi' require 'gir_ffi-base' require 'ffi-gobject_introspection/lib' require 'ffi-gobject_introspection/g_error' require 'ffi-gobject_introspection/i_base_info' require 'ffi-gobject_introspection/i_callable_info' require 'ffi-gobject_introspection/i_callback_info' require 'ffi-gobject_introspection/i_function_info' require 'ffi-gobject_introspection/i_constant_info' require 'ffi-gobject_introspection/i_field_info' require 'ffi-gobject_introspection/i_registered_type_info' require 'ffi-gobject_introspection/i_interface_info' require 'ffi-gobject_introspection/i_property_info' require 'ffi-gobject_introspection/i_vfunc_info' require 'ffi-gobject_introspection/i_signal_info' require 'ffi-gobject_introspection/i_object_info' require 'ffi-gobject_introspection/i_struct_info' require 'ffi-gobject_introspection/i_value_info' require 'ffi-gobject_introspection/i_union_info' require 'ffi-gobject_introspection/i_enum_info' require 'ffi-gobject_introspection/i_flags_info' module GObjectIntrospection GObject.type_init # The Gobject Introspection Repository. This class is the point of # access to the introspection typelibs. # This class wraps the GIRepository struct. class IRepository # Map info type to class. Default is IBaseInfo. TYPEMAP = { :invalid => IBaseInfo, :function => IFunctionInfo, :callback => ICallbackInfo, :struct => IStructInfo, # TODO: There's no GIBoxedInfo, so what does :boxed mean? :boxed => IBaseInfo, :enum => IEnumInfo, :flags => IFlagsInfo, :object => IObjectInfo, :interface => IInterfaceInfo, :constant => IConstantInfo, :invalid_was_error_domain => IBaseInfo, :union => IUnionInfo, :value => IValueInfo, :signal => ISignalInfo, :vfunc => IVFuncInfo, :property => IPropertyInfo, :field => IFieldInfo, :arg => IArgInfo, :type => ITypeInfo, :unresolved => IBaseInfo } def initialize @gobj = Lib::g_irepository_get_default end include Singleton def self.default self.instance end def self.prepend_search_path path Lib.g_irepository_prepend_search_path path end def self.type_tag_to_string type Lib.g_type_tag_to_string type end def require namespace, version=nil, flags=0 errpp = FFI::MemoryPointer.new(:pointer).write_pointer nil Lib.g_irepository_require @gobj, namespace, version, flags, errpp errp = errpp.read_pointer raise GError.new(errp).message unless errp.null? end def n_infos namespace Lib.g_irepository_get_n_infos @gobj, namespace end def info namespace, index ptr = Lib.g_irepository_get_info @gobj, namespace, index return wrap ptr end # Utility method def infos namespace (0..(n_infos(namespace) - 1)).map do |idx| info namespace, idx end end def find_by_name namespace, name ptr = Lib.g_irepository_find_by_name @gobj, namespace, name return wrap ptr end def find_by_gtype gtype raise ArgumentError, "Type #{gtype} is not a valid type" if gtype == 0 ptr = Lib.g_irepository_find_by_gtype @gobj, gtype return wrap ptr end def dependencies namespace strv_p = Lib.g_irepository_get_dependencies(@gobj, namespace) strv = GLib::Strv.new strv_p strv.to_a end def shared_library namespace Lib.g_irepository_get_shared_library @gobj, namespace end def self.wrap_ibaseinfo_pointer ptr return nil if ptr.null? type = Lib.g_base_info_get_type ptr klass = TYPEMAP[type] return klass.wrap(ptr) end private def wrap ptr IRepository.wrap_ibaseinfo_pointer ptr end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_registered_type_info.rb0000644000004100000410000000060312224462647026144 0ustar www-datawww-datamodule GObjectIntrospection # Wraps a GIRegisteredTypeInfo struct. # Represents a registered type. class IRegisteredTypeInfo < IBaseInfo def type_name Lib.g_registered_type_info_get_type_name @gobj end def type_init Lib.g_registered_type_info_get_type_init @gobj end def g_type Lib.g_registered_type_info_get_g_type @gobj end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_field_info.rb0000644000004100000410000000101312224462647024025 0ustar www-datawww-datamodule GObjectIntrospection # Wraps a GIFieldInfo struct. # Represents a field of an IStructInfo or an IUnionInfo. class IFieldInfo < IBaseInfo def flags Lib.g_field_info_get_flags @gobj end def size Lib.g_field_info_get_size @gobj end def offset Lib.g_field_info_get_offset @gobj end def field_type ITypeInfo.wrap(Lib.g_field_info_get_type @gobj) end def readable? flags & 1 != 0 end def writable? flags & 2 != 0 end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/g_error.rb0000644000004100000410000000054312224462647023065 0ustar www-datawww-datamodule GObjectIntrospection # Wraps GLib's GError struct. class GError # GLib's GError struct. class Struct < FFI::Struct layout :domain, :uint32, :code, :int, :message, :string end def initialize ptr @struct = self.class::Struct.new(ptr) end def message @struct[:message] end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_arg_info.rb0000644000004100000410000000166312224462647023526 0ustar www-datawww-datarequire 'ffi-gobject_introspection/i_base_info' module GObjectIntrospection # Wraps a GIArgInfo struct. # Represents an argument. class IArgInfo < IBaseInfo def direction Lib.g_arg_info_get_direction @gobj end def return_value? Lib.g_arg_info_is_return_value @gobj end def optional? Lib.g_arg_info_is_optional @gobj end def caller_allocates? Lib.g_arg_info_is_caller_allocates @gobj end def may_be_null? Lib.g_arg_info_may_be_null @gobj end def skip? Lib.g_arg_info_is_skip @gobj end def ownership_transfer Lib.g_arg_info_get_ownership_transfer @gobj end def scope Lib.g_arg_info_get_scope @gobj end def closure Lib.g_arg_info_get_closure @gobj end def destroy Lib.g_arg_info_get_destroy @gobj end def argument_type ITypeInfo.wrap(Lib.g_arg_info_get_type @gobj) end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_callback_info.rb0000644000004100000410000000027112224462647024503 0ustar www-datawww-datamodule GObjectIntrospection # Wraps a GICallbackInfo struct. Has no methods in addition to the ones # inherited from ICallableInfo. class ICallbackInfo < ICallableInfo end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_constant_info.rb0000644000004100000410000000156112224462647024603 0ustar www-datawww-datamodule GObjectIntrospection # Wraps a GIConstantInfo struct; represents a constant. class IConstantInfo < IBaseInfo TYPE_TAG_TO_UNION_MEMBER = { :gint8 => :v_int8, :gint16 => :v_int16, :gint32 => :v_int32, :gint64 => :v_int64, :guint8 => :v_uint8, :guint16 => :v_uint16, :guint32 => :v_uint32, :guint64 => :v_uint64, :gdouble => :v_double, :utf8 => :v_string } def value_union val = Lib::GIArgument.new Lib.g_constant_info_get_value @gobj, val return val end def value tag = constant_type.tag val = value_union[TYPE_TAG_TO_UNION_MEMBER[tag]] if RUBY_VERSION >= "1.9" and tag == :utf8 val.force_encoding("utf-8") else val end end def constant_type ITypeInfo.wrap(Lib.g_constant_info_get_type @gobj) end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/lib.rb0000644000004100000410000002575412224462647022207 0ustar www-datawww-datarequire 'ffi' module GObjectIntrospection module Lib extend FFI::Library ffi_lib "girepository-1.0" # IRepository enum :IRepositoryLoadFlags, [:LAZY, (1<<0)] attach_function :g_irepository_get_default, [], :pointer attach_function :g_irepository_prepend_search_path, [:string], :void attach_function :g_irepository_require, [:pointer, :string, :string, :IRepositoryLoadFlags, :pointer], :pointer attach_function :g_irepository_get_n_infos, [:pointer, :string], :int attach_function :g_irepository_get_info, [:pointer, :string, :int], :pointer attach_function :g_irepository_find_by_name, [:pointer, :string, :string], :pointer attach_function :g_irepository_find_by_gtype, [:pointer, :size_t], :pointer attach_function :g_irepository_get_dependencies, [:pointer, :string], :pointer attach_function :g_irepository_get_shared_library, [:pointer, :string], :string # IBaseInfo enum :IInfoType, [ :invalid, :function, :callback, :struct, :boxed, :enum, :flags, :object, :interface, :constant, :invalid_was_error_domain, # deprecated in GI 1.29.17 :union, :value, :signal, :vfunc, :property, :field, :arg, :type, :unresolved ] attach_function :g_base_info_ref, [:pointer], :void attach_function :g_base_info_unref, [:pointer], :void attach_function :g_base_info_get_type, [:pointer], :IInfoType attach_function :g_base_info_get_name, [:pointer], :string attach_function :g_base_info_get_namespace, [:pointer], :string attach_function :g_base_info_get_container, [:pointer], :pointer attach_function :g_base_info_is_deprecated, [:pointer], :bool attach_function :g_base_info_equal, [:pointer, :pointer], :bool # IFunctionInfo attach_function :g_function_info_get_symbol, [:pointer], :string # TODO: return type is bitfield attach_function :g_function_info_get_flags, [:pointer], :int # ICallableInfo enum :ITransfer, [ :nothing, :container, :everything ] attach_function :g_callable_info_get_return_type, [:pointer], :pointer attach_function :g_callable_info_get_caller_owns, [:pointer], :ITransfer attach_function :g_callable_info_may_return_null, [:pointer], :bool attach_function :g_callable_info_get_n_args, [:pointer], :int attach_function :g_callable_info_get_arg, [:pointer, :int], :pointer attach_function :g_callable_info_skip_return, [:pointer], :bool # IArgInfo enum :IDirection, [ :in, :out, :inout ] enum :IScopeType, [ :invalid, :call, :async, :notified ] attach_function :g_arg_info_get_direction, [:pointer], :IDirection attach_function :g_arg_info_is_return_value, [:pointer], :bool attach_function :g_arg_info_is_optional, [:pointer], :bool attach_function :g_arg_info_is_caller_allocates, [:pointer], :bool attach_function :g_arg_info_is_skip, [:pointer], :bool attach_function :g_arg_info_may_be_null, [:pointer], :bool attach_function :g_arg_info_get_ownership_transfer, [:pointer], :ITransfer attach_function :g_arg_info_get_scope, [:pointer], :IScopeType attach_function :g_arg_info_get_closure, [:pointer], :int attach_function :g_arg_info_get_destroy, [:pointer], :int attach_function :g_arg_info_get_type, [:pointer], :pointer # The values of ITypeTag were changed in an incompatible way between # gobject-introspection version 0.9.0 and 0.9.1. Therefore, we need to # retrieve the correct values before declaring the ITypeTag enum. attach_function :tmp_type_tag_to_string, :g_type_tag_to_string, [:int], :string type_tag_map = (0..31).map { |id| sym = tmp_type_tag_to_string(id).to_sym if sym == :unknown nil else [sym, id] end }.compact.flatten enum :ITypeTag, type_tag_map # Now, attach g_type_tag_to_string again under its own name with an # improved signature. attach_function :g_type_tag_to_string, [:ITypeTag], :string #define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY) enum :IArrayType, [ :c, :array, :ptr_array, :byte_array ] attach_function :g_type_info_is_pointer, [:pointer], :bool attach_function :g_type_info_get_tag, [:pointer], :ITypeTag attach_function :g_type_info_get_param_type, [:pointer, :int], :pointer attach_function :g_type_info_get_interface, [:pointer], :pointer attach_function :g_type_info_get_array_length, [:pointer], :int attach_function :g_type_info_get_array_fixed_size, [:pointer], :int attach_function :g_type_info_get_array_type, [:pointer], :IArrayType attach_function :g_type_info_is_zero_terminated, [:pointer], :bool # IStructInfo attach_function :g_struct_info_get_n_fields, [:pointer], :int attach_function :g_struct_info_get_field, [:pointer, :int], :pointer attach_function :g_struct_info_get_n_methods, [:pointer], :int attach_function :g_struct_info_get_method, [:pointer, :int], :pointer attach_function :g_struct_info_find_method, [:pointer, :string], :pointer attach_function :g_struct_info_get_size, [:pointer], :int attach_function :g_struct_info_get_alignment, [:pointer], :int attach_function :g_struct_info_is_gtype_struct, [:pointer], :bool # IValueInfo attach_function :g_value_info_get_value, [:pointer], :long # IFieldInfo enum :IFieldInfoFlags, [ :readable, (1 << 0), :writable, (1 << 1) ] # TODO: return type is bitfield :IFieldInfoFlags attach_function :g_field_info_get_flags, [:pointer], :int attach_function :g_field_info_get_size, [:pointer], :int attach_function :g_field_info_get_offset, [:pointer], :int attach_function :g_field_info_get_type, [:pointer], :pointer # IUnionInfo attach_function :g_union_info_get_n_fields, [:pointer], :int attach_function :g_union_info_get_field, [:pointer, :int], :pointer attach_function :g_union_info_get_n_methods, [:pointer], :int attach_function :g_union_info_get_method, [:pointer, :int], :pointer attach_function :g_union_info_find_method, [:pointer, :string], :pointer attach_function :g_union_info_get_size, [:pointer], :int attach_function :g_union_info_get_alignment, [:pointer], :int # IRegisteredTypeInfo attach_function :g_registered_type_info_get_type_name, [:pointer], :string attach_function :g_registered_type_info_get_type_init, [:pointer], :string attach_function :g_registered_type_info_get_g_type, [:pointer], :size_t # IEnumInfo attach_function :g_enum_info_get_storage_type, [:pointer], :ITypeTag attach_function :g_enum_info_get_n_values, [:pointer], :int attach_function :g_enum_info_get_value, [:pointer, :int], :pointer attach_function :g_enum_info_get_n_methods, [:pointer], :int attach_function :g_enum_info_get_method, [:pointer, :int], :pointer # IObjectInfo attach_function :g_object_info_get_type_name, [:pointer], :string attach_function :g_object_info_get_type_init, [:pointer], :string attach_function :g_object_info_get_abstract, [:pointer], :bool attach_function :g_object_info_get_parent, [:pointer], :pointer attach_function :g_object_info_get_n_interfaces, [:pointer], :int attach_function :g_object_info_get_interface, [:pointer, :int], :pointer attach_function :g_object_info_get_n_fields, [:pointer], :int attach_function :g_object_info_get_field, [:pointer, :int], :pointer attach_function :g_object_info_get_n_properties, [:pointer], :int attach_function :g_object_info_get_property, [:pointer, :int], :pointer attach_function :g_object_info_get_n_methods, [:pointer], :int attach_function :g_object_info_get_method, [:pointer, :int], :pointer attach_function :g_object_info_find_method, [:pointer, :string], :pointer attach_function :g_object_info_get_n_signals, [:pointer], :int attach_function :g_object_info_get_signal, [:pointer, :int], :pointer attach_function :g_object_info_get_n_vfuncs, [:pointer], :int attach_function :g_object_info_get_vfunc, [:pointer, :int], :pointer attach_function :g_object_info_find_vfunc, [:pointer, :string], :pointer attach_function :g_object_info_get_n_constants, [:pointer], :int attach_function :g_object_info_get_constant, [:pointer, :int], :pointer attach_function :g_object_info_get_class_struct, [:pointer], :pointer attach_function :g_object_info_get_fundamental, [:pointer], :bool # IVFuncInfo enum :IVFuncInfoFlags, [ :must_chain_up, (1 << 0), :must_override, (1 << 1), :must_not_override, (1 << 2) ] attach_function :g_vfunc_info_get_flags, [:pointer], :IVFuncInfoFlags attach_function :g_vfunc_info_get_offset, [:pointer], :int attach_function :g_vfunc_info_get_signal, [:pointer], :pointer attach_function :g_vfunc_info_get_invoker, [:pointer], :pointer # IInterfaceInfo attach_function :g_interface_info_get_n_prerequisites, [:pointer], :int attach_function :g_interface_info_get_prerequisite, [:pointer, :int], :pointer attach_function :g_interface_info_get_n_properties, [:pointer], :int attach_function :g_interface_info_get_property, [:pointer, :int], :pointer attach_function :g_interface_info_get_n_methods, [:pointer], :int attach_function :g_interface_info_get_method, [:pointer, :int], :pointer attach_function :g_interface_info_find_method, [:pointer, :string], :pointer attach_function :g_interface_info_get_n_signals, [:pointer], :int attach_function :g_interface_info_get_signal, [:pointer, :int], :pointer attach_function :g_interface_info_get_n_vfuncs, [:pointer], :int attach_function :g_interface_info_get_vfunc, [:pointer, :int], :pointer attach_function :g_interface_info_find_vfunc, [:pointer, :string], :pointer attach_function :g_interface_info_get_n_constants, [:pointer], :int attach_function :g_interface_info_get_constant, [:pointer, :int], :pointer attach_function :g_interface_info_get_iface_struct, [:pointer], :pointer # Union type representing an argument value class GIArgument < FFI::Union signed_size_t = "int#{FFI.type_size(:size_t) * 8}".to_sym layout :v_boolean, :int, :v_int8, :int8, :v_uint8, :uint8, :v_int16, :int16, :v_uint16, :uint16, :v_int32, :int32, :v_uint32, :uint32, :v_int64, :int64, :v_uint64, :uint64, :v_float, :float, :v_double, :double, :v_short, :short, :v_ushort, :ushort, :v_int, :int, :v_uint, :uint, :v_long, :long, :v_ulong, :ulong, :v_ssize, signed_size_t, :v_size, :size_t, :v_string, :string, :v_pointer, :pointer end # IConstInfo # attach_function :g_constant_info_get_type, [:pointer], :pointer attach_function :g_constant_info_get_value, [:pointer, :pointer], :int # IPropertyInfo # attach_function :g_property_info_get_type, [:pointer], :pointer end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_union_info.rb0000644000004100000410000000141612224462647024101 0ustar www-datawww-datamodule GObjectIntrospection # Wraps a GIUnionInfo struct. # Represents a union. class IUnionInfo < IRegisteredTypeInfo def n_fields Lib.g_union_info_get_n_fields @gobj end def field(index) IFieldInfo.wrap(Lib.g_union_info_get_field @gobj, index) end ## build_array_method :fields def get_n_methods Lib.g_union_info_get_n_methods @gobj end def get_method(index) IFunctionInfo.wrap(Lib.g_union_info_get_method @gobj, index) end ## build_array_method :get_methods def find_method(name) IFunctionInfo.wrap(Lib.g_union_info_find_method @gobj, name) end def size Lib.g_union_info_get_size @gobj end def alignment Lib.g_union_info_get_alignment @gobj end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_vfunc_info.rb0000644000004100000410000000065212224462647024073 0ustar www-datawww-datamodule GObjectIntrospection # Wraps a GIVFuncInfo struct. # Represents a virtual function. class IVFuncInfo < IBaseInfo def flags Lib.g_vfunc_info_get_flags @gobj end def offset Lib.g_vfunc_info_get_offset @gobj end def signal ISignalInfo.wrap(Lib.g_vfunc_info_get_signal @gobj) end def invoker IFunctionInfo.wrap(Lib.g_vfunc_info_get_invoker @gobj) end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_enum_info.rb0000644000004100000410000000136312224462647023716 0ustar www-datawww-datamodule GObjectIntrospection # Wraps a GIEnumInfo struct if it represents an enum. # If it represents a flag, an IFlagsInfo object is used instead. class IEnumInfo < IRegisteredTypeInfo def n_values Lib.g_enum_info_get_n_values @gobj end def value(index) IValueInfo.wrap(Lib.g_enum_info_get_value @gobj, index) end ## build_array_method :values def get_n_methods Lib.g_enum_info_get_n_methods @gobj end def get_method(index) IFunctionInfo.wrap(Lib.g_enum_info_get_method @gobj, index) end ## build_array_method :get_methods build_finder_method :find_method, :get_n_methods, :get_method def storage_type Lib.g_enum_info_get_storage_type @gobj end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_callable_info.rb0000644000004100000410000000152012224462647024504 0ustar www-datawww-datarequire 'ffi-gobject_introspection/i_base_info' require 'ffi-gobject_introspection/i_type_info' require 'ffi-gobject_introspection/i_arg_info' module GObjectIntrospection # Wraps a GICallableInfo struct; represents a callable, either # IFunctionInfo, ICallbackInfo or IVFuncInfo. class ICallableInfo < IBaseInfo def return_type ITypeInfo.wrap(Lib.g_callable_info_get_return_type @gobj) end def caller_owns Lib.g_callable_info_get_caller_owns @gobj end def may_return_null? Lib.g_callable_info_may_return_null @gobj end def n_args Lib.g_callable_info_get_n_args @gobj end def arg(index) IArgInfo.wrap(Lib.g_callable_info_get_arg @gobj, index) end ## build_array_method :args def skip_return? Lib.g_callable_info_skip_return @gobj end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_object_info.rb0000644000004100000410000000453412224462647024223 0ustar www-datawww-datamodule GObjectIntrospection # Wraps a GIObjectInfo struct. # Represents an object. class IObjectInfo < IRegisteredTypeInfo def type_name Lib.g_object_info_get_type_name @gobj end def type_init Lib.g_object_info_get_type_init @gobj end def abstract? Lib.g_object_info_get_abstract @gobj end def fundamental? Lib.g_object_info_get_fundamental @gobj end def parent IObjectInfo.wrap(Lib.g_object_info_get_parent @gobj) end def n_interfaces Lib.g_object_info_get_n_interfaces @gobj end def interface(index) IInterfaceInfo.wrap(Lib.g_object_info_get_interface @gobj, index) end ## build_array_method :interfaces def n_fields Lib.g_object_info_get_n_fields @gobj end def field(index) IFieldInfo.wrap(Lib.g_object_info_get_field @gobj, index) end ## build_array_method :fields def n_properties Lib.g_object_info_get_n_properties @gobj end def property(index) IPropertyInfo.wrap(Lib.g_object_info_get_property @gobj, index) end ## build_array_method :properties, :property build_finder_method :find_property, :n_properties def get_n_methods Lib.g_object_info_get_n_methods @gobj end def get_method(index) IFunctionInfo.wrap(Lib.g_object_info_get_method @gobj, index) end ## build_array_method :get_methods def find_method(name) IFunctionInfo.wrap(Lib.g_object_info_find_method @gobj, name) end def n_signals Lib.g_object_info_get_n_signals @gobj end def signal(index) ISignalInfo.wrap(Lib.g_object_info_get_signal @gobj, index) end ## build_array_method :signals build_finder_method :find_signal def n_vfuncs Lib.g_object_info_get_n_vfuncs @gobj end def vfunc(index) IVFuncInfo.wrap(Lib.g_object_info_get_vfunc @gobj, index) end def find_vfunc name IVFuncInfo.wrap(Lib.g_object_info_find_vfunc @gobj, name) end ## build_array_method :vfuncs def n_constants Lib.g_object_info_get_n_constants @gobj end def constant(index) IConstantInfo.wrap(Lib.g_object_info_get_constant @gobj, index) end ## build_array_method :constants def class_struct IStructInfo.wrap(Lib.g_object_info_get_class_struct @gobj) end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_type_info.rb0000644000004100000410000000155612224462647023737 0ustar www-datawww-datamodule GObjectIntrospection # Wraps a GITypeInfo struct. # Represents type information, direction, transfer etc. class ITypeInfo < IBaseInfo def pointer? Lib.g_type_info_is_pointer @gobj end def tag Lib.g_type_info_get_tag @gobj end def param_type(index) ITypeInfo.wrap(Lib.g_type_info_get_param_type @gobj, index) end def interface ptr = Lib.g_type_info_get_interface @gobj IRepository.wrap_ibaseinfo_pointer ptr end def array_length Lib.g_type_info_get_array_length @gobj end def array_fixed_size Lib.g_type_info_get_array_fixed_size @gobj end def array_type Lib.g_type_info_get_array_type @gobj end def zero_terminated? Lib.g_type_info_is_zero_terminated @gobj end def name raise "Should not call this for ITypeInfo" end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_signal_info.rb0000644000004100000410000000023512224462647024224 0ustar www-datawww-datamodule GObjectIntrospection # Wraps a GISignalInfo struct. # Represents a signal. # Not implemented yet. class ISignalInfo < ICallableInfo end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_base_info.rb0000644000004100000410000000622212224462647023663 0ustar www-datawww-datamodule GObjectIntrospection # Wraps GIBaseInfo struct, the base \type for all info types. # Decendant types will be implemented as needed. class IBaseInfo def initialize ptr, lib=Lib raise ArgumentError, "ptr must not be null" if ptr.null? unless defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx' ObjectSpace.define_finalizer self, self.class.make_finalizer(lib, ptr) end @gobj = ptr @lib = lib end def self.make_finalizer lib, ptr proc { lib.g_base_info_unref ptr } end def to_ptr @gobj end # This is a helper method to construct a method returning an array, out # of the methods returning their number and the individual elements. # # For example, given the methods +n_foos+ and +foo+(+i+), this method # will create an additional method +foos+ returning all foos. # # Provide the second parameter if the plural is not trivially # constructed by adding +s+ to the singular. # # Examples: # # build_array_method :fields # build_array_mehtod :properties, :property # build_array_method :get_methods # def self.build_array_method method, single = nil method = method.to_s single ||= method.to_s[0..-2] count = method.sub(/^(get_)?/, "\\1n_") self.class_eval <<-CODE def #{method} (0..(#{count} - 1)).map do |i| #{single} i end end CODE end # This is a helper method to construct a method for finding an element, out # of the methods returning their number and the individual elements. # # For example, given the methods +n_foos+ and +foo+(+i+), this method will # create an additional method +find_foo+ returning the foo with the # matching name. # # Optionally provide counter and fetcher methods if they cannot be # trivially derived from the finder method. # # Examples: # # build_finder_method :find_field # build_finder_method :find_property, :n_properties # build_finder_method :find_method, :get_n_methods, :get_method # def self.build_finder_method method, counter = nil, fetcher = nil method = method.to_s single = method.sub(/^find_/, "") counter ||= "n_#{single}s" fetcher ||= "#{single}" self.class_eval <<-CODE def #{method}(name) (0..(#{counter} - 1)).each do |i| it = #{fetcher}(i) return it if it.name == name end nil end CODE end def name Lib.g_base_info_get_name @gobj end def info_type Lib.g_base_info_get_type @gobj end def namespace Lib.g_base_info_get_namespace @gobj end def safe_namespace namespace.gsub(/^(.)/) { $1.upcase } end def container ptr = Lib.g_base_info_get_container @gobj Lib.g_base_info_ref ptr IRepository.wrap_ibaseinfo_pointer ptr end def deprecated? Lib.g_base_info_is_deprecated @gobj end def self.wrap ptr return nil if ptr.null? return new ptr end def == other Lib.g_base_info_equal @gobj, other.to_ptr end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_property_info.rb0000644000004100000410000000040412224462647024631 0ustar www-datawww-datamodule GObjectIntrospection # Wraps a GIPropertyInfo struct. # Represents a property of an IObjectInfo or an IInterfaceInfo. class IPropertyInfo < IBaseInfo def property_type ITypeInfo.wrap(Lib.g_property_info_get_type @gobj) end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_flags_info.rb0000644000004100000410000000030212224462647024036 0ustar www-datawww-datamodule GObjectIntrospection # Wraps a GIEnumInfo struct, if it represents a flag type. # TODO: Perhaps just use IEnumInfo. Seems to make more sense. class IFlagsInfo < IEnumInfo end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_interface_info.rb0000644000004100000410000000344312224462647024713 0ustar www-datawww-datamodule GObjectIntrospection # Wraps a IInterfaceInfo struct. # Represents an interface. class IInterfaceInfo < IRegisteredTypeInfo def n_prerequisites Lib.g_interface_info_get_n_prerequisites @gobj end def prerequisite index IBaseInfo.wrap(Lib.g_interface_info_get_prerequisite @gobj, index) end ## build_array_method :prerequisites def n_properties Lib.g_interface_info_get_n_properties @gobj end def property index IPropertyInfo.wrap(Lib.g_interface_info_get_property @gobj, index) end ## build_array_method :properties, :property def get_n_methods Lib.g_interface_info_get_n_methods @gobj end def get_method index IFunctionInfo.wrap(Lib.g_interface_info_get_method @gobj, index) end ## build_array_method :get_methods def find_method name IFunctionInfo.wrap(Lib.g_interface_info_find_method @gobj, name) end def n_signals Lib.g_interface_info_get_n_signals @gobj end def signal index ISignalInfo.wrap(Lib.g_interface_info_get_signal @gobj, index) end ## build_array_method :signals build_finder_method :find_signal def n_vfuncs Lib.g_interface_info_get_n_vfuncs @gobj end def vfunc index IVFuncInfo.wrap(Lib.g_interface_info_get_vfunc @gobj, index) end ## build_array_method :vfuncs def find_vfunc name IVFuncInfo.wrap(Lib.g_interface_info_find_vfunc @gobj, name) end def n_constants Lib.g_interface_info_get_n_constants @gobj end def constant index IConstantInfo.wrap(Lib.g_interface_info_get_constant @gobj, index) end ## build_array_method :constants def iface_struct IStructInfo.wrap(Lib.g_interface_info_get_iface_struct @gobj) end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_value_info.rb0000644000004100000410000000033212224462647024061 0ustar www-datawww-datamodule GObjectIntrospection # Wraps a GIValueInfo struct. # Represents one of the enum values of an IEnumInfo. class IValueInfo < IBaseInfo def value Lib.g_value_info_get_value @gobj end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_struct_info.rb0000644000004100000410000000166512224462647024303 0ustar www-datawww-datamodule GObjectIntrospection # Wraps a GIStructInfo struct. # Represents a struct. class IStructInfo < IRegisteredTypeInfo def n_fields Lib.g_struct_info_get_n_fields @gobj end def field(index) IFieldInfo.wrap(Lib.g_struct_info_get_field @gobj, index) end ## build_array_method :fields build_finder_method :find_field def get_n_methods Lib.g_struct_info_get_n_methods @gobj end def get_method(index) IFunctionInfo.wrap(Lib.g_struct_info_get_method @gobj, index) end ## build_array_method :get_methods # There is a function g_object_info_find_method but it causes a core dump. build_finder_method :find_method, :get_n_methods, :get_method def size Lib.g_struct_info_get_size @gobj end def alignment Lib.g_struct_info_get_alignment @gobj end def gtype_struct? Lib.g_struct_info_is_gtype_struct @gobj end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection/i_function_info.rb0000644000004100000410000000111312224462647024570 0ustar www-datawww-datamodule GObjectIntrospection # Wraps a GIFunctioInfo struct. # Represents a function. class IFunctionInfo < ICallableInfo def symbol Lib.g_function_info_get_symbol @gobj end def flags Lib.g_function_info_get_flags @gobj end #TODO: Use some sort of bitfield def method? flags & 1 != 0 end def constructor? flags & 2 != 0 end def getter? flags & 4 != 0 end def setter? flags & 8 != 0 end def wraps_vfunc? flags & 16 != 0 end def throws? flags & 32 != 0 end end end gir_ffi-0.6.7/lib/gir_ffi/0000755000004100000410000000000012224462647015345 5ustar www-datawww-datagir_ffi-0.6.7/lib/gir_ffi/enum_base.rb0000644000004100000410000000121612224462647017630 0ustar www-datawww-datarequire 'gir_ffi/type_base' module GirFFI module EnumBase include TypeBase # TODO: Make this a DataConverter def [](arg) self::Enum[arg] end def wrap arg self[arg] end def to_native *args self::Enum.to_native(*args) end def setup_and_call method, *arguments, &block result = setup_method method.to_s unless result raise RuntimeError, "Unable to set up method #{method} in #{self}" end self.send method, *arguments, &block end def to_ffitype self::Enum end def setup_method name gir_ffi_builder.setup_method name end end end gir_ffi-0.6.7/lib/gir_ffi/union_base.rb0000644000004100000410000000102312224462647020010 0ustar www-datawww-datamodule GirFFI class UnionBase < ClassBase extend FFI::DataConverter def self.native_type FFI::Type::Struct.new(self::Struct) end def self.to_ffitype self end # FIXME: Duplicate of GirFFI::Struct def self.get_value_from_pointer pointer pointer.to_ptr end # FIXME: Duplicate of GirFFI::Struct def self.copy_value_to_pointer value, pointer, offset=0 size = self::Struct.size pointer.put_bytes offset, value.to_ptr.read_bytes(size), 0, size end end end gir_ffi-0.6.7/lib/gir_ffi/info_ext/0000755000004100000410000000000012224462647017160 5ustar www-datawww-datagir_ffi-0.6.7/lib/gir_ffi/info_ext/i_registered_type_info.rb0000644000004100000410000000071112224462647024225 0ustar www-datawww-datarequire 'gir_ffi/builder_helper' module GirFFI module InfoExt module IRegisteredTypeInfo def to_ffitype to_type.to_ffitype end def to_type Builder.build_class self end def find_instance_method method info = find_method method return info if info && info.method? end end end end GObjectIntrospection::IRegisteredTypeInfo.send :include, GirFFI::InfoExt::IRegisteredTypeInfo gir_ffi-0.6.7/lib/gir_ffi/info_ext/i_field_info.rb0000644000004100000410000000051712224462647022116 0ustar www-datawww-datamodule GirFFI module InfoExt # Extensions for GObjectIntrospection::IFieldInfo needed by GirFFI module IFieldInfo def layout_specification [ name.to_sym, field_type.to_ffitype, offset ] end end end end GObjectIntrospection::IFieldInfo.send :include, GirFFI::InfoExt::IFieldInfo gir_ffi-0.6.7/lib/gir_ffi/info_ext/i_arg_info.rb0000644000004100000410000000050712224462647021603 0ustar www-datawww-datamodule GirFFI module InfoExt # Extensions for GObjectIntrospection::IArgInfo needed by GirFFI module IArgInfo def to_ffitype return :pointer if direction != :in return argument_type.to_ffitype end end end end GObjectIntrospection::IArgInfo.send :include, GirFFI::InfoExt::IArgInfo gir_ffi-0.6.7/lib/gir_ffi/info_ext/i_callable_info.rb0000644000004100000410000000076512224462647022577 0ustar www-datawww-datamodule GirFFI module InfoExt # Extensions for GObjectIntrospection::ICallableInfo needed by GirFFI module ICallableInfo def argument_ffi_types args.map { |arg| arg.to_ffitype } end def return_ffi_type return_type.to_ffitype end # TODO: Move to extension just for ICallbackInfo def to_ffitype Builder.build_class(self) end end end end GObjectIntrospection::ICallableInfo.send :include, GirFFI::InfoExt::ICallableInfo gir_ffi-0.6.7/lib/gir_ffi/info_ext/i_type_info.rb0000644000004100000410000000750312224462647022016 0ustar www-datawww-datarequire 'gir_ffi/builder_helper' module GirFFI module InfoExt # Extensions for GObjectIntrospection::IArgInfo needed by GirFFI module ITypeInfo include BuilderHelper def g_type tag = self.tag case tag when :interface interface.g_type else GObject::TYPE_TAG_TO_GTYPE[tag] end end def make_g_value GObject::Value.for_g_type g_type end def element_type case tag when :glist, :gslist, :array subtype_tag_or_class 0 when :ghash [subtype_tag_or_class(0), subtype_tag_or_class(1)] else nil end end def flattened_tag case tag when :interface interface_type when :array flattened_array_type else tag end end def interface_type tag == :interface && interface.info_type end def subtype_tag_or_class index = 0 param_type(index).tag_or_class end def tag_or_class base = case flattened_tag when :struct, :union, :object, :interface, :enum, :flags Builder.build_class interface else flattened_tag end if pointer? && tag != :utf8 && tag != :filename || interface_type == :object [:pointer, base] else base end end TAG_TO_WRAPPER_CLASS_MAP = { :array => 'GLib::Array', :byte_array => 'GLib::ByteArray', :c => 'GLib::SizedArray', :callback => 'GirFFI::Callback', :error => 'GLib::Error', :ghash => 'GLib::HashTable', :glist => 'GLib::List', :gslist => 'GLib::SList', :ptr_array => 'GLib::PtrArray', :strv => 'GLib::Strv', :utf8 => 'GirFFI::InPointer', :void => 'GirFFI::InPointer', :zero_terminated => 'GirFFI::ZeroTerminated' } # TODO: Use class rather than class name def argument_class_name case flattened_tag when :struct, :union, :object, :interface, :enum, :flags, :callback interface.full_type_name else TAG_TO_WRAPPER_CLASS_MAP[flattened_tag] end end def to_ffitype return :pointer if pointer? type_tag = tag case type_tag when :interface interface.to_ffitype when :array subtype = param_type(0).to_ffitype # NOTE: Don't use pointer directly to appease JRuby. if subtype == :pointer subtype = :"uint#{FFI.type_size(:pointer)*8}" end [subtype, array_fixed_size] else TypeMap.map_basic_type type_tag end end def to_callback_ffitype type_tag = tag return :pointer if pointer? if type_tag == :interface case interface.info_type when :enum, :flags :int32 else :pointer end else return TypeMap.map_basic_type type_tag end end def extra_conversion_arguments case flattened_tag when :utf8, :void [flattened_tag] when :c [subtype_tag_or_class, array_fixed_size] when :array, :ghash, :glist, :gslist, :ptr_array, :zero_terminated [element_type] else [] end end private def flattened_array_type if zero_terminated? zero_terminated_array_type else array_type end end def zero_terminated_array_type case element_type when :utf8, :filename :strv else :zero_terminated end end end end end GObjectIntrospection::ITypeInfo.send :include, GirFFI::InfoExt::ITypeInfo gir_ffi-0.6.7/lib/gir_ffi/info_ext/safe_constant_name.rb0000644000004100000410000000146412224462647023341 0ustar www-datawww-datamodule GirFFI module InfoExt # Extension module provinding a #safe_name method suitable for types. module SafeConstantName def safe_name name.tr('-', '_').gsub(/^./) do |char| case char when "_" "Private___" else char.upcase end end end # FIXME: Remove leading colons. def full_type_name "::#{safe_namespace}::#{safe_name}" end end end end GObjectIntrospection::ICallbackInfo.send :include, GirFFI::InfoExt::SafeConstantName GObjectIntrospection::IConstantInfo.send :include, GirFFI::InfoExt::SafeConstantName GObjectIntrospection::IRegisteredTypeInfo.send :include, GirFFI::InfoExt::SafeConstantName GObjectIntrospection::ISignalInfo.send :include, GirFFI::InfoExt::SafeConstantName gir_ffi-0.6.7/lib/gir_ffi/info_ext/i_signal_info.rb0000644000004100000410000000420012224462647022301 0ustar www-datawww-datamodule GirFFI module InfoExt # Extensions for GObjectIntrospection::ISignalInfo needed by GirFFI # TODO: Rename methods to not include 'signal' everywhere. module ISignalInfo # Create a signal hander callback. Wraps the given block in such a way that # arguments and return value are cast correctly to the ruby world and back. # # @param block The body of the signal handler # # @return [FFI::Function] The signal handler, ready to be passed as a # callback to C. def signal_callback &block rettype = self.return_ffi_type argtypes = self.ffi_callback_argument_types raise ArgumentError, "Block needed" unless block # TODO: Find the signal module directly, then retrieve the info # from that, instead of vice versa. bldr = Builders::SignalBuilder.new(self) wrapped = bldr.build_class.from(block) FFI::Function.new rettype, argtypes, &wrapped end def signal_arguments_to_gvalue_array instance, *rest arr = ::GObject::ValueArray.new self.n_args + 1 arr.append GObject::Value.wrap_instance(instance) self.args.zip(rest).each do |info, arg| arr.append info.argument_type.make_g_value.set_value(arg) end arr end def gvalue_for_signal_return_value GObject::Value.for_g_type return_type.g_type end # TODO: Rename and clarify relation to argument_ffi_types: # The types returned by ffi_callback_argument_types are more basic than # those returned by argument_ffi_types. Is there a way to make these # methods more related? Perhaps argument_ffi_types can return more basic # types as well? def ffi_callback_argument_types types = args.map do |arg| arg.argument_type.to_callback_ffitype end types.unshift(:pointer).push(:pointer) end def return_ffi_type result = super if result == GLib::Boolean :bool else result end end end end end GObjectIntrospection::ISignalInfo.send :include, GirFFI::InfoExt::ISignalInfo gir_ffi-0.6.7/lib/gir_ffi/info_ext/safe_function_name.rb0000644000004100000410000000052712224462647023334 0ustar www-datawww-datamodule GirFFI module InfoExt # Extension module provinding a #safe_name method suitable for functions. module SafeFunctionName def safe_name name = self.name return "_" if name.empty? name end end end end GObjectIntrospection::IFunctionInfo.send :include, GirFFI::InfoExt::SafeFunctionName gir_ffi-0.6.7/lib/gir_ffi/info_ext/i_property_info.rb0000644000004100000410000000044412224462647022716 0ustar www-datawww-datamodule GirFFI module InfoExt # Extensions for GObjectIntrospection::IPropertyInfo needed by GirFFI module IPropertyInfo def getter_name name.gsub(/-/, '_') end end end end GObjectIntrospection::IPropertyInfo.send :include, GirFFI::InfoExt::IPropertyInfo gir_ffi-0.6.7/lib/gir_ffi/info_ext/i_function_info.rb0000644000004100000410000000061212224462647022654 0ustar www-datawww-datamodule GirFFI module InfoExt # Extensions for GObjectIntrospection::IFunctionInfo needed by GirFFI module IFunctionInfo def argument_ffi_types super.tap do |types| types.unshift :pointer if method? types << :pointer if throws? end end end end end GObjectIntrospection::IFunctionInfo.send :include, GirFFI::InfoExt::IFunctionInfo gir_ffi-0.6.7/lib/gir_ffi/version.rb0000644000004100000410000000004612224462647017357 0ustar www-datawww-datamodule GirFFI VERSION = "0.6.7" end gir_ffi-0.6.7/lib/gir_ffi/type_map.rb0000644000004100000410000000216012224462647017507 0ustar www-datawww-datamodule GirFFI module TypeMap sz = FFI.type_size(:size_t) * 8 gtype_type = "uint#{sz}".to_sym TAG_TYPE_MAP = { :enum => :int32, :flags => :int32, :ghash => :pointer, :glist => :pointer, :gslist => :pointer, :strv => :pointer, :object => :pointer, :struct => :pointer, :error => :pointer, :ptr_array => :pointer, :array => :pointer, :utf8 => :pointer, :GType => gtype_type, :gboolean => GLib::Boolean, :gunichar => :uint32, :gint8 => :int8, :guint8 => :uint8, :gint16 => :int16, :guint16 => :uint16, :gint => :int, :gint32 => :int32, :guint32 => :uint32, :gint64 => :int64, :guint64 => :uint64, :gfloat => :float, :gdouble => :double, :void => :void } def self.map_basic_type type sym = type.to_sym TAG_TYPE_MAP[sym] || sym end def self.type_specification_to_ffitype type case type when Module type.to_ffitype when Array type[0] else map_basic_type(type) end end end end gir_ffi-0.6.7/lib/gir_ffi/builder.rb0000644000004100000410000000205612224462647017323 0ustar www-datawww-datarequire 'gir_ffi/builders/type_builder' require 'gir_ffi/builders/module_builder' require 'gir_ffi/builder_helper' require 'gir_ffi/unintrospectable_type_info' module GirFFI # Builds modules and classes based on information found in the # introspection repository. Call its build_module and build_class methods # to create the modules and classes used in your program. module Builder extend BuilderHelper def self.build_class info Builders::TypeBuilder.build(info) end def self.build_by_gtype gtype info = GObjectIntrospection::IRepository.default.find_by_gtype gtype info ||= UnintrospectableTypeInfo.new gtype build_class info end def self.build_module namespace, version=nil Builders::ModuleBuilder.new(namespace, version).generate end # TODO: Move elsewhere, perhaps to FunctionBuilder. def self.attach_ffi_function lib, info sym = info.symbol return if lib.method_defined? sym lib.attach_function sym, info.argument_ffi_types, info.return_ffi_type end end end gir_ffi-0.6.7/lib/gir_ffi/struct_base.rb0000644000004100000410000000100112224462647020200 0ustar www-datawww-datamodule GirFFI class StructBase < ClassBase extend FFI::DataConverter def self.native_type self::Struct.native_type end def self.to_native value, context self::Struct.new(value.to_ptr) end def self.to_ffitype self end def self.copy_value_to_pointer value, pointer, offset=0 self::Struct.copy_value_to_pointer value, pointer, offset end def self.get_value_from_pointer pointer self::Struct.get_value_from_pointer pointer end end end gir_ffi-0.6.7/lib/gir_ffi/arg_helper.rb0000644000004100000410000000212412224462647020001 0ustar www-datawww-datarequire 'gir_ffi/allocation_helper' require 'gir_ffi/builder' module GirFFI module ArgHelper OBJECT_STORE = {} # @deprecated Compatibility function. Remove in 0.7.0. def self.ptr_to_utf8 ptr ptr.to_utf8 end def self.ptr_to_utf8_length ptr, len ptr.null? ? nil : ptr.read_string(len) end def self.check_error errpp err = GLib::Error.wrap(errpp.read_pointer) raise err.message if err end def self.check_fixed_array_size size, arr, name unless arr.size == size raise ArgumentError, "#{name} should have size #{size}" end end def self.cast_from_pointer type, it case type when :utf8, :filename it.to_utf8 when :gint32 cast_pointer_to_int32 it else # FIXME: Only handles symbolic types. it.address end end def self.cast_uint32_to_int32 val if val >= 0x80000000 -(0x100000000-val) else val end end def self.cast_pointer_to_int32 ptr cast_uint32_to_int32(ptr.address & 0xffffffff) end end end gir_ffi-0.6.7/lib/gir_ffi/allocation_helper.rb0000644000004100000410000000030012224462647021347 0ustar www-datawww-datarequire 'gir_ffi/lib_c' module GirFFI module AllocationHelper def self.safe_malloc size ptr = LibC.malloc size raise NoMemoryError if ptr.null? ptr end end end gir_ffi-0.6.7/lib/gir_ffi/ffi_ext.rb0000644000004100000410000000004212224462647017312 0ustar www-datawww-datarequire 'gir_ffi/ffi_ext/pointer' gir_ffi-0.6.7/lib/gir_ffi/callback_base.rb0000644000004100000410000000125412224462647020422 0ustar www-datawww-datarequire 'gir_ffi/type_base' module GirFFI module CallbackBase CALLBACKS = [] def store_callback prc CALLBACKS << prc end def self.store_callback prc CALLBACKS << prc end # Create Callback from a Proc. Makes sure arguments are properly wrapped, # and the callback is stored to prevent garbage collection. def from prc wrap_in_callback_args_mapper(prc).tap do |cb| store_callback cb end end def wrap_in_callback_args_mapper prc return prc if FFI::Function === prc return nil if prc.nil? return Proc.new do |*args| call_with_argument_mapping(prc, *args) end end end end gir_ffi-0.6.7/lib/gir_ffi/unintrospectable_type_info.rb0000644000004100000410000000161012224462647023325 0ustar www-datawww-datamodule GirFFI # Represents a type not found in the GIR, conforming, as needed, to the # interface of GObjectIntrospection::IObjectInfo. class UnintrospectableTypeInfo attr_reader :g_type def initialize(gtype, gir = GObjectIntrospection::IRepository.default, gobject = ::GObject) @g_type = gtype @gir = gir @gobject = gobject end def info_type :unintrospectable end def safe_name @gobject.type_name @g_type end def parent parent_gtype = @gobject.type_parent(@g_type) @gir.find_by_gtype(parent_gtype) || self.class.new(parent_gtype, @gir, @gobject) end def namespace parent.namespace end def interfaces @gobject.type_interfaces(@g_type).map do |gtype| @gir.find_by_gtype gtype end.compact end def fields [] end end end gir_ffi-0.6.7/lib/gir_ffi/zero_terminated.rb0000644000004100000410000000260112224462647021064 0ustar www-datawww-datamodule GirFFI # Represents a null-terminated array. class ZeroTerminated include Enumerable attr_reader :element_type def initialize elm_t, ptr @element_type = elm_t @ptr = ptr end def to_ptr @ptr end def self.from type, arg self.new type, InPointer.from_array(type, arg) end def self.wrap type, arg self.new type, arg end def each return if @ptr.null? offset = 0 while val = read_value(offset) offset += FFI.type_size(ffi_type) if complex_element_type? val = element_class.wrap val end yield val end end def ==(other) self.to_a == other.to_a end private def read_value offset val = @ptr.send("get_#{ffi_type}", offset) return val unless is_null_value(val) end def ffi_type @ffi_type ||= TypeMap.type_specification_to_ffitype basic_element_type end def complex_element_type? Array === element_type end def basic_element_type if complex_element_type? element_type.first else element_type end end def is_null_value value if basic_element_type == :pointer value.null? else value == 0 end end def element_class if complex_element_type? element_type.last end end end end gir_ffi-0.6.7/lib/gir_ffi/user_defined_property_info.rb0000644000004100000410000000052112224462647023303 0ustar www-datawww-datamodule GirFFI # Represents a property of a user defined type, conforming, as needed, to the # interface of GObjectIntrospection::IPropertyInfo. class UserDefinedPropertyInfo def initialize param_spec @param_spec = param_spec end attr_reader :param_spec def name @param_spec.get_name end end end gir_ffi-0.6.7/lib/gir_ffi/setter_argument_info.rb0000644000004100000410000000060212224462647022113 0ustar www-datawww-datamodule GirFFI # Class to represent argument info for the argument of a setter method. # Implements the necessary parts of IArgumentInfo's interface. class SetterArgumentInfo attr_reader :name, :argument_type def initialize name, type @name = name @argument_type = type end def direction :in end def skip? false end end end gir_ffi-0.6.7/lib/gir_ffi/builders/0000755000004100000410000000000012224462647017156 5ustar www-datawww-datagir_ffi-0.6.7/lib/gir_ffi/builders/null_builder.rb0000644000004100000410000000017712224462647022170 0ustar www-datawww-datamodule GirFFI class NullBuilder def find_signal _ nil end def find_property _ nil end end end gir_ffi-0.6.7/lib/gir_ffi/builders/mapping_method_builder.rb0000644000004100000410000000471412224462647024212 0ustar www-datawww-datarequire 'gir_ffi/builders/return_value_builder' module GirFFI module Builders # Implements the creation mapping method for a callback or signal # handler. This method converts arguments from C to Ruby, and the # result from Ruby to C. class MappingMethodBuilder # TODO: Make CallbackArgumentBuilder accept argument name # TODO: Fix name of #post method class CallbackArgumentBuilder < ReturnValueBuilder def post if specialized_type_tag == :enum ["#{retname} = #{argument_class_name}[#{callarg}]"] else super end end def retval if specialized_type_tag == :enum retname else super end end end def initialize argument_infos, return_type_info @argument_infos = argument_infos @return_type_info = return_type_info end attr_reader :argument_infos attr_reader :return_type_info def method_definition code = "def self.call_with_argument_mapping(#{method_arguments.join(', ')})" method_lines.each { |line| code << "\n #{line}" } code << "\nend\n" end def method_lines lines = argument_builders.map(&:post).flatten + ["#{capture}_proc.call(#{call_arguments.join(', ')})"] + return_value_builder.post lines << "return #{return_value_builder.retval}" if return_value_builder.is_relevant? lines end def capture @capture ||= return_value_builder.is_relevant? ? "#{return_value_builder.callarg} = " : "" end def call_arguments @call_arguments ||= argument_builders.map(&:retval) end def method_arguments @method_arguments ||= argument_builders.map(&:callarg).unshift('_proc') end def return_value_builder @return_value_builder ||= ReturnValueBuilder.new(vargen, return_type_info) end def argument_builders unless defined?(@argument_builders) @argument_builders = argument_infos.map {|arg| CallbackArgumentBuilder.new vargen, arg.argument_type } argument_infos.each do |arg| if (idx = arg.closure) >= 0 @argument_builders[idx].is_closure = true end end end @argument_builders end def vargen @vargen ||= GirFFI::VariableNameGenerator.new end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/callback_builder.rb0000644000004100000410000000177512224462647022757 0ustar www-datawww-datarequire 'gir_ffi/builders/base_type_builder' require 'gir_ffi/builders/mapping_method_builder' require 'gir_ffi/callback_base' module GirFFI module Builders # Implements the creation of a callback type. The type will be # attached to the appropriate namespace module, and will be defined # as a callback for FFI. class CallbackBuilder < BaseTypeBuilder def instantiate_class @klass ||= optionally_define_constant namespace_module, @classname do cb = lib.callback callback_sym, argument_types, return_type cb.instance_eval mapping_method_definition cb.extend CallbackBase cb end @klass end def mapping_method_definition MappingMethodBuilder.new(info.args, info.return_type).method_definition end def callback_sym @classname.to_sym end def argument_types @info.argument_ffi_types end def return_type @info.return_ffi_type end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/registered_type_builder.rb0000644000004100000410000000216312224462647024411 0ustar www-datawww-datarequire 'gir_ffi/builders/base_type_builder' require 'gir_ffi/class_base' module GirFFI module Builders # Base class for type builders building types specified by subtypes # of IRegisteredTypeInfo. These are types whose C representation is # complex, i.e., a struct or a union. class RegisteredTypeBuilder < BaseTypeBuilder private def target_gtype info.g_type end # TODO: Rename the created method, or use a constant. # FIXME: Only used in some of the subclases. Make mixin? def setup_gtype_getter gtype = target_gtype return if gtype.nil? @klass.instance_eval " def self.get_gtype #{gtype} end " end # FIXME: Only used in some of the subclases. Make mixin? def provide_constructor return if info.find_method 'new' (class << @klass; self; end).class_eval { alias_method :new, :_allocate } end def parent nil end def fields info.fields end def superclass ClassBase end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/signal_builder.rb0000644000004100000410000000423412224462647022471 0ustar www-datawww-datarequire 'gir_ffi/builders/base_type_builder' require 'gir_ffi/builders/mapping_method_builder' require 'gir_ffi/signal_base' module GirFFI module Builders # Implements the creation of a signal module for handling a particular # signal. The type will be attached to the appropriate class. class SignalBuilder < BaseTypeBuilder class SignalReceiverTypeInfo include InfoExt::ITypeInfo def initialize interface_info @interface_info = interface_info end def interface @interface_info end def tag :interface end end class SignalReceiverArgumentInfo attr_reader :argument_type def initialize type @argument_type = type end def closure -1 end end class UserDataTypeInfo include InfoExt::ITypeInfo def tag :void end def pointer? true end end class UserDataArgumentInfo attr_reader :argument_type attr_reader :closure def initialize type, position @argument_type = type @closure = position end end def instantiate_class @klass ||= get_or_define_module container_class, @classname unless already_set_up @klass.extend SignalBase setup_constants @klass.class_eval mapping_method_definition end @klass end def mapping_method_definition arg_infos = info.args container_type_info = SignalReceiverTypeInfo.new(container_info) arg_infos.unshift SignalReceiverArgumentInfo.new(container_type_info) user_data_type_info = UserDataTypeInfo.new user_data_argument_info = UserDataArgumentInfo.new(user_data_type_info, arg_infos.length) arg_infos.push user_data_argument_info MappingMethodBuilder.new(arg_infos, info.return_type).method_definition end def container_class @container_class ||= Builder.build_class(container_info) end def container_info @container_info ||= info.container end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/base_argument_builder.rb0000644000004100000410000000512412224462647024027 0ustar www-datawww-datamodule GirFFI # Abstract parent class of the argument building classes. These # classes are used by FunctionBuilder to create the code that # processes each argument before and after the actual function call. class BaseArgumentBuilder KEYWORDS = [ "alias", "and", "begin", "break", "case", "class", "def", "do", "else", "elsif", "end", "ensure", "false", "for", "if", "in", "module", "next", "nil", "not", "or", "redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless", "until", "when", "while", "yield" ] attr_reader :name, :retname attr_accessor :length_arg, :array_arg attr_accessor :is_closure def initialize var_gen, name, typeinfo, direction @var_gen = var_gen @typeinfo = typeinfo @direction = direction @name = safe(name) @inarg = nil @retname = nil @length_arg = nil @array_arg = nil @is_closure = false end def type_info @typeinfo end def specialized_type_tag type_info.flattened_tag end # TODO: Use class rather than class name def argument_class_name type_info.argument_class_name end def array_size if @length_arg @length_arg.retname else type_info.array_fixed_size end end def safe name if KEYWORDS.include? name "#{name}_" else name end end def inarg @array_arg.nil? ? @inarg : nil end def retval @array_arg.nil? ? retname : nil end def callarg @callarg ||= @var_gen.new_var end def pre [] end def post [] end def cleanup [] end def new_variable @var_gen.new_var end private def needs_outgoing_parameter_conversion? [ :array, :byte_array, :c, :error, :filename, :ghash, :glist, :gslist, :interface, :object, :ptr_array, :struct, :strv, :union, :utf8, :zero_terminated ].include?(specialized_type_tag) end def outgoing_conversion base args = output_conversion_arguments base case specialized_type_tag when :utf8, :filename "#{base}.to_utf8" else "#{argument_class_name}.wrap(#{args})" end end def output_conversion_arguments arg if specialized_type_tag == :c "#{type_info.subtype_tag_or_class.inspect}, #{array_size}, #{arg}" else conversion_arguments arg end end def conversion_arguments name type_info.extra_conversion_arguments.map(&:inspect).push(name).join(", ") end end end gir_ffi-0.6.7/lib/gir_ffi/builders/struct_builder.rb0000644000004100000410000000144512224462647022541 0ustar www-datawww-datarequire 'gir_ffi/builders/registered_type_builder' require 'gir_ffi/builders/with_layout' require 'gir_ffi/builders/with_methods' require 'gir_ffi/struct_base' module GirFFI module Builders # Implements the creation of a class representing a Struct. class StructBuilder < RegisteredTypeBuilder include WithMethods include WithLayout private def setup_class setup_layout setup_constants stub_methods setup_gtype_getter setup_field_accessors provide_constructor end # FIXME: Private method only in subclass def layout_superclass # FIXME: Is this needed now that StructBase is a DataConverter? GirFFI::Struct end def superclass StructBase end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/object_builder.rb0000644000004100000410000000621512224462647022463 0ustar www-datawww-datarequire 'gir_ffi/builders/registered_type_builder' require 'gir_ffi/builders/with_layout' require 'gir_ffi/builders/with_methods' require 'gir_ffi/builders/property_builder' require 'gir_ffi/object_base' module GirFFI module Builders # Implements the creation of a class representing a GObject Object. class ObjectBuilder < RegisteredTypeBuilder include WithMethods include WithLayout def find_signal signal_name signal_definers.each do |inf| sig = inf.find_signal signal_name return sig if sig end superclass.find_signal signal_name or raise "Signal #{signal_name} not found" end def find_property property_name info.find_property property_name or superclass.find_property property_name or raise "Property #{property_name} not found" end private def setup_class setup_layout setup_constants stub_methods setup_gtype_getter if info.fundamental? setup_field_accessors else setup_property_accessors end setup_vfunc_invokers setup_interfaces end # FIXME: Private method only used in subclass def layout_superclass FFI::Struct end def parent unless defined? @parent pr = info.parent if pr.nil? or (pr.safe_name == @classname and pr.namespace == @namespace) @parent = nil else @parent = pr end end @parent end def superclass @superclass ||= if parent Builder.build_class parent else ObjectBase end end # TODO: Unify with field accessor setup. def setup_property_accessors info.properties.each do |prop| setup_accessors_for_property_info prop end end def setup_accessors_for_property_info prop builder = Builder::Property.new prop unless info.find_instance_method prop.getter_name @klass.class_eval builder.getter_def end @klass.class_eval builder.setter_def end # TODO: Guard agains accidental invocation of undefined vfuncs. # TODO: Create object responsible for creating these invokers def setup_vfunc_invokers info.vfuncs.each do |vfinfo| if (invoker = vfinfo.invoker) define_vfunc_invoker vfinfo.name, invoker.name end end end def define_vfunc_invoker vfunc_name, invoker_name return if vfunc_name == invoker_name @klass.class_eval " def #{vfunc_name} *args, &block #{invoker_name}(*args, &block) end " end def setup_interfaces interfaces.each do |iface| @klass.class_eval do include iface end end end def signal_definers [info] + info.interfaces end def interfaces info.interfaces.map do |ifinfo| GirFFI::Builder.build_class ifinfo end end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/module_builder.rb0000644000004100000410000000572312224462647022505 0ustar www-datawww-datarequire 'gir_ffi/builder_helper' require 'gir_ffi/module_base' require 'gir_ffi/builders/function_builder' require 'indentation' module GirFFI module Builders # Builds a module based on information found in the introspection # repository. class ModuleBuilder include BuilderHelper def initialize namespace, version=nil @namespace = namespace @version = version # FIXME: Pass safe namespace as an argument @safe_namespace = @namespace.gsub(/^(.)/) { $1.upcase } end def generate build_module end def setup_method method go = function_introspection_data method.to_s return false if go.nil? modul = build_module Builder.attach_ffi_function libmodule, go definition = function_definition go modul.class_eval definition true end def build_namespaced_class classname info = gir.find_by_name @namespace, classname.to_s if info.nil? raise NameError.new( "Class #{classname} not found in namespace #{@namespace}") end Builder.build_class info end def build_module unless defined? @module build_dependencies instantiate_module setup_lib_for_ffi setup_module unless already_set_up end @module end private def build_dependencies deps = gir.dependencies @namespace deps.each {|dep| name, version = dep.split '-' Builder.build_module name, version } end def instantiate_module @module = get_or_define_module ::Object, @safe_namespace end def setup_module @module.extend ModuleBase @module.const_set :GIR_FFI_BUILDER, self end def already_set_up @module.respond_to? :method_missing end def setup_lib_for_ffi @lib = get_or_define_module @module, :Lib unless (class << @lib; self.include? GirFFI::Library; end) @lib.extend GirFFI::Library @lib.ffi_lib_flags :global, :lazy libspec = gir.shared_library(@namespace) unless libspec.nil? @lib.ffi_lib(*libspec.split(/,/)) end end end def sub_builder info if info.info_type == :function FunctionBuilder.new info else TypeBuilder.builder_for info end end def libmodule @module.const_get(:Lib) end def function_introspection_data function info = gir.find_by_name @namespace, function.to_s return nil if info.nil? info.info_type == :function ? info : nil end def function_definition info FunctionBuilder.new(info).generate end def gir unless defined? @gir @gir = GObjectIntrospection::IRepository.default @gir.require @namespace, @version end @gir end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/enum_builder.rb0000644000004100000410000000302312224462647022153 0ustar www-datawww-datarequire 'gir_ffi/builders/registered_type_builder' require 'gir_ffi/builders/with_methods' require 'gir_ffi/enum_base' module GirFFI module Builders # Implements the creation of an enum or flags type. The type will be # attached to the appropriate namespace module, and will be defined # as an enum for FFI. class EnumBuilder < RegisteredTypeBuilder include WithMethods private def enum_sym @classname.to_sym end def value_spec return info.values.map {|vinfo| val = GirFFI::ArgHelper.cast_uint32_to_int32(vinfo.value) [vinfo.name.to_sym, val] }.flatten end def instantiate_class @klass = get_or_define_module namespace_module, @classname @enum = optionally_define_constant @klass, :Enum do lib.enum(enum_sym, value_spec) end unless already_set_up @klass.extend superclass setup_constants setup_gtype_getter stub_methods setup_inspect end end def setup_inspect @klass.instance_eval <<-EOS def self.inspect "#{@namespace}::#{@classname}" end EOS end def already_set_up @klass.respond_to? :get_gtype end def superclass @superclass ||= EnumBase end # FIXME: Remove duplication with ModuleBuilder def get_or_define_module parent, name optionally_define_constant(parent, name) { ::Module.new } end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/constant_builder.rb0000644000004100000410000000110312224462647023035 0ustar www-datawww-datarequire 'gir_ffi/builders/base_type_builder' module GirFFI module Builders # Implements the creation of a constant. Though semantically not a # type, its build method is like that of the types, in that it is # triggered by a missing constant in the parent namespace. The # constant will be attached to the appropriate namespace module. class ConstantBuilder < BaseTypeBuilder private def instantiate_class @klass = optionally_define_constant namespace_module, @classname do info.value end end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/null_argument_builder.rb0000644000004100000410000000033212224462647024063 0ustar www-datawww-datamodule GirFFI # Argument builder that does nothing. Implements the Null Object pattern. class NullArgumentBuilder def initialize *; end def pre; []; end def post; []; end def callarg; end end end gir_ffi-0.6.7/lib/gir_ffi/builders/user_defined_builder.rb0000644000004100000410000000471312224462647023652 0ustar www-datawww-datarequire 'gir_ffi/builders/object_builder' module GirFFI module Builders # Implements the creation of GObject subclasses from Ruby. class UserDefinedBuilder < ObjectBuilder def initialize info @info = info end def instantiate_class @klass = @info.described_class parent_type = @klass.get_gtype @parent = gir.find_by_gtype(parent_type) query_result = GObject.type_query parent_type type_info = GObject::TypeInfo.new type_info.class_size = query_result.class_size type_info.instance_size = query_result.instance_size properties.each do type_info.instance_size += FFI.type_size(:int32) end @gtype = GObject.type_register_static(parent_type, @klass.name, type_info, 0) @structklass = get_or_define_class @klass, :Struct, layout_superclass setup_class unless already_set_up TypeBuilder::CACHE[@gtype] = @klass end def setup_class setup_layout setup_constants #stub_methods setup_gtype_getter setup_property_accessors #setup_vfunc_invokers #setup_interfaces setup_constructor end private def target_gtype @gtype end def parent @parent end def properties info.properties end def layout_specification parent_spec = [:parent, superclass::Struct, 0] offset = superclass::Struct.size fields_spec = properties.map do |pinfo| spec = [pinfo.name.to_sym, :int32, offset] offset += FFI.type_size(:int32) spec end.flatten(1) parent_spec + fields_spec end def setup_property_accessors properties.each do |pinfo| setup_accessors_for_param_info pinfo end end def setup_accessors_for_param_info pinfo code = <<-CODE def #{pinfo.name} @struct[:#{pinfo.name}] end def #{pinfo.name}= val @struct[:#{pinfo.name}] = val end CODE @klass.class_eval code end def method_introspection_data method nil end def setup_constructor code = <<-CODE def self.new gptr = GObject::Lib.g_object_newv #{@gtype}, 0, nil self.wrap(gptr) end CODE @klass.class_eval code end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/return_value_builder.rb0000644000004100000410000000277612224462647023740 0ustar www-datawww-datarequire 'gir_ffi/builders/base_argument_builder' module GirFFI module Builders # Implements building post-processing statements for return values. class ReturnValueBuilder < BaseArgumentBuilder def initialize var_gen, type_info, is_constructor = false, skip = false super var_gen, nil, type_info, :return @is_constructor = is_constructor @skip = skip end def post if has_conversion? [ "#{retname} = #{post_conversion}" ] else [] end end def inarg nil end def retval if has_conversion? super elsif is_relevant? callarg else nil end end def is_relevant? !is_void_return_value? && !@skip end private def has_conversion? is_closure || needs_outgoing_parameter_conversion? || needs_constructor_wrap? end def post_conversion if is_closure "GirFFI::ArgHelper::OBJECT_STORE[#{callarg}.address]" elsif needs_constructor_wrap? "self.constructor_wrap(#{callarg})" else outgoing_conversion callarg end end def retname @retname ||= @var_gen.new_var end def needs_constructor_wrap? @is_constructor && [ :interface, :object ].include?(specialized_type_tag) end def is_void_return_value? specialized_type_tag == :void && !type_info.pointer? end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/property_builder.rb0000644000004100000410000000102612224462647023074 0ustar www-datawww-datamodule GirFFI module Builder # Creates property getter and setter code for a given IPropertyInfo. class Property def initialize property_info @info = property_info end def getter_def return <<-CODE def #{@info.getter_name} get_property "#{@info.name}" end CODE end def setter_def return <<-CODE def #{@info.getter_name}= value set_property "#{@info.name}", value end CODE end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/field_builder.rb0000644000004100000410000000502312224462647022274 0ustar www-datawww-datarequire 'gir_ffi/builders/argument_builder' require 'gir_ffi/builders/return_value_builder' require 'gir_ffi/variable_name_generator' require 'gir_ffi/setter_argument_info' module GirFFI module Builders # Creates field getter and setter code for a given IFieldInfo. class FieldBuilder attr_reader :info def initialize field_info @info = field_info end def build unless container_info.find_instance_method info.name container_class.class_eval getter_def end container_class.class_eval setter_def if info.writable? end def getter_def builder = return_value_builder field_ptr = builder.new_variable typed_ptr = builder.new_variable return <<-CODE.reset_indentation def #{info.name} #{field_ptr} = @struct.to_ptr + #{info.offset} #{typed_ptr} = GirFFI::InOutPointer.new(#{field_type_tag_or_class.inspect}, #{field_ptr}) #{builder.callarg} = #{typed_ptr}.to_value #{builder.post.join("\n")} #{builder.retval} end CODE end def setter_def builder = setter_builder field_ptr = builder.new_variable typed_ptr = builder.new_variable return <<-CODE.reset_indentation def #{info.name}= #{builder.inarg} #{field_ptr} = @struct.to_ptr + #{info.offset} #{typed_ptr} = GirFFI::InOutPointer.new(#{field_type_tag_or_class.inspect}, #{field_ptr}) #{builder.pre.join("\n ")} #{typed_ptr}.set_value #{builder.callarg} end CODE end private def struct_class container_class::Struct end def field_type_tag_or_class @field_type_tag_or_class ||= info.field_type.tag_or_class end def container_class @container_class ||= container_module.const_get(container_info.safe_name) end def container_module @container_module ||= Object.const_get(container_info.safe_namespace) end def container_info @container_info ||= info.container end def field_symbol @info.name.to_sym end def return_value_builder vargen = VariableNameGenerator.new @rv_builder ||= ReturnValueBuilder.new vargen, @info.field_type end def setter_builder vargen = VariableNameGenerator.new argument_info = SetterArgumentInfo.new "value", @info.field_type ArgumentBuilder.new vargen, argument_info end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/with_methods.rb0000644000004100000410000000211612224462647022201 0ustar www-datawww-datarequire 'gir_ffi/method_stubber' module GirFFI module Builders # Implements method creation for types such as, :union, :struct, # :object, :interface. module WithMethods def setup_method method go = info.find_method method attach_and_define_method method, go, meta_class end def setup_instance_method method go = info.find_instance_method method attach_and_define_method method, go, build_class end private def meta_class klass = build_class return (class << klass; self; end) end def function_definition go FunctionBuilder.new(go).generate end def attach_and_define_method method, go, modul return false if go.nil? Builder.attach_ffi_function lib, go modul.class_eval { remove_method method } build_class.class_eval function_definition(go) true end def stub_methods info.get_methods.each do |minfo| @klass.class_eval MethodStubber.new(minfo).method_stub end end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/with_layout.rb0000644000004100000410000000254412224462647022060 0ustar www-datawww-datarequire 'gir_ffi/builders/field_builder' module GirFFI module Builders # Implements the creation of classes representing types with layout, # i.e., :union, :struct, :object. # Note: This module depends on the additional inclusion of # WithMethods. module WithLayout def layout_specification spec = base_layout_specification if spec.empty? dummy_layout_specification else spec end end private def setup_layout spec = layout_specification @structklass.class_eval { layout(*spec) } end def dummy_layout_specification if parent [:parent, superclass.const_get(:Struct), 0] else [:dummy, :char, 0] end end def base_layout_specification fields.map { |finfo| finfo.layout_specification }.flatten(1) end def setup_accessors_for_field_info finfo FieldBuilder.new(finfo).build end def setup_field_accessors fields.each do |finfo| setup_accessors_for_field_info finfo end end def instantiate_class @klass = get_or_define_class namespace_module, @classname, superclass @structklass = get_or_define_class @klass, :Struct, layout_superclass setup_class unless already_set_up end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/argument_builder.rb0000644000004100000410000000673112224462647023042 0ustar www-datawww-datarequire 'gir_ffi/builders/base_argument_builder' module GirFFI module Builders # Implements building pre- and post-processing statements for arguments. class ArgumentBuilder < BaseArgumentBuilder def initialize var_gen, arginfo super var_gen, arginfo.name, arginfo.argument_type, arginfo.direction @arginfo = arginfo end def inarg if has_input_value? && !is_array_length_parameter? @name end end def retname if has_output_value? @retname ||= @var_gen.new_var end end def pre pr = [] if has_input_value? pr << fixed_array_size_check if needs_size_check? pr << array_length_assignment if is_array_length_parameter? end pr << set_function_call_argument pr end def post if has_output_value? value = output_value ["#{retname} = #{value}"] else [] end end private def output_value if is_caller_allocated_object? callarg else base = "#{callarg}.to_value" if needs_outgoing_parameter_conversion? outgoing_conversion base else base end end end def is_array_length_parameter? @array_arg end def needs_size_check? specialized_type_tag == :c && type_info.array_fixed_size > -1 end def fixed_array_size_check size = type_info.array_fixed_size "GirFFI::ArgHelper.check_fixed_array_size #{size}, #{@name}, \"#{@name}\"" end def skipped? @arginfo.skip? || @array_arg && @array_arg.specialized_type_tag == :strv end def has_output_value? (@direction == :inout || @direction == :out) && !skipped? end def has_input_value? (@direction == :inout || @direction == :in) && !skipped? end def array_length_assignment arrname = @array_arg.name "#{@name} = #{arrname}.nil? ? 0 : #{arrname}.length" end def set_function_call_argument value = if skipped? @direction == :in ? "0" : "nil" elsif !has_input_value? if is_caller_allocated_object? if specialized_type_tag == :array "#{argument_class_name}.new #{type_info.element_type.inspect}" else "#{argument_class_name}.new" end else "GirFFI::InOutPointer.for #{type_info.tag_or_class.inspect}" end else ingoing_parameter_conversion end "#{callarg} = #{value}" end def is_caller_allocated_object? [ :struct, :array ].include?(specialized_type_tag) && @arginfo.caller_allocates? end def ingoing_parameter_conversion args = conversion_arguments @name base = case specialized_type_tag when :array, :c, :callback, :ghash, :glist, :gslist, :object, :ptr_array, :struct, :strv, :utf8, :void, :zero_terminated "#{argument_class_name}.from(#{args})" else args end if has_output_value? "GirFFI::InOutPointer.from #{type_info.tag_or_class.inspect}, #{base}" else base end end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/function_builder.rb0000644000004100000410000000656512224462647023052 0ustar www-datawww-datarequire 'gir_ffi/builders/argument_builder' require 'gir_ffi/builders/return_value_builder' require 'gir_ffi/builders/error_argument_builder' require 'gir_ffi/builders/null_argument_builder' require 'gir_ffi/variable_name_generator' module GirFFI module Builders # Implements the creation of a Ruby function definition out of a GIR # IFunctionInfo. class FunctionBuilder def initialize info @info = info end def generate vargen = GirFFI::VariableNameGenerator.new @argument_builders = @info.args.map {|arg| ArgumentBuilder.new vargen, arg } @return_value_builder = ReturnValueBuilder.new(vargen, @info.return_type, @info.constructor?, @info.skip_return?) link_array_length_arguments setup_error_argument vargen return filled_out_template end private def libmodule Object.const_get(@info.safe_namespace)::Lib end def link_array_length_arguments alldata = @argument_builders.dup << @return_value_builder alldata.each {|data| idx = data.type_info.array_length if idx > -1 other_data = @argument_builders[idx] data.length_arg = other_data other_data.array_arg = data end } end def setup_error_argument vargen klass = @info.throws? ? ErrorArgumentBuilder : NullArgumentBuilder @errarg = klass.new vargen, nil, nil, :error end def filled_out_template meta = @info.method? ? '' : "self." code = "def #{meta}#{@info.safe_name} #{method_arguments.join(', ')}\n" code << method_body code << "\nend\n" end def method_body lines = preparation << function_call << post_processing << cleanup lines << "return #{return_values.join(', ')}" if has_return_values? lines.flatten.join("\n").indent end def function_call "#{capture}#{libmodule}.#{@info.symbol} #{function_call_arguments.join(', ')}" end def method_arguments @argument_builders.map(&:inarg).compact end def function_call_arguments ca = @argument_builders.map(&:callarg) ca << @errarg.callarg ca.unshift "self" if @info.method? ca.compact end def preparation pr = @argument_builders.map(&:pre) pr << @errarg.pre pr.flatten end def capture if has_capture? "#{@return_value_builder.callarg} = " else "" end end def post_processing # FIXME: Sorting knows too much about internals of ArgumentBuilder. args = @argument_builders.sort_by {|arg| arg.type_info.array_length} args << @return_value_builder args.unshift @errarg args.map {|arg| arg.post} end def cleanup @argument_builders.map {|item| item.cleanup} end def return_values @return_values ||= ([@return_value_builder.retval] + @argument_builders.map(&:retval)).compact end def has_return_values? !return_values.empty? end def has_capture? @return_value_builder.is_relevant? end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/type_builder.rb0000644000004100000410000000221112224462647022166 0ustar www-datawww-datarequire 'gir_ffi/builders/callback_builder' require 'gir_ffi/builders/constant_builder' require 'gir_ffi/builders/enum_builder' require 'gir_ffi/builders/interface_builder' require 'gir_ffi/builders/object_builder' require 'gir_ffi/builders/struct_builder' require 'gir_ffi/builders/signal_builder' require 'gir_ffi/builders/unintrospectable_builder' require 'gir_ffi/builders/union_builder' module GirFFI module Builders # Builds a class based on information found in the introspection # repository. module TypeBuilder CACHE = {} TYPE_MAP = { :callback => CallbackBuilder, :constant => ConstantBuilder, :enum => EnumBuilder, :flags => EnumBuilder, :interface => InterfaceBuilder, :object => ObjectBuilder, :struct => StructBuilder, :union => UnionBuilder, :unintrospectable => UnintrospectableBuilder } def self.build info TYPE_MAP[info.info_type].new(info).build_class end # TODO: Pull up to include :function and :module def self.builder_for info TYPE_MAP[info.info_type].new(info) end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/base_type_builder.rb0000644000004100000410000000151712224462647023170 0ustar www-datawww-datarequire 'gir_ffi/builder_helper' module GirFFI # Base class for type builders. class BaseTypeBuilder include BuilderHelper def initialize info @info = info @namespace = @info.namespace @classname = @info.safe_name end def build_class unless defined? @klass instantiate_class end @klass end attr_reader :info private def namespace_module @namespace_module ||= Builder.build_module @namespace end def lib @lib ||= namespace_module.const_get :Lib end def setup_constants @klass.const_set :GIR_INFO, info @klass.const_set :GIR_FFI_BUILDER, self end def already_set_up const_defined_for @klass, :GIR_FFI_BUILDER end def gir @gir ||= GObjectIntrospection::IRepository.default end end end gir_ffi-0.6.7/lib/gir_ffi/builders/interface_builder.rb0000644000004100000410000000132712224462647023154 0ustar www-datawww-datarequire 'gir_ffi/builders/registered_type_builder' require 'gir_ffi/builders/with_methods' require 'gir_ffi/interface_base' module GirFFI module Builders # Implements the creation of a module representing an Interface. class InterfaceBuilder < RegisteredTypeBuilder include WithMethods private # FIXME: The word 'class' is not really correct. def instantiate_class @klass = optionally_define_constant(namespace_module, @classname) do ::Module.new end setup_module unless already_set_up end def setup_module @klass.extend InterfaceBase setup_constants stub_methods setup_gtype_getter end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/union_builder.rb0000644000004100000410000000136712224462647022350 0ustar www-datawww-datarequire 'gir_ffi/builders/registered_type_builder' require 'gir_ffi/builders/with_layout' require 'gir_ffi/builders/with_methods' require 'gir_ffi/union_base' module GirFFI module Builders # Implements the creation of a class representing union type. The # class will have a nested FFI::Union class to represent its C union. class UnionBuilder < RegisteredTypeBuilder include WithMethods include WithLayout def layout_superclass FFI::Union end private def setup_class setup_layout setup_constants stub_methods setup_gtype_getter setup_field_accessors provide_constructor end def superclass UnionBase end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/unintrospectable_builder.rb0000644000004100000410000000162612224462647024577 0ustar www-datawww-datarequire 'gir_ffi/builders/object_builder' module GirFFI module Builders # Implements the creation of a class representing an object type for # which no data is found in the GIR. Typically, these are created to # cast objects returned by a function that returns an interface. class UnintrospectableBuilder < ObjectBuilder def instantiate_class gtype = target_gtype TypeBuilder::CACHE[gtype] ||= Class.new(superclass) @klass = TypeBuilder::CACHE[gtype] @structklass = get_or_define_class @klass, :Struct, layout_superclass setup_class unless already_set_up end def setup_class setup_constants setup_layout setup_interfaces setup_gtype_getter end def setup_instance_method method false end private def signal_definers info.interfaces end end end end gir_ffi-0.6.7/lib/gir_ffi/builders/error_argument_builder.rb0000644000004100000410000000104712224462647024246 0ustar www-datawww-datarequire 'gir_ffi/builders/base_argument_builder' module GirFFI module Builders # Implements argument processing for error handling arguments. These # arguments are not part of the introspected signature, but their # presence is indicated by the 'throws' attribute of the function. class ErrorArgumentBuilder < BaseArgumentBuilder def pre [ "#{callarg} = FFI::MemoryPointer.new(:pointer).write_pointer nil" ] end def post [ "GirFFI::ArgHelper.check_error(#{callarg})" ] end end end end gir_ffi-0.6.7/lib/gir_ffi/ffi_ext/0000755000004100000410000000000012224462647016771 5ustar www-datawww-datagir_ffi-0.6.7/lib/gir_ffi/ffi_ext/pointer.rb0000644000004100000410000000133012224462647020773 0ustar www-datawww-datamodule GirFFI module FFIExt module Pointer def to_ptr self end def to_value self end def to_object gtype = GObject.type_from_instance_pointer self wrap_by_gtype gtype end def wrap_by_gtype gtype return nil if self.null? klass = Builder.build_by_gtype gtype klass.direct_wrap self end if RUBY_VERSION < "1.9" def to_utf8 null? ? nil : read_string end else def to_utf8 null? ? nil : read_string.force_encoding("utf-8") end end end end end # TODO: Move use to InPointer and InOutPointer? FFI::Pointer.send :include, GirFFI::FFIExt::Pointer gir_ffi-0.6.7/lib/gir_ffi/in_out_pointer.rb0000644000004100000410000000446012224462647020733 0ustar www-datawww-datamodule GirFFI # The InOutPointer class handles conversion between ruby types and # pointers for arguments with direction :inout and :out. # # TODO: This has now become a more general extende pointer class and should be renamed. class InOutPointer < FFI::Pointer attr_reader :value_type def initialize type, ptr = nil @value_type = type ptr ||= AllocationHelper.safe_malloc(value_type_size) super ptr end private :initialize # TODO: Create type classes that extract values from pointers. def to_value case value_ffi_type when Class value_ffi_type.get_value_from_pointer(self) # FIXME: This is a hack, since :c is not really a FFI type. Make # SizedArray a type FFI understands instead. when :c self when Symbol self.send("get_#{value_ffi_type}", 0) when FFI::Enum value_ffi_type[self.get_int32(0)] else raise NotImplementedError end end # Convert more fully to a ruby value than #to_value def to_ruby_value bare_value = to_value case value_type when :utf8 bare_value.to_utf8 when Array value_type[1].wrap bare_value when Class value_type.wrap bare_value else bare_value end end def set_value value case value_ffi_type when Class value_ffi_type.copy_value_to_pointer(value, self) # FIXME: Make SizedArray an FFI DataConverter so it conflates with the code above. when :c GLib::SizedArray.copy_value_to_pointer(value, self) when Symbol self.send "put_#{value_ffi_type}", 0, value when FFI::Enum self.send "put_int32", 0, value_ffi_type.to_native(value, nil) else raise NotImplementedError, value_ffi_type end end def clear set_value nil_value end def self.for type self.new(type).tap {|ptr| ptr.clear} end def self.from type, value self.new(type).tap {|ptr| ptr.set_value value} end private def value_ffi_type @value_ffi_type ||= TypeMap.type_specification_to_ffitype value_type end def value_type_size @value_type_size ||= FFI.type_size value_ffi_type end def nil_value value_ffi_type == :pointer ? nil : 0 end end end gir_ffi-0.6.7/lib/gir_ffi/variable_name_generator.rb0000644000004100000410000000040012224462647022517 0ustar www-datawww-datamodule GirFFI # Generates a sequence of unique variable names used in generating # function definitions. class VariableNameGenerator def initialize @varno = 0 end def new_var @varno += 1 "_v#{@varno}" end end end gir_ffi-0.6.7/lib/gir_ffi/class_base.rb0000644000004100000410000000511412224462647017772 0ustar www-datawww-datarequire 'forwardable' require 'gir_ffi/builders/null_builder' require 'gir_ffi/type_base' module GirFFI # Base class for all generated classes. Contains code for dealing with # the generated Struct classes. class ClassBase extend TypeBase # TODO: Make separate base for :struct, :union, :object. extend Forwardable def_delegators :@struct, :to_ptr GIR_FFI_BUILDER = NullBuilder.new def setup_and_call method, *arguments, &block result = self.class.ancestors.any? do |klass| klass.respond_to?(:setup_instance_method) && klass.setup_instance_method(method.to_s) end unless result raise RuntimeError, "Unable to set up instance method #{method} in #{self}" end self.send method, *arguments, &block end if RUBY_PLATFORM == 'java' # FIXME: JRuby should fix FFI::MemoryPointer#== to return true for # equivalent FFI::Pointer. def ==(other) other.class == self.class && self.to_ptr.address == other.to_ptr.address end else def ==(other) other.class == self.class && self.to_ptr == other.to_ptr end end def self.setup_and_call method, *arguments, &block result = self.ancestors.any? do |klass| klass.respond_to?(:setup_method) && klass.setup_method(method.to_s) end unless result raise RuntimeError, "Unable to set up method #{method} in #{self}" end self.send method, *arguments, &block end class << self def to_ffitype self::Struct end def setup_method name gir_ffi_builder.setup_method name end def setup_instance_method name gir_ffi_builder.setup_instance_method name end alias_method :_real_new, :new undef new # Wrap the passed pointer in an instance of the current class, or a # descendant type if applicable. def wrap ptr direct_wrap ptr end # Wrap the passed pointer in an instance of the current class. Will not # do any casting to subtypes. def direct_wrap ptr return nil if !ptr or ptr.null? obj = _real_new obj.instance_variable_set :@struct, self::Struct.new(ptr.to_ptr) obj end def _allocate obj = _real_new obj.instance_variable_set :@struct, self::Struct.new obj end # Pass-through casting method. This may become a type checking # method. It is overridden by GValue to implement wrapping of plain # Ruby objects. def from val val end end end end gir_ffi-0.6.7/lib/gir_ffi/interface_base.rb0000644000004100000410000000040012224462647020616 0ustar www-datawww-datamodule GirFFI module InterfaceBase def gir_ffi_builder self.const_get :GIR_FFI_BUILDER end def setup_instance_method name gir_ffi_builder.setup_instance_method name end def wrap ptr ptr.to_object end end end gir_ffi-0.6.7/lib/gir_ffi/method_stubber.rb0000644000004100000410000000063412224462647020703 0ustar www-datawww-datamodule GirFFI # Generates method stubs that will replace themselves with the real # method upon being called. class MethodStubber def initialize method_info @info = method_info end def method_stub symbol = @info.name " def #{@info.method? ? '' : 'self.'}#{symbol} *args, &block setup_and_call :#{symbol}, *args, &block end " end end end gir_ffi-0.6.7/lib/gir_ffi/info_ext.rb0000644000004100000410000000065512224462647017513 0ustar www-datawww-datarequire 'gir_ffi/info_ext/i_arg_info' require 'gir_ffi/info_ext/i_callable_info' require 'gir_ffi/info_ext/i_field_info' require 'gir_ffi/info_ext/i_function_info' require 'gir_ffi/info_ext/i_property_info' require 'gir_ffi/info_ext/i_registered_type_info' require 'gir_ffi/info_ext/i_signal_info' require 'gir_ffi/info_ext/i_type_info' require 'gir_ffi/info_ext/safe_constant_name' require 'gir_ffi/info_ext/safe_function_name' gir_ffi-0.6.7/lib/gir_ffi/object_base.rb0000644000004100000410000000262612224462647020140 0ustar www-datawww-datamodule GirFFI # Base class for all generated classes of type :object. class ObjectBase < ClassBase # # Wraps a pointer retrieved from a constructor method. Here, it is simply # defined as a wrapper around direct_wrap, but, e.g., InitiallyUnowned # overrides it to sink the floating object. # # Unlike wrap, this method assumes the pointer will always be of the type # corresponding to the current class, and never of a subtype. # # @param ptr Pointer to the object's C structure # # @return An object of the current class wrapping the pointer # def self.constructor_wrap ptr direct_wrap ptr end # Wrap the passed pointer in an instance of its type's corresponding class, # generally assumed to be a descendant of the current type. def self.wrap ptr ptr.to_object end # # Find property info for the named property. # # @param name The property's name # # @return [GObjectIntrospection::IPropertyInfo] The property's info # def self.find_property name gir_ffi_builder.find_property name end # # Find signal info for the named signal. # # @param name The signal's name # # @return [GObjectIntrospection::ISignalInfo] The signal's info # def self.find_signal name gir_ffi_builder.find_signal name end def self.to_ffitype :pointer end end end gir_ffi-0.6.7/lib/gir_ffi/in_pointer.rb0000644000004100000410000000575712224462647020056 0ustar www-datawww-datamodule GirFFI # The InPointer class handles conversion from ruby types to pointers for # arguments with direction :in. This is used for arguments that are # arrays, strings, or interfaces. class InPointer < FFI::Pointer def self.from_array type, ary return if !ary case type when :utf8, :filename from_utf8_array ary when :gboolean from_boolean_array ary when Symbol from_basic_type_array type, ary when Class if type == GObject::Value from_gvalue_array type, ary else from_struct_array type, ary end when Module from_enum_array type, ary when Array from_interface_pointer_array ary else raise NotImplementedError, type end end def self.from type, val return if !val case type when :utf8, :filename from_utf8 val when :gint32, :guint32, :gint8 self.new val when Module self.new type[val] when :void from_object val else raise NotImplementedError, type end end class << self # FIXME: Hideous def from_object obj return nil if obj.nil? return obj.to_ptr if obj.respond_to? :to_ptr FFI::Pointer.new(obj.object_id).tap {|ptr| ArgHelper::OBJECT_STORE[ptr.address] = obj } end private def from_utf8_array ary from_basic_type_array :pointer, ary.map {|str| from_utf8 str} end def from_boolean_array ary from_basic_type_array :int, ary.map {|val| val ? 1 : 0} end def from_interface_pointer_array ary from_basic_type_array :pointer, ary.map {|ifc| ifc.to_ptr} end def from_gvalue_array type, ary ary = ary.map do |it| if it.is_a? GObject::Value it else GObject::Value.wrap_ruby_value it end end from_struct_array type, ary end def from_struct_array type, ary type_size = type::Struct.size length = ary.length ptr = AllocationHelper.safe_malloc length * type_size ary.each_with_index do |item, idx| type.copy_value_to_pointer item, ptr, idx * type_size end new ptr end def from_enum_array type, ary from_basic_type_array :int32, ary.map {|sym| type.to_native sym, nil } end def from_utf8 str len = str.bytesize ptr = AllocationHelper.safe_malloc(len + 1).write_string(str).put_char(len, 0) new ptr end def from_basic_type_array type, ary ffi_type = TypeMap.map_basic_type type length = ary.length size = FFI.type_size ffi_type block = AllocationHelper.safe_malloc size * (length + 1) block.send "put_array_of_#{ffi_type}", 0, ary block.send("put_#{ffi_type}", length * size, (ffi_type == :pointer ? nil : 0)) new block end end end end gir_ffi-0.6.7/lib/gir_ffi/type_base.rb0000644000004100000410000000025112224462647017643 0ustar www-datawww-datamodule GirFFI module TypeBase def gir_ffi_builder self.const_get :GIR_FFI_BUILDER end def gir_info self.const_get :GIR_INFO end end end gir_ffi-0.6.7/lib/gir_ffi/lib_c.rb0000644000004100000410000000031312224462647016737 0ustar www-datawww-datarequire 'ffi' module GirFFI module LibC extend FFI::Library ffi_lib FFI::Library::LIBC attach_function :malloc, [:size_t], :pointer attach_function :free, [:pointer], :void end end gir_ffi-0.6.7/lib/gir_ffi/builder_helper.rb0000644000004100000410000000121412224462647020655 0ustar www-datawww-datamodule GirFFI module BuilderHelper def const_defined_for parent, name if RUBY_VERSION < "1.9" parent.const_defined? name else parent.const_defined? name, false end end def optionally_define_constant parent, name if const_defined_for parent, name parent.const_get name else parent.const_set name, yield end end def get_or_define_class namespace, name, parent optionally_define_constant(namespace, name) { Class.new parent } end def get_or_define_module parent, name optionally_define_constant(parent, name) { Module.new } end end end gir_ffi-0.6.7/lib/gir_ffi/signal_base.rb0000644000004100000410000000071512224462647020144 0ustar www-datawww-datarequire 'gir_ffi/type_base' module GirFFI module SignalBase include TypeBase # Create signal handler from a Proc. Makes sure arguments are properly # wrapped. def from prc wrap_in_callback_args_mapper(prc) end def wrap_in_callback_args_mapper prc return prc if FFI::Function === prc return nil if prc.nil? return Proc.new do |*args| call_with_argument_mapping(prc, *args) end end end end gir_ffi-0.6.7/lib/gir_ffi/user_defined_type_info.rb0000644000004100000410000000103112224462647022375 0ustar www-datawww-datarequire 'gir_ffi/user_defined_property_info' module GirFFI # Represents a user defined type, conforming, as needed, to the interface of # GObjectIntrospection::IObjectInfo. class UserDefinedTypeInfo def initialize klass, &block @klass = klass @properties = [] self.instance_eval(&block) if block end def described_class @klass end def install_property property @properties << UserDefinedPropertyInfo.new(property) end def properties @properties end end end gir_ffi-0.6.7/lib/gir_ffi/module_base.rb0000644000004100000410000000123212224462647020147 0ustar www-datawww-datamodule GirFFI module ModuleBase def method_missing method, *arguments, &block result = setup_method method.to_s return super unless result self.send method, *arguments, &block end def const_missing classname load_class(classname) || super end # @deprecated Compatibility function. Remove in 0.7.0. def load_class classname setup_class classname end def setup_class classname gir_ffi_builder.build_namespaced_class classname.to_s end def gir_ffi_builder self.const_get :GIR_FFI_BUILDER end def setup_method name gir_ffi_builder.setup_method name end end end gir_ffi-0.6.7/lib/ffi-gobject_introspection.rb0000644000004100000410000000006212224462647021422 0ustar www-datawww-datarequire 'ffi-gobject_introspection/i_repository' gir_ffi-0.6.7/lib/ffi-glib.rb0000644000004100000410000000253112224462647015745 0ustar www-datawww-data# NOTE: Do not require this file directly. Require 'gir_ffi' instead. # GirFFI.setup :GLib require 'ffi-glib/array' require 'ffi-glib/byte_array' require 'ffi-glib/hash_table' require 'ffi-glib/list' require 'ffi-glib/ptr_array' require 'ffi-glib/s_list' require 'ffi-glib/sized_array' require 'ffi-glib/strv' require 'ffi-glib/variant' module GLib load_class :HFunc load_class :HashFunc load_class :EqualFunc load_class :Func module Lib attach_function :g_slist_prepend, [:pointer, :pointer], :pointer attach_function :g_list_append, [:pointer, :pointer], :pointer attach_function :g_hash_table_foreach, [:pointer, HFunc, :pointer], :void attach_function :g_hash_table_new, [HashFunc, EqualFunc], :pointer attach_function :g_hash_table_insert, [:pointer, :pointer, :pointer], :void attach_function :g_byte_array_new, [], :pointer attach_function :g_byte_array_append, [:pointer, :pointer, :uint], :pointer attach_function :g_array_new, [:int, :int, :uint], :pointer attach_function :g_array_append_vals, [:pointer, :pointer, :uint], :pointer attach_function :g_array_get_element_size, [:pointer], :uint attach_function :g_ptr_array_new, [], :pointer attach_function :g_ptr_array_add, [:pointer, :pointer], :void attach_function :g_ptr_array_foreach, [:pointer, Func, :pointer], :pointer end end gir_ffi-0.6.7/lib/ffi-gobject/0000755000004100000410000000000012224462647016117 5ustar www-datawww-datagir_ffi-0.6.7/lib/ffi-gobject/ruby_closure.rb0000644000004100000410000000243512224462647021165 0ustar www-datawww-datarequire 'ffi-gobject/closure' module GObject # This class encapsulates Ruby # blocks as GObject Closures. class RubyClosure < Closure BLOCK_STORE = {} # Extend the standard GClosure layout with a field block_id to store # the object_id of the associated block. class Struct < FFI::Struct layout :parent, Closure::Struct, 0, :block_id, :int64 end def block BLOCK_STORE[@struct[:block_id]] end def block= block id = block.object_id BLOCK_STORE[id] = block @struct[:block_id] = id end def invoke_block *args block.call(*args) end def self.new &block raise ArgumentError unless block_given? closure = wrap(new_simple(self::Struct.size, nil).to_ptr) closure.block = block closure.set_marshal Proc.new {|*args| marshaller(*args)} return closure end def self.marshaller(closure, return_value, n_param_values, param_values, _invocation_hint, _marshal_data) rclosure = wrap(closure.to_ptr) args = n_param_values.times.map {|idx| Value.wrap(param_values.to_ptr + idx * Value::Struct.size).get_value } result = rclosure.invoke_block(*args) return_value.set_ruby_value(result) if return_value end end end gir_ffi-0.6.7/lib/ffi-gobject/base.rb0000644000004100000410000000167512224462647017367 0ustar www-datawww-datamodule GObject TYPE_INVALID = type_from_name("invalid") TYPE_NONE = type_from_name("void") TYPE_INTERFACE = type_from_name("GInterface") TYPE_CHAR = type_from_name("gchar") TYPE_UCHAR = type_from_name("guchar") TYPE_BOOLEAN = type_from_name("gboolean") TYPE_INT = type_from_name("gint") TYPE_UINT = type_from_name("guint") TYPE_LONG = type_from_name("glong") TYPE_ULONG = type_from_name("gulong") TYPE_INT64 = type_from_name("gint64") TYPE_UINT64 = type_from_name("guint64") TYPE_ENUM = type_from_name("GEnum") TYPE_FLAGS = type_from_name("GFlags") TYPE_FLOAT = type_from_name("gfloat") TYPE_DOUBLE = type_from_name("gdouble") TYPE_STRING = type_from_name("gchararray") TYPE_POINTER = type_from_name("gpointer") TYPE_BOXED = type_from_name("GBoxed") TYPE_PARAM = type_from_name("GParam") TYPE_OBJECT = type_from_name("GObject") TYPE_GTYPE = type_from_name("GType") TYPE_VARIANT = type_from_name("GVariant") end gir_ffi-0.6.7/lib/ffi-gobject/value.rb0000644000004100000410000001016112224462647017557 0ustar www-datawww-datamodule GObject load_class :Value # Overrides for GValue, GObject's generic value container structure. class Value # TODO: Give more generic name def set_ruby_value val if current_gtype == 0 init_for_ruby_value val end set_value val end TYPE_TO_SET_METHOD_MAP = { TYPE_BOOLEAN => :set_boolean, TYPE_BOXED => :set_boxed, TYPE_CHAR => :set_char, TYPE_DOUBLE => :set_double, TYPE_ENUM => :set_enum, TYPE_FLOAT => :set_float, TYPE_GTYPE => :set_gtype, TYPE_INT64 => :set_int64, TYPE_INT => :set_int, TYPE_LONG => :set_long, TYPE_OBJECT => :set_instance_enhanced, TYPE_PARAM => :set_param, TYPE_POINTER => :set_pointer, TYPE_STRING => :set_string, TYPE_UCHAR => :set_uchar, TYPE_UINT => :set_uint, TYPE_UINT64 => :set_uint64, TYPE_ULONG => :set_ulong, TYPE_VARIANT => :set_variant, } def value= val set_value val end def set_value val send set_method, val self end CLASS_TO_GTYPE_MAP = { true => TYPE_BOOLEAN, false => TYPE_BOOLEAN, Integer => TYPE_INT, String => TYPE_STRING } def init_for_ruby_value val CLASS_TO_GTYPE_MAP.each do |klass, type| if klass === val init type return self end end raise "Can't handle #{val.class}" end def current_gtype @struct[:g_type] end def current_fundamental_type GObject.type_fundamental current_gtype end def current_gtype_name GObject.type_name current_gtype end TYPE_TO_GET_METHOD_MAP = { TYPE_BOOLEAN => :get_boolean, TYPE_BOXED => :get_boxed, TYPE_CHAR => :get_char, TYPE_DOUBLE => :get_double, TYPE_FLOAT => :get_float, TYPE_GTYPE => :get_gtype, TYPE_INT64 => :get_int64, TYPE_INT => :get_int, TYPE_LONG => :get_long, TYPE_OBJECT => :get_object, TYPE_POINTER => :get_pointer, TYPE_STRING => :get_string, TYPE_UCHAR => :get_uchar, TYPE_UINT => :get_uint, TYPE_UINT64 => :get_uint64, TYPE_ULONG => :get_ulong, TYPE_VARIANT => :get_variant, } def get_value value = get_value_plain if current_fundamental_type == TYPE_BOXED wrap_boxed value else value end end def get_value_plain send get_method end # @deprecated Compatibility function. Remove in 0.7.0. def ruby_value get_value end class << self # TODO: Give more generic name def wrap_ruby_value val self.new.set_ruby_value val end def from val case val when self val when nil nil else wrap_ruby_value val end end def for_g_type g_type return nil if g_type == TYPE_NONE self.new.tap {|it| it.init g_type } end end # TODO: Combine with wrap_ruby_value def self.wrap_instance instance self.new.tap {|it| it.init GObject.type_from_instance instance it.set_instance instance } end private def set_instance_enhanced val check_type_compatibility val if val set_instance val end def check_type_compatibility val if !GObject::Value.type_compatible(GObject.type_from_instance(val), current_gtype) raise ArgumentError, "#{val.class} is incompatible with #{current_gtype_name}" end end def wrap_boxed boxed case current_gtype when TYPE_STRV GLib::Strv.wrap boxed when TYPE_HASH_TABLE GLib::HashTable.wrap [:gpointer, :gpointer], boxed else boxed.wrap_by_gtype current_gtype end end def get_method TYPE_TO_GET_METHOD_MAP[current_gtype] or TYPE_TO_GET_METHOD_MAP[current_fundamental_type] or raise "Can't find method to get #{current_gtype_name}" end def set_method TYPE_TO_SET_METHOD_MAP[current_gtype] or TYPE_TO_SET_METHOD_MAP[current_fundamental_type] or raise "Can't find method to set #{current_gtype_name}" end end end gir_ffi-0.6.7/lib/ffi-gobject/initially_unowned.rb0000644000004100000410000000044312224462647022202 0ustar www-datawww-datamodule GObject load_class :InitiallyUnowned # Overrides for GInitiallyUnowned, GObject's base class for objects that # start with a floating reference. class InitiallyUnowned def self.constructor_wrap ptr super.tap {|obj| ::GObject.object_ref_sink obj} end end end gir_ffi-0.6.7/lib/ffi-gobject/closure.rb0000644000004100000410000000041712224462647020122 0ustar www-datawww-datamodule GObject load_class :Closure # Overrides for GClosure, GObject's base class for closure objects. class Closure def set_marshal marshal callback = GObject::ClosureMarshal.from marshal Lib.g_closure_set_marshal self, callback end end end gir_ffi-0.6.7/lib/ffi-gobject/object.rb0000644000004100000410000000425212224462647017715 0ustar www-datawww-datamodule GObject load_class :Object # Overrides for GObject, GObject's generic base class. class Object setup_method "new" # TODO: Generate accessor methods from GIR at class definition time def method_missing(method, *args) if respond_to?("get_#{method}") return send("get_#{method}", *args) end if method.to_s =~ /(.*)=$/ && respond_to?("set_#{$1}") return send("set_#{$1}", *args) end super end def signal_connect(event, &block) GObject.signal_connect(self, event, &block) end setup_instance_method "get_property" setup_instance_method "set_property" def get_property_with_override property_name type_info = get_property_type property_name pspec = type_class.find_property property_name gvalue = GObject::Value.for_g_type pspec.value_type get_property_without_override property_name, gvalue case type_info.tag when :ghash, :glist adjust_value_to_type gvalue.get_value_plain, type_info else gvalue.get_value end end def set_property_with_override property_name, value type_info = get_property_type property_name pspec = type_class.find_property property_name gvalue = GObject::Value.for_g_type pspec.value_type gvalue.set_value adjust_value_to_type(value, type_info) set_property_without_override property_name, gvalue end def type_class GObject::ObjectClass.wrap(self.to_ptr.get_pointer 0) end alias get_property_without_override get_property alias get_property get_property_with_override alias set_property_without_override set_property alias set_property set_property_with_override private def get_property_type property_name prop = self.class.find_property property_name prop.property_type end # TODO: Move to ITypeInfo def adjust_value_to_type val, type_info case type_info.flattened_tag when :ghash GLib::HashTable.from type_info.element_type, val when :glist GLib::List.from type_info.element_type, val when :strv GLib::Strv.from val else val end end end end gir_ffi-0.6.7/lib/gir_ffi.rb0000644000004100000410000000130012224462647015664 0ustar www-datawww-datarequire 'ffi' require 'gir_ffi-base' require 'ffi-gobject_introspection' require 'gir_ffi/ffi_ext' require 'gir_ffi/class_base' require 'gir_ffi/type_map' require 'gir_ffi/info_ext' require 'gir_ffi/in_pointer' require 'gir_ffi/in_out_pointer' require 'gir_ffi/zero_terminated' require 'gir_ffi/arg_helper' require 'gir_ffi/builder' module GirFFI def self.setup module_name, version=nil module_name = module_name.to_s GirFFI::Builder.build_module module_name, version end def self.define_type klass, &block info = UserDefinedTypeInfo.new(klass, &block) Builders::UserDefinedBuilder.new(info).build_class klass.get_gtype end end require 'ffi-glib' require 'ffi-gobject' gir_ffi-0.6.7/lib/ffi-glib/0000755000004100000410000000000012224462647015417 5ustar www-datawww-datagir_ffi-0.6.7/lib/ffi-glib/sized_array.rb0000644000004100000410000000403112224462647020256 0ustar www-datawww-data# FIXME: SizedArray does not really belong in GLib, does it? module GLib # Class representing an array with a determined size class SizedArray include Enumerable attr_reader :element_type, :size def initialize element_type, size, pointer @element_type = element_type @size = size @pointer = pointer end def to_ptr @pointer end def index idx ptr = GirFFI::InOutPointer.new element_type, @pointer + idx * element_size ptr.to_ruby_value end def each &block size.times do |idx| yield index(idx) end end def ==(other) self.to_a == other.to_a end def size_in_bytes size * element_size end def self.copy_value_to_pointer value, pointer size = value.size_in_bytes pointer.put_bytes(0, value.to_ptr.read_bytes(size), 0, size) end private def element_ffi_type @element_ffi_type ||= GirFFI::TypeMap.type_specification_to_ffitype element_type end def element_size @element_size ||= FFI.type_size element_ffi_type end def self.wrap element_type, size, pointer new element_type, size, pointer unless pointer.null? end class << self def from element_type, size, item return unless item case item when FFI::Pointer wrap element_type, size, item when self from_sized_array size, item else from_enumerable element_type, size, item end end private def from_sized_array size, sized_array check_size(size, sized_array.size) sized_array end def from_enumerable element_type, size, arr check_size(size, arr.size) ptr = GirFFI::InPointer.from_array element_type, arr self.wrap element_type, arr.size, ptr end def check_size(expected_size, size) if expected_size > 0 && size != expected_size raise ArgumentError, "Expected size #{expected_size}, got #{size}" end end end end end gir_ffi-0.6.7/lib/ffi-glib/variant.rb0000644000004100000410000000051412224462647017410 0ustar www-datawww-datamodule GLib load_class :Variant # Overrides for GVariant, GLib's variant data type. class Variant setup_instance_method "get_string" def get_string_with_override get_string_without_override.first end alias get_string_without_override get_string alias get_string get_string_with_override end end gir_ffi-0.6.7/lib/ffi-glib/byte_array.rb0000644000004100000410000000100612224462647020102 0ustar www-datawww-datamodule GLib load_class :ByteArray # Overrides for GByteArray, GLib's automatically growing array of bytes. class ByteArray def to_string GirFFI::ArgHelper.ptr_to_utf8_length @struct[:data], @struct[:len] end def append data bytes = GirFFI::InPointer.from :utf8, data len = data.bytesize self.class.wrap(Lib.g_byte_array_append self.to_ptr, bytes, len) end class << self undef :new def new wrap(Lib.g_byte_array_new) end end end end gir_ffi-0.6.7/lib/ffi-glib/strv.rb0000644000004100000410000000071612224462647016746 0ustar www-datawww-datamodule GLib # Extra methods for GLib::Strv. The bulk is defined in `gir_ffi-base/glib/strv.rb` class Strv def ==(other) self.to_a == other.to_a end def self.from it case it when nil nil when FFI::Pointer wrap it when self it else from_enumerable it end end def self.from_enumerable enum self.wrap GirFFI::InPointer.from_array :utf8, enum end end end gir_ffi-0.6.7/lib/ffi-glib/hash_table.rb0000644000004100000410000000364412224462647020045 0ustar www-datawww-datarequire 'ffi-glib/container_class_methods' module GLib load_class :HashTable # Overrides for GHashTable, GLib's hash table implementation. class HashTable include Enumerable extend ContainerClassMethods attr_reader :key_type attr_reader :value_type def each prc = Proc.new {|keyptr, valptr, userdata| key = GirFFI::ArgHelper.cast_from_pointer key_type, keyptr val = GirFFI::ArgHelper.cast_from_pointer value_type, valptr yield key, val } ::GLib::Lib.g_hash_table_foreach self.to_ptr, prc, nil end def to_hash Hash[self.to_a] end def insert key, value keyptr = GirFFI::InPointer.from key_type, key valptr = GirFFI::InPointer.from value_type, value ::GLib::Lib.g_hash_table_insert self.to_ptr, keyptr, valptr end class << self remove_method :new end def self.new keytype, valtype wrap [keytype, valtype], Lib.g_hash_table_new( hash_function_for(keytype), equality_function_for(keytype)) end def reset_typespec typespec @key_type, @value_type = *typespec self end def self.from_enumerable typespec, hash ghash = self.new(*typespec) hash.each do |key, val| ghash.insert key, val end ghash end def self.hash_function_for keytype case keytype when :utf8 FFI::Function.new(:uint, [:pointer], find_support_function("g_str_hash")) else nil end end def self.equality_function_for keytype case keytype when :utf8 FFI::Function.new(:int, [:pointer, :pointer], find_support_function("g_str_equal")) else nil end end def self.find_support_function name lib = ::GLib::Lib.ffi_libraries.first lib.find_function(name) end end end gir_ffi-0.6.7/lib/ffi-glib/ptr_array.rb0000644000004100000410000000270112224462647017747 0ustar www-datawww-datamodule GLib load_class :PtrArray # Overrides for GPtrArray, GLib's automatically growing array of # pointers. class PtrArray include Enumerable attr_accessor :element_type POINTER_SIZE = FFI.type_size(:pointer) class << self remove_method :new # Remove stub generated by builder. remove_method :add if method_defined? :add end def self.new type wrap(type, Lib.g_ptr_array_new) end def self.wrap type, ptr super(ptr).tap {|it| it.element_type = type} end def self.from type, it case it when self then it when FFI::Pointer then wrap type, it else self.new(type).tap {|arr| arr.add_array it} end end def self.add array, data array.add data end def add data ptr = GirFFI::InPointer.from element_type, data Lib.g_ptr_array_add self, ptr end def add_array ary ary.each {|item| add item} end # Re-implementation of the g_ptr_array_index macro def index idx if idx >= length or idx < 0 raise IndexError, "Index #{idx} outside of bounds 0..#{length - 1}" end ptr = GirFFI::InOutPointer.new element_type, @struct[:pdata] + idx * POINTER_SIZE ptr.to_ruby_value end def each length.times do |idx| yield index(idx) end end def length @struct[:len] end def ==(other) self.to_a == other.to_a end end end gir_ffi-0.6.7/lib/ffi-glib/array.rb0000644000004100000410000000421012224462647017057 0ustar www-datawww-datamodule GLib load_class :Array # Overrides for GArray, GLib's automatically growing array. It should not # be necessary to create objects of this class from Ruby directly. class Array include Enumerable attr_reader :element_type def element_type= val @element_type = val check_element_size_match end class << self undef :new def new type ptr = Lib.g_array_new(0, 0, calculated_element_size(type)) wrap type, ptr end end def append_vals ary bytes = GirFFI::InPointer.from_array element_type, ary Lib.g_array_append_vals(self, bytes, ary.length) self end # Re-implementation of the g_array_index macro def index idx if idx >= length or idx < 0 raise IndexError, "Index #{idx} outside of bounds 0..#{length - 1}" end ptr = GirFFI::InOutPointer.new element_type, data_ptr + idx * get_element_size ptr.to_ruby_value end def each length.times do |idx| yield index(idx) end end def length @struct[:len] end def data_ptr @struct[:data] end undef :data # @deprecated From 0.7.0, data will return the actual data as a string, # as generated by GirFFI. alias data data_ptr def get_element_size Lib.g_array_get_element_size self end def ==(other) self.to_a == other.to_a end def self.wrap elmttype, ptr super(ptr).tap do |array| array.element_type = elmttype if array end end def self.from elmtype, it case it when self then it when FFI::Pointer then wrap elmtype, it else self.new(elmtype).tap {|arr| arr.append_vals it } end end private def self.calculated_element_size type ffi_type = GirFFI::TypeMap.type_specification_to_ffitype(type) FFI.type_size(ffi_type) end def calculated_element_size self.class.calculated_element_size self.element_type end def check_element_size_match unless calculated_element_size == self.get_element_size warn "WARNING: Element sizes do not match" end end end end gir_ffi-0.6.7/lib/ffi-glib/container_class_methods.rb0000644000004100000410000000065012224462647022637 0ustar www-datawww-datamodule GLib module ContainerClassMethods def wrap typespec, ptr super(ptr).tap do |container| container.reset_typespec typespec if container end end def from typespec, it case it when nil nil when FFI::Pointer wrap typespec, it when self it.reset_typespec typespec else from_enumerable typespec, it end end end end gir_ffi-0.6.7/lib/ffi-glib/list.rb0000644000004100000410000000132712224462647016722 0ustar www-datawww-datarequire 'ffi-glib/list_methods' module GLib load_class :List # Overrides for GList, GLib's doubly linked list implementation. class List include ListMethods class << self remove_method :new end def self.new type _real_new.tap do |it| struct = self::Struct.new(FFI::Pointer.new(0)) it.instance_variable_set :@struct, struct it.element_type = type end end def self.from_enumerable type, arr arr.inject(self.new type) { |lst, val| lst.append val } end def append data elm_t = element_type data_ptr = GirFFI::InPointer.from(elm_t, data) self.class.wrap(elm_t, Lib.g_list_append(self, data_ptr)) end end end gir_ffi-0.6.7/lib/ffi-glib/list_methods.rb0000644000004100000410000000211412224462647020440 0ustar www-datawww-datarequire 'ffi-glib/container_class_methods' module GLib module ListMethods include Enumerable attr_accessor :element_type def self.included base base.extend ContainerClassMethods # Override default field accessors. replace_method base, :next, :tail replace_method base, :data, :head end def self.replace_method base, old, new base.class_eval do remove_method old alias_method old, new end end def each reset_iterator while (elem = next_element) yield elem end end def tail self.class.wrap(element_type, @struct[:next]) end def head GirFFI::ArgHelper.cast_from_pointer(element_type, @struct[:data]) end def reset_typespec typespec self.element_type = typespec self end def ==(other) self.to_a == other.to_a end private def reset_iterator @current = self end def next_element return if !@current element = @current.head @current = @current.tail element end end end gir_ffi-0.6.7/lib/ffi-glib/s_list.rb0000644000004100000410000000134612224462647017245 0ustar www-datawww-datarequire 'ffi-glib/list_methods' module GLib load_class :SList # Overrides for GSList, GLib's singly-linked list implementation. class SList include ListMethods class << self remove_method :new end def self.new type _real_new.tap do |it| struct = self::Struct.new(FFI::Pointer.new(0)) it.instance_variable_set :@struct, struct it.element_type = type end end def self.from_enumerable type, arr arr.reverse.inject(self.new type) { |lst, val| lst.prepend val } end def prepend data elm_t = element_type data_ptr = GirFFI::InPointer.from(elm_t, data) self.class.wrap(elm_t, Lib.g_slist_prepend(self, data_ptr)) end end end