ffi 0.2.0 → 0.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 (305) hide show
  1. data/README.rdoc +19 -0
  2. data/Rakefile +65 -55
  3. data/ext/{AbstractMemory.c → ffi_c/AbstractMemory.c} +67 -40
  4. data/ext/{AbstractMemory.h → ffi_c/AbstractMemory.h} +10 -8
  5. data/ext/{AutoPointer.c → ffi_c/AutoPointer.c} +17 -8
  6. data/ext/{AutoPointer.h → ffi_c/AutoPointer.h} +0 -0
  7. data/ext/ffi_c/Buffer.c +136 -0
  8. data/ext/{Callback.c → ffi_c/Callback.c} +60 -35
  9. data/ext/{Callback.h → ffi_c/Callback.h} +1 -7
  10. data/ext/{Invoker.c → ffi_c/Invoker.c} +472 -102
  11. data/ext/ffi_c/MemoryPointer.c +146 -0
  12. data/ext/{MemoryPointer.h → ffi_c/MemoryPointer.h} +2 -7
  13. data/ext/ffi_c/NativeLibrary.c +149 -0
  14. data/ext/{NativeLibrary.h → ffi_c/NativeLibrary.h} +0 -0
  15. data/ext/ffi_c/NullPointer.c +104 -0
  16. data/ext/{Platform.c → ffi_c/Platform.c} +0 -0
  17. data/ext/{Platform.h → ffi_c/Platform.h} +0 -7
  18. data/ext/{Pointer.c → ffi_c/Pointer.c} +35 -15
  19. data/ext/{Pointer.h → ffi_c/Pointer.h} +4 -2
  20. data/ext/ffi_c/Struct.c +542 -0
  21. data/ext/ffi_c/Struct.h +26 -0
  22. data/ext/ffi_c/Types.c +76 -0
  23. data/ext/{Types.h → ffi_c/Types.h} +23 -28
  24. data/ext/{compat.h → ffi_c/compat.h} +2 -2
  25. data/ext/{extconf.rb → ffi_c/extconf.rb} +12 -7
  26. data/ext/ffi_c/ffi.c +99 -0
  27. data/ext/ffi_c/ffi.mk +23 -0
  28. data/ext/{libffi.darwin.mk → ffi_c/libffi.darwin.mk} +0 -0
  29. data/ext/ffi_c/libffi.mk +11 -0
  30. data/ext/{libffi → ffi_c/libffi}/ChangeLog +0 -0
  31. data/ext/{libffi → ffi_c/libffi}/ChangeLog.libffi +0 -0
  32. data/ext/{libffi → ffi_c/libffi}/ChangeLog.libgcj +0 -0
  33. data/ext/{libffi → ffi_c/libffi}/ChangeLog.v1 +0 -0
  34. data/ext/{libffi → ffi_c/libffi}/LICENSE +0 -0
  35. data/ext/{libffi → ffi_c/libffi}/Makefile.am +0 -0
  36. data/ext/{libffi → ffi_c/libffi}/Makefile.in +0 -0
  37. data/ext/{libffi → ffi_c/libffi}/README +0 -0
  38. data/ext/{libffi → ffi_c/libffi}/TODO +0 -0
  39. data/ext/{libffi → ffi_c/libffi}/acinclude.m4 +0 -0
  40. data/ext/{libffi → ffi_c/libffi}/aclocal.m4 +0 -0
  41. data/ext/{libffi → ffi_c/libffi}/compile +0 -0
  42. data/ext/{libffi → ffi_c/libffi}/config.guess +0 -0
  43. data/ext/{libffi → ffi_c/libffi}/config.sub +0 -0
  44. data/ext/{libffi → ffi_c/libffi}/configure +0 -0
  45. data/ext/{libffi → ffi_c/libffi}/configure.ac +0 -0
  46. data/ext/{libffi → ffi_c/libffi}/configure.host +0 -0
  47. data/ext/{libffi → ffi_c/libffi}/depcomp +0 -0
  48. data/ext/{libffi → ffi_c/libffi}/doc/libffi.info +0 -0
  49. data/ext/{libffi → ffi_c/libffi}/doc/libffi.texi +0 -0
  50. data/ext/{libffi → ffi_c/libffi}/doc/stamp-vti +0 -0
  51. data/ext/{libffi → ffi_c/libffi}/doc/version.texi +0 -0
  52. data/ext/{libffi → ffi_c/libffi}/fficonfig.h.in +0 -0
  53. data/ext/{libffi → ffi_c/libffi}/include/Makefile.am +0 -0
  54. data/ext/{libffi → ffi_c/libffi}/include/Makefile.in +0 -0
  55. data/ext/{libffi → ffi_c/libffi}/include/ffi.h.in +0 -0
  56. data/ext/{libffi → ffi_c/libffi}/include/ffi_common.h +0 -0
  57. data/ext/{libffi → ffi_c/libffi}/install-sh +0 -0
  58. data/ext/{libffi → ffi_c/libffi}/libffi.pc.in +0 -0
  59. data/ext/{libffi → ffi_c/libffi}/libtool-version +0 -0
  60. data/ext/{libffi → ffi_c/libffi}/ltcf-c.sh +0 -0
  61. data/ext/{libffi → ffi_c/libffi}/ltcf-cxx.sh +0 -0
  62. data/ext/{libffi → ffi_c/libffi}/ltcf-gcj.sh +0 -0
  63. data/ext/{libffi → ffi_c/libffi}/ltconfig +0 -0
  64. data/ext/{libffi → ffi_c/libffi}/ltmain.sh +0 -0
  65. data/ext/{libffi → ffi_c/libffi}/man/Makefile.am +0 -0
  66. data/ext/{libffi → ffi_c/libffi}/man/Makefile.in +0 -0
  67. data/ext/{libffi → ffi_c/libffi}/man/ffi.3 +0 -0
  68. data/ext/{libffi → ffi_c/libffi}/man/ffi_call.3 +0 -0
  69. data/ext/{libffi → ffi_c/libffi}/man/ffi_prep_cif.3 +0 -0
  70. data/ext/{libffi → ffi_c/libffi}/mdate-sh +0 -0
  71. data/ext/{libffi → ffi_c/libffi}/missing +0 -0
  72. data/ext/{libffi → ffi_c/libffi}/mkinstalldirs +0 -0
  73. data/ext/{libffi → ffi_c/libffi}/src/alpha/ffi.c +0 -0
  74. data/ext/{libffi → ffi_c/libffi}/src/alpha/ffitarget.h +0 -0
  75. data/ext/{libffi → ffi_c/libffi}/src/alpha/osf.S +0 -0
  76. data/ext/{libffi → ffi_c/libffi}/src/arm/ffi.c +0 -0
  77. data/ext/{libffi → ffi_c/libffi}/src/arm/ffitarget.h +0 -0
  78. data/ext/{libffi → ffi_c/libffi}/src/arm/sysv.S +0 -0
  79. data/ext/{libffi → ffi_c/libffi}/src/closures.c +0 -0
  80. data/ext/{libffi → ffi_c/libffi}/src/cris/ffi.c +0 -0
  81. data/ext/{libffi → ffi_c/libffi}/src/cris/ffitarget.h +0 -0
  82. data/ext/{libffi → ffi_c/libffi}/src/cris/sysv.S +0 -0
  83. data/ext/{libffi → ffi_c/libffi}/src/debug.c +0 -0
  84. data/ext/{libffi → ffi_c/libffi}/src/dlmalloc.c +0 -0
  85. data/ext/{libffi → ffi_c/libffi}/src/frv/eabi.S +0 -0
  86. data/ext/{libffi → ffi_c/libffi}/src/frv/ffi.c +0 -0
  87. data/ext/{libffi → ffi_c/libffi}/src/frv/ffitarget.h +0 -0
  88. data/ext/{libffi → ffi_c/libffi}/src/ia64/ffi.c +0 -0
  89. data/ext/{libffi → ffi_c/libffi}/src/ia64/ffitarget.h +0 -0
  90. data/ext/{libffi → ffi_c/libffi}/src/ia64/ia64_flags.h +0 -0
  91. data/ext/{libffi → ffi_c/libffi}/src/ia64/unix.S +0 -0
  92. data/ext/{libffi → ffi_c/libffi}/src/java_raw_api.c +0 -0
  93. data/ext/{libffi → ffi_c/libffi}/src/m32r/ffi.c +0 -0
  94. data/ext/{libffi → ffi_c/libffi}/src/m32r/ffitarget.h +0 -0
  95. data/ext/{libffi → ffi_c/libffi}/src/m32r/sysv.S +0 -0
  96. data/ext/{libffi → ffi_c/libffi}/src/m68k/ffi.c +0 -0
  97. data/ext/{libffi → ffi_c/libffi}/src/m68k/ffitarget.h +0 -0
  98. data/ext/{libffi → ffi_c/libffi}/src/m68k/sysv.S +0 -0
  99. data/ext/{libffi → ffi_c/libffi}/src/mips/ffi.c +0 -0
  100. data/ext/{libffi → ffi_c/libffi}/src/mips/ffitarget.h +0 -0
  101. data/ext/{libffi → ffi_c/libffi}/src/mips/n32.S +0 -0
  102. data/ext/{libffi → ffi_c/libffi}/src/mips/o32.S +0 -0
  103. data/ext/{libffi → ffi_c/libffi}/src/pa/ffi.c +0 -0
  104. data/ext/{libffi → ffi_c/libffi}/src/pa/ffitarget.h +0 -0
  105. data/ext/{libffi → ffi_c/libffi}/src/pa/hpux32.S +0 -0
  106. data/ext/{libffi → ffi_c/libffi}/src/pa/linux.S +0 -0
  107. data/ext/{libffi → ffi_c/libffi}/src/powerpc/aix.S +0 -0
  108. data/ext/{libffi → ffi_c/libffi}/src/powerpc/aix_closure.S +0 -0
  109. data/ext/{libffi → ffi_c/libffi}/src/powerpc/asm.h +0 -0
  110. data/ext/{libffi → ffi_c/libffi}/src/powerpc/darwin.S +0 -0
  111. data/ext/{libffi → ffi_c/libffi}/src/powerpc/darwin_closure.S +0 -0
  112. data/ext/{libffi → ffi_c/libffi}/src/powerpc/ffi.c +0 -0
  113. data/ext/{libffi → ffi_c/libffi}/src/powerpc/ffi_darwin.c +0 -0
  114. data/ext/{libffi → ffi_c/libffi}/src/powerpc/ffitarget.h +0 -0
  115. data/ext/{libffi → ffi_c/libffi}/src/powerpc/linux64.S +0 -0
  116. data/ext/{libffi → ffi_c/libffi}/src/powerpc/linux64_closure.S +0 -0
  117. data/ext/{libffi → ffi_c/libffi}/src/powerpc/ppc_closure.S +0 -0
  118. data/ext/{libffi → ffi_c/libffi}/src/powerpc/sysv.S +0 -0
  119. data/ext/{libffi → ffi_c/libffi}/src/prep_cif.c +0 -0
  120. data/ext/{libffi → ffi_c/libffi}/src/raw_api.c +0 -0
  121. data/ext/{libffi → ffi_c/libffi}/src/s390/ffi.c +0 -0
  122. data/ext/{libffi → ffi_c/libffi}/src/s390/ffitarget.h +0 -0
  123. data/ext/{libffi → ffi_c/libffi}/src/s390/sysv.S +0 -0
  124. data/ext/{libffi → ffi_c/libffi}/src/sh/ffi.c +0 -0
  125. data/ext/{libffi → ffi_c/libffi}/src/sh/ffitarget.h +0 -0
  126. data/ext/{libffi → ffi_c/libffi}/src/sh/sysv.S +0 -0
  127. data/ext/{libffi → ffi_c/libffi}/src/sh64/ffi.c +0 -0
  128. data/ext/{libffi → ffi_c/libffi}/src/sh64/ffitarget.h +0 -0
  129. data/ext/{libffi → ffi_c/libffi}/src/sh64/sysv.S +0 -0
  130. data/ext/{libffi → ffi_c/libffi}/src/sparc/ffi.c +0 -0
  131. data/ext/{libffi → ffi_c/libffi}/src/sparc/ffitarget.h +0 -0
  132. data/ext/{libffi → ffi_c/libffi}/src/sparc/v8.S +0 -0
  133. data/ext/{libffi → ffi_c/libffi}/src/sparc/v9.S +0 -0
  134. data/ext/{libffi → ffi_c/libffi}/src/types.c +0 -0
  135. data/ext/{libffi → ffi_c/libffi}/src/x86/darwin.S +0 -0
  136. data/ext/{libffi → ffi_c/libffi}/src/x86/darwin64.S +0 -0
  137. data/ext/{libffi → ffi_c/libffi}/src/x86/ffi.c +0 -0
  138. data/ext/{libffi → ffi_c/libffi}/src/x86/ffi64.c +0 -0
  139. data/ext/{libffi → ffi_c/libffi}/src/x86/ffitarget.h +0 -0
  140. data/ext/{libffi → ffi_c/libffi}/src/x86/freebsd.S +0 -0
  141. data/ext/{libffi → ffi_c/libffi}/src/x86/sysv.S +0 -0
  142. data/ext/{libffi → ffi_c/libffi}/src/x86/unix64.S +0 -0
  143. data/ext/{libffi → ffi_c/libffi}/src/x86/win32.S +0 -0
  144. data/ext/{libffi → ffi_c/libffi}/testsuite/Makefile.am +0 -0
  145. data/ext/{libffi → ffi_c/libffi}/testsuite/Makefile.in +0 -0
  146. data/ext/{libffi → ffi_c/libffi}/testsuite/config/default.exp +0 -0
  147. data/ext/{libffi → ffi_c/libffi}/testsuite/lib/libffi-dg.exp +0 -0
  148. data/ext/{libffi → ffi_c/libffi}/testsuite/lib/target-libpath.exp +0 -0
  149. data/ext/{libffi → ffi_c/libffi}/testsuite/lib/wrapper.exp +0 -0
  150. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/call.exp +0 -0
  151. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn0.c +0 -0
  152. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn1.c +0 -0
  153. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn2.c +0 -0
  154. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn3.c +0 -0
  155. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn4.c +0 -0
  156. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn5.c +0 -0
  157. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn6.c +0 -0
  158. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_stdcall.c +0 -0
  159. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_12byte.c +0 -0
  160. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_16byte.c +0 -0
  161. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_18byte.c +0 -0
  162. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_19byte.c +0 -0
  163. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_1_1byte.c +0 -0
  164. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_20byte.c +0 -0
  165. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_20byte1.c +0 -0
  166. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_24byte.c +0 -0
  167. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_2byte.c +0 -0
  168. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_3_1byte.c +0 -0
  169. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_3byte1.c +0 -0
  170. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_3byte2.c +0 -0
  171. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_4_1byte.c +0 -0
  172. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_4byte.c +0 -0
  173. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_5_1_byte.c +0 -0
  174. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_5byte.c +0 -0
  175. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_64byte.c +0 -0
  176. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_6_1_byte.c +0 -0
  177. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_6byte.c +0 -0
  178. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_7_1_byte.c +0 -0
  179. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_7byte.c +0 -0
  180. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_8byte.c +0 -0
  181. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_9byte1.c +0 -0
  182. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_9byte2.c +0 -0
  183. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_double.c +0 -0
  184. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_float.c +0 -0
  185. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_longdouble.c +0 -0
  186. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_pointer.c +0 -0
  187. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_sint16.c +0 -0
  188. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_sint32.c +0 -0
  189. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_sint64.c +0 -0
  190. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_uint16.c +0 -0
  191. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_uint32.c +0 -0
  192. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_uint64.c +0 -0
  193. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_double.c +0 -0
  194. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_float.c +0 -0
  195. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_schar.c +0 -0
  196. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_sshort.c +0 -0
  197. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_sshortchar.c +0 -0
  198. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_uchar.c +0 -0
  199. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_ushort.c +0 -0
  200. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_ushortchar.c +0 -0
  201. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_schar.c +0 -0
  202. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_sint.c +0 -0
  203. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_sshort.c +0 -0
  204. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_uchar.c +0 -0
  205. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_uint.c +0 -0
  206. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_ulonglong.c +0 -0
  207. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_ushort.c +0 -0
  208. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/ffitest.h +0 -0
  209. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/float.c +0 -0
  210. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/float1.c +0 -0
  211. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/float2.c +0 -0
  212. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/float3.c +0 -0
  213. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/float4.c +0 -0
  214. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/many.c +0 -0
  215. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/many_win32.c +0 -0
  216. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/negint.c +0 -0
  217. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct.c +0 -0
  218. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct1.c +0 -0
  219. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct10.c +0 -0
  220. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct2.c +0 -0
  221. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct3.c +0 -0
  222. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct4.c +0 -0
  223. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct5.c +0 -0
  224. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct6.c +0 -0
  225. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct7.c +0 -0
  226. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct8.c +0 -0
  227. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct9.c +0 -0
  228. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/problem1.c +0 -0
  229. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/promotion.c +0 -0
  230. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/pyobjc-tc.c +0 -0
  231. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_dbl.c +0 -0
  232. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_dbl1.c +0 -0
  233. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_dbl2.c +0 -0
  234. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_fl.c +0 -0
  235. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_fl1.c +0 -0
  236. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_fl2.c +0 -0
  237. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_fl3.c +0 -0
  238. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_ldl.c +0 -0
  239. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_ll.c +0 -0
  240. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_ll1.c +0 -0
  241. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_sc.c +0 -0
  242. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_sl.c +0 -0
  243. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_uc.c +0 -0
  244. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_ul.c +0 -0
  245. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/strlen.c +0 -0
  246. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/strlen_win32.c +0 -0
  247. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct1.c +0 -0
  248. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct2.c +0 -0
  249. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct3.c +0 -0
  250. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct4.c +0 -0
  251. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct5.c +0 -0
  252. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct6.c +0 -0
  253. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct7.c +0 -0
  254. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct8.c +0 -0
  255. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct9.c +0 -0
  256. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.special/ffitestcxx.h +0 -0
  257. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.special/special.exp +0 -0
  258. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.special/unwindtest.cc +0 -0
  259. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.special/unwindtest_ffi_call.cc +0 -0
  260. data/ext/{libffi → ffi_c/libffi}/texinfo.tex +0 -0
  261. data/ext/{rbffi.h → ffi_c/rbffi.h} +1 -8
  262. data/lib/ffi/autopointer.rb +7 -7
  263. data/lib/ffi/buffer.rb +0 -25
  264. data/lib/ffi/ffi.rb +1 -0
  265. data/lib/ffi/library.rb +103 -37
  266. data/lib/ffi/memorypointer.rb +25 -28
  267. data/lib/ffi/platform.rb +2 -2
  268. data/lib/ffi/pointer.rb +21 -7
  269. data/lib/ffi/struct.rb +161 -179
  270. data/lib/ffi/types.rb +3 -3
  271. data/lib/ffi/union.rb +17 -0
  272. data/nbproject/configurations.xml +98 -88
  273. data/samples/hello.rb +1 -2
  274. data/samples/sample_helper.rb +6 -0
  275. data/{specs → spec/ffi}/buffer_spec.rb +0 -0
  276. data/{specs → spec/ffi}/callback_spec.rb +114 -89
  277. data/{specs → spec/ffi}/errno_spec.rb +0 -0
  278. data/spec/ffi/library_spec.rb +144 -0
  279. data/{specs → spec/ffi}/managed_struct_spec.rb +12 -1
  280. data/{specs → spec/ffi}/number_spec.rb +34 -16
  281. data/{specs → spec/ffi}/pointer_spec.rb +46 -2
  282. data/{specs → spec/ffi}/rbx/attach_function_spec.rb +2 -1
  283. data/{specs → spec/ffi}/rbx/memory_pointer_spec.rb +19 -19
  284. data/{specs → spec/ffi}/rbx/spec_helper.rb +0 -0
  285. data/{specs → spec/ffi}/rbx/struct_spec.rb +0 -0
  286. data/spec/ffi/spec_helper.rb +13 -0
  287. data/{specs → spec/ffi}/string_spec.rb +8 -0
  288. data/spec/ffi/struct_spec.rb +453 -0
  289. data/{specs → spec/ffi}/typedef_spec.rb +3 -3
  290. data/spec/ffi/union_spec.rb +60 -0
  291. data/{specs → spec/ffi}/variadic_spec.rb +0 -0
  292. data/spec/spec.opts +4 -0
  293. metadata +356 -334
  294. data/README +0 -0
  295. data/ext/Buffer.c +0 -98
  296. data/ext/MemoryPointer.c +0 -99
  297. data/ext/NativeLibrary.c +0 -90
  298. data/ext/Types.c +0 -76
  299. data/ext/ffi.c +0 -64
  300. data/ext/ffi.mk +0 -24
  301. data/ext/libffi.mk +0 -10
  302. data/gen/Rakefile +0 -12
  303. data/specs/library_spec.rb +0 -55
  304. data/specs/spec_helper.rb +0 -9
  305. data/specs/struct_spec.rb +0 -223
@@ -1,25 +0,0 @@
1
- module FFI
2
- class Buffer
3
- def self.__calc_size(type)
4
- if type.kind_of? Fixnum
5
- type
6
- elsif type.kind_of? Symbol
7
- FFI.type_size(type)
8
- else
9
- type.size
10
- end
11
- end
12
- def self.new(size, count=nil, clear=true)
13
- self.__alloc_inout(self.__calc_size(size), count, clear)
14
- end
15
- def self.alloc_in(size, count=nil, clear=true)
16
- self.__alloc_in(self.__calc_size(size), count, clear)
17
- end
18
- def self.alloc_out(size, count=nil, clear=true)
19
- self.__alloc_out(self.__calc_size(size), count, clear)
20
- end
21
- def self.alloc_inout(size, count=nil, clear=true)
22
- self.__alloc_inout(self.__calc_size(size), count, clear)
23
- end
24
- end
25
- end
@@ -48,6 +48,7 @@ require 'ffi/errno'
48
48
  require 'ffi/memorypointer'
49
49
  require 'ffi/buffer'
50
50
  require 'ffi/struct'
51
+ require 'ffi/union'
51
52
  require 'ffi/managedstruct'
52
53
  require 'ffi/callback'
53
54
  require 'ffi/io'
@@ -1,19 +1,21 @@
1
1
  module FFI::Library
2
2
  DEFAULT = FFI::DynamicLibrary.open(nil, FFI::DynamicLibrary::RTLD_LAZY)
3
3
 
4
- # TODO: Rubinius does *names here and saves the array. Multiple libs?
5
4
  def ffi_lib(*names)
6
- mapped_names = names.map { |name| FFI.map_library_name(name) }
7
- errors = Hash.new
8
- ffi_libs = mapped_names.map do |name|
9
- begin
10
- FFI::DynamicLibrary.open(name, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_LOCAL)
11
- rescue LoadError => ex
12
- errors[name] = ex
13
- nil
5
+ ffi_libs = []
6
+ names.each do |name|
7
+ [ name, FFI.map_library_name(name) ].each do |libname|
8
+ begin
9
+ lib = FFI::DynamicLibrary.open(libname, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_LOCAL)
10
+ if lib
11
+ ffi_libs << lib
12
+ break
13
+ end
14
+ rescue LoadError => ex
15
+ end
14
16
  end
15
- end.compact
16
- raise LoadError, "Could not open any of [#{mapped_names.join(", ")}]" if ffi_libs.empty?
17
+ end
18
+ raise LoadError, "Could not open any of [#{names.join(", ")}]" if ffi_libs.empty?
17
19
  @ffi_libs = ffi_libs
18
20
  end
19
21
  def ffi_convention(convention)
@@ -35,21 +37,8 @@ module FFI::Library
35
37
  convention = defined?(@ffi_convention) ? @ffi_convention : :default
36
38
 
37
39
  # Convert :foo to the native type
38
- callback_count = 0
39
- arg_types.map! { |e|
40
- begin
41
- find_type(e)
42
- rescue FFI::TypeError => ex
43
- if defined?(@ffi_callbacks) && @ffi_callbacks.has_key?(e)
44
- callback_count += 1
45
- @ffi_callbacks[e]
46
- elsif e.is_a?(Class) && e < FFI::Struct
47
- FFI::NativeType::POINTER
48
- else
49
- raise ex
50
- end
51
- end
52
- }
40
+ arg_types.map! { |e| find_type(e) }
41
+ has_callback = arg_types.any? {|t| t.kind_of?(FFI::CallbackInfo)}
53
42
  options = Hash.new
54
43
  options[:convention] = convention
55
44
  options[:type_map] = @ffi_typedefs if defined?(@ffi_typedefs)
@@ -69,24 +58,97 @@ module FFI::Library
69
58
  params = (1..arity).map {|i| "a#{i}" }.join(",")
70
59
 
71
60
  # Always use rest args for functions with callback parameters
72
- if callback_count > 0 || invoker.kind_of?(FFI::VariadicInvoker)
61
+ if has_callback || invoker.kind_of?(FFI::VariadicInvoker)
73
62
  params = "*args, &block"
74
63
  end
75
- call = arity <= 3 && callback_count < 1 && !invoker.kind_of?(FFI::VariadicInvoker)? "call#{arity}" : "call"
64
+ call = arity <= 3 && !has_callback && !invoker.kind_of?(FFI::VariadicInvoker)? "call#{arity}" : "call"
76
65
 
77
66
  #
78
67
  # Attach the invoker to this module as 'mname'.
79
68
  #
80
- self.module_eval <<-code
81
- @@#{mname} = invoker
82
- def self.#{mname}(#{params})
83
- @@#{mname}.#{call}(#{params})
69
+ if !has_callback && !invoker.kind_of?(FFI::VariadicInvoker)
70
+ invoker.attach(self, mname.to_s)
71
+ else
72
+ self.module_eval <<-code
73
+ @@#{mname} = invoker
74
+ def self.#{mname}(#{params})
75
+ @@#{mname}.#{call}(#{params})
76
+ end
77
+ def #{mname}(#{params})
78
+ @@#{mname}.#{call}(#{params})
79
+ end
80
+ code
81
+ end
82
+ invoker
83
+ end
84
+ def attach_variable(mname, a1, a2 = nil)
85
+ cname, type = a2 ? [ a1, a2 ] : [ mname.to_s, a1 ]
86
+ libraries = defined?(@ffi_libs) ? @ffi_libs : [ DEFAULT ]
87
+ address = nil
88
+ libraries.each do |lib|
89
+ begin
90
+ address = lib.find_symbol(cname.to_s)
91
+ break unless address.nil?
92
+ rescue LoadError
84
93
  end
85
- def #{mname}(#{params})
86
- @@#{mname}.#{call}(#{params})
94
+ end
95
+ raise FFI::NotFoundError.new(cname, libraries) if address.nil?
96
+ case ffi_type = find_type(type)
97
+ when :pointer, FFI::NativeType::POINTER
98
+ op = :pointer
99
+ when :char, FFI::NativeType::INT8
100
+ op = :int8
101
+ when :uchar, FFI::NativeType::UINT8
102
+ op = :uint8
103
+ when :short, FFI::NativeType::INT16
104
+ op = :int16
105
+ when :ushort, FFI::NativeType::UINT16
106
+ op = :uint16
107
+ when :int, FFI::NativeType::INT32
108
+ op = :int32
109
+ when :uint, FFI::NativeType::UINT32
110
+ op = :uint32
111
+ when :long, FFI::NativeType::LONG
112
+ op = :long
113
+ when :ulong, FFI::NativeType::ULONG
114
+ op = :ulong
115
+ when :long_long, FFI::NativeType::INT64
116
+ op = :int64
117
+ when :ulong_long, FFI::NativeType::UINT64
118
+ op = :uint64
119
+ else
120
+ if ffi_type.is_a?(FFI::CallbackInfo)
121
+ op = :callback
122
+ else
123
+ raise FFI::TypeError, "Cannot access library variable of type #{type}"
87
124
  end
88
- code
89
- invoker
125
+ end
126
+ #
127
+ # Attach to this module as mname/mname=
128
+ #
129
+ if op == :callback
130
+ self.module_eval <<-code
131
+ @@ffi_gvar_#{mname} = address
132
+ @@ffi_gvar_#{mname}_cbinfo = ffi_type
133
+ def self.#{mname}
134
+ raise ArgError, "Cannot get callback fields"
135
+ end
136
+ def self.#{mname}=(value)
137
+ @@ffi_gvar_#{mname}.put_callback(0, value, @@ffi_gvar_#{mname}_cbinfo)
138
+ end
139
+ code
140
+ else
141
+ self.module_eval <<-code
142
+ @@ffi_gvar_#{mname} = address
143
+ def self.#{mname}
144
+ @@ffi_gvar_#{mname}.get_#{op.to_s}(0)
145
+ end
146
+ def self.#{mname}=(value)
147
+ @@ffi_gvar_#{mname}.put_#{op.to_s}(0, value)
148
+ end
149
+ code
150
+ end
151
+ address
90
152
  end
91
153
  def callback(name, args, ret)
92
154
  @ffi_callbacks = Hash.new unless defined?(@ffi_callbacks)
@@ -103,8 +165,12 @@ module FFI::Library
103
165
  @ffi_typedefs[add] = code
104
166
  end
105
167
  def find_type(name)
106
- code = if defined?(@ffi_typedefs)
168
+ code = if defined?(@ffi_typedefs) && @ffi_typedefs.has_key?(name)
107
169
  @ffi_typedefs[name]
170
+ elsif defined?(@ffi_callbacks) && @ffi_callbacks.has_key?(name)
171
+ @ffi_callbacks[name]
172
+ elsif name.is_a?(Class) && name < FFI::Struct
173
+ FFI::NativeType::POINTER
108
174
  end
109
175
  code = name if !code && name.kind_of?(FFI::CallbackInfo)
110
176
  if code.nil? || code.kind_of?(Symbol)
@@ -23,34 +23,34 @@ module FFI
23
23
  # with a block yields the MemoryPointer instance and frees the memory
24
24
  # when the block returns. The value returned is the value of the block.
25
25
 
26
- def self.new(type, count=nil, clear=true)
27
- size = if type.kind_of? Fixnum
28
- type
29
- elsif type.kind_of? Symbol
30
- FFI.type_size(type)
31
- else
32
- type.size
33
- end
34
- ptr = self.__allocate(size, count, clear)
35
- ptr.type_size = size
36
- if block_given?
37
- begin
38
- value = yield ptr
39
- ensure
40
- ptr.free
41
- end
42
- value
43
- else
44
- ptr
45
- end
46
- end
26
+ # def self.new(type, count=nil, clear=true)
27
+ # size = if type.kind_of? Fixnum
28
+ # type
29
+ # elsif type.kind_of? Symbol
30
+ # FFI.type_size(type)
31
+ # else
32
+ # type.size
33
+ # end
34
+ # ptr = self.__allocate(size, count, clear)
35
+ # ptr.type_size = size
36
+ # if block_given?
37
+ # begin
38
+ # value = yield ptr
39
+ # ensure
40
+ # ptr.free
41
+ # end
42
+ # value
43
+ # else
44
+ # ptr
45
+ # end
46
+ # end
47
47
  def self.from_string(s)
48
48
  ptr = self.new(s.length + 1, 1, false)
49
49
  ptr.put_string(0, s)
50
50
  ptr
51
51
  end
52
52
  # Indicates how many bytes the type that the pointer is cast as uses.
53
- attr_accessor :type_size
53
+ # attr_accessor :type_size
54
54
 
55
55
  # Access the MemoryPointer like a C array, accessing the +which+ number
56
56
  # element in memory. The position of the element is calculate from
@@ -66,11 +66,8 @@ module FFI
66
66
  # int *new_ptr;
67
67
  # new_ptr = &ptr[9];
68
68
  #
69
- def [](which)
70
- raise ArgumentError, "unknown type size" unless @type_size
71
- self + (which * @type_size)
72
- end
69
+ # def [](which)
70
+ # self + (which * type_size)
71
+ # end
73
72
  end
74
73
  end
75
-
76
- MemoryPointer = FFI::MemoryPointer
@@ -14,10 +14,10 @@ module FFI
14
14
  "openbsd"
15
15
  when /sunos|solaris/
16
16
  "solaris"
17
- when /win/
17
+ when /win|mingw/
18
18
  "windows"
19
19
  else
20
- raise FFI::PlatformError, "Unknown operating system: #{OS_}"
20
+ raise FFI::PlatformError, "Unknown operating system: #{Config::CONFIG['host_os']}"
21
21
  end
22
22
  ARCH = case CPU.downcase
23
23
  when /amd64|x86_64/
@@ -35,9 +35,14 @@ module FFI
35
35
  def read_long_long
36
36
  get_int64(0)
37
37
  end
38
+
38
39
  def read_pointer
39
40
  get_pointer(0)
40
41
  end
42
+ def write_pointer(ptr)
43
+ put_pointer(0, ptr)
44
+ end
45
+
41
46
  def read_float
42
47
  get_float32(0)
43
48
  end
@@ -59,20 +64,20 @@ module FFI
59
64
  get_string(0)
60
65
  end
61
66
  def write_string_length(str, len)
62
- put_string(0, str, len)
67
+ put_bytes(0, str, 0, len)
63
68
  end
64
69
  def write_string(str, len=nil)
65
70
  len = str.size unless len
66
71
  # Write the string data without NUL termination
67
- put_string(0, str, len)
72
+ put_bytes(0, str, 0, len)
68
73
  end
69
74
  def read_array_of_type(type, reader, length)
70
75
  ary = []
71
76
  size = FFI.type_size(type)
72
77
  tmp = self
73
- length.times {
78
+ length.times { |j|
74
79
  ary << tmp.send(reader)
75
- tmp += size
80
+ tmp += size unless j == length-1 # avoid OOB
76
81
  }
77
82
  ary
78
83
  end
@@ -80,9 +85,9 @@ module FFI
80
85
  def write_array_of_type(type, writer, ary)
81
86
  size = FFI.type_size(type)
82
87
  tmp = self
83
- ary.each {|i|
88
+ ary.each_with_index {|i, j|
84
89
  tmp.send(writer, i)
85
- tmp += size
90
+ tmp += size unless j == ary.length-1 # avoid OOB
86
91
  }
87
92
  self
88
93
  end
@@ -101,5 +106,14 @@ module FFI
101
106
  def write_array_of_long(ary)
102
107
  put_array_of_long(0, ary)
103
108
  end
109
+
110
+ def read_array_of_pointer(length)
111
+ read_array_of_type(:pointer, :read_pointer, length)
112
+ end
113
+
114
+ def write_array_of_pointer(ary)
115
+ write_array_of_type(:pointer, :write_pointer, ary)
116
+ end
117
+
104
118
  end
105
- end
119
+ end
@@ -1,164 +1,103 @@
1
1
  require 'ffi/platform'
2
2
  module FFI
3
3
  class StructLayout
4
- def initialize(fields, size)
5
- @fields = fields
6
- @size = size
4
+ attr_reader :size, :align
5
+
6
+ def members
7
+ @field_names
7
8
  end
8
-
9
- def [](name)
10
- @fields[name]
9
+ def offsets
10
+ @fields.map { |name, field| [name, field.offset] }.sort { |a, b| a[1] <=> b[1] }
11
11
  end
12
- def size
13
- @size
12
+ def offset_of(field_name)
13
+ @fields[field_name].offset
14
14
  end
15
15
  end
16
16
  class StructLayoutBuilder
17
17
  class Field
18
- def initialize(off)
19
- @off = off
20
- end
21
-
22
- def offset
23
- @off
24
- end
25
18
  def size
26
- self.size
19
+ self.class.size
27
20
  end
28
21
  def align
29
- self.align
30
- end
31
- def self.align
32
- self.size
33
- end
34
- end
35
- class Signed8 < Field
36
- def self.size; 8; end
37
- def self.align; Platform::INT8_ALIGN; end
38
- def put(ptr, val)
39
- ptr.put_int8(@off, val)
40
- end
41
- def get(ptr)
42
- ptr.get_int8(@off)
43
- end
44
- end
45
- class Unsigned8 < Field
46
- def self.size; 8; end
47
- def self.align; Platform::INT8_ALIGN; end
48
- def put(ptr, val)
49
- ptr.put_uint8(@off, val)
50
- end
51
- def get(ptr)
52
- ptr.get_uint8(@off)
53
- end
54
- end
55
- class Signed16 < Field
56
- def self.size; 16; end
57
- def self.align; Platform::INT16_ALIGN; end
58
- def put(ptr, val)
59
- ptr.put_int16(@off, val)
60
- end
61
- def get(ptr)
62
- ptr.get_int16(@off)
63
- end
64
- end
65
- class Unsigned16 < Field
66
- def self.size; 16; end
67
- def self.align; Platform::INT16_ALIGN; end
68
- def put(ptr, val)
69
- ptr.put_uint16(@off, val)
70
- end
71
- def get(ptr)
72
- ptr.get_uint16(@off)
73
- end
74
- end
75
- class Signed32 < Field
76
- def self.size; 32; end
77
- def self.align; Platform::INT32_ALIGN; end
78
- def put(ptr, val)
79
- ptr.put_int32(@off, val)
80
- end
81
- def get(ptr)
82
- ptr.get_int32(@off)
83
- end
84
- end
85
- class Unsigned32 < Field
86
- def self.size; 32; end
87
- def self.align; Platform::INT32_ALIGN; end
88
- def put(ptr, val)
89
- ptr.put_uint32(@off, val)
90
- end
91
- def get(ptr)
92
- ptr.get_uint32(@off)
93
- end
94
- end
95
- class Signed64 < Field
96
- def self.size; 64; end
97
- def self.align; Platform::INT64_ALIGN; end
98
- def put(ptr, val)
99
- ptr.put_int64(@off, val)
100
- end
101
- def get(ptr)
102
- ptr.get_int64(@off)
103
- end
104
- end
105
- class Unsigned64 < Field
106
- def self.size; 64; end
107
- def self.align; Platform::INT64_ALIGN; end
108
- def put(ptr, val)
109
- ptr.put_uint64(@off, val)
110
- end
111
- def get(ptr)
112
- ptr.get_uint64(@off)
113
- end
114
- end
115
- class FloatField < Field
116
- def self.size; Platform::FLOAT_SIZE; end
117
- def self.align; Platform::FLOAT_ALIGN; end
118
- def put(ptr, val)
119
- ptr.put_float32(@off, val)
22
+ self.class.align
120
23
  end
121
- def get(ptr)
122
- ptr.get_float32(@off)
123
- end
124
- end
125
- class DoubleField < Field
126
- def self.size; Platform::DOUBLE_SIZE; end
127
- def self.align; Platform::DOUBLE_ALIGN; end
128
- def put(ptr, val)
129
- ptr.put_float64(@off, val)
24
+ def offset
25
+ @off
130
26
  end
131
- def get(ptr)
132
- ptr.get_float64(@off)
27
+ def self.size
28
+ const_get(:SIZE)
133
29
  end
134
- end
135
- class PointerField < Field
136
- def self.size; Platform::ADDRESS_SIZE; end
137
- def self.align; Platform::ADDRESS_ALIGN; end
138
- def put(ptr, val)
139
- ptr.put_pointer(@off, val)
30
+ def self.align
31
+ const_get(:ALIGN)
32
+ end
33
+ end
34
+ def self.struct_field_class_from(type)
35
+ klass_name = type.name.split('::').last
36
+ code = <<-code
37
+ class StructField_#{klass_name} < Field
38
+ @info = #{type}
39
+ class << self
40
+ attr_reader :info
41
+ def size
42
+ #{type.size} * 8
43
+ end
44
+ def align
45
+ #{type.align}
46
+ end
47
+ end
48
+ def get(ptr)
49
+ self.class.info.new(ptr + @off)
50
+ end
140
51
  end
141
- def get(ptr)
142
- ptr.get_pointer(@off)
52
+ StructField_#{klass_name}
53
+ code
54
+ self.module_eval(code)
55
+ end
56
+ def self.array_field_class_from(type, num)
57
+ klass_name = type.name.split('::').last
58
+ code = <<-code
59
+ class ArrayField_#{klass_name}_#{num} < Field
60
+ @info = #{type}
61
+ @num = #{num}
62
+ class << self
63
+ attr_reader :info, :num
64
+ def size
65
+ #{type.size} * #{num}
66
+ end
67
+ def align
68
+ #{type.align}
69
+ end
70
+ end
71
+ def get(ptr)
72
+ @array ? @array : get_array_data(ptr)
73
+ end
74
+ private
75
+ def get_array_data(ptr)
76
+ @array = FFI::Struct::Array.new(ptr + @off, self.class.info, self.class.num)
77
+ end
143
78
  end
79
+ ArrayField_#{klass_name}_#{num}
80
+ code
81
+ self.module_eval(code)
144
82
  end
145
- class StringField < Field
83
+ class CallbackField < Field
146
84
  def self.size; Platform::ADDRESS_SIZE; end
147
85
  def self.align; Platform::ADDRESS_ALIGN; end
148
- def put(ptr, val)
149
- raise ArgumentError, "Cannot set :string fields"
86
+ def put(ptr, proc)
87
+ ptr.put_callback(@off, proc, @info)
150
88
  end
151
89
  def get(ptr)
152
- strp = ptr.get_pointer(@off)
153
- (strp.nil? || strp.null?) ? nil : strp.get_string(0)
90
+ raise ArgumentError, "Cannot get callback fields"
154
91
  end
155
92
  end
156
93
  def initialize
94
+ @field_names = []
157
95
  @fields = {}
158
96
  @size = 0
97
+ @min_align = 1
159
98
  end
160
- def add_field(name, type, offset=nil)
161
- field_class = case type
99
+ def native_field_class_from(type)
100
+ case type
162
101
  when :char, NativeType::INT8
163
102
  Signed8
164
103
  when :uchar, NativeType::UINT8
@@ -187,17 +126,35 @@ module FFI
187
126
  PointerField
188
127
  when :string, NativeType::STRING
189
128
  StringField
190
- else
191
- raise ArgumentError, "Unknown type: #{type}"
192
129
  end
193
-
194
- size = field_class.size / 8
195
- off = offset ? offset.to_i : align(@size, field_class.align)
196
- @fields[name] = field_class.new(off)
197
- @size = off + size
130
+ end
131
+ def callback_field_class_from(type)
132
+ return CallbackField, type if type.is_a?(FFI::CallbackInfo)
133
+ end
134
+ def struct_field_class_from(type)
135
+ self.class.struct_field_class_from(type) if type.is_a?(Class) and type < FFI::Struct
136
+ end
137
+ def array_field_class_from(type)
138
+ self.class.array_field_class_from(field_class_from(type[0]), type[1]) if type.is_a?(Array)
139
+ end
140
+ def field_class_from(type)
141
+ field_class = native_field_class_from(type) ||
142
+ callback_field_class_from(type) ||
143
+ array_field_class_from(type) ||
144
+ struct_field_class_from(type)
145
+ field_class or raise ArgumentError, "Unknown type: #{type}"
146
+ end
147
+ def add_field(name, type, offset = nil)
148
+ field_class, info = field_class_from(type)
149
+ off = calc_alignment_of(field_class, offset)
150
+ calc_current_size(off, field_class.size / 8)
151
+ @field_names << name
152
+ @fields[name] = field_class.new(off, info)
153
+ @min_align = field_class.align if field_class.align > @min_align
198
154
  end
199
155
  def build
200
- StructLayout.new @fields, @size
156
+ align = @min_align / 8
157
+ StructLayout.new @field_names, @fields, align + ((@size - 1) & ~(align - 1)), @min_align
201
158
  end
202
159
  def align(offset, bits)
203
160
  bytes = bits / 8
@@ -205,28 +162,38 @@ module FFI
205
162
  off = offset;
206
163
  ((off & mask) != 0) ? (off & ~mask) + bytes : off
207
164
  end
208
- end
209
- class BaseStruct
210
- Buffer = FFI::Buffer
211
- attr_reader :pointer
212
-
213
- def initialize(pointer = nil, *spec)
214
- @cspec = self.class.layout(*spec)
215
-
216
- if pointer then
217
- @pointer = pointer
218
- else
219
- @pointer = MemoryPointer.new size
220
- end
221
- end
222
- def self.alloc_inout(clear = true)
223
- self.new(Buffer.alloc_inout(@size, 1, clear))
165
+ private
166
+ def calc_alignment_of(field_class, offset)
167
+ offset ? offset.to_i : align(@size, field_class.align)
224
168
  end
225
- def self.alloc_in(clear = true)
226
- self.new(Buffer.alloc_in(@size, 1, clear))
169
+ def calc_current_size(offset, size)
170
+ @size = offset + size
227
171
  end
228
- def self.alloc_out(clear = true)
229
- self.new(Buffer.alloc_out(@size, 1, clear))
172
+ end
173
+ class Struct
174
+ class Array
175
+ include Enumerable
176
+ def initialize(ptr, type, num)
177
+ @pointer, @type, @num = ptr, type, num
178
+ end
179
+ def to_ptr
180
+ @pointer
181
+ end
182
+ def to_a
183
+ get_array_data(@pointer)
184
+ end
185
+ def size
186
+ @num * @type.size / 8
187
+ end
188
+ def each(&blk)
189
+ to_a.each(&blk)
190
+ end
191
+ private
192
+ def get_array_data(ptr)
193
+ (0..@num - 1).inject([]) do |array, index|
194
+ array << @type.new(0).get(ptr + index * @type.size / 8)
195
+ end
196
+ end
230
197
  end
231
198
  def self.size
232
199
  @size
@@ -234,27 +201,39 @@ module FFI
234
201
  def self.members
235
202
  @layout.members
236
203
  end
204
+ def self.align
205
+ @layout.align
206
+ end
207
+ def self.offsets
208
+ @layout.offsets
209
+ end
210
+ def self.offset_of(field_name)
211
+ @layout.offset_of(field_name)
212
+ end
237
213
  def size
238
214
  self.class.size
239
215
  end
240
- def [](field)
241
- @cspec[field].get(@pointer)
242
- end
243
- def []=(field, val)
244
- @cspec[field].put(@pointer, val)
216
+ def align
217
+ self.class.align
245
218
  end
246
219
  def members
247
- @cspec.members
220
+ layout.members
248
221
  end
249
222
  def values
250
- @cspec.members.map { |m| self[m] }
223
+ layout.members.map { |m| self[m] }
224
+ end
225
+ def offsets
226
+ self.class.offsets
227
+ end
228
+ def offset_of(field_name)
229
+ self.class.offset_of(field_name)
251
230
  end
252
231
  def clear
253
- @pointer.clear
232
+ pointer.clear
254
233
  self
255
234
  end
256
235
  def to_ptr
257
- @pointer
236
+ pointer
258
237
  end
259
238
  def self.in
260
239
  :buffer_in
@@ -262,9 +241,10 @@ module FFI
262
241
  def self.out
263
242
  :buffer_out
264
243
  end
265
- end
266
- class Struct < BaseStruct
267
244
  private
245
+ def self.builder
246
+ StructLayoutBuilder.new
247
+ end
268
248
  def self.enclosing_module
269
249
  begin
270
250
  mod = self.name.split("::")[0..-2].inject(Object) { |obj, c| obj.const_get(c) }
@@ -273,12 +253,16 @@ module FFI
273
253
  nil
274
254
  end
275
255
  end
256
+ def self.is_a_struct?(type)
257
+ type.is_a?(Class) and type < Struct
258
+ end
276
259
  def self.find_type(type, mod = nil)
277
- return mod ? mod.find_type(type) : FFI.find_type(type)
260
+ return type if is_a_struct?(type) or type.is_a?(::Array)
261
+ mod ? mod.find_type(type) : FFI.find_type(type)
278
262
  end
279
263
  def self.hash_layout(spec)
280
264
  raise "Ruby version not supported" if RUBY_VERSION =~ /1.8.*/
281
- builder = FFI::StructLayoutBuilder.new
265
+ builder = self.builder
282
266
  mod = enclosing_module
283
267
  spec[0].each do |name,type|
284
268
  builder.add_field(name, find_type(type, mod))
@@ -286,14 +270,14 @@ module FFI
286
270
  builder.build
287
271
  end
288
272
  def self.array_layout(spec)
289
- builder = FFI::StructLayoutBuilder.new
273
+ builder = self.builder
290
274
  mod = enclosing_module
291
275
  i = 0
292
276
  while i < spec.size
293
277
  name, type = spec[i, 2]
294
278
  i += 2
295
- code = find_type(type, mod)
296
- # If the next param is a Fixnu, it specifies the offset
279
+ code = find_type(type, mod)
280
+ # If the next param is a Fixnum, it specifies the offset
297
281
  if spec[i].kind_of?(Fixnum)
298
282
  offset = spec[i]
299
283
  i += 1
@@ -306,10 +290,8 @@ module FFI
306
290
  end
307
291
  public
308
292
  def self.layout(*spec)
309
-
310
293
  return @layout if spec.size == 0
311
294
  cspec = spec[0].kind_of?(Hash) ? hash_layout(spec) : array_layout(spec)
312
-
313
295
  @layout = cspec unless self == FFI::Struct
314
296
  @size = cspec.size
315
297
  return cspec