ffi 0.5.0-x86-mingw32

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 (328) hide show
  1. data/LICENSE +51 -0
  2. data/README.rdoc +69 -0
  3. data/Rakefile +191 -0
  4. data/ext/ffi_c/AbstractMemory.c +489 -0
  5. data/ext/ffi_c/AbstractMemory.h +160 -0
  6. data/ext/ffi_c/ArrayType.c +129 -0
  7. data/ext/ffi_c/ArrayType.h +58 -0
  8. data/ext/ffi_c/AutoPointer.c +61 -0
  9. data/ext/ffi_c/AutoPointer.h +18 -0
  10. data/ext/ffi_c/Buffer.c +187 -0
  11. data/ext/ffi_c/Call.c +853 -0
  12. data/ext/ffi_c/Call.h +86 -0
  13. data/ext/ffi_c/ClosurePool.c +302 -0
  14. data/ext/ffi_c/ClosurePool.h +29 -0
  15. data/ext/ffi_c/DynamicLibrary.c +216 -0
  16. data/ext/ffi_c/DynamicLibrary.h +22 -0
  17. data/ext/ffi_c/Function.c +478 -0
  18. data/ext/ffi_c/Function.h +80 -0
  19. data/ext/ffi_c/FunctionInfo.c +221 -0
  20. data/ext/ffi_c/LastError.c +159 -0
  21. data/ext/ffi_c/LastError.h +18 -0
  22. data/ext/ffi_c/MemoryPointer.c +178 -0
  23. data/ext/ffi_c/MemoryPointer.h +20 -0
  24. data/ext/ffi_c/MethodHandle.c +346 -0
  25. data/ext/ffi_c/MethodHandle.h +53 -0
  26. data/ext/ffi_c/Platform.c +59 -0
  27. data/ext/ffi_c/Platform.h +16 -0
  28. data/ext/ffi_c/Pointer.c +224 -0
  29. data/ext/ffi_c/Pointer.h +49 -0
  30. data/ext/ffi_c/Struct.c +770 -0
  31. data/ext/ffi_c/Struct.h +80 -0
  32. data/ext/ffi_c/StructByValue.c +140 -0
  33. data/ext/ffi_c/StructByValue.h +53 -0
  34. data/ext/ffi_c/StructLayout.c +450 -0
  35. data/ext/ffi_c/Type.c +329 -0
  36. data/ext/ffi_c/Type.h +57 -0
  37. data/ext/ffi_c/Types.c +103 -0
  38. data/ext/ffi_c/Types.h +85 -0
  39. data/ext/ffi_c/Variadic.c +260 -0
  40. data/ext/ffi_c/compat.h +72 -0
  41. data/ext/ffi_c/endian.h +40 -0
  42. data/ext/ffi_c/extconf.rb +30 -0
  43. data/ext/ffi_c/ffi.c +82 -0
  44. data/ext/ffi_c/libffi.bsd.mk +34 -0
  45. data/ext/ffi_c/libffi.darwin.mk +75 -0
  46. data/ext/ffi_c/libffi.gnu.mk +29 -0
  47. data/ext/ffi_c/libffi.mk +13 -0
  48. data/ext/ffi_c/libffi/ChangeLog +3243 -0
  49. data/ext/ffi_c/libffi/ChangeLog.libffi +347 -0
  50. data/ext/ffi_c/libffi/ChangeLog.libgcj +40 -0
  51. data/ext/ffi_c/libffi/ChangeLog.v1 +764 -0
  52. data/ext/ffi_c/libffi/LICENSE +21 -0
  53. data/ext/ffi_c/libffi/Makefile.am +177 -0
  54. data/ext/ffi_c/libffi/Makefile.in +1640 -0
  55. data/ext/ffi_c/libffi/README +328 -0
  56. data/ext/ffi_c/libffi/TODO +1 -0
  57. data/ext/ffi_c/libffi/acinclude.m4 +92 -0
  58. data/ext/ffi_c/libffi/aclocal.m4 +7516 -0
  59. data/ext/ffi_c/libffi/compile +142 -0
  60. data/ext/ffi_c/libffi/config.guess +1516 -0
  61. data/ext/ffi_c/libffi/config.sub +1626 -0
  62. data/ext/ffi_c/libffi/configure +24414 -0
  63. data/ext/ffi_c/libffi/configure.ac +365 -0
  64. data/ext/ffi_c/libffi/configure.host +11 -0
  65. data/ext/ffi_c/libffi/depcomp +584 -0
  66. data/ext/ffi_c/libffi/doc/libffi.info +533 -0
  67. data/ext/ffi_c/libffi/doc/libffi.texi +541 -0
  68. data/ext/ffi_c/libffi/doc/stamp-vti +4 -0
  69. data/ext/ffi_c/libffi/doc/version.texi +4 -0
  70. data/ext/ffi_c/libffi/fficonfig.h.in +160 -0
  71. data/ext/ffi_c/libffi/include/Makefile.am +9 -0
  72. data/ext/ffi_c/libffi/include/Makefile.in +422 -0
  73. data/ext/ffi_c/libffi/include/ffi.h.in +393 -0
  74. data/ext/ffi_c/libffi/include/ffi_common.h +98 -0
  75. data/ext/ffi_c/libffi/install-sh +323 -0
  76. data/ext/ffi_c/libffi/libffi.pc.in +10 -0
  77. data/ext/ffi_c/libffi/libtool-version +29 -0
  78. data/ext/ffi_c/libffi/ltcf-c.sh +861 -0
  79. data/ext/ffi_c/libffi/ltcf-cxx.sh +1069 -0
  80. data/ext/ffi_c/libffi/ltcf-gcj.sh +700 -0
  81. data/ext/ffi_c/libffi/ltconfig +2862 -0
  82. data/ext/ffi_c/libffi/ltmain.sh +6930 -0
  83. data/ext/ffi_c/libffi/man/Makefile.am +8 -0
  84. data/ext/ffi_c/libffi/man/Makefile.in +395 -0
  85. data/ext/ffi_c/libffi/man/ffi.3 +31 -0
  86. data/ext/ffi_c/libffi/man/ffi_call.3 +103 -0
  87. data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +66 -0
  88. data/ext/ffi_c/libffi/mdate-sh +201 -0
  89. data/ext/ffi_c/libffi/missing +353 -0
  90. data/ext/ffi_c/libffi/mkinstalldirs +158 -0
  91. data/ext/ffi_c/libffi/src/alpha/ffi.c +284 -0
  92. data/ext/ffi_c/libffi/src/alpha/ffitarget.h +48 -0
  93. data/ext/ffi_c/libffi/src/alpha/osf.S +366 -0
  94. data/ext/ffi_c/libffi/src/arm/ffi.c +309 -0
  95. data/ext/ffi_c/libffi/src/arm/ffitarget.h +49 -0
  96. data/ext/ffi_c/libffi/src/arm/sysv.S +299 -0
  97. data/ext/ffi_c/libffi/src/closures.c +596 -0
  98. data/ext/ffi_c/libffi/src/cris/ffi.c +383 -0
  99. data/ext/ffi_c/libffi/src/cris/ffitarget.h +51 -0
  100. data/ext/ffi_c/libffi/src/cris/sysv.S +215 -0
  101. data/ext/ffi_c/libffi/src/debug.c +59 -0
  102. data/ext/ffi_c/libffi/src/dlmalloc.c +5099 -0
  103. data/ext/ffi_c/libffi/src/frv/eabi.S +128 -0
  104. data/ext/ffi_c/libffi/src/frv/ffi.c +292 -0
  105. data/ext/ffi_c/libffi/src/frv/ffitarget.h +61 -0
  106. data/ext/ffi_c/libffi/src/ia64/ffi.c +580 -0
  107. data/ext/ffi_c/libffi/src/ia64/ffitarget.h +50 -0
  108. data/ext/ffi_c/libffi/src/ia64/ia64_flags.h +40 -0
  109. data/ext/ffi_c/libffi/src/ia64/unix.S +560 -0
  110. data/ext/ffi_c/libffi/src/java_raw_api.c +359 -0
  111. data/ext/ffi_c/libffi/src/m32r/ffi.c +232 -0
  112. data/ext/ffi_c/libffi/src/m32r/ffitarget.h +48 -0
  113. data/ext/ffi_c/libffi/src/m32r/sysv.S +121 -0
  114. data/ext/ffi_c/libffi/src/m68k/ffi.c +278 -0
  115. data/ext/ffi_c/libffi/src/m68k/ffitarget.h +49 -0
  116. data/ext/ffi_c/libffi/src/m68k/sysv.S +234 -0
  117. data/ext/ffi_c/libffi/src/mips/ffi.c +926 -0
  118. data/ext/ffi_c/libffi/src/mips/ffitarget.h +202 -0
  119. data/ext/ffi_c/libffi/src/mips/n32.S +534 -0
  120. data/ext/ffi_c/libffi/src/mips/o32.S +381 -0
  121. data/ext/ffi_c/libffi/src/pa/ffi.c +709 -0
  122. data/ext/ffi_c/libffi/src/pa/ffitarget.h +77 -0
  123. data/ext/ffi_c/libffi/src/pa/hpux32.S +368 -0
  124. data/ext/ffi_c/libffi/src/pa/linux.S +357 -0
  125. data/ext/ffi_c/libffi/src/powerpc/aix.S +225 -0
  126. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +247 -0
  127. data/ext/ffi_c/libffi/src/powerpc/asm.h +125 -0
  128. data/ext/ffi_c/libffi/src/powerpc/darwin.S +245 -0
  129. data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +317 -0
  130. data/ext/ffi_c/libffi/src/powerpc/ffi.c +1429 -0
  131. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +800 -0
  132. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +118 -0
  133. data/ext/ffi_c/libffi/src/powerpc/linux64.S +187 -0
  134. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +236 -0
  135. data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +327 -0
  136. data/ext/ffi_c/libffi/src/powerpc/sysv.S +230 -0
  137. data/ext/ffi_c/libffi/src/prep_cif.c +174 -0
  138. data/ext/ffi_c/libffi/src/raw_api.c +254 -0
  139. data/ext/ffi_c/libffi/src/s390/ffi.c +780 -0
  140. data/ext/ffi_c/libffi/src/s390/ffitarget.h +60 -0
  141. data/ext/ffi_c/libffi/src/s390/sysv.S +434 -0
  142. data/ext/ffi_c/libffi/src/sh/ffi.c +716 -0
  143. data/ext/ffi_c/libffi/src/sh/ffitarget.h +49 -0
  144. data/ext/ffi_c/libffi/src/sh/sysv.S +850 -0
  145. data/ext/ffi_c/libffi/src/sh64/ffi.c +453 -0
  146. data/ext/ffi_c/libffi/src/sh64/ffitarget.h +53 -0
  147. data/ext/ffi_c/libffi/src/sh64/sysv.S +530 -0
  148. data/ext/ffi_c/libffi/src/sparc/ffi.c +610 -0
  149. data/ext/ffi_c/libffi/src/sparc/ffitarget.h +66 -0
  150. data/ext/ffi_c/libffi/src/sparc/v8.S +272 -0
  151. data/ext/ffi_c/libffi/src/sparc/v9.S +307 -0
  152. data/ext/ffi_c/libffi/src/types.c +77 -0
  153. data/ext/ffi_c/libffi/src/x86/darwin.S +443 -0
  154. data/ext/ffi_c/libffi/src/x86/darwin64.S +416 -0
  155. data/ext/ffi_c/libffi/src/x86/ffi.c +475 -0
  156. data/ext/ffi_c/libffi/src/x86/ffi64.c +572 -0
  157. data/ext/ffi_c/libffi/src/x86/ffitarget.h +90 -0
  158. data/ext/ffi_c/libffi/src/x86/freebsd.S +458 -0
  159. data/ext/ffi_c/libffi/src/x86/sysv.S +437 -0
  160. data/ext/ffi_c/libffi/src/x86/unix64.S +418 -0
  161. data/ext/ffi_c/libffi/src/x86/win32.S +391 -0
  162. data/ext/ffi_c/libffi/testsuite/Makefile.am +71 -0
  163. data/ext/ffi_c/libffi/testsuite/Makefile.in +447 -0
  164. data/ext/ffi_c/libffi/testsuite/config/default.exp +1 -0
  165. data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +289 -0
  166. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +263 -0
  167. data/ext/ffi_c/libffi/testsuite/lib/wrapper.exp +45 -0
  168. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +36 -0
  169. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn0.c +97 -0
  170. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn1.c +89 -0
  171. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn2.c +89 -0
  172. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn3.c +90 -0
  173. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn4.c +97 -0
  174. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn5.c +99 -0
  175. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn6.c +98 -0
  176. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_stdcall.c +72 -0
  177. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +102 -0
  178. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +103 -0
  179. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +104 -0
  180. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +110 -0
  181. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +97 -0
  182. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +99 -0
  183. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +101 -0
  184. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +121 -0
  185. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +98 -0
  186. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +103 -0
  187. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +98 -0
  188. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +98 -0
  189. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +106 -0
  190. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +98 -0
  191. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +117 -0
  192. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +106 -0
  193. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +132 -0
  194. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +121 -0
  195. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +107 -0
  196. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +125 -0
  197. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +105 -0
  198. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +96 -0
  199. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +98 -0
  200. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +99 -0
  201. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +101 -0
  202. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +99 -0
  203. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +100 -0
  204. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +101 -0
  205. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +99 -0
  206. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +99 -0
  207. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +99 -0
  208. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +99 -0
  209. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +99 -0
  210. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +100 -0
  211. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double.c +51 -0
  212. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_float.c +51 -0
  213. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_schar.c +82 -0
  214. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshort.c +82 -0
  215. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshortchar.c +94 -0
  216. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_uchar.c +99 -0
  217. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushort.c +82 -0
  218. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushortchar.c +94 -0
  219. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_schar.c +52 -0
  220. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sint.c +50 -0
  221. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sshort.c +50 -0
  222. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar.c +50 -0
  223. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint.c +51 -0
  224. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +54 -0
  225. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort.c +51 -0
  226. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +86 -0
  227. data/ext/ffi_c/libffi/testsuite/libffi.call/float.c +59 -0
  228. data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +58 -0
  229. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +57 -0
  230. data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +72 -0
  231. data/ext/ffi_c/libffi/testsuite/libffi.call/float4.c +62 -0
  232. data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +69 -0
  233. data/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c +63 -0
  234. data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +53 -0
  235. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +160 -0
  236. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +169 -0
  237. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +141 -0
  238. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +118 -0
  239. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +119 -0
  240. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +119 -0
  241. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +120 -0
  242. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +139 -0
  243. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +119 -0
  244. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +139 -0
  245. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +139 -0
  246. data/ext/ffi_c/libffi/testsuite/libffi.call/problem1.c +98 -0
  247. data/ext/ffi_c/libffi/testsuite/libffi.call/promotion.c +59 -0
  248. data/ext/ffi_c/libffi/testsuite/libffi.call/pyobjc-tc.c +114 -0
  249. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +35 -0
  250. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl1.c +43 -0
  251. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl2.c +42 -0
  252. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl.c +35 -0
  253. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl1.c +36 -0
  254. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl2.c +49 -0
  255. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl3.c +42 -0
  256. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +34 -0
  257. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll.c +41 -0
  258. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +42 -0
  259. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +36 -0
  260. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c +38 -0
  261. data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +38 -0
  262. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c +38 -0
  263. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +44 -0
  264. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c +44 -0
  265. data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +65 -0
  266. data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +67 -0
  267. data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +59 -0
  268. data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +63 -0
  269. data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +65 -0
  270. data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +64 -0
  271. data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +74 -0
  272. data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +80 -0
  273. data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +67 -0
  274. data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +86 -0
  275. data/ext/ffi_c/libffi/testsuite/libffi.special/special.exp +38 -0
  276. data/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest.cc +123 -0
  277. data/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc +53 -0
  278. data/ext/ffi_c/libffi/texinfo.tex +7482 -0
  279. data/ext/ffi_c/rbffi.h +26 -0
  280. data/gen/Rakefile +12 -0
  281. data/lib/1.8/ffi_c.so +0 -0
  282. data/lib/1.9/ffi_c.so +0 -0
  283. data/lib/ffi.rb +11 -0
  284. data/lib/ffi/autopointer.rb +61 -0
  285. data/lib/ffi/buffer.rb +0 -0
  286. data/lib/ffi/callback.rb +10 -0
  287. data/lib/ffi/enum.rb +78 -0
  288. data/lib/ffi/errno.rb +8 -0
  289. data/lib/ffi/ffi.rb +99 -0
  290. data/lib/ffi/io.rb +21 -0
  291. data/lib/ffi/library.rb +218 -0
  292. data/lib/ffi/managedstruct.rb +55 -0
  293. data/lib/ffi/memorypointer.rb +73 -0
  294. data/lib/ffi/platform.rb +88 -0
  295. data/lib/ffi/pointer.rb +119 -0
  296. data/lib/ffi/struct.rb +183 -0
  297. data/lib/ffi/tools/const_generator.rb +177 -0
  298. data/lib/ffi/tools/generator.rb +58 -0
  299. data/lib/ffi/tools/generator_task.rb +35 -0
  300. data/lib/ffi/tools/struct_generator.rb +194 -0
  301. data/lib/ffi/tools/types_generator.rb +123 -0
  302. data/lib/ffi/types.rb +153 -0
  303. data/lib/ffi/union.rb +12 -0
  304. data/lib/ffi/variadic.rb +25 -0
  305. data/spec/ffi/bool_spec.rb +24 -0
  306. data/spec/ffi/buffer_spec.rb +202 -0
  307. data/spec/ffi/callback_spec.rb +591 -0
  308. data/spec/ffi/enum_spec.rb +164 -0
  309. data/spec/ffi/errno_spec.rb +13 -0
  310. data/spec/ffi/function_spec.rb +73 -0
  311. data/spec/ffi/library_spec.rb +148 -0
  312. data/spec/ffi/managed_struct_spec.rb +56 -0
  313. data/spec/ffi/number_spec.rb +231 -0
  314. data/spec/ffi/pointer_spec.rb +195 -0
  315. data/spec/ffi/rbx/attach_function_spec.rb +27 -0
  316. data/spec/ffi/rbx/memory_pointer_spec.rb +102 -0
  317. data/spec/ffi/rbx/spec_helper.rb +1 -0
  318. data/spec/ffi/rbx/struct_spec.rb +13 -0
  319. data/spec/ffi/spec_helper.rb +17 -0
  320. data/spec/ffi/string_spec.rb +103 -0
  321. data/spec/ffi/struct_callback_spec.rb +64 -0
  322. data/spec/ffi/struct_initialize_spec.rb +30 -0
  323. data/spec/ffi/struct_spec.rb +529 -0
  324. data/spec/ffi/typedef_spec.rb +48 -0
  325. data/spec/ffi/union_spec.rb +60 -0
  326. data/spec/ffi/variadic_spec.rb +84 -0
  327. data/spec/spec.opts +4 -0
  328. metadata +396 -0
data/LICENSE ADDED
@@ -0,0 +1,51 @@
1
+ Copyright (c) 2008, JRuby Project
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name of the JRuby Project nor the names of its contributors
13
+ may be used to endorse or promote products derived from this software
14
+ without specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+
27
+ Copyright (c) 2007, Evan Phoenix
28
+ All rights reserved.
29
+
30
+ Redistribution and use in source and binary forms, with or without
31
+ modification, are permitted provided that the following conditions are met:
32
+
33
+ * Redistributions of source code must retain the above copyright notice, this
34
+ list of conditions and the following disclaimer.
35
+ * Redistributions in binary form must reproduce the above copyright notice
36
+ this list of conditions and the following disclaimer in the documentation
37
+ and/or other materials provided with the distribution.
38
+ * Neither the name of the Evan Phoenix nor the names of its contributors
39
+ may be used to endorse or promote products derived from this software
40
+ without specific prior written permission.
41
+
42
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
43
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
45
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
46
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
48
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
49
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
51
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,69 @@
1
+ ruby-ffi
2
+ by Wayne Meissner
3
+ http://wiki.github.com/ffi/ffi
4
+
5
+ == DESCRIPTION:
6
+
7
+ Ruby-FFI is a ruby extension for programmatically loading dynamic
8
+ libraries, binding functions within them, and calling those functions
9
+ from Ruby code. Moreover, a Ruby-FFI extension works without changes
10
+ on Ruby and JRuby. Discover why should you write your next extension
11
+ using Ruby-FFI here[http://wiki.github.com/ffi/ffi/why-use-ffi].
12
+
13
+ == FEATURES/PROBLEMS:
14
+
15
+ * It has a very intuitive DSL
16
+ * It supports all C native types
17
+ * It supports C structs (also nested), enums and global variables
18
+ * It supports callbacks
19
+ * It has smart methods to handle memory management of pointers and structs
20
+
21
+ == SYNOPSIS:
22
+
23
+ require 'ffi'
24
+
25
+ module MyLib
26
+ extend FFI::Library
27
+ attach_function :puts, [ :string ], :int
28
+ end
29
+
30
+ MyLib.puts 'Hello boys using libc!'
31
+
32
+ For less minimalistic and more sane examples you may look at:
33
+
34
+ * the samples/ folder
35
+ * the examples on the wiki[http://wiki.github.com/ffi/ffi]
36
+ * the projects using FFI listed on this page[http://wiki.github.com/ffi/ffi/projects-using-ffi]
37
+
38
+ == REQUIREMENTS:
39
+
40
+ * You need a sane building environment in order to compile the extension.
41
+
42
+ == DOWNLOAD/INSTALL:
43
+
44
+ From rubyforge:
45
+
46
+ [sudo] gem install ffi
47
+
48
+ or from the git repository on github:
49
+
50
+ git clone git://github.com/ffi/ffi.git
51
+ cd ffi
52
+ rake gem:install
53
+
54
+ == CREDITS:
55
+
56
+ Special thanks to:
57
+
58
+ * Yehuda Katz
59
+ * Luc Heinrich
60
+ * Andrea Fazzi
61
+ * Mike Dalessio
62
+ * Hongli Lai
63
+ * Evan Phoenix
64
+ * Aman Gupta
65
+ * Beoran
66
+
67
+ == LICENSE:
68
+
69
+ See LICENSE file.
@@ -0,0 +1,191 @@
1
+ require 'rubygems'
2
+ require 'rbconfig'
3
+
4
+ USE_RAKE_COMPILER = (RUBY_PLATFORM =~ /java/) ? false : true
5
+ if USE_RAKE_COMPILER
6
+ gem 'rake-compiler', '>=0.6.0'
7
+ require 'rake/extensiontask'
8
+ ENV['RUBY_CC_VERSION'] = '1.8.6:1.9.1'
9
+ end
10
+
11
+ require 'date'
12
+ require 'fileutils'
13
+ require 'rbconfig'
14
+
15
+ begin
16
+ require 'bones'
17
+ Bones.setup
18
+ rescue LoadError
19
+ begin
20
+ load 'tasks/setup.rb'
21
+ rescue LoadError
22
+ raise RuntimeError, '### please install the "bones" gem ###'
23
+ end
24
+ end
25
+
26
+ LIBEXT = case Config::CONFIG['host_os'].downcase
27
+ when /darwin/
28
+ "dylib"
29
+ when /mswin|mingw/
30
+ "dll"
31
+ else
32
+ Config::CONFIG['DLEXT']
33
+ end
34
+
35
+ CPU = case Config::CONFIG['host_cpu'].downcase
36
+ when /i[3456]86/
37
+ # Darwin always reports i686, even when running in 64bit mode
38
+ if Config::CONFIG['host_os'] =~ /darwin/ && 0xfee1deadbeef.is_a?(Fixnum)
39
+ "x86_64"
40
+ else
41
+ "i386"
42
+ end
43
+ when /amd64|x86_64/
44
+ "x86_64"
45
+ when /ppc|powerpc/
46
+ "powerpc"
47
+ else
48
+ Config::CONFIG['host_cpu']
49
+ end
50
+
51
+ OS = case Config::CONFIG['host_os'].downcase
52
+ when /linux/
53
+ "linux"
54
+ when /darwin/
55
+ "darwin"
56
+ when /freebsd/
57
+ "freebsd"
58
+ when /openbsd/
59
+ "openbsd"
60
+ when /sunos|solaris/
61
+ "solaris"
62
+ when /mswin|mingw/
63
+ "win32"
64
+ else
65
+ Config::CONFIG['host_os'].downcase
66
+ end
67
+
68
+ CC=ENV['CC'] || Config::CONFIG['CC'] || "gcc"
69
+
70
+ GMAKE = Config::CONFIG['host_os'].downcase =~ /bsd|solaris/ ? "gmake" : "make"
71
+
72
+ LIBTEST = "build/libtest.#{LIBEXT}"
73
+ BUILD_DIR = "build"
74
+ BUILD_EXT_DIR = File.join(BUILD_DIR, "#{Config::CONFIG['arch']}", 'ffi_c', RUBY_VERSION)
75
+
76
+ # Project general information
77
+ PROJ.name = 'ffi'
78
+ PROJ.authors = 'Wayne Meissner'
79
+ PROJ.email = 'wmeissner@gmail.com'
80
+ PROJ.url = 'http://wiki.github.com/ffi/ffi'
81
+ PROJ.version = '0.5.0'
82
+ PROJ.rubyforge.name = 'ffi'
83
+ PROJ.readme_file = 'README.rdoc'
84
+
85
+ # Annoucement
86
+ PROJ.ann.paragraphs << 'FEATURES' << 'SYNOPSIS' << 'REQUIREMENTS' << 'DOWNLOAD/INSTALL' << 'CREDITS' << 'LICENSE'
87
+
88
+ PROJ.ann.email[:from] = 'andrea.fazzi@alcacoop.it'
89
+ PROJ.ann.email[:to] << 'ruby-ffi@groups.google.com'
90
+ PROJ.ann.email[:server] = 'smtp.gmail.com'
91
+
92
+ # Gem specifications
93
+ PROJ.gem.need_tar = false
94
+ PROJ.gem.files = %w(LICENSE README.rdoc Rakefile) + Dir.glob("{ext,gen,lib,spec}/**/*")
95
+ PROJ.gem.platform = Gem::Platform::RUBY
96
+
97
+ # Override Mr. Bones autogenerated extensions and force ours in
98
+ PROJ.gem.extras['extensions'] = %w(ext/ffi_c/extconf.rb gen/Rakefile)
99
+
100
+ # RDoc
101
+ PROJ.rdoc.exclude << '^ext\/'
102
+ PROJ.rdoc.opts << '-x' << 'ext'
103
+
104
+ # Ruby
105
+ PROJ.ruby_opts = []
106
+ PROJ.ruby_opts << '-I' << BUILD_EXT_DIR unless RUBY_PLATFORM == "java"
107
+
108
+ # RSpec
109
+ PROJ.spec.files.exclude /rbx/
110
+ PROJ.spec.opts << '--color' << '-fs'
111
+
112
+ # Dependencies
113
+
114
+ depend_on 'rake', '>=0.8.7'
115
+
116
+ TEST_DEPS = [ LIBTEST ]
117
+ if RUBY_PLATFORM == "java"
118
+ desc "Run all specs"
119
+ task :specs => TEST_DEPS do
120
+ sh %{#{Gem.ruby} -S spec #{Dir["spec/ffi/*_spec.rb"].join(" ")} -fs --color}
121
+ end
122
+ desc "Run rubinius specs"
123
+ task :rbxspecs => TEST_DEPS do
124
+ sh %{#{Gem.ruby} -S spec #{Dir["spec/ffi/rbx/*_spec.rb"].join(" ")} -fs --color}
125
+ end
126
+ else
127
+ TEST_DEPS.unshift :compile
128
+ desc "Run all specs"
129
+ task :specs => TEST_DEPS do
130
+ ENV["MRI_FFI"] = "1"
131
+ sh %{#{Gem.ruby} -Ilib -I#{BUILD_EXT_DIR} -S spec #{Dir["spec/ffi/*_spec.rb"].join(" ")} -fs --color}
132
+ end
133
+ desc "Run rubinius specs"
134
+ task :rbxspecs => TEST_DEPS do
135
+ ENV["MRI_FFI"] = "1"
136
+ sh %{#{Gem.ruby} -Ilib -I#{BUILD_EXT_DIR} -S spec #{Dir["spec/ffi/rbx/*_spec.rb"].join(" ")} -fs --color}
137
+ end
138
+ end
139
+
140
+ desc "Build all packages"
141
+ task :package => 'gem:package'
142
+
143
+ desc "Install the gem locally"
144
+ task :install => 'gem:install'
145
+
146
+
147
+ desc "Clean all built files"
148
+ task :distclean => :clobber do
149
+ FileUtils.rm_rf('build')
150
+ FileUtils.rm_rf(Dir["lib/**/ffi_c.#{Config::CONFIG['DLEXT']}"])
151
+ FileUtils.rm_rf('lib/1.8')
152
+ FileUtils.rm_rf('lib/1.9')
153
+ FileUtils.rm_rf('conftest.dSYM')
154
+ FileUtils.rm_rf('pkg')
155
+ end
156
+
157
+
158
+ desc "Build the native test lib"
159
+ task "build/libtest.#{LIBEXT}" do
160
+ sh %{#{GMAKE} -f libtest/GNUmakefile CPU=#{CPU} OS=#{OS} }
161
+ end
162
+
163
+
164
+ desc "Build test helper lib"
165
+ task :libtest => "build/libtest.#{LIBEXT}"
166
+
167
+ desc "Test the extension"
168
+ task :test => [ :specs, :rbxspecs ]
169
+
170
+
171
+ namespace :bench do
172
+ ITER = ENV['ITER'] ? ENV['ITER'].to_i : 100000
173
+ bench_libs = "-Ilib -I#{BUILD_DIR}" unless RUBY_PLATFORM == "java"
174
+ bench_files = Dir["bench/bench_*.rb"].reject { |f| f == "bench_helper.rb" }
175
+ bench_files.each do |bench|
176
+ task File.basename(bench, ".rb")[6..-1] => TEST_DEPS do
177
+ sh %{#{Gem.ruby} #{bench_libs} #{bench} #{ITER}}
178
+ end
179
+ end
180
+ task :all => TEST_DEPS do
181
+ bench_files.each do |bench|
182
+ sh %{#{Gem.ruby} #{bench_libs} #{bench}}
183
+ end
184
+ end
185
+ end
186
+
187
+ task 'spec:run' => TEST_DEPS
188
+ task 'spec:specdoc' => TEST_DEPS
189
+
190
+ task :default => :specs
191
+
@@ -0,0 +1,489 @@
1
+ /*
2
+ * Copyright (c) 2008, 2009, Wayne Meissner
3
+ *
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are met:
8
+ *
9
+ * * Redistributions of source code must retain the above copyright notice, this
10
+ * list of conditions and the following disclaimer.
11
+ * * Redistributions in binary form must reproduce the above copyright notice
12
+ * this list of conditions and the following disclaimer in the documentation
13
+ * and/or other materials provided with the distribution.
14
+ * * The name of the author or authors may not be used to endorse or promote
15
+ * products derived from this software without specific prior written permission.
16
+ *
17
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ */
28
+
29
+ #include <sys/types.h>
30
+ #include <sys/param.h>
31
+ #include <stdint.h>
32
+ #include <stdbool.h>
33
+ #include <ruby.h>
34
+ #include "rbffi.h"
35
+ #include "compat.h"
36
+ #include "AbstractMemory.h"
37
+ #include "Pointer.h"
38
+ #include "Function.h"
39
+
40
+
41
+ static inline char* memory_address(VALUE self);
42
+ VALUE rbffi_AbstractMemoryClass = Qnil;
43
+ static VALUE NullPointerErrorClass = Qnil;
44
+ static ID id_to_ptr = 0, id_plus = 0, id_call = 0;
45
+
46
+ static VALUE
47
+ memory_allocate(VALUE klass)
48
+ {
49
+ AbstractMemory* memory;
50
+ VALUE obj;
51
+ obj = Data_Make_Struct(klass, AbstractMemory, NULL, -1, memory);
52
+ memory->ops = &rbffi_AbstractMemoryOps;
53
+ memory->access = MEM_RD | MEM_WR;
54
+
55
+ return obj;
56
+ }
57
+
58
+ #define NUM_OP(name, type, toNative, fromNative) \
59
+ static void memory_op_put_##name(AbstractMemory* memory, long off, VALUE value); \
60
+ static void \
61
+ memory_op_put_##name(AbstractMemory* memory, long off, VALUE value) \
62
+ { \
63
+ type tmp = (type) toNative(value); \
64
+ checkWrite(memory); \
65
+ checkBounds(memory, off, sizeof(type)); \
66
+ memcpy(memory->address + off, &tmp, sizeof(tmp)); \
67
+ } \
68
+ static VALUE memory_put_##name(VALUE self, VALUE offset, VALUE value); \
69
+ static VALUE \
70
+ memory_put_##name(VALUE self, VALUE offset, VALUE value) \
71
+ { \
72
+ AbstractMemory* memory; \
73
+ Data_Get_Struct(self, AbstractMemory, memory); \
74
+ memory_op_put_##name(memory, NUM2LONG(offset), value); \
75
+ return self; \
76
+ } \
77
+ static VALUE memory_op_get_##name(AbstractMemory* memory, long off); \
78
+ static VALUE \
79
+ memory_op_get_##name(AbstractMemory* memory, long off) \
80
+ { \
81
+ type tmp; \
82
+ checkRead(memory); \
83
+ checkBounds(memory, off, sizeof(type)); \
84
+ memcpy(&tmp, memory->address + off, sizeof(tmp)); \
85
+ return fromNative(tmp); \
86
+ } \
87
+ static VALUE memory_get_##name(VALUE self, VALUE offset); \
88
+ static VALUE \
89
+ memory_get_##name(VALUE self, VALUE offset) \
90
+ { \
91
+ AbstractMemory* memory; \
92
+ Data_Get_Struct(self, AbstractMemory, memory); \
93
+ return memory_op_get_##name(memory, NUM2LONG(offset)); \
94
+ } \
95
+ static MemoryOp memory_op_##name = { memory_op_get_##name, memory_op_put_##name }; \
96
+ \
97
+ static VALUE memory_put_array_of_##name(VALUE self, VALUE offset, VALUE ary); \
98
+ static VALUE \
99
+ memory_put_array_of_##name(VALUE self, VALUE offset, VALUE ary) \
100
+ { \
101
+ long count = RARRAY_LEN(ary); \
102
+ long off = NUM2LONG(offset); \
103
+ AbstractMemory* memory = MEMORY(self); \
104
+ long i; \
105
+ checkWrite(memory); \
106
+ checkBounds(memory, off, count * sizeof(type)); \
107
+ for (i = 0; i < count; i++) { \
108
+ type tmp = (type) toNative(RARRAY_PTR(ary)[i]); \
109
+ memcpy(memory->address + off + (i * sizeof(type)), &tmp, sizeof(tmp)); \
110
+ } \
111
+ return self; \
112
+ } \
113
+ static VALUE memory_get_array_of_##name(VALUE self, VALUE offset, VALUE length); \
114
+ static VALUE \
115
+ memory_get_array_of_##name(VALUE self, VALUE offset, VALUE length) \
116
+ { \
117
+ long count = NUM2LONG(length); \
118
+ long off = NUM2LONG(offset); \
119
+ AbstractMemory* memory = MEMORY(self); \
120
+ long i; \
121
+ checkRead(memory); \
122
+ checkBounds(memory, off, count * sizeof(type)); \
123
+ VALUE retVal = rb_ary_new2(count); \
124
+ for (i = 0; i < count; ++i) { \
125
+ type tmp; \
126
+ memcpy(&tmp, memory->address + off + (i * sizeof(type)), sizeof(tmp)); \
127
+ rb_ary_push(retVal, fromNative(tmp)); \
128
+ } \
129
+ return retVal; \
130
+ }
131
+
132
+ NUM_OP(int8, int8_t, NUM2INT, INT2NUM);
133
+ NUM_OP(uint8, uint8_t, NUM2UINT, UINT2NUM);
134
+ NUM_OP(int16, int16_t, NUM2INT, INT2NUM);
135
+ NUM_OP(uint16, uint16_t, NUM2UINT, UINT2NUM);
136
+ NUM_OP(int32, int32_t, NUM2INT, INT2NUM);
137
+ NUM_OP(uint32, uint32_t, NUM2UINT, UINT2NUM);
138
+ NUM_OP(int64, int64_t, NUM2LL, LL2NUM);
139
+ NUM_OP(uint64, uint64_t, NUM2ULL, ULL2NUM);
140
+ NUM_OP(float32, float, NUM2DBL, rb_float_new);
141
+ NUM_OP(float64, double, NUM2DBL, rb_float_new);
142
+
143
+ static inline void*
144
+ get_pointer_value(VALUE value)
145
+ {
146
+ const int type = TYPE(value);
147
+ if (type == T_DATA && rb_obj_is_kind_of(value, rbffi_PointerClass)) {
148
+ return memory_address(value);
149
+ } else if (type == T_NIL) {
150
+ return NULL;
151
+ } else if (type == T_FIXNUM) {
152
+ return (void *) (uintptr_t) FIX2INT(value);
153
+ } else if (type == T_BIGNUM) {
154
+ return (void *) (uintptr_t) NUM2ULL(value);
155
+ } else if (rb_respond_to(value, id_to_ptr)) {
156
+ return MEMORY_PTR(rb_funcall2(value, id_to_ptr, 0, NULL));
157
+ } else {
158
+ rb_raise(rb_eArgError, "value is not a pointer");
159
+ }
160
+ }
161
+
162
+ NUM_OP(pointer, void *, get_pointer_value, rbffi_Pointer_NewInstance);
163
+
164
+ static VALUE
165
+ memory_clear(VALUE self)
166
+ {
167
+ AbstractMemory* ptr = MEMORY(self);
168
+ memset(ptr->address, 0, ptr->size);
169
+ return self;
170
+ }
171
+
172
+ static VALUE
173
+ memory_size(VALUE self)
174
+ {
175
+ AbstractMemory* ptr;
176
+
177
+ Data_Get_Struct(self, AbstractMemory, ptr);
178
+
179
+ return LONG2NUM(ptr->size);
180
+ }
181
+
182
+ static VALUE
183
+ memory_get_string(int argc, VALUE* argv, VALUE self)
184
+ {
185
+ VALUE length = Qnil, offset = Qnil;
186
+ AbstractMemory* ptr = MEMORY(self);
187
+ long off, len;
188
+ char* end;
189
+ int nargs = rb_scan_args(argc, argv, "11", &offset, &length);
190
+
191
+ off = NUM2LONG(offset);
192
+ len = nargs > 1 && length != Qnil ? NUM2LONG(length) : (ptr->size - off);
193
+ checkRead(ptr);
194
+ checkBounds(ptr, off, len);
195
+
196
+ end = memchr(ptr->address + off, 0, len);
197
+ return rb_tainted_str_new((char *) ptr->address + off,
198
+ (end != NULL ? end - ptr->address - off : len));
199
+ }
200
+
201
+ static VALUE
202
+ memory_get_array_of_string(int argc, VALUE* argv, VALUE self)
203
+ {
204
+ VALUE offset = Qnil, countnum = Qnil, retVal = Qnil;
205
+ AbstractMemory* ptr;
206
+ long off;
207
+ int count;
208
+
209
+ rb_scan_args(argc, argv, "11", &offset, &countnum);
210
+ off = NUM2LONG(offset);
211
+ count = (countnum == Qnil ? 0 : NUM2INT(countnum));
212
+ retVal = rb_ary_new2(count);
213
+
214
+ Data_Get_Struct(self, AbstractMemory, ptr);
215
+ checkRead(ptr);
216
+
217
+ if (countnum != Qnil) {
218
+ int i;
219
+
220
+ checkBounds(ptr, off, count * sizeof (char*));
221
+
222
+ for (i = 0; i < count; ++i) {
223
+ const char* strptr = *((const char**) (ptr->address + off) + i);
224
+ rb_ary_push(retVal, (strptr == NULL ? Qnil : rb_tainted_str_new2(strptr)));
225
+ }
226
+
227
+ } else {
228
+ checkBounds(ptr, off, sizeof (char*));
229
+ for ( ; off < ptr->size - sizeof (void *); off += sizeof (void *)) {
230
+ const char* strptr = *(const char**) (ptr->address + off);
231
+ if (strptr == NULL) {
232
+ break;
233
+ }
234
+ rb_ary_push(retVal, rb_tainted_str_new2(strptr));
235
+ }
236
+ }
237
+
238
+ return retVal;
239
+ }
240
+
241
+ static VALUE
242
+ memory_put_string(VALUE self, VALUE offset, VALUE str)
243
+ {
244
+ AbstractMemory* ptr = MEMORY(self);
245
+ long off, len;
246
+
247
+ Check_Type(str, T_STRING);
248
+ off = NUM2LONG(offset);
249
+ len = RSTRING_LEN(str);
250
+
251
+ checkWrite(ptr);
252
+ checkBounds(ptr, off, len + 1);
253
+
254
+ if (rb_safe_level() >= 1 && OBJ_TAINTED(str)) {
255
+ rb_raise(rb_eSecurityError, "Writing unsafe string to memory");
256
+ }
257
+
258
+ memcpy(ptr->address + off, RSTRING_PTR(str), len);
259
+ *((char *) ptr->address + off + len) = '\0';
260
+
261
+ return self;
262
+ }
263
+
264
+ static VALUE
265
+ memory_get_bytes(VALUE self, VALUE offset, VALUE length)
266
+ {
267
+ AbstractMemory* ptr = MEMORY(self);
268
+ long off, len;
269
+
270
+ off = NUM2LONG(offset);
271
+ len = NUM2LONG(length);
272
+
273
+ checkRead(ptr);
274
+ checkBounds(ptr, off, len);
275
+
276
+ return rb_tainted_str_new((char *) ptr->address + off, len);
277
+ }
278
+
279
+ static VALUE
280
+ memory_put_bytes(int argc, VALUE* argv, VALUE self)
281
+ {
282
+ AbstractMemory* ptr = MEMORY(self);
283
+ VALUE offset = Qnil, str = Qnil, rbIndex = Qnil, rbLength = Qnil;
284
+ long off, len, idx;
285
+ int nargs = rb_scan_args(argc, argv, "22", &offset, &str, &rbIndex, &rbLength);
286
+
287
+ Check_Type(str, T_STRING);
288
+
289
+ off = NUM2LONG(offset);
290
+ idx = nargs > 2 ? NUM2LONG(rbIndex) : 0;
291
+ if (idx < 0) {
292
+ rb_raise(rb_eRangeError, "index canot be less than zero");
293
+ }
294
+ len = nargs > 3 ? NUM2LONG(rbLength) : (RSTRING_LEN(str) - idx);
295
+ if ((idx + len) > RSTRING_LEN(str)) {
296
+ rb_raise(rb_eRangeError, "index+length is greater than size of string");
297
+ }
298
+
299
+ checkWrite(ptr);
300
+ checkBounds(ptr, off, len);
301
+
302
+ if (rb_safe_level() >= 1 && OBJ_TAINTED(str)) {
303
+ rb_raise(rb_eSecurityError, "Writing unsafe string to memory");
304
+ }
305
+ memcpy(ptr->address + off, RSTRING_PTR(str) + idx, len);
306
+
307
+ return self;
308
+ }
309
+
310
+ static VALUE
311
+ memory_type_size(VALUE self)
312
+ {
313
+ AbstractMemory* ptr;
314
+
315
+ Data_Get_Struct(self, AbstractMemory, ptr);
316
+
317
+ return INT2NUM(ptr->typeSize);
318
+ }
319
+
320
+ static VALUE
321
+ memory_aref(VALUE self, VALUE idx)
322
+ {
323
+ AbstractMemory* ptr;
324
+ VALUE rbOffset = Qnil;
325
+
326
+ Data_Get_Struct(self, AbstractMemory, ptr);
327
+
328
+ rbOffset = ULONG2NUM(NUM2ULONG(idx) * ptr->typeSize);
329
+
330
+ return rb_funcall2(self, id_plus, 1, &rbOffset);
331
+ }
332
+
333
+ static inline char*
334
+ memory_address(VALUE obj)
335
+ {
336
+ return ((AbstractMemory *) DATA_PTR(obj))->address;
337
+ }
338
+
339
+ AbstractMemory*
340
+ rbffi_AbstractMemory_Cast(VALUE obj, VALUE klass)
341
+ {
342
+ if (rb_obj_is_kind_of(obj, klass)) {
343
+ AbstractMemory* memory;
344
+ Data_Get_Struct(obj, AbstractMemory, memory);
345
+ return memory;
346
+ }
347
+
348
+ rb_raise(rb_eArgError, "Invalid Memory object");
349
+ return NULL;
350
+ }
351
+
352
+ void
353
+ rbffi_AbstractMemory_Error(AbstractMemory *mem, int op)
354
+ {
355
+ VALUE rbErrorClass = mem->address == NULL ? NullPointerErrorClass : rb_eRuntimeError;
356
+ if (op == MEM_RD) {
357
+ rb_raise(rbErrorClass, "invalid memory read at address=%p", mem->address);
358
+ } else if (op == MEM_WR) {
359
+ rb_raise(rbErrorClass, "invalid memory write at address=%p", mem->address);
360
+ } else {
361
+ rb_raise(rbErrorClass, "invalid memory access at address=%p", mem->address);
362
+ }
363
+ }
364
+
365
+ static VALUE
366
+ memory_op_get_strptr(AbstractMemory* ptr, long offset)
367
+ {
368
+ void* tmp = NULL;
369
+
370
+ if (ptr != NULL && ptr->address != NULL) {
371
+ checkRead(ptr);
372
+ checkBounds(ptr, offset, sizeof(tmp));
373
+ memcpy(&tmp, ptr->address + offset, sizeof(tmp));
374
+ }
375
+
376
+ return tmp != NULL ? rb_tainted_str_new2(tmp) : Qnil;
377
+ }
378
+
379
+ static void
380
+ memory_op_put_strptr(AbstractMemory* ptr, long offset, VALUE value)
381
+ {
382
+ rb_raise(rb_eArgError, "Cannot set :string fields");
383
+ }
384
+
385
+ static MemoryOp memory_op_strptr = { memory_op_get_strptr, memory_op_put_strptr };
386
+
387
+ //static MemoryOp memory_op_pointer = { memory_op_get_pointer, memory_op_put_pointer };
388
+
389
+ MemoryOps rbffi_AbstractMemoryOps = {
390
+ .int8 = &memory_op_int8,
391
+ .uint8 = &memory_op_uint8,
392
+ .int16 = &memory_op_int16,
393
+ .uint16 = &memory_op_uint16,
394
+ .int32 = &memory_op_int32,
395
+ .uint32 = &memory_op_uint32,
396
+ .int64 = &memory_op_int64,
397
+ .uint64 = &memory_op_uint64,
398
+ .float32 = &memory_op_float32,
399
+ .float64 = &memory_op_float64,
400
+ .pointer = &memory_op_pointer,
401
+ .strptr = &memory_op_strptr,
402
+ };
403
+
404
+ void
405
+ rbffi_AbstractMemory_Init(VALUE moduleFFI)
406
+ {
407
+ VALUE classMemory = rb_define_class_under(moduleFFI, "AbstractMemory", rb_cObject);
408
+ rbffi_AbstractMemoryClass = classMemory;
409
+ rb_global_variable(&rbffi_AbstractMemoryClass);
410
+ rb_define_alloc_func(classMemory, memory_allocate);
411
+
412
+ NullPointerErrorClass = rb_define_class_under(moduleFFI, "NullPointerError", rb_eRuntimeError);
413
+ rb_global_variable(&NullPointerErrorClass);
414
+
415
+
416
+ #undef INT
417
+ #define INT(type) \
418
+ rb_define_method(classMemory, "put_" #type, memory_put_##type, 2); \
419
+ rb_define_method(classMemory, "get_" #type, memory_get_##type, 1); \
420
+ rb_define_method(classMemory, "put_u" #type, memory_put_u##type, 2); \
421
+ rb_define_method(classMemory, "get_u" #type, memory_get_u##type, 1); \
422
+ rb_define_method(classMemory, "put_array_of_" #type, memory_put_array_of_##type, 2); \
423
+ rb_define_method(classMemory, "get_array_of_" #type, memory_get_array_of_##type, 2); \
424
+ rb_define_method(classMemory, "put_array_of_u" #type, memory_put_array_of_u##type, 2); \
425
+ rb_define_method(classMemory, "get_array_of_u" #type, memory_get_array_of_u##type, 2);
426
+
427
+ INT(int8);
428
+ INT(int16);
429
+ INT(int32);
430
+ INT(int64);
431
+
432
+ #define ALIAS(name, old) \
433
+ rb_define_alias(classMemory, "put_" #name, "put_" #old); \
434
+ rb_define_alias(classMemory, "get_" #name, "get_" #old); \
435
+ rb_define_alias(classMemory, "put_u" #name, "put_u" #old); \
436
+ rb_define_alias(classMemory, "get_u" #name, "get_u" #old); \
437
+ rb_define_alias(classMemory, "put_array_of_" #name, "put_array_of_" #old); \
438
+ rb_define_alias(classMemory, "get_array_of_" #name, "get_array_of_" #old); \
439
+ rb_define_alias(classMemory, "put_array_of_u" #name, "put_array_of_u" #old); \
440
+ rb_define_alias(classMemory, "get_array_of_u" #name, "get_array_of_u" #old);
441
+
442
+ ALIAS(char, int8);
443
+ ALIAS(short, int16);
444
+ ALIAS(int, int32);
445
+ ALIAS(long_long, int64);
446
+
447
+ if (sizeof(long) == 4) {
448
+ ALIAS(long, int32);
449
+ } else {
450
+ ALIAS(long, int64);
451
+ }
452
+
453
+ rb_define_method(classMemory, "put_float32", memory_put_float32, 2);
454
+ rb_define_method(classMemory, "get_float32", memory_get_float32, 1);
455
+ rb_define_alias(classMemory, "put_float", "put_float32");
456
+ rb_define_alias(classMemory, "get_float", "get_float32");
457
+ rb_define_method(classMemory, "put_array_of_float32", memory_put_array_of_float32, 2);
458
+ rb_define_method(classMemory, "get_array_of_float32", memory_get_array_of_float32, 2);
459
+ rb_define_alias(classMemory, "put_array_of_float", "put_array_of_float32");
460
+ rb_define_alias(classMemory, "get_array_of_float", "get_array_of_float32");
461
+ rb_define_method(classMemory, "put_float64", memory_put_float64, 2);
462
+ rb_define_method(classMemory, "get_float64", memory_get_float64, 1);
463
+ rb_define_alias(classMemory, "put_double", "put_float64");
464
+ rb_define_alias(classMemory, "get_double", "get_float64");
465
+ rb_define_method(classMemory, "put_array_of_float64", memory_put_array_of_float64, 2);
466
+ rb_define_method(classMemory, "get_array_of_float64", memory_get_array_of_float64, 2);
467
+ rb_define_alias(classMemory, "put_array_of_double", "put_array_of_float64");
468
+ rb_define_alias(classMemory, "get_array_of_double", "get_array_of_float64");
469
+ rb_define_method(classMemory, "put_pointer", memory_put_pointer, 2);
470
+ rb_define_method(classMemory, "get_pointer", memory_get_pointer, 1);
471
+ rb_define_method(classMemory, "put_array_of_pointer", memory_put_array_of_pointer, 2);
472
+ rb_define_method(classMemory, "get_array_of_pointer", memory_get_array_of_pointer, 2);
473
+ rb_define_method(classMemory, "get_string", memory_get_string, -1);
474
+ rb_define_method(classMemory, "put_string", memory_put_string, 2);
475
+ rb_define_method(classMemory, "get_bytes", memory_get_bytes, 2);
476
+ rb_define_method(classMemory, "put_bytes", memory_put_bytes, -1);
477
+ rb_define_method(classMemory, "get_array_of_string", memory_get_array_of_string, -1);
478
+
479
+ rb_define_method(classMemory, "clear", memory_clear, 0);
480
+ rb_define_method(classMemory, "total", memory_size, 0);
481
+ rb_define_alias(classMemory, "size", "total");
482
+ rb_define_method(classMemory, "type_size", memory_type_size, 0);
483
+ rb_define_method(classMemory, "[]", memory_aref, 1);
484
+
485
+ id_to_ptr = rb_intern("to_ptr");
486
+ id_call = rb_intern("call");
487
+ id_plus = rb_intern("+");
488
+ }
489
+