ffi 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ffi might be problematic. Click here for more details.

Files changed (67) hide show
  1. data/README.md +10 -5
  2. data/ext/ffi_c/ArrayType.c +6 -2
  3. data/ext/ffi_c/Buffer.c +3 -1
  4. data/ext/ffi_c/Call.c +12 -21
  5. data/ext/ffi_c/FunctionInfo.c +27 -2
  6. data/ext/ffi_c/MappedType.c +1 -2
  7. data/ext/ffi_c/MemoryPointer.c +35 -4
  8. data/ext/ffi_c/Pointer.c +5 -4
  9. data/ext/ffi_c/Struct.c +125 -8
  10. data/ext/ffi_c/StructByReference.c +33 -0
  11. data/ext/ffi_c/StructByValue.c +2 -2
  12. data/ext/ffi_c/StructLayout.c +135 -1
  13. data/ext/ffi_c/Type.c +1 -0
  14. data/ext/ffi_c/extconf.rb +1 -1
  15. data/ffi.gemspec +1 -1
  16. data/lib/ffi.rb +2 -1
  17. data/lib/ffi/library.rb +2 -0
  18. data/lib/ffi/managedstruct.rb +37 -37
  19. data/lib/ffi/struct.rb +74 -1
  20. data/lib/ffi/struct_layout_builder.rb +50 -1
  21. data/lib/ffi/tools/generator.rb +2 -0
  22. data/lib/ffi/tools/generator_task.rb +1 -0
  23. data/lib/ffi/tools/types_generator.rb +2 -0
  24. data/libtest/Benchmark.c +1 -15
  25. data/libtest/BoolTest.c +2 -16
  26. data/libtest/BufferTest.c +3 -17
  27. data/libtest/ClosureTest.c +1 -15
  28. data/libtest/EnumTest.c +1 -15
  29. data/libtest/FunctionTest.c +2 -16
  30. data/libtest/GlobalVariable.c +2 -16
  31. data/libtest/LastErrorTest.c +2 -16
  32. data/libtest/NumberTest.c +1 -15
  33. data/libtest/PointerTest.c +1 -15
  34. data/libtest/ReferenceTest.c +1 -15
  35. data/libtest/StringTest.c +1 -15
  36. data/libtest/StructTest.c +1 -15
  37. data/libtest/UnionTest.c +1 -15
  38. data/libtest/VariadicTest.c +2 -16
  39. data/spec/ffi/async_callback_spec.rb +3 -14
  40. data/spec/ffi/bool_spec.rb +7 -18
  41. data/spec/ffi/buffer_spec.rb +26 -37
  42. data/spec/ffi/callback_spec.rb +96 -107
  43. data/spec/ffi/custom_param_type.rb +2 -13
  44. data/spec/ffi/custom_type_spec.rb +1 -12
  45. data/spec/ffi/dup_spec.rb +7 -18
  46. data/spec/ffi/enum_spec.rb +128 -139
  47. data/spec/ffi/errno_spec.rb +2 -13
  48. data/spec/ffi/ffi_spec.rb +4 -15
  49. data/spec/ffi/function_spec.rb +6 -17
  50. data/spec/ffi/library_spec.rb +26 -26
  51. data/spec/ffi/long_double.rb +1 -12
  52. data/spec/ffi/managed_struct_spec.rb +3 -18
  53. data/spec/ffi/number_spec.rb +32 -43
  54. data/spec/ffi/pointer_spec.rb +7 -22
  55. data/spec/ffi/rbx/memory_pointer_spec.rb +17 -17
  56. data/spec/ffi/rbx/struct_spec.rb +2 -2
  57. data/spec/ffi/spec_helper.rb +10 -12
  58. data/spec/ffi/string_spec.rb +9 -20
  59. data/spec/ffi/strptr_spec.rb +2 -13
  60. data/spec/ffi/struct_callback_spec.rb +3 -14
  61. data/spec/ffi/struct_initialize_spec.rb +3 -14
  62. data/spec/ffi/struct_packed_spec.rb +7 -18
  63. data/spec/ffi/struct_spec.rb +93 -104
  64. data/spec/ffi/typedef_spec.rb +5 -16
  65. data/spec/ffi/union_spec.rb +4 -15
  66. data/spec/ffi/variadic_spec.rb +7 -18
  67. metadata +73 -58
@@ -27,20 +27,32 @@ module FFI
27
27
 
28
28
  class StructLayout
29
29
 
30
+ # @return [Array<Array(Symbol, Numeric)>
31
+ # Get an array of tuples (field name, offset of the field).
30
32
  def offsets
31
33
  members.map { |m| [ m, self[m].offset ] }
32
34
  end
33
35
 
36
+ # @return [Numeric]
37
+ # Get the offset of a field.
34
38
  def offset_of(field_name)
35
39
  self[field_name].offset
36
40
  end
37
41
 
42
+ # An enum {Field} in a {StructLayout}.
38
43
  class Enum < Field
39
-
44
+
45
+ # @param [AbstractMemory] ptr pointer on a {Struct}
46
+ # @return [Object]
47
+ # Get an object of type {#type} from memory pointed by +ptr+.
40
48
  def get(ptr)
41
49
  type.find(ptr.get_int(offset))
42
50
  end
43
51
 
52
+ # @param [AbstractMemory] ptr pointer on a {Struct}
53
+ # @param value
54
+ # @return [nil]
55
+ # Set +value+ into memory pointed by +ptr+.
44
56
  def put(ptr, value)
45
57
  ptr.put_int(offset, type.find(value))
46
58
  end
@@ -77,61 +89,82 @@ module FFI
77
89
 
78
90
  class Struct
79
91
 
92
+ # Get struct size
93
+ # @return [Numeric]
80
94
  def size
81
95
  self.class.size
82
96
  end
83
97
 
98
+ # @return [Fixnum] Struct alignment
84
99
  def alignment
85
100
  self.class.alignment
86
101
  end
87
102
  alias_method :align, :alignment
88
103
 
104
+ # (see FFI::StructLayout#offset_of)
89
105
  def offset_of(name)
90
106
  self.class.offset_of(name)
91
107
  end
92
108
 
109
+ # (see FFI::StructLayout#members)
93
110
  def members
94
111
  self.class.members
95
112
  end
96
113
 
114
+ # @return [Array]
115
+ # Get array of values from Struct fields.
97
116
  def values
98
117
  members.map { |m| self[m] }
99
118
  end
100
119
 
120
+ # (see FFI::StructLayout#offsets)
101
121
  def offsets
102
122
  self.class.offsets
103
123
  end
104
124
 
125
+ # Clear the struct content.
126
+ # @return [self]
105
127
  def clear
106
128
  pointer.clear
107
129
  self
108
130
  end
109
131
 
132
+ # Get {Pointer} to struct content.
133
+ # @return [AbstractMemory]
110
134
  def to_ptr
111
135
  pointer
112
136
  end
113
137
 
138
+ # Get struct size
139
+ # @return [Numeric]
114
140
  def self.size
115
141
  defined?(@layout) ? @layout.size : defined?(@size) ? @size : 0
116
142
  end
117
143
 
144
+ # set struct size
145
+ # @param [Numeric] size
146
+ # @return [size]
118
147
  def self.size=(size)
119
148
  raise ArgumentError, "Size already set" if defined?(@size) || defined?(@layout)
120
149
  @size = size
121
150
  end
122
151
 
152
+ # @return (see Struct#alignment)
123
153
  def self.alignment
124
154
  @layout.alignment
125
155
  end
126
156
 
157
+ # (see FFI::Type#members)
127
158
  def self.members
128
159
  @layout.members
129
160
  end
130
161
 
162
+ # (see FFI::StructLayout#offsets)
131
163
  def self.offsets
132
164
  @layout.offsets
133
165
  end
134
166
 
167
+ # (see FFI::StructLayout#offset_of)
135
168
  def self.offset_of(name)
136
169
  @layout.offset_of(name)
137
170
  end
@@ -162,6 +195,7 @@ module FFI
162
195
 
163
196
  class ManagedStructConverter < StructByReference
164
197
 
198
+ # @param [Struct] struct_class
165
199
  def initialize(struct_class)
166
200
  super(struct_class)
167
201
 
@@ -169,6 +203,9 @@ module FFI
169
203
  @method = struct_class.method(:release)
170
204
  end
171
205
 
206
+ # @param [Pointer] ptr
207
+ # @param [nil] ctx
208
+ # @return [Struct]
172
209
  def from_native(ptr, ctx)
173
210
  struct_class.new(AutoPointer.new(ptr, @method))
174
211
  end
@@ -182,6 +219,33 @@ module FFI
182
219
  class << self
183
220
  public
184
221
 
222
+ # @return [StructLayout]
223
+ # @overload layout
224
+ # @return [StructLayout]
225
+ # Get struct layout.
226
+ # @overload layout(*spec)
227
+ # @param [Array<Symbol, Integer>,Array(Hash)] spec
228
+ # @return [StructLayout]
229
+ # Create struct layout from +spec+.
230
+ # @example Creating a layout from an array +spec+
231
+ # class MyStruct < Struct
232
+ # layout :field1, :int,
233
+ # :field2, :pointer,
234
+ # :field3, :string
235
+ # end
236
+ # @example Creating a layout from an array +spec+ with offset
237
+ # class MyStructWithOffset < Struct
238
+ # layout :field1, :int,
239
+ # :field2, :pointer, 6, # set offset to 6 for this field
240
+ # :field3, :string
241
+ # end
242
+ # @example Creating a layout from a hash +spec+ (Ruby 1.9 only)
243
+ # class MyStructFromHash < Struct
244
+ # layout :field1 => :int,
245
+ # :field2 => :pointer,
246
+ # :field3 => :string
247
+ # end
248
+ # @note Creating a layout from a hash +spec+ is supported only for Ruby 1.9.
185
249
  def layout(*spec)
186
250
  # raise RuntimeError, "struct layout already defined for #{self.inspect}" if defined?(@layout)
187
251
  return @layout if spec.size == 0
@@ -254,6 +318,11 @@ module FFI
254
318
 
255
319
  private
256
320
 
321
+ # @param [StructLayoutBuilder] builder
322
+ # @param [Hash] spec
323
+ # @return [builder]
324
+ # @raise if Ruby 1.8
325
+ # Add hash +spec+ to +builder+.
257
326
  def hash_layout(builder, spec)
258
327
  raise "Ruby version not supported" if RUBY_VERSION =~ /1.8.*/
259
328
  spec[0].each do |name, type|
@@ -261,6 +330,10 @@ module FFI
261
330
  end
262
331
  end
263
332
 
333
+ # @param [StructLayoutBuilder] builder
334
+ # @param [Array<Symbol, Integer>] spec
335
+ # @return [builder]
336
+ # Add array +spec+ to +builder+.
264
337
  def array_layout(builder, spec)
265
338
  i = 0
266
339
  while i < spec.size
@@ -19,8 +19,11 @@
19
19
  #
20
20
 
21
21
  module FFI
22
+
23
+ # Build a {StructLayout struct layout}.
22
24
  class StructLayoutBuilder
23
- attr_reader :size, :alignment
25
+ attr_reader :size
26
+ attr_reader :alignment
24
27
 
25
28
  def initialize
26
29
  @size = 0
@@ -31,23 +34,42 @@ module FFI
31
34
  @fields = Array.new
32
35
  end
33
36
 
37
+ # @param [Numeric] size
38
+ # Set size attribute with +size+ only if +size+ is greater than attribute value.
34
39
  def size=(size)
35
40
  @size = size if size > @size
36
41
  end
37
42
 
43
+ # @param [Numeric] alignment
44
+ # Set alignment attribute with +alignment+ only if it is greater than attribute value.
38
45
  def alignment=(align)
39
46
  @alignment = align if align > @alignment
40
47
  @min_alignment = align
41
48
  end
42
49
 
50
+ # @param [Boolean] is_union
51
+ # @return [is_union]
52
+ # Set union attribute.
53
+ # Set to +true+ to build a {Union} instead of a {Struct}.
43
54
  def union=(is_union)
44
55
  @union = is_union
45
56
  end
46
57
 
58
+ # @return [Boolean]
59
+ # Building a {Union} or a {Struct} ?
47
60
  def union?
48
61
  @union
49
62
  end
50
63
 
64
+ # Set packed attribute
65
+ # @overload packed=(packed)
66
+ # @param [Fixnum] packed
67
+ # @return [packed]
68
+ # Set alignment and packed attributes to +packed+.
69
+ # @overload packed=(packed)
70
+ # @param packed
71
+ # @return [0,1]
72
+ # Set packed attribute.
51
73
  def packed=(packed)
52
74
  if packed.is_a?(Fixnum)
53
75
  @alignment = packed
@@ -58,6 +80,7 @@ module FFI
58
80
  end
59
81
 
60
82
 
83
+ # List of number types
61
84
  NUMBER_TYPES = [
62
85
  Type::INT8,
63
86
  Type::UINT8,
@@ -75,6 +98,12 @@ module FFI
75
98
  Type::BOOL,
76
99
  ]
77
100
 
101
+ # @param [String, Symbol] name name of the field
102
+ # @param [Array, DataConverter, Struct, StructLayout::Field, Symbol, Type] type type of the field
103
+ # @param [Numeric, nil] offset
104
+ # @return [self]
105
+ # Add a field to the builder.
106
+ # @note Setting +offset+ to +nil+ or +-1+ is equivalent to +0+.
78
107
  def add(name, type, offset = nil)
79
108
 
80
109
  if offset.nil? || offset == -1
@@ -92,18 +121,33 @@ module FFI
92
121
  return self
93
122
  end
94
123
 
124
+ # @param (see #add)
125
+ # @return (see #add)
126
+ # Same as {#add}.
127
+ # @see #add
95
128
  def add_field(name, type, offset = nil)
96
129
  add(name, type, offset)
97
130
  end
98
131
 
132
+ # @param (see #add)
133
+ # @return (see #add)
134
+ # Add a struct as a field to the builder.
99
135
  def add_struct(name, type, offset = nil)
100
136
  add(name, Type::Struct.new(type), offset)
101
137
  end
102
138
 
139
+ # @param name (see #add)
140
+ # @param type (see #add)
141
+ # @param [Numeric] count array length
142
+ # @param offset (see #add)
143
+ # @return (see #add)
144
+ # Add an array as a field to the builder.
103
145
  def add_array(name, type, count, offset = nil)
104
146
  add(name, Type::Array.new(type, count), offset)
105
147
  end
106
148
 
149
+ # @return [StructLayout]
150
+ # Build and return the struct layout.
107
151
  def build
108
152
  # Add tail padding if the struct is not packed
109
153
  size = @packed ? @size : align(@size, @alignment)
@@ -115,10 +159,15 @@ module FFI
115
159
 
116
160
  private
117
161
 
162
+ # @param [Numeric] offset
163
+ # @param [Numeric] align
164
+ # @return [Numeric]
118
165
  def align(offset, align)
119
166
  align + ((offset - 1) & ~(align - 1));
120
167
  end
121
168
 
169
+ # @param (see #add)
170
+ # @return [StructLayout::Field]
122
171
  def field_for_type(name, offset, type)
123
172
  field_class = case
124
173
  when type.is_a?(Type::Function)
@@ -1,4 +1,6 @@
1
1
  module FFI
2
+
3
+ # @private
2
4
  class Generator
3
5
 
4
6
  def initialize(ffi_name, rb_name, options = {})
@@ -16,6 +16,7 @@ require 'tempfile'
16
16
  ##
17
17
  # Rake task that calculates C structs for FFI::Struct.
18
18
 
19
+ # @private
19
20
  class FFI::Generator::Task < Rake::TaskLib
20
21
 
21
22
  def initialize(rb_names)
@@ -1,6 +1,8 @@
1
1
  require 'tempfile'
2
2
 
3
3
  module FFI
4
+
5
+ # @private
4
6
  class TypesGenerator
5
7
 
6
8
  ##
@@ -1,21 +1,7 @@
1
1
  /*
2
2
  * Copyright (c) 2007 Wayne Meissner. All rights reserved.
3
3
  *
4
- * All rights reserved.
5
- *
6
- * This file is part of ruby-ffi.
7
- *
8
- * This code is free software: you can redistribute it and/or modify it under
9
- * the terms of the GNU Lesser General Public License version 3 only, as
10
- * published by the Free Software Foundation.
11
- *
12
- * This code is distributed in the hope that it will be useful, but WITHOUT
13
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15
- * version 3 for more details.
16
- *
17
- * You should have received a copy of the GNU Lesser General Public License
18
- * version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
4
+ * For licensing, see LICENSE.SPECS
19
5
  */
20
6
  #include <sys/types.h>
21
7
  #include <stdint.h>
@@ -1,21 +1,7 @@
1
1
  /*
2
- * Copyright (c) 2009 Aman Gupta. All rights reserved.
3
- *
4
- * All rights reserved.
2
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
5
3
  *
6
- * This file is part of ruby-ffi.
7
- *
8
- * This code is free software: you can redistribute it and/or modify it under
9
- * the terms of the GNU Lesser General Public License version 3 only, as
10
- * published by the Free Software Foundation.
11
- *
12
- * This code is distributed in the hope that it will be useful, but WITHOUT
13
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15
- * version 3 for more details.
16
- *
17
- * You should have received a copy of the GNU Lesser General Public License
18
- * version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
4
+ * For licensing, see LICENSE.SPECS
19
5
  */
20
6
 
21
7
  #include <stdbool.h>
@@ -1,21 +1,7 @@
1
- /*
2
- * Copyright (C) 2007 Wayne Meissner
3
- *
4
- * All rights reserved.
1
+ /*
2
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
5
3
  *
6
- * This file is part of ruby-ffi.
7
- *
8
- * This code is free software: you can redistribute it and/or modify it under
9
- * the terms of the GNU Lesser General Public License version 3 only, as
10
- * published by the Free Software Foundation.
11
- *
12
- * This code is distributed in the hope that it will be useful, but WITHOUT
13
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15
- * version 3 for more details.
16
- *
17
- * You should have received a copy of the GNU Lesser General Public License
18
- * version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
4
+ * For licensing, see LICENSE.SPECS
19
5
  */
20
6
 
21
7
 
@@ -1,21 +1,7 @@
1
1
  /*
2
2
  * Copyright (c) 2007 Wayne Meissner. All rights reserved.
3
- *
4
- * All rights reserved.
5
3
  *
6
- * This file is part of ruby-ffi.
7
- *
8
- * This code is free software: you can redistribute it and/or modify it under
9
- * the terms of the GNU Lesser General Public License version 3 only, as
10
- * published by the Free Software Foundation.
11
- *
12
- * This code is distributed in the hope that it will be useful, but WITHOUT
13
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15
- * version 3 for more details.
16
- *
17
- * You should have received a copy of the GNU Lesser General Public License
18
- * version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
4
+ * For licensing, see LICENSE.SPECS
19
5
  */
20
6
 
21
7
  #include <stdlib.h>
@@ -1,21 +1,7 @@
1
1
  /*
2
2
  * Copyright (c) 2007 Wayne Meissner. All rights reserved.
3
3
  *
4
- * All rights reserved.
5
- *
6
- * This file is part of ruby-ffi.
7
- *
8
- * This code is free software: you can redistribute it and/or modify it under
9
- * the terms of the GNU Lesser General Public License version 3 only, as
10
- * published by the Free Software Foundation.
11
- *
12
- * This code is distributed in the hope that it will be useful, but WITHOUT
13
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15
- * version 3 for more details.
16
- *
17
- * You should have received a copy of the GNU Lesser General Public License
18
- * version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
4
+ * For licensing, see LICENSE.SPECS
19
5
  */
20
6
 
21
7
  int test_untagged_enum(int val) {