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
data/README.md CHANGED
@@ -22,9 +22,9 @@ using Ruby-FFI [here](http://wiki.github.com/ffi/ffi/why-use-ffi).
22
22
  require 'ffi'
23
23
 
24
24
  module MyLib
25
- extend FFI::Library
26
- ffi_lib 'c'
27
- attach_function :puts, [ :string ], :int
25
+ extend FFI::Library
26
+ ffi_lib 'c'
27
+ attach_function :puts, [ :string ], :int
28
28
  end
29
29
 
30
30
  MyLib.puts 'Hello, World using libc!'
@@ -38,7 +38,10 @@ For less minimalistic and more sane examples you may look at:
38
38
 
39
39
  ## Requirements
40
40
 
41
- * You need a sane building environment in order to compile the extension.
41
+ You need a sane building environment in order to compile the extension.
42
+ At a minimum, you will need:
43
+ * A C compiler (e.g. Xcode on OSX, gcc on everything else)
44
+ * libffi development library - this is commonly in the libffi-dev or libffi-devel
42
45
 
43
46
  ## Installation
44
47
 
@@ -54,7 +57,9 @@ or from the git repository on github:
54
57
 
55
58
  ## License
56
59
 
57
- See LICENSE file.
60
+ The ffi library is covered by the LGPL3 license, also see the LICENSE file.
61
+ The specs are shared with Rubyspec and are licensed by the same license
62
+ as Rubyspec, see the LICENSE.SPECS file.
58
63
 
59
64
  ## Credits
60
65
 
@@ -126,12 +126,16 @@ array_type_element_type(VALUE self)
126
126
  void
127
127
  rbffi_ArrayType_Init(VALUE moduleFFI)
128
128
  {
129
+ VALUE ffi_Type;
130
+
131
+ ffi_Type = rbffi_TypeClass;
132
+
129
133
  /*
130
134
  * Document-class: FFI::ArrayType < FFI::Type
131
135
  *
132
136
  * This is a typed array. The type is a {NativeType native type}.
133
137
  */
134
- rbffi_ArrayTypeClass = rb_define_class_under(moduleFFI, "ArrayType", rbffi_TypeClass);
138
+ rbffi_ArrayTypeClass = rb_define_class_under(moduleFFI, "ArrayType", ffi_Type);
135
139
  /*
136
140
  * Document-variable: FFI::ArrayType
137
141
  */
@@ -139,7 +143,7 @@ rbffi_ArrayType_Init(VALUE moduleFFI)
139
143
  /*
140
144
  * Document-constant: FFI::Type::Array
141
145
  */
142
- rb_define_const(rbffi_TypeClass, "Array", rbffi_ArrayTypeClass);
146
+ rb_define_const(ffi_Type, "Array", rbffi_ArrayTypeClass);
143
147
 
144
148
  rb_define_alloc_func(rbffi_ArrayTypeClass, array_type_s_allocate);
145
149
  rb_define_method(rbffi_ArrayTypeClass, "initialize", array_type_initialize, 2);
@@ -310,12 +310,14 @@ buffer_mark(Buffer* ptr)
310
310
  void
311
311
  rbffi_Buffer_Init(VALUE moduleFFI)
312
312
  {
313
+ VALUE ffi_AbstractMemory = rbffi_AbstractMemoryClass;
314
+
313
315
  /*
314
316
  * Document-class: FFI::Buffer < FFI::AbstractMemory
315
317
  *
316
318
  * A Buffer is a function argument type. It should be use with functions playing with C arrays.
317
319
  */
318
- BufferClass = rb_define_class_under(moduleFFI, "Buffer", rbffi_AbstractMemoryClass);
320
+ BufferClass = rb_define_class_under(moduleFFI, "Buffer", ffi_AbstractMemory);
319
321
 
320
322
  /*
321
323
  * Document-variable: FFI::Buffer
@@ -79,7 +79,6 @@ typedef int bool;
79
79
 
80
80
  static void* callback_param(VALUE proc, VALUE cbinfo);
81
81
  static inline void* getPointer(VALUE value, int type);
82
- static inline char* getString(VALUE value, int type);
83
82
 
84
83
  static ID id_to_ptr, id_map_symbol, id_to_native;
85
84
 
@@ -221,7 +220,18 @@ rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes,
221
220
 
222
221
 
223
222
  case NATIVE_STRING:
224
- param->ptr = getString(argv[argidx++], type);
223
+ if (type == T_NIL) {
224
+ param->ptr = NULL;
225
+
226
+ } else {
227
+ if (rb_safe_level() >= 1 && OBJ_TAINTED(argv[argidx])) {
228
+ rb_raise(rb_eSecurityError, "Unsafe string parameter");
229
+ }
230
+
231
+ param->ptr = StringValueCStr(argv[argidx]);
232
+ ++argidx;
233
+ }
234
+
225
235
  ADJ(param, ADDRESS);
226
236
  break;
227
237
 
@@ -397,25 +407,6 @@ getPointer(VALUE value, int type)
397
407
  return NULL;
398
408
  }
399
409
 
400
- static inline char*
401
- getString(VALUE value, int type)
402
- {
403
- if (type == T_STRING) {
404
-
405
- if (rb_safe_level() >= 1 && OBJ_TAINTED(value)) {
406
- rb_raise(rb_eSecurityError, "Unsafe string parameter");
407
- }
408
-
409
- return StringValueCStr(value);
410
-
411
- } else if (type == T_NIL) {
412
- return NULL;
413
- }
414
-
415
- rb_raise(rb_eArgError, "Invalid String value");
416
- }
417
-
418
-
419
410
  Invoker
420
411
  rbffi_GetInvoker(FunctionType *fnInfo)
421
412
  {
@@ -91,6 +91,17 @@ fntype_free(FunctionType* fnInfo)
91
91
  xfree(fnInfo);
92
92
  }
93
93
 
94
+ /*
95
+ * call-seq: initialize(return_type, param_types, options={})
96
+ * @param [Type, Symbol] return_type return type for the function
97
+ * @param [Array<Type, Symbol>] param_types array of parameters types
98
+ * @param [Hash] options
99
+ * @option options [Boolean] :blocking set to true if the C function is a blocking call
100
+ * @option options [Symbol] :convention calling convention see {FFI::Library#calling_convention}
101
+ * @option options [FFI::Enums] :enums
102
+ * @return [self]
103
+ * A new FunctionType instance.
104
+ */
94
105
  static VALUE
95
106
  fntype_initialize(int argc, VALUE* argv, VALUE self)
96
107
  {
@@ -186,6 +197,11 @@ fntype_initialize(int argc, VALUE* argv, VALUE self)
186
197
  return self;
187
198
  }
188
199
 
200
+ /*
201
+ * call-seq: result_type
202
+ * @return [Type]
203
+ * Get the return type of the function type
204
+ */
189
205
  static VALUE
190
206
  fntype_result_type(VALUE self)
191
207
  {
@@ -196,6 +212,11 @@ fntype_result_type(VALUE self)
196
212
  return ft->rbReturnType;
197
213
  }
198
214
 
215
+ /*
216
+ * call-seq: param_types
217
+ * @return [Array<Type>]
218
+ * Get parameters types.
219
+ */
199
220
  static VALUE
200
221
  fntype_param_types(VALUE self)
201
222
  {
@@ -209,10 +230,14 @@ fntype_param_types(VALUE self)
209
230
  void
210
231
  rbffi_FunctionInfo_Init(VALUE moduleFFI)
211
232
  {
233
+ VALUE ffi_Type;
234
+
235
+ ffi_Type = rbffi_TypeClass;
236
+
212
237
  /*
213
238
  * Document-class: FFI::FunctionType < FFI::Type
214
239
  */
215
- rbffi_FunctionTypeClass = rb_define_class_under(moduleFFI, "FunctionType", rbffi_TypeClass);
240
+ rbffi_FunctionTypeClass = rb_define_class_under(moduleFFI, "FunctionType",ffi_Type);
216
241
  rb_global_variable(&rbffi_FunctionTypeClass);
217
242
  /*
218
243
  * Document-const: FFI::CallbackInfo = FFI::FunctionType
@@ -225,7 +250,7 @@ rbffi_FunctionInfo_Init(VALUE moduleFFI)
225
250
  /*
226
251
  * Document-const: FFI::Type::Function = FFI::FunctionType
227
252
  */
228
- rb_define_const(rbffi_TypeClass, "Function", rbffi_FunctionTypeClass);
253
+ rb_define_const(ffi_Type, "Function", rbffi_FunctionTypeClass);
229
254
 
230
255
  rb_define_alloc_func(rbffi_FunctionTypeClass, fntype_allocate);
231
256
  rb_define_method(rbffi_FunctionTypeClass, "initialize", fntype_initialize, -1);
@@ -138,9 +138,8 @@ mapped_from_native(int argc, VALUE* argv, VALUE self)
138
138
  void
139
139
  rbffi_MappedType_Init(VALUE moduleFFI)
140
140
  {
141
-
142
141
  /*
143
- * Document-class: FFI::Type::Mapped
142
+ * Document-class: FFI::Type::Mapped < FFI::Type
144
143
  */
145
144
  rbffi_MappedTypeClass = rb_define_class_under(rbffi_TypeClass, "Mapped", rbffi_TypeClass);
146
145
 
@@ -63,6 +63,14 @@ memptr_allocate(VALUE klass)
63
63
  return obj;
64
64
  }
65
65
 
66
+ /*
67
+ * call-seq: initialize(size, count=1, clear=true)
68
+ * @param [Fixnum, Bignum, Symbol, FFI::Type] size size of a memory cell (in bytes, or type whom size will be used)
69
+ * @param [Numeric] count number of cells in memory
70
+ * @param [Boolean] clear set memory to all-zero if +true+
71
+ * @return [self]
72
+ * A new instance of FFI::MeoryPointer.
73
+ */
66
74
  static VALUE
67
75
  memptr_initialize(int argc, VALUE* argv, VALUE self)
68
76
  {
@@ -71,7 +79,7 @@ memptr_initialize(int argc, VALUE* argv, VALUE self)
71
79
 
72
80
  memptr_malloc(self, rbffi_type_size(size), nargs > 1 ? NUM2LONG(count) : 1,
73
81
  RTEST(clear) || clear == Qnil);
74
-
82
+
75
83
  if (rb_block_given_p()) {
76
84
  return rb_ensure(rb_yield, self, memptr_free, self);
77
85
  }
@@ -100,7 +108,7 @@ memptr_malloc(VALUE self, long size, long count, bool clear)
100
108
  /* ensure the memory is aligned on at least a 8 byte boundary */
101
109
  p->memory.address = (char *) (((uintptr_t) p->storage + 0x7) & (uintptr_t) ~0x7UL);;
102
110
  p->allocated = true;
103
-
111
+
104
112
  if (clear && p->memory.size > 0) {
105
113
  memset(p->memory.address, 0, p->memory.size);
106
114
  }
@@ -136,6 +144,12 @@ memptr_release(Pointer* ptr)
136
144
  xfree(ptr);
137
145
  }
138
146
 
147
+ /*
148
+ * call-seq: from_string(s)
149
+ * @param [String] s string
150
+ * @return [MemoryPointer]
151
+ * Create a {MemoryPointer} with +s+ inside.
152
+ */
139
153
  static VALUE
140
154
  memptr_s_from_string(VALUE klass, VALUE to_str)
141
155
  {
@@ -143,14 +157,31 @@ memptr_s_from_string(VALUE klass, VALUE to_str)
143
157
  VALUE args[] = { INT2FIX(1), LONG2NUM(RSTRING_LEN(s) + 1), Qfalse };
144
158
  VALUE obj = rb_class_new_instance(3, args, klass);
145
159
  rb_funcall(obj, rb_intern("put_string"), 2, INT2FIX(0), s);
146
-
160
+
147
161
  return obj;
148
162
  }
149
163
 
150
164
  void
151
165
  rbffi_MemoryPointer_Init(VALUE moduleFFI)
152
166
  {
153
- rbffi_MemoryPointerClass = rb_define_class_under(moduleFFI, "MemoryPointer", rbffi_PointerClass);
167
+ VALUE ffi_Pointer;
168
+
169
+ ffi_Pointer = rbffi_PointerClass;
170
+
171
+ /*
172
+ * Document-class: FFI::MemoryPointer < FFI::Pointer
173
+ * A MemoryPointer is a specific {Pointer}. It points to a memory composed of cells. All cells have the
174
+ * same size.
175
+ *
176
+ * @example Create a new MemoryPointer
177
+ * mp = FFI::MemoryPointer.new(:long, 16) # Create a pointer on a memory of 16 long ints.
178
+ * @example Create a new MemoryPointer from a String
179
+ * mp1 = FFI::MemoryPointer.from_string("this is a string")
180
+ * # same as:
181
+ * mp2 = FFI::MemoryPointer.new(:char,16)
182
+ * mp2.put_string("this is a string")
183
+ */
184
+ rbffi_MemoryPointerClass = rb_define_class_under(moduleFFI, "MemoryPointer", ffi_Pointer);
154
185
  rb_global_variable(&rbffi_MemoryPointerClass);
155
186
 
156
187
  rb_define_alloc_func(rbffi_MemoryPointerClass, memptr_allocate);
@@ -322,9 +322,9 @@ ptr_address(VALUE self)
322
322
 
323
323
  /*
324
324
  * Get or set +self+'s endianness
325
- * @overload ptr.order
325
+ * @overload order
326
326
  * @return [:big, :little] endianness of +self+
327
- * @overload ptr.order(order)
327
+ * @overload order(order)
328
328
  * @param [Symbol] order endianness to set (+:little+, +:big+ or +:network+). +:big+ and +:network+
329
329
  * are synonymous.
330
330
  * @return [self]
@@ -449,8 +449,9 @@ void
449
449
  rbffi_Pointer_Init(VALUE moduleFFI)
450
450
  {
451
451
  VALUE rbNullAddress = ULL2NUM(0);
452
+ VALUE ffi_AbstractMemory = rbffi_AbstractMemoryClass;
452
453
 
453
- /*
454
+ /*
454
455
  * Document-class: FFI::Pointer < FFI::AbstractMemory
455
456
  * Pointer class is used to manage C pointers with ease. A {Pointer} object is defined by his
456
457
  * {#address} (as a C pointer). It permits additions with an integer for pointer arithmetic.
@@ -459,7 +460,7 @@ rbffi_Pointer_Init(VALUE moduleFFI)
459
460
  * A pointer object may autorelease his contents when freed (by default). This behaviour may be
460
461
  * changed with {#autorelease=} method.
461
462
  */
462
- rbffi_PointerClass = rb_define_class_under(moduleFFI, "Pointer", rbffi_AbstractMemoryClass);
463
+ rbffi_PointerClass = rb_define_class_under(moduleFFI, "Pointer", ffi_AbstractMemory);
463
464
  /*
464
465
  * Document-variable: Pointer
465
466
  */
@@ -90,6 +90,13 @@ struct_allocate(VALUE klass)
90
90
  return obj;
91
91
  }
92
92
 
93
+ /*
94
+ * call-seq: initialize
95
+ * @overload initialize(pointer, *args)
96
+ * @param [AbstractMemory] pointer
97
+ * @param [Array] args
98
+ * @return [self]
99
+ */
93
100
  static VALUE
94
101
  struct_initialize(int argc, VALUE* argv, VALUE self)
95
102
  {
@@ -124,6 +131,11 @@ struct_initialize(int argc, VALUE* argv, VALUE self)
124
131
  return self;
125
132
  }
126
133
 
134
+ /*
135
+ * call-seq: initialize_copy(other)
136
+ * @return [nil]
137
+ * DO NOT CALL THIS METHOD
138
+ */
127
139
  static VALUE
128
140
  struct_initialize_copy(VALUE self, VALUE other)
129
141
  {
@@ -165,11 +177,11 @@ static VALUE
165
177
  struct_class_layout(VALUE klass)
166
178
  {
167
179
  VALUE layout;
168
- if (!rb_cvar_defined(klass, id_layout_ivar)) {
180
+ if (!rb_ivar_defined(klass, id_layout_ivar)) {
169
181
  rb_raise(rb_eRuntimeError, "no Struct layout configured for %s", rb_class2name(klass));
170
182
  }
171
183
 
172
- layout = rb_cvar_get(klass, id_layout_ivar);
184
+ layout = rb_ivar_get(klass, id_layout_ivar);
173
185
  if (!rb_obj_is_kind_of(layout, rbffi_StructLayoutClass)) {
174
186
  rb_raise(rb_eRuntimeError, "invalid Struct layout for %s", rb_class2name(klass));
175
187
  }
@@ -279,6 +291,11 @@ struct_field(Struct* s, VALUE fieldName)
279
291
  return rbField;
280
292
  }
281
293
 
294
+ /*
295
+ * call-seq: struct[field_name]
296
+ * @param field_name field to access
297
+ * Acces to a Struct field.
298
+ */
282
299
  static VALUE
283
300
  struct_aref(VALUE self, VALUE fieldName)
284
301
  {
@@ -304,6 +321,13 @@ struct_aref(VALUE self, VALUE fieldName)
304
321
  }
305
322
  }
306
323
 
324
+ /*
325
+ * call-seq: []=(field_name, value)
326
+ * @param field_name field to access
327
+ * @param value value to set to +field_name+
328
+ * @return [value]
329
+ * Set a field in Struct.
330
+ */
307
331
  static VALUE
308
332
  struct_aset(VALUE self, VALUE fieldName, VALUE value)
309
333
  {
@@ -338,6 +362,12 @@ struct_aset(VALUE self, VALUE fieldName, VALUE value)
338
362
  return value;
339
363
  }
340
364
 
365
+ /*
366
+ * call-seq: pointer= pointer
367
+ * @param [AbstractMemory] pointer
368
+ * @return [self]
369
+ * Make Struct point to +pointer+.
370
+ */
341
371
  static VALUE
342
372
  struct_set_pointer(VALUE self, VALUE pointer)
343
373
  {
@@ -368,6 +398,11 @@ struct_set_pointer(VALUE self, VALUE pointer)
368
398
  return self;
369
399
  }
370
400
 
401
+ /*
402
+ * call-seq: pointer
403
+ * @return [AbstractMemory]
404
+ * Get pointer to Struct contents.
405
+ */
371
406
  static VALUE
372
407
  struct_get_pointer(VALUE self)
373
408
  {
@@ -378,6 +413,12 @@ struct_get_pointer(VALUE self)
378
413
  return s->rbPointer;
379
414
  }
380
415
 
416
+ /*
417
+ * call-seq: layout= layout
418
+ * @param [StructLayout] layout
419
+ * @return [self]
420
+ * Set the Struct's layout.
421
+ */
381
422
  static VALUE
382
423
  struct_set_layout(VALUE self, VALUE layout)
383
424
  {
@@ -396,6 +437,11 @@ struct_set_layout(VALUE self, VALUE layout)
396
437
  return self;
397
438
  }
398
439
 
440
+ /*
441
+ * call-seq: layout
442
+ * @return [StructLayout]
443
+ * Get the Struct's layout.
444
+ */
399
445
  static VALUE
400
446
  struct_get_layout(VALUE self)
401
447
  {
@@ -406,7 +452,11 @@ struct_get_layout(VALUE self)
406
452
  return s->rbLayout;
407
453
  }
408
454
 
409
-
455
+ /*
456
+ * call-seq: null?
457
+ * @return [Boolean]
458
+ * Test if Struct's pointer is NULL
459
+ */
410
460
  static VALUE
411
461
  struct_null_p(VALUE self)
412
462
  {
@@ -417,6 +467,9 @@ struct_null_p(VALUE self)
417
467
  return s->pointer->address == NULL ? Qtrue : Qfalse;
418
468
  }
419
469
 
470
+ /*
471
+ * (see Pointer#order)
472
+ */
420
473
  static VALUE
421
474
  struct_order(int argc, VALUE* argv, VALUE self)
422
475
  {
@@ -435,7 +488,6 @@ struct_order(int argc, VALUE* argv, VALUE self)
435
488
  }
436
489
  }
437
490
 
438
-
439
491
  static VALUE
440
492
  inline_array_allocate(VALUE klass)
441
493
  {
@@ -456,6 +508,13 @@ inline_array_mark(InlineArray* array)
456
508
  rb_gc_mark(array->rbMemory);
457
509
  }
458
510
 
511
+ /*
512
+ * Document-method: FFI::Struct::InlineArray#initialize
513
+ * call-seq: initialize(memory, field)
514
+ * @param [AbstractMemory] memory
515
+ * @param [StructField] field
516
+ * @return [self]
517
+ */
459
518
  static VALUE
460
519
  inline_array_initialize(VALUE self, VALUE rbMemory, VALUE rbField)
461
520
  {
@@ -480,6 +539,11 @@ inline_array_initialize(VALUE self, VALUE rbMemory, VALUE rbField)
480
539
  return self;
481
540
  }
482
541
 
542
+ /*
543
+ * call-seq: size
544
+ * @return [Numeric]
545
+ * Get size
546
+ */
483
547
  static VALUE
484
548
  inline_array_size(VALUE self)
485
549
  {
@@ -500,6 +564,11 @@ inline_array_offset(InlineArray* array, int index)
500
564
  return (int) array->field->offset + (index * (int) array->componentType->ffiType->size);
501
565
  }
502
566
 
567
+ /*
568
+ * call-seq: [](index)
569
+ * @param [Numeric] index
570
+ * @return [Type, Struct]
571
+ */
503
572
  static VALUE
504
573
  inline_array_aref(VALUE self, VALUE rbIndex)
505
574
  {
@@ -530,6 +599,12 @@ inline_array_aref(VALUE self, VALUE rbIndex)
530
599
  }
531
600
  }
532
601
 
602
+ /*
603
+ * call-seq: []=(index, value)
604
+ * @param [Numeric] index
605
+ * @param [Type, Struct]
606
+ * @return [value]
607
+ */
533
608
  static VALUE
534
609
  inline_array_aset(VALUE self, VALUE rbIndex, VALUE rbValue)
535
610
  {
@@ -574,6 +649,10 @@ inline_array_aset(VALUE self, VALUE rbIndex, VALUE rbValue)
574
649
  return rbValue;
575
650
  }
576
651
 
652
+ /*
653
+ * call-seq: each
654
+ * Yield block for each element of +self+.
655
+ */
577
656
  static VALUE
578
657
  inline_array_each(VALUE self)
579
658
  {
@@ -590,6 +669,11 @@ inline_array_each(VALUE self)
590
669
  return self;
591
670
  }
592
671
 
672
+ /*
673
+ * call-seq: to_a
674
+ * @return [Array]
675
+ * Convert +self+ to an array.
676
+ */
593
677
  static VALUE
594
678
  inline_array_to_a(VALUE self)
595
679
  {
@@ -608,6 +692,12 @@ inline_array_to_a(VALUE self)
608
692
  return obj;
609
693
  }
610
694
 
695
+ /*
696
+ * Document-method: FFI::StructLayout::CharArray#to_s
697
+ * call-seq: to_s
698
+ * @return [String]
699
+ * Convert +self+ to a string.
700
+ */
611
701
  static VALUE
612
702
  inline_array_to_s(VALUE self)
613
703
  {
@@ -627,7 +717,11 @@ inline_array_to_s(VALUE self)
627
717
  return rb_funcall2(array->rbMemory, rb_intern("get_string"), 2, argv);
628
718
  }
629
719
 
630
-
720
+ /*
721
+ * call-seq: to_ptr
722
+ * @return [AbstractMemory]
723
+ * Get pointer to +self+ content.
724
+ */
631
725
  static VALUE
632
726
  inline_array_to_ptr(VALUE self)
633
727
  {
@@ -647,14 +741,37 @@ rbffi_Struct_Init(VALUE moduleFFI)
647
741
 
648
742
  rbffi_StructLayout_Init(moduleFFI);
649
743
 
650
- rbffi_StructClass = StructClass = rb_define_class_under(moduleFFI, "Struct", rb_cObject);
744
+ /*
745
+ * Document-class: FFI::Struct
746
+ *
747
+ * A FFI::Struct means to mirror a C struct.
748
+ *
749
+ * A Struct is defined as:
750
+ * class MyStruct < FFI::Struct
751
+ * layout :value1, :int,
752
+ * :value2, :double
753
+ * end
754
+ * and is used as:
755
+ * my_struct = MyStruct.new
756
+ * my_struct[:value1] = 12
757
+ *
758
+ * For more information, see http://github.com/ffi/ffi/wiki/Structs
759
+ */
760
+ rbffi_StructClass = rb_define_class_under(moduleFFI, "Struct", rb_cObject);
761
+ StructClass = rbffi_StructClass; // put on a line alone to help RDoc
651
762
  rb_global_variable(&rbffi_StructClass);
652
763
 
764
+ /*
765
+ * Document-class: FFI::Struct::InlineArray
766
+ */
653
767
  rbffi_StructInlineArrayClass = rb_define_class_under(rbffi_StructClass, "InlineArray", rb_cObject);
654
768
  rb_global_variable(&rbffi_StructInlineArrayClass);
655
769
 
656
- rbffi_StructLayoutCharArrayClass = rb_define_class_under(rbffi_StructLayoutClass,
657
- "CharArray", rbffi_StructInlineArrayClass);
770
+ /*
771
+ * Document-class: FFI::StructLayout::CharArray < FFI::Struct::InlineArray
772
+ */
773
+ rbffi_StructLayoutCharArrayClass = rb_define_class_under(rbffi_StructLayoutClass, "CharArray",
774
+ rbffi_StructInlineArrayClass);
658
775
  rb_global_variable(&rbffi_StructLayoutCharArrayClass);
659
776
 
660
777