ffi 0.4.0-x86-mswin32

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 (316) hide show
  1. data/LICENSE +51 -0
  2. data/README.rdoc +69 -0
  3. data/Rakefile +142 -0
  4. data/ext/ffi_c/AbstractMemory.c +412 -0
  5. data/ext/ffi_c/AbstractMemory.h +68 -0
  6. data/ext/ffi_c/AutoPointer.c +60 -0
  7. data/ext/ffi_c/AutoPointer.h +18 -0
  8. data/ext/ffi_c/Buffer.c +171 -0
  9. data/ext/ffi_c/Callback.c +374 -0
  10. data/ext/ffi_c/Callback.h +47 -0
  11. data/ext/ffi_c/DynamicLibrary.c +213 -0
  12. data/ext/ffi_c/DynamicLibrary.h +22 -0
  13. data/ext/ffi_c/Invoker.c +962 -0
  14. data/ext/ffi_c/LastError.c +135 -0
  15. data/ext/ffi_c/LastError.h +18 -0
  16. data/ext/ffi_c/MemoryPointer.c +156 -0
  17. data/ext/ffi_c/MemoryPointer.h +20 -0
  18. data/ext/ffi_c/NullPointer.c +143 -0
  19. data/ext/ffi_c/Platform.c +59 -0
  20. data/ext/ffi_c/Platform.h +16 -0
  21. data/ext/ffi_c/Pointer.c +164 -0
  22. data/ext/ffi_c/Pointer.h +25 -0
  23. data/ext/ffi_c/Struct.c +477 -0
  24. data/ext/ffi_c/Struct.h +26 -0
  25. data/ext/ffi_c/Type.c +230 -0
  26. data/ext/ffi_c/Type.h +28 -0
  27. data/ext/ffi_c/Types.c +118 -0
  28. data/ext/ffi_c/Types.h +54 -0
  29. data/ext/ffi_c/compat.h +22 -0
  30. data/ext/ffi_c/endian.h +40 -0
  31. data/ext/ffi_c/extconf.rb +31 -0
  32. data/ext/ffi_c/ffi.c +76 -0
  33. data/ext/ffi_c/libffi.bsd.mk +34 -0
  34. data/ext/ffi_c/libffi.darwin.mk +75 -0
  35. data/ext/ffi_c/libffi.gnu.mk +29 -0
  36. data/ext/ffi_c/libffi.mk +13 -0
  37. data/ext/ffi_c/libffi/ChangeLog +3243 -0
  38. data/ext/ffi_c/libffi/ChangeLog.libffi +347 -0
  39. data/ext/ffi_c/libffi/ChangeLog.libgcj +40 -0
  40. data/ext/ffi_c/libffi/ChangeLog.v1 +764 -0
  41. data/ext/ffi_c/libffi/LICENSE +21 -0
  42. data/ext/ffi_c/libffi/Makefile.am +177 -0
  43. data/ext/ffi_c/libffi/Makefile.in +1640 -0
  44. data/ext/ffi_c/libffi/README +328 -0
  45. data/ext/ffi_c/libffi/TODO +1 -0
  46. data/ext/ffi_c/libffi/acinclude.m4 +92 -0
  47. data/ext/ffi_c/libffi/aclocal.m4 +7516 -0
  48. data/ext/ffi_c/libffi/compile +142 -0
  49. data/ext/ffi_c/libffi/config.guess +1516 -0
  50. data/ext/ffi_c/libffi/config.sub +1626 -0
  51. data/ext/ffi_c/libffi/configure +24414 -0
  52. data/ext/ffi_c/libffi/configure.ac +365 -0
  53. data/ext/ffi_c/libffi/configure.host +11 -0
  54. data/ext/ffi_c/libffi/depcomp +584 -0
  55. data/ext/ffi_c/libffi/doc/libffi.info +533 -0
  56. data/ext/ffi_c/libffi/doc/libffi.texi +541 -0
  57. data/ext/ffi_c/libffi/doc/stamp-vti +4 -0
  58. data/ext/ffi_c/libffi/doc/version.texi +4 -0
  59. data/ext/ffi_c/libffi/fficonfig.h.in +160 -0
  60. data/ext/ffi_c/libffi/include/Makefile.am +9 -0
  61. data/ext/ffi_c/libffi/include/Makefile.in +422 -0
  62. data/ext/ffi_c/libffi/include/ffi.h.in +393 -0
  63. data/ext/ffi_c/libffi/include/ffi_common.h +98 -0
  64. data/ext/ffi_c/libffi/install-sh +323 -0
  65. data/ext/ffi_c/libffi/libffi.pc.in +10 -0
  66. data/ext/ffi_c/libffi/libtool-version +29 -0
  67. data/ext/ffi_c/libffi/ltcf-c.sh +861 -0
  68. data/ext/ffi_c/libffi/ltcf-cxx.sh +1069 -0
  69. data/ext/ffi_c/libffi/ltcf-gcj.sh +700 -0
  70. data/ext/ffi_c/libffi/ltconfig +2862 -0
  71. data/ext/ffi_c/libffi/ltmain.sh +6930 -0
  72. data/ext/ffi_c/libffi/man/Makefile.am +8 -0
  73. data/ext/ffi_c/libffi/man/Makefile.in +395 -0
  74. data/ext/ffi_c/libffi/man/ffi.3 +31 -0
  75. data/ext/ffi_c/libffi/man/ffi_call.3 +103 -0
  76. data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +66 -0
  77. data/ext/ffi_c/libffi/mdate-sh +201 -0
  78. data/ext/ffi_c/libffi/missing +353 -0
  79. data/ext/ffi_c/libffi/mkinstalldirs +158 -0
  80. data/ext/ffi_c/libffi/src/alpha/ffi.c +284 -0
  81. data/ext/ffi_c/libffi/src/alpha/ffitarget.h +48 -0
  82. data/ext/ffi_c/libffi/src/alpha/osf.S +366 -0
  83. data/ext/ffi_c/libffi/src/arm/ffi.c +309 -0
  84. data/ext/ffi_c/libffi/src/arm/ffitarget.h +49 -0
  85. data/ext/ffi_c/libffi/src/arm/sysv.S +299 -0
  86. data/ext/ffi_c/libffi/src/closures.c +596 -0
  87. data/ext/ffi_c/libffi/src/cris/ffi.c +383 -0
  88. data/ext/ffi_c/libffi/src/cris/ffitarget.h +51 -0
  89. data/ext/ffi_c/libffi/src/cris/sysv.S +215 -0
  90. data/ext/ffi_c/libffi/src/debug.c +59 -0
  91. data/ext/ffi_c/libffi/src/dlmalloc.c +5099 -0
  92. data/ext/ffi_c/libffi/src/frv/eabi.S +128 -0
  93. data/ext/ffi_c/libffi/src/frv/ffi.c +292 -0
  94. data/ext/ffi_c/libffi/src/frv/ffitarget.h +61 -0
  95. data/ext/ffi_c/libffi/src/ia64/ffi.c +580 -0
  96. data/ext/ffi_c/libffi/src/ia64/ffitarget.h +50 -0
  97. data/ext/ffi_c/libffi/src/ia64/ia64_flags.h +40 -0
  98. data/ext/ffi_c/libffi/src/ia64/unix.S +560 -0
  99. data/ext/ffi_c/libffi/src/java_raw_api.c +359 -0
  100. data/ext/ffi_c/libffi/src/m32r/ffi.c +232 -0
  101. data/ext/ffi_c/libffi/src/m32r/ffitarget.h +48 -0
  102. data/ext/ffi_c/libffi/src/m32r/sysv.S +121 -0
  103. data/ext/ffi_c/libffi/src/m68k/ffi.c +278 -0
  104. data/ext/ffi_c/libffi/src/m68k/ffitarget.h +49 -0
  105. data/ext/ffi_c/libffi/src/m68k/sysv.S +234 -0
  106. data/ext/ffi_c/libffi/src/mips/ffi.c +926 -0
  107. data/ext/ffi_c/libffi/src/mips/ffitarget.h +202 -0
  108. data/ext/ffi_c/libffi/src/mips/n32.S +534 -0
  109. data/ext/ffi_c/libffi/src/mips/o32.S +381 -0
  110. data/ext/ffi_c/libffi/src/pa/ffi.c +709 -0
  111. data/ext/ffi_c/libffi/src/pa/ffitarget.h +77 -0
  112. data/ext/ffi_c/libffi/src/pa/hpux32.S +368 -0
  113. data/ext/ffi_c/libffi/src/pa/linux.S +357 -0
  114. data/ext/ffi_c/libffi/src/powerpc/aix.S +225 -0
  115. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +247 -0
  116. data/ext/ffi_c/libffi/src/powerpc/asm.h +125 -0
  117. data/ext/ffi_c/libffi/src/powerpc/darwin.S +245 -0
  118. data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +317 -0
  119. data/ext/ffi_c/libffi/src/powerpc/ffi.c +1429 -0
  120. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +800 -0
  121. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +118 -0
  122. data/ext/ffi_c/libffi/src/powerpc/linux64.S +187 -0
  123. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +236 -0
  124. data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +327 -0
  125. data/ext/ffi_c/libffi/src/powerpc/sysv.S +230 -0
  126. data/ext/ffi_c/libffi/src/prep_cif.c +174 -0
  127. data/ext/ffi_c/libffi/src/raw_api.c +254 -0
  128. data/ext/ffi_c/libffi/src/s390/ffi.c +780 -0
  129. data/ext/ffi_c/libffi/src/s390/ffitarget.h +60 -0
  130. data/ext/ffi_c/libffi/src/s390/sysv.S +434 -0
  131. data/ext/ffi_c/libffi/src/sh/ffi.c +716 -0
  132. data/ext/ffi_c/libffi/src/sh/ffitarget.h +49 -0
  133. data/ext/ffi_c/libffi/src/sh/sysv.S +850 -0
  134. data/ext/ffi_c/libffi/src/sh64/ffi.c +453 -0
  135. data/ext/ffi_c/libffi/src/sh64/ffitarget.h +53 -0
  136. data/ext/ffi_c/libffi/src/sh64/sysv.S +530 -0
  137. data/ext/ffi_c/libffi/src/sparc/ffi.c +610 -0
  138. data/ext/ffi_c/libffi/src/sparc/ffitarget.h +66 -0
  139. data/ext/ffi_c/libffi/src/sparc/v8.S +272 -0
  140. data/ext/ffi_c/libffi/src/sparc/v9.S +307 -0
  141. data/ext/ffi_c/libffi/src/types.c +77 -0
  142. data/ext/ffi_c/libffi/src/x86/darwin.S +443 -0
  143. data/ext/ffi_c/libffi/src/x86/darwin64.S +416 -0
  144. data/ext/ffi_c/libffi/src/x86/ffi.c +475 -0
  145. data/ext/ffi_c/libffi/src/x86/ffi64.c +572 -0
  146. data/ext/ffi_c/libffi/src/x86/ffitarget.h +90 -0
  147. data/ext/ffi_c/libffi/src/x86/freebsd.S +458 -0
  148. data/ext/ffi_c/libffi/src/x86/sysv.S +437 -0
  149. data/ext/ffi_c/libffi/src/x86/unix64.S +418 -0
  150. data/ext/ffi_c/libffi/src/x86/win32.S +391 -0
  151. data/ext/ffi_c/libffi/testsuite/Makefile.am +71 -0
  152. data/ext/ffi_c/libffi/testsuite/Makefile.in +447 -0
  153. data/ext/ffi_c/libffi/testsuite/config/default.exp +1 -0
  154. data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +289 -0
  155. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +263 -0
  156. data/ext/ffi_c/libffi/testsuite/lib/wrapper.exp +45 -0
  157. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +36 -0
  158. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn0.c +97 -0
  159. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn1.c +89 -0
  160. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn2.c +89 -0
  161. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn3.c +90 -0
  162. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn4.c +97 -0
  163. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn5.c +99 -0
  164. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn6.c +98 -0
  165. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_stdcall.c +72 -0
  166. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +102 -0
  167. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +103 -0
  168. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +104 -0
  169. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +110 -0
  170. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +97 -0
  171. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +99 -0
  172. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +101 -0
  173. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +121 -0
  174. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +98 -0
  175. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +103 -0
  176. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +98 -0
  177. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +98 -0
  178. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +106 -0
  179. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +98 -0
  180. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +117 -0
  181. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +106 -0
  182. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +132 -0
  183. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +121 -0
  184. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +107 -0
  185. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +125 -0
  186. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +105 -0
  187. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +96 -0
  188. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +98 -0
  189. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +99 -0
  190. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +101 -0
  191. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +99 -0
  192. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +100 -0
  193. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +101 -0
  194. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +99 -0
  195. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +99 -0
  196. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +99 -0
  197. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +99 -0
  198. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +99 -0
  199. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +100 -0
  200. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double.c +51 -0
  201. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_float.c +51 -0
  202. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_schar.c +82 -0
  203. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshort.c +82 -0
  204. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshortchar.c +94 -0
  205. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_uchar.c +99 -0
  206. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushort.c +82 -0
  207. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushortchar.c +94 -0
  208. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_schar.c +52 -0
  209. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sint.c +50 -0
  210. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sshort.c +50 -0
  211. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar.c +50 -0
  212. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint.c +51 -0
  213. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +54 -0
  214. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort.c +51 -0
  215. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +86 -0
  216. data/ext/ffi_c/libffi/testsuite/libffi.call/float.c +59 -0
  217. data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +58 -0
  218. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +57 -0
  219. data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +72 -0
  220. data/ext/ffi_c/libffi/testsuite/libffi.call/float4.c +62 -0
  221. data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +69 -0
  222. data/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c +63 -0
  223. data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +53 -0
  224. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +160 -0
  225. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +169 -0
  226. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +141 -0
  227. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +118 -0
  228. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +119 -0
  229. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +119 -0
  230. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +120 -0
  231. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +139 -0
  232. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +119 -0
  233. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +139 -0
  234. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +139 -0
  235. data/ext/ffi_c/libffi/testsuite/libffi.call/problem1.c +98 -0
  236. data/ext/ffi_c/libffi/testsuite/libffi.call/promotion.c +59 -0
  237. data/ext/ffi_c/libffi/testsuite/libffi.call/pyobjc-tc.c +114 -0
  238. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +35 -0
  239. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl1.c +43 -0
  240. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl2.c +42 -0
  241. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl.c +35 -0
  242. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl1.c +36 -0
  243. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl2.c +49 -0
  244. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl3.c +42 -0
  245. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +34 -0
  246. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll.c +41 -0
  247. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +42 -0
  248. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +36 -0
  249. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c +38 -0
  250. data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +38 -0
  251. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c +38 -0
  252. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +44 -0
  253. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c +44 -0
  254. data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +65 -0
  255. data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +67 -0
  256. data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +59 -0
  257. data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +63 -0
  258. data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +65 -0
  259. data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +64 -0
  260. data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +74 -0
  261. data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +80 -0
  262. data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +67 -0
  263. data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +86 -0
  264. data/ext/ffi_c/libffi/testsuite/libffi.special/special.exp +38 -0
  265. data/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest.cc +123 -0
  266. data/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc +53 -0
  267. data/ext/ffi_c/libffi/texinfo.tex +7482 -0
  268. data/ext/ffi_c/rbffi.h +23 -0
  269. data/gen/Rakefile +12 -0
  270. data/lib/1.8/ffi_c.so +0 -0
  271. data/lib/1.9/ffi_c.so +0 -0
  272. data/lib/ffi.rb +11 -0
  273. data/lib/ffi/autopointer.rb +61 -0
  274. data/lib/ffi/buffer.rb +0 -0
  275. data/lib/ffi/callback.rb +10 -0
  276. data/lib/ffi/enum.rb +78 -0
  277. data/lib/ffi/errno.rb +8 -0
  278. data/lib/ffi/ffi.rb +96 -0
  279. data/lib/ffi/io.rb +21 -0
  280. data/lib/ffi/library.rb +243 -0
  281. data/lib/ffi/managedstruct.rb +55 -0
  282. data/lib/ffi/memorypointer.rb +73 -0
  283. data/lib/ffi/platform.rb +78 -0
  284. data/lib/ffi/pointer.rb +119 -0
  285. data/lib/ffi/struct.rb +354 -0
  286. data/lib/ffi/tools/const_generator.rb +177 -0
  287. data/lib/ffi/tools/generator.rb +58 -0
  288. data/lib/ffi/tools/generator_task.rb +35 -0
  289. data/lib/ffi/tools/struct_generator.rb +194 -0
  290. data/lib/ffi/tools/types_generator.rb +123 -0
  291. data/lib/ffi/types.rb +153 -0
  292. data/lib/ffi/union.rb +17 -0
  293. data/lib/ffi/variadic.rb +30 -0
  294. data/spec/ffi/bool_spec.rb +24 -0
  295. data/spec/ffi/buffer_spec.rb +196 -0
  296. data/spec/ffi/callback_spec.rb +560 -0
  297. data/spec/ffi/enum_spec.rb +164 -0
  298. data/spec/ffi/errno_spec.rb +13 -0
  299. data/spec/ffi/library_spec.rb +144 -0
  300. data/spec/ffi/managed_struct_spec.rb +56 -0
  301. data/spec/ffi/number_spec.rb +231 -0
  302. data/spec/ffi/pointer_spec.rb +195 -0
  303. data/spec/ffi/rbx/attach_function_spec.rb +27 -0
  304. data/spec/ffi/rbx/memory_pointer_spec.rb +102 -0
  305. data/spec/ffi/rbx/spec_helper.rb +1 -0
  306. data/spec/ffi/rbx/struct_spec.rb +13 -0
  307. data/spec/ffi/spec_helper.rb +17 -0
  308. data/spec/ffi/string_spec.rb +103 -0
  309. data/spec/ffi/struct_callback_spec.rb +41 -0
  310. data/spec/ffi/struct_initialize_spec.rb +30 -0
  311. data/spec/ffi/struct_spec.rb +476 -0
  312. data/spec/ffi/typedef_spec.rb +48 -0
  313. data/spec/ffi/union_spec.rb +60 -0
  314. data/spec/ffi/variadic_spec.rb +84 -0
  315. data/spec/spec.opts +4 -0
  316. metadata +375 -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.
data/README.rdoc ADDED
@@ -0,0 +1,69 @@
1
+ ruby-ffi
2
+ by Wayne Meissner
3
+ http://kenai.com/projects/ruby-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://kenai.com/projects/ruby-ffi/pages/WhyUseFFI].
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 Kenai {wiki}[http://kenai.com/projects/ruby-ffi/pages/Home]
36
+ * the projects using FFI listed on this {page}[http://kenai.com/projects/ruby-ffi/pages/ProjectsUsingFFI]
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 mercurial repository on Kenai:
49
+
50
+ hg clone https://kenai.com/hg/ruby-ffi~mercurial ruby-ffi
51
+ cd ruby-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.
data/Rakefile ADDED
@@ -0,0 +1,142 @@
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 = Config::CONFIG['host_os'].downcase =~ /darwin/ ? "dylib" : "so"
27
+ GMAKE = Config::CONFIG['host_os'].downcase =~ /bsd/ ? "gmake" : "make"
28
+ LIBTEST = "build/libtest.#{LIBEXT}"
29
+ BUILD_DIR = "build"
30
+ BUILD_EXT_DIR = File.join(BUILD_DIR, "#{Config::CONFIG['arch']}", 'ffi_c', RUBY_VERSION)
31
+
32
+ # Project general information
33
+ PROJ.name = 'ffi'
34
+ PROJ.authors = 'Wayne Meissner'
35
+ PROJ.email = 'wmeissner@gmail.com'
36
+ PROJ.url = 'http://kenai.com/projects/ruby-ffi'
37
+ PROJ.version = '0.4.0'
38
+ PROJ.rubyforge.name = 'ffi'
39
+ PROJ.readme_file = 'README.rdoc'
40
+
41
+ # Annoucement
42
+ PROJ.ann.paragraphs << 'FEATURES' << 'SYNOPSIS' << 'REQUIREMENTS' << 'DOWNLOAD/INSTALL' << 'CREDITS' << 'LICENSE'
43
+
44
+ PROJ.ann.email[:from] = 'andrea.fazzi@alcacoop.it'
45
+ PROJ.ann.email[:to] << 'dev@ruby-ffi.kenai.com' << 'users@ruby-ffi.kenai.com'
46
+ PROJ.ann.email[:server] = 'smtp.gmail.com'
47
+
48
+ # Gem specifications
49
+ PROJ.gem.need_tar = false
50
+ PROJ.gem.files = %w(LICENSE README.rdoc Rakefile) + Dir.glob("{ext,gen,lib,spec}/**/*")
51
+ PROJ.gem.platform = Gem::Platform::RUBY
52
+
53
+ # Override Mr. Bones autogenerated extensions and force ours in
54
+ PROJ.gem.extras['extensions'] = %w(ext/ffi_c/extconf.rb gen/Rakefile)
55
+
56
+ # RDoc
57
+ PROJ.rdoc.exclude << '^ext\/'
58
+ PROJ.rdoc.opts << '-x' << 'ext'
59
+
60
+ # Ruby
61
+ PROJ.ruby_opts = []
62
+ PROJ.ruby_opts << '-I' << BUILD_EXT_DIR unless RUBY_PLATFORM == "java"
63
+
64
+ #RSpec
65
+ PROJ.spec.opts << '--color' << '-fs'
66
+
67
+ TEST_DEPS = [ LIBTEST ]
68
+ if RUBY_PLATFORM == "java"
69
+ desc "Run all specs"
70
+ task :specs => TEST_DEPS do
71
+ sh %{#{Gem.ruby} -S spec #{Dir["spec/ffi/*_spec.rb"].join(" ")} -fs --color}
72
+ end
73
+ desc "Run rubinius specs"
74
+ task :rbxspecs => TEST_DEPS do
75
+ sh %{#{Gem.ruby} -S spec #{Dir["spec/ffi/rbx/*_spec.rb"].join(" ")} -fs --color}
76
+ end
77
+ else
78
+ TEST_DEPS.unshift :compile
79
+ desc "Run all specs"
80
+ task :specs => TEST_DEPS do
81
+ ENV["MRI_FFI"] = "1"
82
+ sh %{#{Gem.ruby} -Ilib -I#{BUILD_EXT_DIR} -S spec #{Dir["spec/ffi/*_spec.rb"].join(" ")} -fs --color}
83
+ end
84
+ desc "Run rubinius specs"
85
+ task :rbxspecs => TEST_DEPS do
86
+ ENV["MRI_FFI"] = "1"
87
+ sh %{#{Gem.ruby} -Ilib -I#{BUILD_EXT_DIR} -S spec #{Dir["spec/ffi/rbx/*_spec.rb"].join(" ")} -fs --color}
88
+ end
89
+ end
90
+
91
+ desc "Build all packages"
92
+ task :package => 'gem:package'
93
+
94
+ desc "Install the gem locally"
95
+ task :install => 'gem:install'
96
+
97
+
98
+ desc "Clean all built files"
99
+ task :distclean => :clobber do
100
+ FileUtils.rm_rf('build')
101
+ FileUtils.rm_rf(Dir['lib/**/ffi_c.so'])
102
+ FileUtils.rm_rf('lib/1.8')
103
+ FileUtils.rm_rf('lib/1.9')
104
+ FileUtils.rm_rf('conftest.dSYM')
105
+ FileUtils.rm_rf('pkg')
106
+ end
107
+
108
+
109
+ desc "Build the native test lib"
110
+ task "build/libtest.#{LIBEXT}" do
111
+ sh %{#{GMAKE} -f libtest/GNUmakefile CPU=#{Config::CONFIG['host_cpu']}}
112
+ end
113
+
114
+
115
+ desc "Build test helper lib"
116
+ task :libtest => "build/libtest.#{LIBEXT}"
117
+
118
+ desc "Test the extension"
119
+ task :test => [ :specs, :rbxspecs ]
120
+
121
+
122
+ namespace :bench do
123
+ ITER = ENV['ITER'] ? ENV['ITER'].to_i : 100000
124
+ bench_libs = "-Ilib -I#{BUILD_DIR}" unless RUBY_PLATFORM == "java"
125
+ bench_files = Dir["bench/bench_*.rb"].reject { |f| f == "bench_helper.rb" }
126
+ bench_files.each do |bench|
127
+ task File.basename(bench, ".rb")[6..-1] => TEST_DEPS do
128
+ sh %{#{Gem.ruby} #{bench_libs} #{bench} #{ITER}}
129
+ end
130
+ end
131
+ task :all => TEST_DEPS do
132
+ bench_files.each do |bench|
133
+ sh %{#{Gem.ruby} #{bench_libs} #{bench}}
134
+ end
135
+ end
136
+ end
137
+
138
+ task 'spec:run' => TEST_DEPS
139
+ task 'spec:specdoc' => TEST_DEPS
140
+
141
+ task :default => :specs
142
+
@@ -0,0 +1,412 @@
1
+ #include <sys/types.h>
2
+ #include <sys/param.h>
3
+ #include <stdint.h>
4
+ #include <stdbool.h>
5
+ #include <ruby.h>
6
+ #include "rbffi.h"
7
+ #include "compat.h"
8
+ #include "AbstractMemory.h"
9
+ #include "Pointer.h"
10
+ #include "Callback.h"
11
+
12
+
13
+ static inline char* memory_address(VALUE self);
14
+ VALUE rbffi_AbstractMemoryClass = Qnil;
15
+ static ID id_to_ptr = 0;
16
+ static ID id_call = 0;
17
+
18
+ static VALUE
19
+ memory_allocate(VALUE klass)
20
+ {
21
+ AbstractMemory* memory;
22
+ VALUE obj;
23
+ obj = Data_Make_Struct(klass, AbstractMemory, NULL, -1, memory);
24
+ memory->ops = &rbffi_AbstractMemoryOps;
25
+
26
+ return obj;
27
+ }
28
+
29
+ #define NUM_OP(name, type, toNative, fromNative) \
30
+ static void memory_op_put_##name(AbstractMemory* memory, long off, VALUE value); \
31
+ static void \
32
+ memory_op_put_##name(AbstractMemory* memory, long off, VALUE value) \
33
+ { \
34
+ type tmp = (type) toNative(value); \
35
+ checkBounds(memory, off, sizeof(type)); \
36
+ memcpy(memory->address + off, &tmp, sizeof(tmp)); \
37
+ } \
38
+ static VALUE memory_put_##name(VALUE self, VALUE offset, VALUE value); \
39
+ static VALUE \
40
+ memory_put_##name(VALUE self, VALUE offset, VALUE value) \
41
+ { \
42
+ AbstractMemory* memory; \
43
+ Data_Get_Struct(self, AbstractMemory, memory); \
44
+ memory_op_put_##name(memory, NUM2LONG(offset), value); \
45
+ return self; \
46
+ } \
47
+ static VALUE memory_op_get_##name(AbstractMemory* memory, long off); \
48
+ static VALUE \
49
+ memory_op_get_##name(AbstractMemory* memory, long off) \
50
+ { \
51
+ type tmp; \
52
+ checkBounds(memory, off, sizeof(type)); \
53
+ memcpy(&tmp, memory->address + off, sizeof(tmp)); \
54
+ return fromNative(tmp); \
55
+ } \
56
+ static VALUE memory_get_##name(VALUE self, VALUE offset); \
57
+ static VALUE \
58
+ memory_get_##name(VALUE self, VALUE offset) \
59
+ { \
60
+ AbstractMemory* memory; \
61
+ Data_Get_Struct(self, AbstractMemory, memory); \
62
+ return memory_op_get_##name(memory, NUM2LONG(offset)); \
63
+ } \
64
+ static MemoryOp memory_op_##name = { memory_op_get_##name, memory_op_put_##name }; \
65
+ \
66
+ static VALUE memory_put_array_of_##name(VALUE self, VALUE offset, VALUE ary); \
67
+ static VALUE \
68
+ memory_put_array_of_##name(VALUE self, VALUE offset, VALUE ary) \
69
+ { \
70
+ long count = RARRAY_LEN(ary); \
71
+ long off = NUM2LONG(offset); \
72
+ AbstractMemory* memory = MEMORY(self); \
73
+ long i; \
74
+ checkBounds(memory, off, count * sizeof(type)); \
75
+ for (i = 0; i < count; i++) { \
76
+ type tmp = (type) toNative(RARRAY_PTR(ary)[i]); \
77
+ memcpy(memory->address + off + (i * sizeof(type)), &tmp, sizeof(tmp)); \
78
+ } \
79
+ return self; \
80
+ } \
81
+ static VALUE memory_get_array_of_##name(VALUE self, VALUE offset, VALUE length); \
82
+ static VALUE \
83
+ memory_get_array_of_##name(VALUE self, VALUE offset, VALUE length) \
84
+ { \
85
+ long count = NUM2LONG(length); \
86
+ long off = NUM2LONG(offset); \
87
+ AbstractMemory* memory = MEMORY(self); \
88
+ long i; \
89
+ checkBounds(memory, off, count * sizeof(type)); \
90
+ VALUE retVal = rb_ary_new2(count); \
91
+ for (i = 0; i < count; ++i) { \
92
+ type tmp; \
93
+ memcpy(&tmp, memory->address + off + (i * sizeof(type)), sizeof(tmp)); \
94
+ rb_ary_push(retVal, fromNative(tmp)); \
95
+ } \
96
+ return retVal; \
97
+ }
98
+
99
+ NUM_OP(int8, int8_t, NUM2INT, INT2NUM);
100
+ NUM_OP(uint8, uint8_t, NUM2UINT, UINT2NUM);
101
+ NUM_OP(int16, int16_t, NUM2INT, INT2NUM);
102
+ NUM_OP(uint16, uint16_t, NUM2UINT, UINT2NUM);
103
+ NUM_OP(int32, int32_t, NUM2INT, INT2NUM);
104
+ NUM_OP(uint32, uint32_t, NUM2UINT, UINT2NUM);
105
+ NUM_OP(int64, int64_t, NUM2LL, LL2NUM);
106
+ NUM_OP(uint64, uint64_t, NUM2ULL, ULL2NUM);
107
+ NUM_OP(float32, float, NUM2DBL, rb_float_new);
108
+ NUM_OP(float64, double, NUM2DBL, rb_float_new);
109
+
110
+ static inline void*
111
+ get_pointer_value(VALUE value)
112
+ {
113
+ const int type = TYPE(value);
114
+ if (type == T_DATA && rb_obj_is_kind_of(value, rbffi_PointerClass)) {
115
+ return memory_address(value);
116
+ } else if (type == T_NIL) {
117
+ return NULL;
118
+ } else if (type == T_FIXNUM) {
119
+ return (void *) (uintptr_t) FIX2INT(value);
120
+ } else if (type == T_BIGNUM) {
121
+ return (void *) (uintptr_t) NUM2ULL(value);
122
+ } else if (rb_respond_to(value, id_to_ptr)) {
123
+ return MEMORY_PTR(rb_funcall2(value, id_to_ptr, 0, NULL));
124
+ } else {
125
+ rb_raise(rb_eArgError, "value is not a pointer");
126
+ }
127
+ }
128
+
129
+ NUM_OP(pointer, void *, get_pointer_value, rbffi_Pointer_NewInstance);
130
+
131
+ static VALUE
132
+ memory_put_callback(VALUE self, VALUE offset, VALUE proc, VALUE cbInfo)
133
+ {
134
+ AbstractMemory* memory = MEMORY(self);
135
+ long off = NUM2LONG(offset);
136
+ checkBounds(memory, off, sizeof(void *));
137
+
138
+ if (rb_obj_is_kind_of(proc, rb_cProc) || rb_respond_to(proc, id_call)) {
139
+ VALUE callback = rbffi_NativeCallback_ForProc(proc, cbInfo);
140
+ void* code = ((NativeCallback *) DATA_PTR(callback))->code;
141
+ memcpy(memory->address + off, &code, sizeof(code));
142
+ } else {
143
+ rb_raise(rb_eArgError, "parameter is not a proc");
144
+ }
145
+
146
+ return self;
147
+ }
148
+
149
+ static VALUE
150
+ memory_clear(VALUE self)
151
+ {
152
+ AbstractMemory* ptr = MEMORY(self);
153
+ memset(ptr->address, 0, ptr->size);
154
+ return self;
155
+ }
156
+
157
+ static VALUE
158
+ memory_size(VALUE self)
159
+ {
160
+ return LONG2FIX((MEMORY(self))->size);
161
+ }
162
+
163
+ static VALUE
164
+ memory_get_string(int argc, VALUE* argv, VALUE self)
165
+ {
166
+ VALUE length = Qnil, offset = Qnil;
167
+ AbstractMemory* ptr = MEMORY(self);
168
+ long off, len;
169
+ char* end;
170
+ int nargs = rb_scan_args(argc, argv, "11", &offset, &length);
171
+
172
+ off = NUM2LONG(offset);
173
+ len = nargs > 1 && length != Qnil ? NUM2LONG(length) : (ptr->size - off);
174
+ checkBounds(ptr, off, len);
175
+ end = memchr(ptr->address + off, 0, len);
176
+ return rb_tainted_str_new((char *) ptr->address + off,
177
+ (end != NULL ? end - ptr->address - off : len));
178
+ }
179
+
180
+ static VALUE
181
+ memory_get_array_of_string(int argc, VALUE* argv, VALUE self)
182
+ {
183
+ VALUE offset = Qnil, countnum = Qnil, retVal = Qnil;
184
+ AbstractMemory* ptr;
185
+ long off;
186
+ int count;
187
+
188
+ rb_scan_args(argc, argv, "11", &offset, &countnum);
189
+ off = NUM2LONG(offset);
190
+ count = (countnum == Qnil ? 0 : NUM2INT(countnum));
191
+ retVal = rb_ary_new2(count);
192
+
193
+ Data_Get_Struct(self, AbstractMemory, ptr);
194
+
195
+ if (countnum != Qnil) {
196
+ int i;
197
+
198
+ checkBounds(ptr, off, count * sizeof (char*));
199
+
200
+ for (i = 0; i < count; ++i) {
201
+ const char* strptr = *((const char**) (ptr->address + off) + i);
202
+ rb_ary_push(retVal, (strptr == NULL ? Qnil : rb_tainted_str_new2(strptr)));
203
+ }
204
+
205
+ } else {
206
+ checkBounds(ptr, off, sizeof (char*));
207
+ for ( ; off < ptr->size - sizeof (void *); off += sizeof (void *)) {
208
+ const char* strptr = *(const char**) (ptr->address + off);
209
+ if (strptr == NULL) {
210
+ break;
211
+ }
212
+ rb_ary_push(retVal, rb_tainted_str_new2(strptr));
213
+ }
214
+ }
215
+
216
+ return retVal;
217
+ }
218
+
219
+ static VALUE
220
+ memory_put_string(VALUE self, VALUE offset, VALUE str)
221
+ {
222
+ AbstractMemory* ptr = MEMORY(self);
223
+ long off, len;
224
+
225
+ Check_Type(str, T_STRING);
226
+ off = NUM2LONG(offset);
227
+ len = RSTRING_LEN(str);
228
+
229
+ checkBounds(ptr, off, len + 1);
230
+ if (rb_safe_level() >= 1 && OBJ_TAINTED(str)) {
231
+ rb_raise(rb_eSecurityError, "Writing unsafe string to memory");
232
+ }
233
+ memcpy(ptr->address + off, RSTRING_PTR(str), len);
234
+ *((char *) ptr->address + off + len) = '\0';
235
+ return self;
236
+ }
237
+
238
+ static VALUE
239
+ memory_get_bytes(VALUE self, VALUE offset, VALUE length)
240
+ {
241
+ AbstractMemory* ptr = MEMORY(self);
242
+ long off, len;
243
+
244
+ off = NUM2LONG(offset);
245
+ len = NUM2LONG(length);
246
+ checkBounds(ptr, off, len);
247
+ return rb_tainted_str_new((char *) ptr->address + off, len);
248
+ }
249
+
250
+ static VALUE
251
+ memory_put_bytes(int argc, VALUE* argv, VALUE self)
252
+ {
253
+ AbstractMemory* ptr = MEMORY(self);
254
+ VALUE offset = Qnil, str = Qnil, rbIndex = Qnil, rbLength = Qnil;
255
+ long off, len, idx;
256
+ int nargs = rb_scan_args(argc, argv, "22", &offset, &str, &rbIndex, &rbLength);
257
+
258
+ Check_Type(str, T_STRING);
259
+
260
+ off = NUM2LONG(offset);
261
+ idx = nargs > 2 ? NUM2LONG(rbIndex) : 0;
262
+ if (idx < 0) {
263
+ rb_raise(rb_eRangeError, "index canot be less than zero");
264
+ }
265
+ len = nargs > 3 ? NUM2LONG(rbLength) : (RSTRING_LEN(str) - idx);
266
+ if ((idx + len) > RSTRING_LEN(str)) {
267
+ rb_raise(rb_eRangeError, "index+length is greater than size of string");
268
+ }
269
+ checkBounds(ptr, off, len);
270
+ if (rb_safe_level() >= 1 && OBJ_TAINTED(str)) {
271
+ rb_raise(rb_eSecurityError, "Writing unsafe string to memory");
272
+ }
273
+ memcpy(ptr->address + off, RSTRING_PTR(str) + idx, len);
274
+ return self;
275
+ }
276
+
277
+ static inline char*
278
+ memory_address(VALUE obj)
279
+ {
280
+ return ((AbstractMemory *) DATA_PTR(obj))->address;
281
+ }
282
+
283
+ AbstractMemory*
284
+ rbffi_AbstractMemory_Cast(VALUE obj, VALUE klass)
285
+ {
286
+ if (rb_obj_is_kind_of(obj, klass)) {
287
+ AbstractMemory* memory;
288
+ Data_Get_Struct(obj, AbstractMemory, memory);
289
+ return memory;
290
+ }
291
+
292
+ rb_raise(rb_eArgError, "Invalid Memory object");
293
+ return NULL;
294
+ }
295
+
296
+ static VALUE
297
+ memory_op_get_strptr(AbstractMemory* ptr, long offset)
298
+ {
299
+ void* tmp = NULL;
300
+
301
+ if (ptr != NULL && ptr->address != NULL) {
302
+ checkBounds(ptr, offset, sizeof(tmp));
303
+ memcpy(&tmp, ptr->address + offset, sizeof(tmp));
304
+ }
305
+
306
+ return tmp != NULL ? rb_tainted_str_new2(tmp) : Qnil;
307
+ }
308
+
309
+ static void
310
+ memory_op_put_strptr(AbstractMemory* ptr, long offset, VALUE value)
311
+ {
312
+ rb_raise(rb_eArgError, "Cannot set :string fields");
313
+ }
314
+
315
+ static MemoryOp memory_op_strptr = { memory_op_get_strptr, memory_op_put_strptr };
316
+
317
+ //static MemoryOp memory_op_pointer = { memory_op_get_pointer, memory_op_put_pointer };
318
+
319
+ MemoryOps rbffi_AbstractMemoryOps = {
320
+ .int8 = &memory_op_int8,
321
+ .uint8 = &memory_op_uint8,
322
+ .int16 = &memory_op_int16,
323
+ .uint16 = &memory_op_uint16,
324
+ .int32 = &memory_op_int32,
325
+ .uint32 = &memory_op_uint32,
326
+ .int64 = &memory_op_int64,
327
+ .uint64 = &memory_op_uint64,
328
+ .float32 = &memory_op_float32,
329
+ .float64 = &memory_op_float64,
330
+ .pointer = &memory_op_pointer,
331
+ .strptr = &memory_op_strptr,
332
+ };
333
+
334
+ void
335
+ rbffi_AbstractMemory_Init(VALUE moduleFFI)
336
+ {
337
+ VALUE classMemory = rb_define_class_under(moduleFFI, "AbstractMemory", rb_cObject);
338
+ rbffi_AbstractMemoryClass = classMemory;
339
+ rb_global_variable(&rbffi_AbstractMemoryClass);
340
+
341
+ rb_define_alloc_func(classMemory, memory_allocate);
342
+ #undef INT
343
+ #define INT(type) \
344
+ rb_define_method(classMemory, "put_" #type, memory_put_##type, 2); \
345
+ rb_define_method(classMemory, "get_" #type, memory_get_##type, 1); \
346
+ rb_define_method(classMemory, "put_u" #type, memory_put_u##type, 2); \
347
+ rb_define_method(classMemory, "get_u" #type, memory_get_u##type, 1); \
348
+ rb_define_method(classMemory, "put_array_of_" #type, memory_put_array_of_##type, 2); \
349
+ rb_define_method(classMemory, "get_array_of_" #type, memory_get_array_of_##type, 2); \
350
+ rb_define_method(classMemory, "put_array_of_u" #type, memory_put_array_of_u##type, 2); \
351
+ rb_define_method(classMemory, "get_array_of_u" #type, memory_get_array_of_u##type, 2);
352
+
353
+ INT(int8);
354
+ INT(int16);
355
+ INT(int32);
356
+ INT(int64);
357
+
358
+ #define ALIAS(name, old) \
359
+ rb_define_alias(classMemory, "put_" #name, "put_" #old); \
360
+ rb_define_alias(classMemory, "get_" #name, "get_" #old); \
361
+ rb_define_alias(classMemory, "put_u" #name, "put_u" #old); \
362
+ rb_define_alias(classMemory, "get_u" #name, "get_u" #old); \
363
+ rb_define_alias(classMemory, "put_array_of_" #name, "put_array_of_" #old); \
364
+ rb_define_alias(classMemory, "get_array_of_" #name, "get_array_of_" #old); \
365
+ rb_define_alias(classMemory, "put_array_of_u" #name, "put_array_of_u" #old); \
366
+ rb_define_alias(classMemory, "get_array_of_u" #name, "get_array_of_u" #old);
367
+
368
+ ALIAS(char, int8);
369
+ ALIAS(short, int16);
370
+ ALIAS(int, int32);
371
+ ALIAS(long_long, int64);
372
+
373
+ if (sizeof(long) == 4) {
374
+ ALIAS(long, int32);
375
+ } else {
376
+ ALIAS(long, int64);
377
+ }
378
+
379
+ rb_define_method(classMemory, "put_float32", memory_put_float32, 2);
380
+ rb_define_method(classMemory, "get_float32", memory_get_float32, 1);
381
+ rb_define_alias(classMemory, "put_float", "put_float32");
382
+ rb_define_alias(classMemory, "get_float", "get_float32");
383
+ rb_define_method(classMemory, "put_array_of_float32", memory_put_array_of_float32, 2);
384
+ rb_define_method(classMemory, "get_array_of_float32", memory_get_array_of_float32, 2);
385
+ rb_define_alias(classMemory, "put_array_of_float", "put_array_of_float32");
386
+ rb_define_alias(classMemory, "get_array_of_float", "get_array_of_float32");
387
+ rb_define_method(classMemory, "put_float64", memory_put_float64, 2);
388
+ rb_define_method(classMemory, "get_float64", memory_get_float64, 1);
389
+ rb_define_alias(classMemory, "put_double", "put_float64");
390
+ rb_define_alias(classMemory, "get_double", "get_float64");
391
+ rb_define_method(classMemory, "put_array_of_float64", memory_put_array_of_float64, 2);
392
+ rb_define_method(classMemory, "get_array_of_float64", memory_get_array_of_float64, 2);
393
+ rb_define_alias(classMemory, "put_array_of_double", "put_array_of_float64");
394
+ rb_define_alias(classMemory, "get_array_of_double", "get_array_of_float64");
395
+ rb_define_method(classMemory, "put_pointer", memory_put_pointer, 2);
396
+ rb_define_method(classMemory, "get_pointer", memory_get_pointer, 1);
397
+ rb_define_method(classMemory, "put_array_of_pointer", memory_put_array_of_pointer, 2);
398
+ rb_define_method(classMemory, "get_array_of_pointer", memory_get_array_of_pointer, 2);
399
+ rb_define_method(classMemory, "put_callback", memory_put_callback, 3);
400
+ rb_define_method(classMemory, "get_string", memory_get_string, -1);
401
+ rb_define_method(classMemory, "put_string", memory_put_string, 2);
402
+ rb_define_method(classMemory, "get_bytes", memory_get_bytes, 2);
403
+ rb_define_method(classMemory, "put_bytes", memory_put_bytes, -1);
404
+ rb_define_method(classMemory, "get_array_of_string", memory_get_array_of_string, -1);
405
+
406
+ rb_define_method(classMemory, "clear", memory_clear, 0);
407
+ rb_define_method(classMemory, "total", memory_size, 0);
408
+
409
+ id_to_ptr = rb_intern("to_ptr");
410
+ id_call = rb_intern("call");
411
+ }
412
+