gir_ffi 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +7 -0
- data/{README.rdoc → README.md} +31 -25
- data/Rakefile +1 -1
- data/TODO.rdoc +1 -1
- data/lib/ffi-glib.rb +5 -5
- data/lib/ffi-glib/container_class_methods.rb +1 -2
- data/lib/ffi-glib/list_methods.rb +16 -6
- data/lib/ffi-gobject.rb +4 -7
- data/lib/ffi-gobject/helper.rb +6 -6
- data/lib/ffi-gobject/object.rb +4 -4
- data/lib/ffi-gobject_introspection.rb +0 -1
- data/lib/ffi-gobject_introspection/g_error.rb +15 -5
- data/lib/ffi-gobject_introspection/i_base_info.rb +7 -4
- data/lib/ffi-gobject_introspection/i_function_info.rb +3 -1
- data/lib/ffi-gobject_introspection/i_repository.rb +8 -15
- data/lib/ffi-gobject_introspection/i_struct_info.rb +5 -10
- data/lib/gir_ffi-base.rb +2 -0
- data/lib/gir_ffi-base/glib/strv.rb +43 -0
- data/lib/{ffi-gobject_introspection/gobject_lib.rb → gir_ffi-base/gobject/lib.rb} +4 -2
- data/lib/gir_ffi/arg_helper.rb +4 -2
- data/lib/gir_ffi/builder.rb +1 -7
- data/lib/gir_ffi/builder/argument.rb +34 -108
- data/lib/gir_ffi/builder/argument/base.rb +26 -20
- data/lib/gir_ffi/builder/type/object.rb +14 -2
- data/lib/gir_ffi/builder/type/registered_type.rb +1 -11
- data/lib/gir_ffi/class_base.rb +21 -26
- data/lib/gir_ffi/in_pointer.rb +11 -5
- data/lib/gir_ffi/info_ext/i_type_info.rb +26 -0
- data/lib/gir_ffi/interface_base.rb +10 -0
- data/lib/gir_ffi/module_base.rb +14 -4
- data/lib/gir_ffi/object_base.rb +39 -0
- data/lib/gir_ffi/type_map.rb +1 -3
- data/lib/gir_ffi/version.rb +1 -1
- data/tasks/test.rake +33 -44
- data/test/{test_helper.rb → base_test_helper.rb} +2 -11
- data/test/ffi-glib/array_test.rb +1 -1
- data/test/ffi-glib/byte_array_test.rb +1 -1
- data/test/ffi-glib/hash_table_test.rb +30 -1
- data/test/ffi-glib/list_test.rb +1 -1
- data/test/ffi-glib/ptr_array_test.rb +1 -1
- data/test/ffi-glib/ruby_closure_test.rb +54 -0
- data/test/ffi-glib/s_list_test.rb +1 -1
- data/test/ffi-gobject/gobject_test.rb +1 -1
- data/test/ffi-gobject/helper_test.rb +103 -0
- data/test/ffi-gobject/object_class_test.rb +1 -1
- data/test/ffi-gobject/object_test.rb +1 -1
- data/test/ffi-gobject/ruby_style_test.rb +1 -1
- data/test/ffi-gobject/value_test.rb +1 -1
- data/test/ffi-gobject_introspection/i_base_info_test.rb +1 -1
- data/test/ffi-gobject_introspection/i_constant_info_test.rb +1 -1
- data/test/ffi-gobject_introspection/i_function_info_test.rb +1 -1
- data/test/ffi-gobject_introspection/i_object_info_test.rb +1 -1
- data/test/ffi-gobject_introspection/i_repository_test.rb +1 -1
- data/test/ffi-gobject_introspection/lib_test.rb +1 -1
- data/test/ffi-gobject_test.rb +120 -0
- data/test/{ffi-glib → gir_ffi-base/glib}/strv_test.rb +8 -5
- data/test/{unit → gir_ffi}/arg_helper_test.rb +2 -2
- data/test/{unit/argument_builder_test.rb → gir_ffi/builder/argument/base_test.rb} +1 -13
- data/test/{unit/function_builder_test.rb → gir_ffi/builder/function_test.rb} +2 -2
- data/test/{unit/module_builder_test.rb → gir_ffi/builder/module_test.rb} +1 -1
- data/test/{unit/callback_builder_test.rb → gir_ffi/builder/type/callback_test.rb} +1 -1
- data/test/{unit/constant_builder_test.rb → gir_ffi/builder/type/constant_test.rb} +1 -1
- data/test/{unit/enum_builder_test.rb → gir_ffi/builder/type/enum_test.rb} +1 -1
- data/test/{unit/interface_builder_test.rb → gir_ffi/builder/type/interface_test.rb} +1 -4
- data/test/{unit/object_type_builder_test.rb → gir_ffi/builder/type/object_test.rb} +21 -2
- data/test/{unit/struct_builder_test.rb → gir_ffi/builder/type/struct_test.rb} +1 -1
- data/test/{unit/unintrospectable_type_builder_test.rb → gir_ffi/builder/type/unintrospectable_test.rb} +1 -1
- data/test/{unit/union_builder_test.rb → gir_ffi/builder/type/union_test.rb} +9 -3
- data/test/{unit/user_defined_type_builder_test.rb → gir_ffi/builder/type/user_defined_test.rb} +4 -2
- data/test/gir_ffi/builder_test.rb +398 -0
- data/test/{unit → gir_ffi}/callback_helper_test.rb +1 -1
- data/test/{unit → gir_ffi}/class_base_test.rb +1 -1
- data/test/{unit → gir_ffi}/in_out_pointer_test.rb +1 -1
- data/test/{unit → gir_ffi}/in_pointer_test.rb +24 -3
- data/test/{unit → gir_ffi/info_ext}/i_field_info_test.rb +1 -1
- data/test/gir_ffi/info_ext/i_type_info_test.rb +71 -0
- data/test/{unit/user_defined_object_info_test.rb → gir_ffi/user_defined/i_object_info_test.rb} +1 -1
- data/test/{unit/user_defined_property_info_test.rb → gir_ffi/user_defined/i_property_info_test.rb} +1 -1
- data/test/{unit/user_defined_registered_type_info_test.rb → gir_ffi/user_defined/i_registered_type_info_test.rb} +1 -1
- data/test/{unit → gir_ffi}/variable_name_generator_test.rb +1 -1
- data/test/{unit/gir_ffi_test.rb → gir_ffi_test.rb} +24 -4
- data/test/gir_ffi_test_helper.rb +1 -1
- data/test/integration/derived_classes_test.rb +1 -1
- data/test/integration/generated_gimarshallingtests_test.rb +1 -1
- data/test/integration/generated_gio_test.rb +1 -1
- data/test/integration/generated_gobject_test.rb +1 -1
- data/test/integration/generated_regress_test.rb +2 -3
- data/test/integration/method_lookup_test.rb +1 -1
- data/test/integration/pretty_print_test.rb +1 -1
- data/test/introspection_test_helper.rb +11 -0
- metadata +71 -77
- data/lib/ffi-glib/strv.rb +0 -31
- data/test/builder_test.rb +0 -264
- data/test/ffi-glib/glib_overrides_test.rb +0 -38
- data/test/ffi-gobject/g_object_overrides_test.rb +0 -274
- data/test/girffi_test.rb +0 -27
- data/test/integration/generated_pango_test.rb +0 -20
- data/test/type_builder_test.rb +0 -36
- data/test/unit/builder_test.rb +0 -143
- data/test/unit/hash_table_element_type_provider_test.rb +0 -16
- data/test/unit/i_type_info_test.rb +0 -23
- data/test/unit/list_element_type_provider_test.rb +0 -13
data/History.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
== 0.4.1 / 2012-09-18
|
2
|
+
|
3
|
+
* Remove workarounds for older versions of gobject-introspection
|
4
|
+
* Mark certain methods as deprecated. These will be removed in 0.5.0
|
5
|
+
* Handle :filename type arguments in InPointer
|
6
|
+
* Refactoring
|
7
|
+
|
1
8
|
== 0.4.0 / 2012-08-24
|
2
9
|
|
3
10
|
* Move Gtk+ bindings to their own gem (gir_ffi-gtk).
|
data/{README.rdoc → README.md}
RENAMED
@@ -1,16 +1,14 @@
|
|
1
|
-
|
1
|
+
# GirFFI
|
2
2
|
|
3
3
|
by Matijs van Zuijlen
|
4
4
|
|
5
|
-
|
5
|
+
[![Build Status](https://secure.travis-ci.org/mvz/ruby-gir-ffi.png)](http://travis-ci.org/mvz/ruby-gir-ffi)
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
== Description
|
7
|
+
## Description
|
10
8
|
|
11
9
|
Ruby bindings for GNOME using the GObject Introspection Repository.
|
12
10
|
|
13
|
-
|
11
|
+
## Features/Notes
|
14
12
|
|
15
13
|
* Create bindings to any GObject-based library.
|
16
14
|
* Bindings generated at runtime.
|
@@ -18,40 +16,48 @@ Ruby bindings for GNOME using the GObject Introspection Repository.
|
|
18
16
|
* Install 'gir_ffi-gtk' and require 'gir_ffi-gtk2' or 'gir_ffi-gtk3' to
|
19
17
|
load overrides for Gtk2 or Gtk3.
|
20
18
|
|
21
|
-
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
require 'gir_ffi'
|
22
22
|
|
23
|
-
|
23
|
+
GirFFI.setup :TheNamespace
|
24
24
|
|
25
|
-
|
25
|
+
TheNamespace.some_function
|
26
26
|
|
27
|
-
|
27
|
+
obj = TheNamespace::SomeClass.new
|
28
|
+
obj.some_method with, some, args
|
28
29
|
|
29
|
-
|
30
|
+
## Install
|
30
31
|
|
31
|
-
|
32
|
+
gem install gir_ffi
|
32
33
|
|
33
|
-
|
34
|
-
obj.some_method with, some, args
|
34
|
+
## Requirements
|
35
35
|
|
36
|
-
|
36
|
+
GirFFI should work on MRI 1.8 and 1.9, and JRuby in both 1.8 and 1.9
|
37
|
+
modes. It does not work on Rubinius yet.
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
* The `rr` and `minitest` gems for testing
|
39
|
+
You will also need gobject-introspection installed with some
|
40
|
+
introspection data.
|
41
41
|
|
42
42
|
Depending on the GIR data, GirFFI needs the actual libraries to be
|
43
43
|
available under the name ending in plain `.so`. If GirFFI complains that it
|
44
44
|
cannot find the library, try installing development packages for those
|
45
45
|
libraries.
|
46
46
|
|
47
|
+
GirFFI is developed on Debian sid, and tested through Travis CI on Ubuntu
|
48
|
+
12.04. Older versions of gobject-introspection than the ones used there
|
49
|
+
are therefore not officially supported (although they may work).
|
50
|
+
|
47
51
|
On Debian and Ubuntu, installing `libgirepository1.0-dev` and
|
48
|
-
`gobject-introspection`
|
49
|
-
|
52
|
+
`gobject-introspection` should be enough to get `rake test` working.
|
53
|
+
|
54
|
+
GirFFI has not been tested on Mac OS X or Microsoft Windows. YMMV.
|
50
55
|
|
51
|
-
|
56
|
+
## Hacking and contributing
|
52
57
|
|
53
|
-
If you want to help out, have a look at TODO.rdoc, and the
|
54
|
-
|
58
|
+
If you want to help out, have a look at TODO.rdoc, and check the notes
|
59
|
+
in the code (e.g., using `dnote`). Feel free to file bugs or send pull
|
60
|
+
requests.
|
55
61
|
|
56
62
|
If you want to send pull requests or patches, please:
|
57
63
|
|
@@ -64,9 +70,9 @@ If you want to send pull requests or patches, please:
|
|
64
70
|
* Try not to include changes that are irrelevant to your feature in the
|
65
71
|
same commit.
|
66
72
|
|
67
|
-
|
73
|
+
## License
|
68
74
|
|
69
|
-
Copyright
|
75
|
+
Copyright © 2009–2012 [Matijs van Zuijlen](http://www.matijs.net)
|
70
76
|
|
71
77
|
GirFFI is free software, distributed under the terms of the GNU Lesser
|
72
78
|
General Public License, version 2.1 or later. See the file COPYING.LIB for
|
data/Rakefile
CHANGED
data/TODO.rdoc
CHANGED
data/lib/ffi-glib.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# NOTE: Do not require this file directly. Require 'gir_ffi' instead.
|
2
|
+
#
|
3
|
+
|
1
4
|
GirFFI.setup :GLib
|
2
5
|
|
3
6
|
require 'ffi-glib/s_list'
|
@@ -6,12 +9,11 @@ require 'ffi-glib/hash_table'
|
|
6
9
|
require 'ffi-glib/byte_array'
|
7
10
|
require 'ffi-glib/array'
|
8
11
|
require 'ffi-glib/ptr_array'
|
9
|
-
require 'ffi-glib/strv'
|
10
12
|
|
11
13
|
module GLib
|
12
|
-
#
|
14
|
+
# @deprecated Compatibility function. Remove in version 0.5.0.
|
13
15
|
def self.main_loop_new context, is_running
|
14
|
-
|
16
|
+
GLib::MainLoop.new context, is_running
|
15
17
|
end
|
16
18
|
|
17
19
|
load_class :HFunc
|
@@ -43,7 +45,5 @@ module GLib
|
|
43
45
|
attach_function :g_ptr_array_add, [:pointer, :pointer], :void
|
44
46
|
attach_function :g_ptr_array_foreach, [:pointer, Func, :pointer],
|
45
47
|
:pointer
|
46
|
-
|
47
|
-
attach_function :g_main_loop_new, [:pointer, :bool], :pointer
|
48
48
|
end
|
49
49
|
end
|
@@ -20,13 +20,10 @@ module GLib
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def each
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
rval = yield list.head
|
27
|
-
list = list.tail
|
23
|
+
reset_iterator
|
24
|
+
while (elem = next_element)
|
25
|
+
yield elem
|
28
26
|
end
|
29
|
-
rval
|
30
27
|
end
|
31
28
|
|
32
29
|
def tail
|
@@ -41,6 +38,19 @@ module GLib
|
|
41
38
|
self.element_type = typespec
|
42
39
|
self
|
43
40
|
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def reset_iterator
|
45
|
+
@current = self
|
46
|
+
end
|
47
|
+
|
48
|
+
def next_element
|
49
|
+
return if @current.nil?
|
50
|
+
element = @current.head
|
51
|
+
@current = @current.tail
|
52
|
+
element
|
53
|
+
end
|
44
54
|
end
|
45
55
|
end
|
46
56
|
|
data/lib/ffi-gobject.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# NOTE: Do not require this file directly. Require 'gir_ffi' instead.
|
2
|
+
#
|
3
|
+
|
1
4
|
GirFFI.setup :GObject
|
2
5
|
|
3
6
|
require 'ffi-gobject/base'
|
@@ -34,7 +37,7 @@ module GObject
|
|
34
37
|
def self.type_from_instance_pointer inst_ptr
|
35
38
|
return nil if inst_ptr.null?
|
36
39
|
klsptr = inst_ptr.get_pointer 0
|
37
|
-
klsptr.send "get_#{GirFFI::TypeMap::TAG_TYPE_MAP[:
|
40
|
+
klsptr.send "get_#{GirFFI::TypeMap::TAG_TYPE_MAP[:GType]}", 0
|
38
41
|
end
|
39
42
|
|
40
43
|
def self.type_from_instance instance
|
@@ -90,17 +93,11 @@ module GObject
|
|
90
93
|
load_class :ParamFlags
|
91
94
|
|
92
95
|
module Lib
|
93
|
-
attach_function :g_type_init, [], :void
|
94
96
|
attach_function :g_object_ref, [:pointer], :void
|
95
97
|
attach_function :g_object_ref_sink, [:pointer], :void
|
96
98
|
attach_function :g_object_unref, [:pointer], :void
|
97
99
|
attach_function :g_object_is_floating, [:pointer], :bool
|
98
100
|
|
99
|
-
# XXX: For older GObject/gobject-introspection.
|
100
|
-
unless method_defined? :g_object_newv
|
101
|
-
attach_function :g_object_newv, [:size_t, :uint, :pointer], :pointer
|
102
|
-
end
|
103
|
-
|
104
101
|
attach_function :g_strv_get_type, [], :size_t
|
105
102
|
attach_function :g_hash_table_get_type, [], :size_t
|
106
103
|
|
data/lib/ffi-gobject/helper.rb
CHANGED
@@ -5,12 +5,12 @@ module GObject
|
|
5
5
|
#
|
6
6
|
# @param klass The class of the object that will receive the signal.
|
7
7
|
# @param signal The name of the signal
|
8
|
-
# @param
|
8
|
+
# @param block The body of the signal handler
|
9
9
|
#
|
10
|
-
# @
|
11
|
-
#
|
10
|
+
# @return [FFI::Function] The signal handler, ready to be passed as a
|
11
|
+
# callback to C.
|
12
12
|
def self.signal_callback klass, signal, &block
|
13
|
-
sig_info = klass.
|
13
|
+
sig_info = klass.find_signal signal
|
14
14
|
|
15
15
|
callback_block = signal_callback_args(sig_info, klass, &block)
|
16
16
|
|
@@ -35,7 +35,7 @@ module GObject
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def self.signal_arguments_to_gvalue_array signal, instance, *rest
|
38
|
-
sig = instance.class.
|
38
|
+
sig = instance.class.find_signal signal
|
39
39
|
|
40
40
|
arr = ::GObject::ValueArray.new sig.n_args + 1
|
41
41
|
|
@@ -75,7 +75,7 @@ module GObject
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def self.gvalue_for_signal_return_value signal, object
|
78
|
-
sig = object.class.
|
78
|
+
sig = object.class.find_signal signal
|
79
79
|
rettypeinfo = sig.return_type
|
80
80
|
|
81
81
|
gvalue_for_type_info rettypeinfo
|
data/lib/ffi-gobject/object.rb
CHANGED
@@ -8,9 +8,9 @@ module GObject
|
|
8
8
|
|
9
9
|
include RubyStyle
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
setup_method "new"
|
12
|
+
setup_instance_method "get_property"
|
13
|
+
setup_instance_method "set_property"
|
14
14
|
|
15
15
|
def get_property_with_override property_name
|
16
16
|
type = get_property_type property_name
|
@@ -39,7 +39,7 @@ module GObject
|
|
39
39
|
private
|
40
40
|
|
41
41
|
def get_property_type property_name
|
42
|
-
prop = self.class.
|
42
|
+
prop = self.class.find_property property_name
|
43
43
|
prop.property_type
|
44
44
|
end
|
45
45
|
|
@@ -1,8 +1,18 @@
|
|
1
1
|
module GObjectIntrospection
|
2
|
-
# Wraps
|
3
|
-
class GError
|
4
|
-
|
5
|
-
:
|
6
|
-
|
2
|
+
# Wraps GLib's GError struct.
|
3
|
+
class GError
|
4
|
+
class Struct < FFI::Struct
|
5
|
+
layout :domain, :uint32,
|
6
|
+
:code, :int,
|
7
|
+
:message, :string
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize ptr
|
11
|
+
@struct = self.class::Struct.new(ptr)
|
12
|
+
end
|
13
|
+
|
14
|
+
def message
|
15
|
+
@struct[:message]
|
16
|
+
end
|
7
17
|
end
|
8
18
|
end
|
@@ -38,10 +38,13 @@ module GObjectIntrospection
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def safe_name
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
name.gsub(/^./) do |char|
|
42
|
+
case char
|
43
|
+
when "_"
|
44
|
+
"Private___"
|
45
|
+
else
|
46
|
+
char.upcase
|
47
|
+
end
|
45
48
|
end
|
46
49
|
end
|
47
50
|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'singleton'
|
2
|
+
require 'ffi'
|
3
|
+
require 'gir_ffi-base'
|
4
|
+
|
2
5
|
require 'ffi-gobject_introspection/lib'
|
3
|
-
require 'ffi-gobject_introspection/gobject_lib'
|
4
6
|
require 'ffi-gobject_introspection/g_error'
|
5
7
|
require 'ffi-gobject_introspection/i_base_info'
|
6
8
|
require 'ffi-gobject_introspection/i_callable_info'
|
@@ -21,7 +23,7 @@ require 'ffi-gobject_introspection/i_enum_info'
|
|
21
23
|
require 'ffi-gobject_introspection/i_flags_info'
|
22
24
|
|
23
25
|
module GObjectIntrospection
|
24
|
-
|
26
|
+
GObject::Lib::g_type_init
|
25
27
|
|
26
28
|
# The Gobject Introspection Repository. This class is the point of
|
27
29
|
# access to the introspection typelibs.
|
@@ -78,7 +80,7 @@ module GObjectIntrospection
|
|
78
80
|
Lib.g_irepository_require @gobj, namespace, version, flags, errpp
|
79
81
|
|
80
82
|
errp = errpp.read_pointer
|
81
|
-
raise GError.new(errp)
|
83
|
+
raise GError.new(errp).message unless errp.null?
|
82
84
|
end
|
83
85
|
|
84
86
|
def n_infos namespace
|
@@ -108,8 +110,9 @@ module GObjectIntrospection
|
|
108
110
|
end
|
109
111
|
|
110
112
|
def dependencies namespace
|
111
|
-
|
112
|
-
|
113
|
+
strv_p = Lib.g_irepository_get_dependencies(@gobj, namespace)
|
114
|
+
strv = GLib::Strv.new strv_p
|
115
|
+
strv.to_a
|
113
116
|
end
|
114
117
|
|
115
118
|
def shared_library namespace
|
@@ -130,15 +133,5 @@ module GObjectIntrospection
|
|
130
133
|
def wrap ptr
|
131
134
|
IRepository.wrap_ibaseinfo_pointer ptr
|
132
135
|
end
|
133
|
-
|
134
|
-
def strv_to_utf8_array strv
|
135
|
-
return [] if strv.null?
|
136
|
-
arr, offset = [], 0
|
137
|
-
until (ptr = strv.get_pointer offset).null? do
|
138
|
-
arr << ptr.read_string
|
139
|
-
offset += POINTER_SIZE
|
140
|
-
end
|
141
|
-
return arr
|
142
|
-
end
|
143
136
|
end
|
144
137
|
end
|
@@ -23,8 +23,11 @@ module GObjectIntrospection
|
|
23
23
|
build_array_method :get_methods
|
24
24
|
|
25
25
|
def find_method(name)
|
26
|
-
|
27
|
-
|
26
|
+
method_map[name]
|
27
|
+
end
|
28
|
+
|
29
|
+
def method_map
|
30
|
+
@method_map ||= Hash[get_methods.map {|mthd| [mthd.name, mthd] }]
|
28
31
|
end
|
29
32
|
|
30
33
|
def size
|
@@ -38,13 +41,5 @@ module GObjectIntrospection
|
|
38
41
|
def gtype_struct?
|
39
42
|
Lib.g_struct_info_is_gtype_struct @gobj
|
40
43
|
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def make_method_hash
|
45
|
-
Hash.new.tap do |hash|
|
46
|
-
get_methods.each {|mth| hash[mth.name] = mth }
|
47
|
-
end
|
48
|
-
end
|
49
44
|
end
|
50
45
|
end
|
data/lib/gir_ffi-base.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module GLib
|
4
|
+
# Represents a null-terminated array of strings. GLib uses this
|
5
|
+
# construction, but does not provide any actual functions for this class.
|
6
|
+
class Strv
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
POINTER_SIZE = FFI.type_size(:pointer)
|
10
|
+
|
11
|
+
def initialize ptr
|
12
|
+
@ptr = ptr
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_ptr
|
16
|
+
@ptr
|
17
|
+
end
|
18
|
+
|
19
|
+
def each
|
20
|
+
reset_iterator or return
|
21
|
+
while (ptr = next_ptr)
|
22
|
+
yield ptr.read_string
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.wrap ptr
|
27
|
+
self.new ptr
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def reset_iterator
|
33
|
+
return if @ptr.null?
|
34
|
+
@offset = 0
|
35
|
+
end
|
36
|
+
|
37
|
+
def next_ptr
|
38
|
+
ptr = @ptr.get_pointer @offset
|
39
|
+
@offset += POINTER_SIZE
|
40
|
+
ptr unless ptr.null?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|