ffi 1.17.0.rc1-x86_64-linux-gnu

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +442 -0
  3. data/COPYING +49 -0
  4. data/Gemfile +21 -0
  5. data/LICENSE +24 -0
  6. data/LICENSE.SPECS +22 -0
  7. data/README.md +137 -0
  8. data/Rakefile +206 -0
  9. data/ffi.gemspec +42 -0
  10. data/lib/2.5/ffi_c.so +0 -0
  11. data/lib/2.6/ffi_c.so +0 -0
  12. data/lib/2.7/ffi_c.so +0 -0
  13. data/lib/3.0/ffi_c.so +0 -0
  14. data/lib/3.1/ffi_c.so +0 -0
  15. data/lib/3.2/ffi_c.so +0 -0
  16. data/lib/3.3/ffi_c.so +0 -0
  17. data/lib/ffi/abstract_memory.rb +44 -0
  18. data/lib/ffi/autopointer.rb +188 -0
  19. data/lib/ffi/buffer.rb +4 -0
  20. data/lib/ffi/callback.rb +4 -0
  21. data/lib/ffi/compat.rb +43 -0
  22. data/lib/ffi/data_converter.rb +67 -0
  23. data/lib/ffi/dynamic_library.rb +118 -0
  24. data/lib/ffi/enum.rb +302 -0
  25. data/lib/ffi/errno.rb +43 -0
  26. data/lib/ffi/ffi.rb +50 -0
  27. data/lib/ffi/function.rb +71 -0
  28. data/lib/ffi/io.rb +62 -0
  29. data/lib/ffi/library.rb +576 -0
  30. data/lib/ffi/library_path.rb +109 -0
  31. data/lib/ffi/managedstruct.rb +84 -0
  32. data/lib/ffi/memorypointer.rb +1 -0
  33. data/lib/ffi/platform/aarch64-darwin/types.conf +130 -0
  34. data/lib/ffi/platform/aarch64-freebsd/types.conf +128 -0
  35. data/lib/ffi/platform/aarch64-freebsd12/types.conf +181 -0
  36. data/lib/ffi/platform/aarch64-linux/types.conf +175 -0
  37. data/lib/ffi/platform/aarch64-openbsd/types.conf +134 -0
  38. data/lib/ffi/platform/aarch64-windows/types.conf +52 -0
  39. data/lib/ffi/platform/arm-freebsd/types.conf +152 -0
  40. data/lib/ffi/platform/arm-freebsd12/types.conf +152 -0
  41. data/lib/ffi/platform/arm-linux/types.conf +132 -0
  42. data/lib/ffi/platform/hppa1.1-linux/types.conf +178 -0
  43. data/lib/ffi/platform/hppa2.0-linux/types.conf +178 -0
  44. data/lib/ffi/platform/i386-cygwin/types.conf +3 -0
  45. data/lib/ffi/platform/i386-darwin/types.conf +100 -0
  46. data/lib/ffi/platform/i386-freebsd/types.conf +152 -0
  47. data/lib/ffi/platform/i386-freebsd12/types.conf +152 -0
  48. data/lib/ffi/platform/i386-gnu/types.conf +107 -0
  49. data/lib/ffi/platform/i386-linux/types.conf +103 -0
  50. data/lib/ffi/platform/i386-netbsd/types.conf +126 -0
  51. data/lib/ffi/platform/i386-openbsd/types.conf +128 -0
  52. data/lib/ffi/platform/i386-solaris/types.conf +122 -0
  53. data/lib/ffi/platform/i386-windows/types.conf +52 -0
  54. data/lib/ffi/platform/ia64-linux/types.conf +104 -0
  55. data/lib/ffi/platform/loongarch64-linux/types.conf +141 -0
  56. data/lib/ffi/platform/mips-linux/types.conf +102 -0
  57. data/lib/ffi/platform/mips64-linux/types.conf +104 -0
  58. data/lib/ffi/platform/mips64el-linux/types.conf +104 -0
  59. data/lib/ffi/platform/mipsel-linux/types.conf +102 -0
  60. data/lib/ffi/platform/mipsisa32r6-linux/types.conf +102 -0
  61. data/lib/ffi/platform/mipsisa32r6el-linux/types.conf +102 -0
  62. data/lib/ffi/platform/mipsisa64r6-linux/types.conf +104 -0
  63. data/lib/ffi/platform/mipsisa64r6el-linux/types.conf +104 -0
  64. data/lib/ffi/platform/powerpc-aix/types.conf +180 -0
  65. data/lib/ffi/platform/powerpc-darwin/types.conf +100 -0
  66. data/lib/ffi/platform/powerpc-linux/types.conf +130 -0
  67. data/lib/ffi/platform/powerpc-openbsd/types.conf +156 -0
  68. data/lib/ffi/platform/powerpc64-linux/types.conf +104 -0
  69. data/lib/ffi/platform/powerpc64le-linux/types.conf +100 -0
  70. data/lib/ffi/platform/riscv64-linux/types.conf +104 -0
  71. data/lib/ffi/platform/s390-linux/types.conf +102 -0
  72. data/lib/ffi/platform/s390x-linux/types.conf +102 -0
  73. data/lib/ffi/platform/sparc-linux/types.conf +102 -0
  74. data/lib/ffi/platform/sparc-solaris/types.conf +128 -0
  75. data/lib/ffi/platform/sparcv9-linux/types.conf +102 -0
  76. data/lib/ffi/platform/sparcv9-openbsd/types.conf +156 -0
  77. data/lib/ffi/platform/sparcv9-solaris/types.conf +128 -0
  78. data/lib/ffi/platform/sw_64-linux/types.conf +141 -0
  79. data/lib/ffi/platform/x86_64-cygwin/types.conf +3 -0
  80. data/lib/ffi/platform/x86_64-darwin/types.conf +130 -0
  81. data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +130 -0
  82. data/lib/ffi/platform/x86_64-freebsd/types.conf +128 -0
  83. data/lib/ffi/platform/x86_64-freebsd12/types.conf +158 -0
  84. data/lib/ffi/platform/x86_64-haiku/types.conf +117 -0
  85. data/lib/ffi/platform/x86_64-linux/types.conf +132 -0
  86. data/lib/ffi/platform/x86_64-msys/types.conf +119 -0
  87. data/lib/ffi/platform/x86_64-netbsd/types.conf +128 -0
  88. data/lib/ffi/platform/x86_64-openbsd/types.conf +134 -0
  89. data/lib/ffi/platform/x86_64-solaris/types.conf +122 -0
  90. data/lib/ffi/platform/x86_64-windows/types.conf +52 -0
  91. data/lib/ffi/platform.rb +187 -0
  92. data/lib/ffi/pointer.rb +167 -0
  93. data/lib/ffi/struct.rb +317 -0
  94. data/lib/ffi/struct_by_reference.rb +72 -0
  95. data/lib/ffi/struct_layout.rb +96 -0
  96. data/lib/ffi/struct_layout_builder.rb +227 -0
  97. data/lib/ffi/tools/const_generator.rb +232 -0
  98. data/lib/ffi/tools/generator.rb +105 -0
  99. data/lib/ffi/tools/generator_task.rb +32 -0
  100. data/lib/ffi/tools/struct_generator.rb +195 -0
  101. data/lib/ffi/tools/types_generator.rb +137 -0
  102. data/lib/ffi/types.rb +222 -0
  103. data/lib/ffi/union.rb +43 -0
  104. data/lib/ffi/variadic.rb +80 -0
  105. data/lib/ffi/version.rb +3 -0
  106. data/lib/ffi.rb +27 -0
  107. data/rakelib/ffi_gem_helper.rb +65 -0
  108. data/samples/getlogin.rb +8 -0
  109. data/samples/getpid.rb +8 -0
  110. data/samples/gettimeofday.rb +18 -0
  111. data/samples/hello.rb +8 -0
  112. data/samples/hello_ractor.rb +11 -0
  113. data/samples/inotify.rb +60 -0
  114. data/samples/pty.rb +75 -0
  115. data/samples/qsort.rb +20 -0
  116. data/samples/qsort_ractor.rb +28 -0
  117. data/sig/ffi/abstract_memory.rbs +164 -0
  118. data/sig/ffi/auto_pointer.rbs +27 -0
  119. data/sig/ffi/buffer.rbs +18 -0
  120. data/sig/ffi/data_converter.rbs +10 -0
  121. data/sig/ffi/dynamic_library.rbs +9 -0
  122. data/sig/ffi/enum.rbs +38 -0
  123. data/sig/ffi/function.rbs +39 -0
  124. data/sig/ffi/library.rbs +42 -0
  125. data/sig/ffi/native_type.rbs +86 -0
  126. data/sig/ffi/pointer.rbs +42 -0
  127. data/sig/ffi/struct.rbs +76 -0
  128. data/sig/ffi/struct_by_reference.rbs +11 -0
  129. data/sig/ffi/struct_by_value.rbs +7 -0
  130. data/sig/ffi/struct_layout.rbs +9 -0
  131. data/sig/ffi/struct_layout_builder.rbs +5 -0
  132. data/sig/ffi/type.rbs +39 -0
  133. data/sig/ffi.rbs +26 -0
  134. metadata +244 -0
@@ -0,0 +1,67 @@
1
+ #
2
+ # Copyright (C) 2008-2010 Wayne Meissner
3
+ #
4
+ # This file is part of ruby-ffi.
5
+ #
6
+ # All rights reserved.
7
+ #
8
+ # Redistribution and use in source and binary forms, with or without
9
+ # modification, are permitted provided that the following conditions are met:
10
+ #
11
+ # * Redistributions of source code must retain the above copyright notice, this
12
+ # list of conditions and the following disclaimer.
13
+ # * Redistributions in binary form must reproduce the above copyright notice
14
+ # this list of conditions and the following disclaimer in the documentation
15
+ # and/or other materials provided with the distribution.
16
+ # * Neither the name of the Ruby FFI project nor the names of its contributors
17
+ # may be used to endorse or promote products derived from this software
18
+ # without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
24
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
30
+
31
+ module FFI
32
+ # This module is used to extend somes classes and give then a common API.
33
+ #
34
+ # Most of methods defined here must be overridden.
35
+ module DataConverter
36
+ # Get native type.
37
+ #
38
+ # @overload native_type(type)
39
+ # @param [String, Symbol, Type] type
40
+ # @return [Type]
41
+ # Get native type from +type+.
42
+ #
43
+ # @overload native_type
44
+ # @raise {NotImplementedError} This method must be overridden.
45
+ def native_type(type = nil)
46
+ if type
47
+ @native_type = FFI.find_type(type)
48
+ else
49
+ native_type = @native_type
50
+ unless native_type
51
+ raise NotImplementedError, 'native_type method not overridden and no native_type set'
52
+ end
53
+ native_type
54
+ end
55
+ end
56
+
57
+ # Convert to a native type.
58
+ def to_native(value, ctx)
59
+ value
60
+ end
61
+
62
+ # Convert from a native type.
63
+ def from_native(value, ctx)
64
+ value
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,118 @@
1
+ #
2
+ # Copyright (C) 2008-2010 Wayne Meissner
3
+ #
4
+ # This file is part of ruby-ffi.
5
+ #
6
+ # All rights reserved.
7
+ #
8
+ # Redistribution and use in source and binary forms, with or without
9
+ # modification, are permitted provided that the following conditions are met:
10
+ #
11
+ # * Redistributions of source code must retain the above copyright notice, this
12
+ # list of conditions and the following disclaimer.
13
+ # * Redistributions in binary form must reproduce the above copyright notice
14
+ # this list of conditions and the following disclaimer in the documentation
15
+ # and/or other materials provided with the distribution.
16
+ # * Neither the name of the Ruby FFI project nor the names of its contributors
17
+ # may be used to endorse or promote products derived from this software
18
+ # without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
24
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
30
+
31
+ module FFI
32
+ class DynamicLibrary
33
+ SEARCH_PATH = []
34
+
35
+ # The following search paths are tried, if the library could not be loaded in the first attempt.
36
+ # They are only executed on Macos in the following order:
37
+ if FFI::Platform.mac?
38
+
39
+ # 1. Try library paths possibly defined in LD_LIBRARY_PATH DYLD_LIBRARY_PATH first.
40
+ # This is because dlopen doesn't respect LD_LIBRARY_PATH and DYLD_LIBRARY_PATH is deleted by SIP-protected binaries.
41
+ # See here for details: https://github.com/ffi/ffi/issues/923#issuecomment-1872565313
42
+ %w[LD_LIBRARY_PATH DYLD_LIBRARY_PATH].each do |custom_path|
43
+ SEARCH_PATH.concat ENV.fetch(custom_path,"").split(File::PATH_SEPARATOR)
44
+ end
45
+
46
+ # 2. Then on macos/arm64 try /opt/homebrew/lib, since this is a typical standard directory.
47
+ # FFI is often used together with homebrew, so that we hardcode the path for arm64 here.
48
+ if FFI::Platform::ARCH == 'aarch64'
49
+ SEARCH_PATH << '/opt/homebrew/lib'
50
+ end
51
+
52
+ # 3. Then try typical system directories starting with the /local/ directory first.
53
+ #
54
+ # /usr/local/lib is used by homebrow on x86_64.
55
+ # /opt/local/lib is used by MacPorts and Fink.
56
+ # /usr/lib is there, because it was always there.
57
+ SEARCH_PATH.concat %w[/opt/local/lib /usr/local/lib /usr/lib]
58
+ end
59
+
60
+ # On Linux the library lookup paths are usually defined through /etc/ld.so.conf, which can be changed at will with root permissions.
61
+ # Also LD_LIBRARY_PATH is respected by the dynamic loader, so that there's usually no need and no advantage to do a fallback handling.
62
+ #
63
+ # Windows has it's own library lookup logic, very different to what we do here.
64
+ # See: https://github.com/oneclick/rubyinstaller2/wiki/For-gem-developers#user-content-dll-loading
65
+
66
+ FFI.make_shareable(SEARCH_PATH)
67
+ SEARCH_PATH_MESSAGE = "Searched in <system library path>#{ SEARCH_PATH.map{|a| ', ' + a}.join }".freeze
68
+
69
+ def self.load_library(name, flags)
70
+ if name == FFI::CURRENT_PROCESS
71
+ FFI::DynamicLibrary.open(nil, RTLD_LAZY | RTLD_LOCAL)
72
+ else
73
+ flags ||= RTLD_LAZY | RTLD_LOCAL
74
+
75
+ libnames = (name.is_a?(::Array) ? name : [name])
76
+ libnames = libnames.map(&:to_s).map { |n| [n, FFI.map_library_name(n)].uniq }.flatten.compact
77
+ errors = []
78
+
79
+ libnames.each do |libname|
80
+ lib = try_load(libname, flags, errors)
81
+ return lib if lib
82
+
83
+ unless libname.start_with?("/")
84
+ SEARCH_PATH.each do |prefix|
85
+ path = "#{prefix}/#{libname}"
86
+ if File.exist?(path)
87
+ lib = try_load(path, flags, errors)
88
+ return lib if lib
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ raise LoadError, [*errors, SEARCH_PATH_MESSAGE].join(".\n")
95
+ end
96
+ end
97
+ private_class_method :load_library
98
+
99
+ def self.try_load(libname, flags, errors)
100
+ begin
101
+ lib = FFI::DynamicLibrary.open(libname, flags)
102
+ return lib if lib
103
+
104
+ # LoadError for C ext & JRuby, RuntimeError for TruffleRuby
105
+ rescue LoadError, RuntimeError => ex
106
+ if ex.message =~ /(([^ \t()])+\.so([^ \t:()])*):([ \t])*(invalid ELF header|file too short|invalid file format)/
107
+ if File.binread($1) =~ /(?:GROUP|INPUT) *\( *([^ \)]+)/
108
+ return try_load($1, flags, errors)
109
+ end
110
+ end
111
+
112
+ errors << ex
113
+ nil
114
+ end
115
+ end
116
+ private_class_method :try_load
117
+ end
118
+ end
data/lib/ffi/enum.rb ADDED
@@ -0,0 +1,302 @@
1
+ #
2
+ # Copyright (C) 2009, 2010 Wayne Meissner
3
+ # Copyright (C) 2009 Luc Heinrich
4
+ #
5
+ # This file is part of ruby-ffi.
6
+ #
7
+ # All rights reserved.
8
+ #
9
+ # Redistribution and use in source and binary forms, with or without
10
+ # modification, are permitted provided that the following conditions are met:
11
+ #
12
+ # * Redistributions of source code must retain the above copyright notice, this
13
+ # list of conditions and the following disclaimer.
14
+ # * Redistributions in binary form must reproduce the above copyright notice
15
+ # this list of conditions and the following disclaimer in the documentation
16
+ # and/or other materials provided with the distribution.
17
+ # * Neither the name of the Ruby FFI project nor the names of its contributors
18
+ # may be used to endorse or promote products derived from this software
19
+ # without specific prior written permission.
20
+ #
21
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
25
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ #
32
+
33
+ module FFI
34
+
35
+ # An instance of this class permits to manage {Enum}s. In fact, Enums is a collection of {Enum}s.
36
+ class Enums
37
+
38
+ def initialize
39
+ @all_enums = Array.new
40
+ @tagged_enums = Hash.new
41
+ @symbol_map = Hash.new
42
+ end
43
+
44
+ # @param [Enum] enum
45
+ # Add an {Enum} to the collection.
46
+ def <<(enum)
47
+ @all_enums << enum
48
+ @tagged_enums[enum.tag] = enum unless enum.tag.nil?
49
+ @symbol_map.merge!(enum.symbol_map)
50
+ end
51
+
52
+ # @param query enum tag or part of an enum name
53
+ # @return [Enum]
54
+ # Find a {Enum} in collection.
55
+ def find(query)
56
+ if @tagged_enums.has_key?(query)
57
+ @tagged_enums[query]
58
+ else
59
+ @all_enums.detect { |enum| enum.symbols.include?(query) }
60
+ end
61
+ end
62
+
63
+ # @param symbol a symbol to find in merge symbol maps of all enums.
64
+ # @return a symbol
65
+ def __map_symbol(symbol)
66
+ @symbol_map[symbol]
67
+ end
68
+
69
+ end
70
+
71
+ # Represents a C enum.
72
+ #
73
+ # For a C enum:
74
+ # enum fruits {
75
+ # apple,
76
+ # banana,
77
+ # orange,
78
+ # pineapple
79
+ # };
80
+ # are defined this vocabulary:
81
+ # * a _symbol_ is a word from the enumeration (ie. _apple_, by example);
82
+ # * a _value_ is the value of a symbol in the enumeration (by example, apple has value _0_ and banana _1_).
83
+ class Enum
84
+ include DataConverter
85
+
86
+ attr_reader :tag
87
+ attr_reader :native_type
88
+
89
+ # @overload initialize(info, tag=nil)
90
+ # @param [nil, Enumerable] info
91
+ # @param [nil, Symbol] tag enum tag
92
+ # @overload initialize(native_type, info, tag=nil)
93
+ # @param [FFI::Type] native_type Native type for new Enum
94
+ # @param [nil, Enumerable] info symbols and values for new Enum
95
+ # @param [nil, Symbol] tag name of new Enum
96
+ def initialize(*args)
97
+ @native_type = args.first.kind_of?(FFI::Type) ? args.shift : Type::INT
98
+ info, @tag = *args
99
+ @kv_map = Hash.new
100
+ unless info.nil?
101
+ last_cst = nil
102
+ value = 0
103
+ info.each do |i|
104
+ case i
105
+ when Symbol
106
+ raise ArgumentError, "duplicate enum key" if @kv_map.has_key?(i)
107
+ @kv_map[i] = value
108
+ last_cst = i
109
+ value += 1
110
+ when Integer
111
+ @kv_map[last_cst] = i
112
+ value = i+1
113
+ end
114
+ end
115
+ end
116
+ @vk_map = @kv_map.invert
117
+ end
118
+
119
+ # @return [Array] enum symbol names
120
+ def symbols
121
+ @kv_map.keys
122
+ end
123
+
124
+ # Get a symbol or a value from the enum.
125
+ # @overload [](query)
126
+ # Get enum value from symbol.
127
+ # @param [Symbol] query
128
+ # @return [Integer]
129
+ # @overload [](query)
130
+ # Get enum symbol from value.
131
+ # @param [Integer] query
132
+ # @return [Symbol]
133
+ def [](query)
134
+ case query
135
+ when Symbol
136
+ @kv_map[query]
137
+ when Integer
138
+ @vk_map[query]
139
+ end
140
+ end
141
+ alias find []
142
+
143
+ # Get the symbol map.
144
+ # @return [Hash]
145
+ def symbol_map
146
+ @kv_map
147
+ end
148
+
149
+ alias to_h symbol_map
150
+ alias to_hash symbol_map
151
+
152
+ # @param [Symbol, Integer, #to_int] val
153
+ # @param ctx unused
154
+ # @return [Integer] value of a enum symbol
155
+ def to_native(val, ctx)
156
+ @kv_map[val] || if val.is_a?(Integer)
157
+ val
158
+ elsif val.respond_to?(:to_int)
159
+ val.to_int
160
+ else
161
+ raise ArgumentError, "invalid enum value, #{val.inspect}"
162
+ end
163
+ end
164
+
165
+ # @param val
166
+ # @return symbol name if it exists for +val+.
167
+ def from_native(val, ctx)
168
+ @vk_map[val] || val
169
+ end
170
+ end
171
+
172
+ # Represents a C enum whose values are power of 2
173
+ #
174
+ # @example
175
+ # enum {
176
+ # red = (1<<0),
177
+ # green = (1<<1),
178
+ # blue = (1<<2)
179
+ # }
180
+ #
181
+ # Contrary to classical enums, bitmask values are usually combined
182
+ # when used.
183
+ class Bitmask < Enum
184
+
185
+ # @overload initialize(info, tag=nil)
186
+ # @param [nil, Enumerable] info symbols and bit rank for new Bitmask
187
+ # @param [nil, Symbol] tag name of new Bitmask
188
+ # @overload initialize(native_type, info, tag=nil)
189
+ # @param [FFI::Type] native_type Native type for new Bitmask
190
+ # @param [nil, Enumerable] info symbols and bit rank for new Bitmask
191
+ # @param [nil, Symbol] tag name of new Bitmask
192
+ def initialize(*args)
193
+ @native_type = args.first.kind_of?(FFI::Type) ? args.shift : Type::INT
194
+ @signed = [Type::INT8, Type::INT16, Type::INT32, Type::INT64].include?(@native_type)
195
+ info, @tag = *args
196
+ @kv_map = Hash.new
197
+ unless info.nil?
198
+ last_cst = nil
199
+ value = 0
200
+ info.each do |i|
201
+ case i
202
+ when Symbol
203
+ raise ArgumentError, "duplicate bitmask key" if @kv_map.has_key?(i)
204
+ @kv_map[i] = 1 << value
205
+ last_cst = i
206
+ value += 1
207
+ when Integer
208
+ raise ArgumentError, "bitmask index should be positive" if i<0
209
+ @kv_map[last_cst] = 1 << i
210
+ value = i+1
211
+ end
212
+ end
213
+ end
214
+ @vk_map = @kv_map.invert
215
+ end
216
+
217
+ # Get a symbol list or a value from the bitmask
218
+ # @overload [](*query)
219
+ # Get bitmask value from symbol list
220
+ # @param [Symbol] query
221
+ # @return [Integer]
222
+ # @overload [](query)
223
+ # Get bitmask value from symbol array
224
+ # @param [Array<Symbol>] query
225
+ # @return [Integer]
226
+ # @overload [](*query)
227
+ # Get a list of bitmask symbols corresponding to
228
+ # the or reduction of a list of integer
229
+ # @param [Integer] query
230
+ # @return [Array<Symbol>]
231
+ # @overload [](query)
232
+ # Get a list of bitmask symbols corresponding to
233
+ # the or reduction of a list of integer
234
+ # @param [Array<Integer>] query
235
+ # @return [Array<Symbol>]
236
+ def [](*query)
237
+ flat_query = query.flatten
238
+ raise ArgumentError, "query should be homogeneous, #{query.inspect}" unless flat_query.all? { |o| o.is_a?(Symbol) } || flat_query.all? { |o| o.is_a?(Integer) || o.respond_to?(:to_int) }
239
+ case flat_query[0]
240
+ when Symbol
241
+ flat_query.inject(0) do |val, o|
242
+ v = @kv_map[o]
243
+ if v then val | v else val end
244
+ end
245
+ when Integer, ->(o) { o.respond_to?(:to_int) }
246
+ val = flat_query.inject(0) { |mask, o| mask |= o.to_int }
247
+ @kv_map.select { |_, v| v & val != 0 }.keys
248
+ end
249
+ end
250
+
251
+ # Get the native value of a bitmask
252
+ # @overload to_native(query, ctx)
253
+ # @param [Symbol, Integer, #to_int] query
254
+ # @param ctx unused
255
+ # @return [Integer] value of a bitmask
256
+ # @overload to_native(query, ctx)
257
+ # @param [Array<Symbol, Integer, #to_int>] query
258
+ # @param ctx unused
259
+ # @return [Integer] value of a bitmask
260
+ def to_native(query, ctx)
261
+ return 0 if query.nil?
262
+ flat_query = [query].flatten
263
+ res = flat_query.inject(0) do |val, o|
264
+ case o
265
+ when Symbol
266
+ v = @kv_map[o]
267
+ raise ArgumentError, "invalid bitmask value, #{o.inspect}" unless v
268
+ val | v
269
+ when Integer
270
+ val | o
271
+ when ->(obj) { obj.respond_to?(:to_int) }
272
+ val | o.to_int
273
+ else
274
+ raise ArgumentError, "invalid bitmask value, #{o.inspect}"
275
+ end
276
+ end
277
+ # Take two's complement of positive values bigger than the max value
278
+ # for the type when native type is signed.
279
+ if @signed && res >= (1 << (@native_type.size * 8 - 1))
280
+ res = -(-res & ((1 << (@native_type.size * 8)) - 1))
281
+ end
282
+ res
283
+ end
284
+
285
+ # @param [Integer] val
286
+ # @param ctx unused
287
+ # @return [Array<Symbol, Integer>] list of symbol names corresponding to val, plus an optional remainder if some bits don't match any constant
288
+ def from_native(val, ctx)
289
+ flags = @kv_map.select { |_, v| v & val != 0 }
290
+ list = flags.keys
291
+ # force an unsigned value of the correct size
292
+ val &= (1 << (@native_type.size * 8)) - 1 if @signed
293
+ # If there are unmatch flags,
294
+ # return them in an integer,
295
+ # else information can be lost.
296
+ # Similar to Enum behavior.
297
+ remainder = val ^ flags.values.reduce(0, :|)
298
+ list.push remainder unless remainder == 0
299
+ return list
300
+ end
301
+ end
302
+ end
data/lib/ffi/errno.rb ADDED
@@ -0,0 +1,43 @@
1
+ #
2
+ # Copyright (C) 2008-2010 Wayne Meissner
3
+ #
4
+ # This file is part of ruby-ffi.
5
+ #
6
+ # All rights reserved.
7
+ #
8
+ # Redistribution and use in source and binary forms, with or without
9
+ # modification, are permitted provided that the following conditions are met:
10
+ #
11
+ # * Redistributions of source code must retain the above copyright notice, this
12
+ # list of conditions and the following disclaimer.
13
+ # * Redistributions in binary form must reproduce the above copyright notice
14
+ # this list of conditions and the following disclaimer in the documentation
15
+ # and/or other materials provided with the distribution.
16
+ # * Neither the name of the Ruby FFI project nor the names of its contributors
17
+ # may be used to endorse or promote products derived from this software
18
+ # without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
24
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
30
+
31
+ module FFI
32
+ # @return (see FFI::LastError.error)
33
+ # @see FFI::LastError.error
34
+ def self.errno
35
+ FFI::LastError.error
36
+ end
37
+ # @param error (see FFI::LastError.error=)
38
+ # @return (see FFI::LastError.error=)
39
+ # @see FFI::LastError.error=
40
+ def self.errno=(error)
41
+ FFI::LastError.error = error
42
+ end
43
+ end
data/lib/ffi/ffi.rb ADDED
@@ -0,0 +1,50 @@
1
+ #
2
+ # Copyright (C) 2008-2010 JRuby project
3
+ #
4
+ # This file is part of ruby-ffi.
5
+ #
6
+ # All rights reserved.
7
+ #
8
+ # Redistribution and use in source and binary forms, with or without
9
+ # modification, are permitted provided that the following conditions are met:
10
+ #
11
+ # * Redistributions of source code must retain the above copyright notice, this
12
+ # list of conditions and the following disclaimer.
13
+ # * Redistributions in binary form must reproduce the above copyright notice
14
+ # this list of conditions and the following disclaimer in the documentation
15
+ # and/or other materials provided with the distribution.
16
+ # * Neither the name of the Ruby FFI project nor the names of its contributors
17
+ # may be used to endorse or promote products derived from this software
18
+ # without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
24
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ require 'ffi/compat'
32
+ require 'ffi/platform'
33
+ require 'ffi/data_converter'
34
+ require 'ffi/types'
35
+ require 'ffi/library_path'
36
+ require 'ffi/library'
37
+ require 'ffi/errno'
38
+ require 'ffi/abstract_memory'
39
+ require 'ffi/pointer'
40
+ require 'ffi/memorypointer'
41
+ require 'ffi/struct'
42
+ require 'ffi/union'
43
+ require 'ffi/managedstruct'
44
+ require 'ffi/callback'
45
+ require 'ffi/io'
46
+ require 'ffi/autopointer'
47
+ require 'ffi/variadic'
48
+ require 'ffi/enum'
49
+ require 'ffi/version'
50
+ require 'ffi/function'
@@ -0,0 +1,71 @@
1
+ #
2
+ # Copyright (C) 2008-2010 JRuby project
3
+ #
4
+ # This file is part of ruby-ffi.
5
+ #
6
+ # All rights reserved.
7
+ #
8
+ # Redistribution and use in source and binary forms, with or without
9
+ # modification, are permitted provided that the following conditions are met:
10
+ #
11
+ # * Redistributions of source code must retain the above copyright notice, this
12
+ # list of conditions and the following disclaimer.
13
+ # * Redistributions in binary form must reproduce the above copyright notice
14
+ # this list of conditions and the following disclaimer in the documentation
15
+ # and/or other materials provided with the distribution.
16
+ # * Neither the name of the Ruby FFI project nor the names of its contributors
17
+ # may be used to endorse or promote products derived from this software
18
+ # without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
24
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ module FFI
32
+ class Function
33
+ # Only MRI allows function type queries
34
+ if private_method_defined?(:type)
35
+ # Retrieve the return type of the function
36
+ #
37
+ # This method returns FFI type returned by the function.
38
+ #
39
+ # @return [FFI::Type]
40
+ def return_type
41
+ type.return_type
42
+ end
43
+
44
+ # Retrieve Array of parameter types
45
+ #
46
+ # This method returns an Array of FFI types accepted as function parameters.
47
+ #
48
+ # @return [Array<FFI::Type>]
49
+ def param_types
50
+ type.param_types
51
+ end
52
+ end
53
+
54
+ # Stash the Function in a module variable so it can be inspected by attached_functions.
55
+ # On CRuby it also ensures that it does not get garbage collected.
56
+ module RegisterAttach
57
+ def attach(mod, name)
58
+ funcs = mod.instance_variable_defined?("@ffi_functions") && mod.instance_variable_get("@ffi_functions")
59
+ unless funcs
60
+ funcs = {}
61
+ mod.instance_variable_set("@ffi_functions", funcs)
62
+ end
63
+ funcs[name.to_sym] = self
64
+ # Jump to the native attach method of CRuby, JRuby or Tuffleruby
65
+ super
66
+ end
67
+ end
68
+ private_constant :RegisterAttach
69
+ prepend RegisterAttach
70
+ end
71
+ end